OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [WizNET_DEMO_TERN_186/] [tern_code/] [socket.c] - Blame information for rev 585

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 585 jeremybenn
/*
2
********************************************************************************
3
* TERN, Inc.
4
* (c) Copyright 2005, http://www.tern.com
5
*
6
* MODIFIED BY RICHARD BARRY TO ADD SEMAPHORE FOR COMMUNICATION BETWEEN THE
7
* WIZnet ISR AND THE HTTP TASK.
8
*
9
* - Derived based on development version provided by Wiznet.
10
*
11
* Filename : socket.h
12
* Programmer(s):
13
* Created : 2002/06/20
14
* Modified :
15
*  2002/09/27 : - Renaming
16
*                              INT_STATUS --> INT_REG
17
*                              STATUS(i) --> INT_STATUS(i)
18
*                              C_STATUS(i) --> SOCK_STATUS(i)
19
*  2003/11/06 : Ported for use with TERN controller.  Note all byte access is at even addresses
20
*  2005/10/8  : Modified constants for easier initialization.
21
*
22
* Description : Header file of W3100A for TERN embedded controller
23
********************************************************************************
24
*/
25
/*
26
###############################################################################
27
File Include Section
28
###############################################################################
29
*/
30
#include "i2chip_hw.h" 
31
#include "socket.h"
32
#include "types.h"
33
#include <string.h>
34
#include <stdio.h>
35
 
36
#include <FreeRTOS.h>
37
#include <semphr.h>
38
#include <portasm.h>
39
 
40
 
41
/*
42
###############################################################################
43
Local Variable Declaration Section
44
###############################################################################
45
*/
46
u_char I_STATUS[4];                             // Store Interrupt Status according to channels
47
u_int Local_Port;                                  // Designate Local Port
48
union un_l2cval SEQ_NUM;                // Set initial sequence number
49
 
50
u_long SMASK[MAX_SOCK_NUM];   // Variable to store MASK of Tx in each channel,
51
                              // on setting dynamic memory size.
52
u_long RMASK[MAX_SOCK_NUM];   // Variable to store MASK of Rx in each channel,
53
                              // on setting dynamic memory size.
54
int SSIZE[MAX_SOCK_NUM];      // Maximun Tx memory size by each channel
55
int RSIZE[MAX_SOCK_NUM];      // Maximun Rx memory size by each channel
56
 
57
u_int SBUFBASEADDRESS[MAX_SOCK_NUM];   // Maximun Tx memory base address by each channel
58
u_int RBUFBASEADDRESS[MAX_SOCK_NUM];   // Maximun Rx memory base address by each channel
59
 
60
/*
61
###############################################################################
62
Function Implementation Section
63
###############################################################################
64
*/
65
 
66
/*
67
********************************************************************************
68
*               Interrupt handling function of the W3100A
69
*
70
* Description :
71
*   Stores the status information that each function waits for in the global variable I_STATUS
72
*   for transfer. I_STATUS stores the interrupt status value for each channel.
73
* Arguments   : None
74
* Returns     : None
75
* Note        : Internal Function
76
********************************************************************************
77
*/
78
 
79
portBASE_TYPE prvProcessISR( void )
80
{
81
unsigned char status;
82
extern xSemaphoreHandle xTCPSemaphore;
83
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
84
 
85
#ifdef I2CHIP_WINDOW
86
u_int current_window = i2chip_get_window();
87
#endif
88
 
89
status = READ_VALUE(INT_REG);
90
 
91
 
92
if (status)
93
  {
94
  xHigherPriorityTaskWoken = pdTRUE;
95
  // channel 0 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)
96
  if (status & 0x01)
97
    {
98
         I_STATUS[0] = READ_VALUE(INT_STATUS(0));
99
 
100
//       if (I_STATUS[0] & SESTABLISHED)
101
//    ISR_ESTABLISHED(0);
102
//       if (I_STATUS[0] & SCLOSED)
103
//    ISR_CLOSED(0);
104
 
105
         WRITE_VALUE(INT_REG, 0x01);
106
         }
107
 
108
  // channel 1 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)
109
  if (status & 0x02)
110
    {
111
         I_STATUS[1] = READ_VALUE(INT_STATUS(1));
112
 
113
//       if (I_STATUS[1] & SESTABLISHED)
114
//    ISR_ESTABLISHED(1);
115
//       if (I_STATUS[1] & SCLOSED)
116
//    ISR_CLOSED(1);
117
 
118
         WRITE_VALUE(INT_REG, 0x02);
119
         }
120
 
121
  // channel 2 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)
122
  if (status & 0x04)
123
    {
124
         I_STATUS[2] = READ_VALUE(INT_STATUS(2));
125
 
126
//       if (I_STATUS[2] & SESTABLISHED)
127
//    ISR_ESTABLISHED(2);
128
//       if (I_STATUS[2] & SCLOSED)
129
//    ISR_CLOSED(2);
130
 
131
         WRITE_VALUE(INT_REG, 0x04);
132
         }
133
 
134
  // channel 3 interrupt(sysinit, sockinit, established, closed, timeout, send_ok, recv_ok)
135
  if (status & 0x08)
136
    {
137
         I_STATUS[3] = READ_VALUE(INT_STATUS(3));
138
 
139
//       if (I_STATUS[3] & SESTABLISHED) ISR_ESTABLISHED(3);
140
//       if (I_STATUS[3] & SCLOSED) ISR_CLOSED(3);
141
 
142
         WRITE_VALUE(INT_REG, 0x08);
143
         }
144
 
145
  // channel 0 receive interrupt
146
  if (status & 0x10)
147
    {
148
//       ISR_RX(0);
149
         WRITE_VALUE(INT_REG, 0x10);
150
         }
151
 
152
  // channel 1 receive interrupt
153
  if (status & 0x20)
154
    {
155
//       ISR_RX(1);
156
         WRITE_VALUE(INT_REG, 0x20);
157
         }
158
 
159
  // channel 2 receive interrupt
160
  if (status & 0x40)
161
    {
162
//       ISR_RX(2);
163
         WRITE_VALUE(INT_REG, 0x40);
164
         }
165
 
166
  // channel 3 receive interrupt
167
  if (status & 0x80)
168
    {
169
//       ISR_RX(3);
170
         WRITE_VALUE(INT_REG, 0x80);
171
         }
172
  status = READ_VALUE(INT_REG);
173
  }
174
 
175
WRITE_VALUE(INT_REG, 0xFF);
176
 
177
#ifdef I2CHIP_WINDOW
178
i2chip_set_window(current_window);
179
#endif
180
 
181
        if( xHigherPriorityTaskWoken == pdTRUE )
182
    {
183
                xSemaphoreGiveFromISR( xTCPSemaphore, &xHigherPriorityTaskWoken );
184
    }
185
 
186
        return xHigherPriorityTaskWoken;
187
}
188
 
189
void far interrupt in4_isr_i2chip(void)
190
{
191
        if( prvProcessISR() == pdTRUE )
192
    {
193
                portEND_SWITCHING_ISR();
194
    }
195
 
196
    INT_EOI;
197
}
198
 
199
/*
200
****************************************************************************************************
201
*               Established connection interrupt handling function.
202
*
203
* Description :
204
*   Called upon connection establishment, and may be inserted in user code if needed by
205
*   the programmer.
206
* Arguments   : None
207
* Returns     : None
208
* Note        : Internal Function
209
****************************************************************************************************
210
*/
211
/*
212
void ISR_ESTABLISHED(SOCKET s)
213
{
214
// TO ADD YOUR CODE
215
}
216
*/
217
 
218
/*
219
****************************************************************************************************
220
*               Closed connection interrupt handling function
221
*
222
* Description :
223
*   Called upon connection closure, and may be inserted in user code if needed by the programmer.
224
* Arguments   : None
225
* Returns     : None
226
* Note        : Internal Function
227
****************************************************************************************************
228
*/
229
/*
230
void ISR_CLOSED(SOCKET s)
231
{
232
// TO ADD YOUR CODE
233
}
234
*/
235
 
236
/*
237
****************************************************************************************************
238
*               Received data interrupt handling function
239
*
240
* Description :
241
*   Called upon receiving data, and may be inserted in user code if needed by the programmer.
242
* Arguments   : None
243
* Returns     : None
244
* Note        : Internal Function
245
****************************************************************************************************
246
*/
247
/*
248
void ISR_RX(SOCKET s)
249
{
250
// TO ADD YOUR CODE
251
}
252
*/
253
 
254
/*
255
****************************************************************************************************
256
*              W3100A Initialization Function
257
*
258
* Description:  Reset of W3100A S/W and Registeration of i386 interrupt
259
* Arguments  : None.
260
* Returns    : None.
261
* Note       :
262
****************************************************************************************************
263
*/
264
void initW3100A(void)
265
{
266
 
267
// Install interrupt handler for i2Chip
268
INT_INIT(in4_isr_i2chip);
269
 
270
 
271
Local_Port = 1000;         // This default value will be set if you didn't designate it when you
272
                           // create a socket. If you don't designate port number and create a
273
                           // socket continuously, the port number will be assigned with
274
                           // incremented by one to Local_Port
275
SEQ_NUM.lVal = 4294967293ul;    // Sets the initial SEQ# to be used for TCP communication.
276
                           // (It should be ramdom value)
277
WRITE_VALUE(COMMAND(0), CSW_RESET);   // Software RESET
278
}
279
 
280
/*
281
****************************************************************************************************
282
*               W3100A initialization function
283
*
284
* Description :
285
*   Sets the Tx, Rx memory size by each channel, source MAC, source IP, gateway, and subnet mask
286
*   to be used by the W3100A to the designated values.
287
*   May be called when reflecting modified network information or Tx, Rx memory size on the W3100A
288
*   Include Ping Request for ARP update (In case that a device embedding W3100A is directly
289
*     connected to Router)
290
* Arguments  : sbufsize - Tx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)
291
*                          bit 1-0 : Tx memory size of channel #0
292
*                          bit 3-2 : Tx memory size of channel #1
293
*                          bit 5-4 : Tx memory size of channel #2
294
*                          bit 7-6 : Tx memory size of channel #3
295
*              rbufsize - Rx memory size (00 - 1KByte, 01- 2KBtye, 10 - 4KByte, 11 - 8KByte)
296
*                          bit 1-0 : Rx memory size of channel #0
297
*                          bit 3-2 : Rx memory size of channel #1
298
*                          bit 5-4 : Rx memory size of channel #2
299
*                          bit 7-6 : Rx memory size of channel #3
300
* Returns    : None
301
* Note       : API Function
302
*              Maximum memory size for Tx, Rx in W3100A is 8KBytes,
303
*              In the range of 8KBytes, the memory size could be allocated dynamically by
304
*              each channel
305
*              Be attentive to sum of memory size shouldn't exceed 8Kbytes
306
*              and to data transmission and receiption from non-allocated channel may cause
307
*              some problems.
308
*              If 8KBytes memory already is assigned to centain channel, other 3 channels
309
*                couldn't be used, for there's no available memory.
310
*              If two 4KBytes memory are assigned to two each channels, other 2 channels couldn't
311
*                be used, for there's no available memory.
312
*              (Example of memory assignment)
313
*               sbufsize => 00000011, rbufsize => 00000011 :
314
*                 Assign 8KBytes for Tx and Rx to channel #0, Cannot use channel #1,#2,#3
315
*               sbufsize => 00001010, rbufsize => 00001010 :
316
*                 Assign 4KBytes for Tx and Rx to each channel #0,#1 respectively. Cannot use
317
*                 channel #2,#3
318
*               sbufsize => 01010101, rbufsize => 01010101 :
319
*                 Assign 2KBytes for Tx and Rx to each all channels respectively.
320
*               sbufsize => 00010110, rbufsize => 01010101 :
321
*                 Assign 4KBytes for Tx, 2KBytes for Rx to channel #0
322
*       s          2KBytes for Tx, 2KBytes for Rx to channel #1
323
*                 2KBytes for Tx, 2KBytes for Rx to channel #2
324
*                 2KBytes is available exclusively for Rx in channel #3. There's no memory for Tx.
325
****************************************************************************************************
326
*/
327
void sysinit(u_char sbufsize, u_char rbufsize)
328
{
329
char i;
330
int ssum,rsum;
331
 
332
ssum = 0;
333
rsum = 0;
334
 
335
// Set Tx memory size for each channel
336
WRITE_VALUE(TX_DMEM_SIZE, sbufsize);
337
 
338
// Set Rx memory size for each channel
339
WRITE_VALUE(RX_DMEM_SIZE, rbufsize);
340
 
341
// Set Base Address of Tx memory for channel #0
342
SBUFBASEADDRESS[0] = 0;
343
 
344
// Set Base Address of Rx memory for channel #0
345
RBUFBASEADDRESS[0] = 0;
346
 
347
// Set maximum memory size for Tx and Rx, mask, base address of memory by each channel
348
for(i = 0 ; i < MAX_SOCK_NUM; i++)
349
  {
350
  SSIZE[i] = 0;
351
  RSIZE[i] = 0;
352
  if(ssum < 8192)
353
         {
354
         switch((sbufsize >> i*2) & 0x03) // Set maximum Tx memory size
355
                {
356
                case 0:
357
                  SSIZE[i] = 1024;
358
                  SMASK[i] = 0x000003FF;
359
                  break;
360
 
361
                case 1:
362
                  SSIZE[i] = 2048;
363
                  SMASK[i] = 0x000007FF;
364
                  break;
365
 
366
                case 2:
367
                  SSIZE[i] = 4096;
368
                  SMASK[i] = 0x00000FFF;
369
                  break;
370
 
371
                case 3:
372
                  SSIZE[i] = 8192;
373
                  SMASK[i] = 0x00001FFF;
374
                  break;
375
                }
376
         }
377
  if(rsum < 8192)
378
         {
379
         switch((rbufsize >> i*2) & 0x03)  // Set maximum Rx memory size
380
                {
381
                case 0:
382
                  RSIZE[i] = 1024;
383
                  RMASK[i] = 0x000003FF;
384
                  break;
385
 
386
                case 1:
387
                  RSIZE[i] = 2048;
388
                  RMASK[i] = 0x000007FF;
389
                  break;
390
 
391
                case 2:
392
                  RSIZE[i] = 4096;
393
                  RMASK[i] = 0x00000FFF;
394
                  break;
395
 
396
                case 3:
397
                  RSIZE[i] = 8192;
398
                  RMASK[i] = 0x00001FFF;
399
                  break;
400
                }
401
         }
402
  ssum += SSIZE[i];
403
  rsum += RSIZE[i];
404
 
405
  // Set base address of Tx and Rx memory for channel #1,#2,#3
406
  if(i != 0)
407
    {
408
    SBUFBASEADDRESS[i] = ssum - SSIZE[i];
409
    RBUFBASEADDRESS[i] = rsum - RSIZE[i];
410
    }
411
  }
412
 
413
  WRITE_VALUE(COMMAND(0), CSYS_INIT);
414
 
415
while(!(I_STATUS[0] & SSYS_INIT_OK))
416
  I2CHIP_POLL_ISR(in4_isr_i2chip);
417
 
418
#ifdef __PING__
419
  {
420
  u_char xdata pingbuf[8];
421
  setIPprotocol(0, IPPROTO_ICMP);
422
  socket(0, SOCK_IPL_RAW, 3000,0);     // Create a socket for ARP update
423
 
424
  pingbuf[0] = 8;                      // ICMP TYPE
425
  pingbuf[1] = 0;                      // ICMP CODE
426
  pingbuf[2] = 0xf7;                   // CHECKSUM (already calculated)
427
  pingbuf[3] = 0xfd;
428
  pingbuf[4] = 0;                      // ID
429
  pingbuf[5] = 1;
430
  pingbuf[6] = 0;                      // SEQ #
431
  pingbuf[7] = 1;
432
  pingbuf[8] = 0;                      // Data 1 Byte
433
 
434
  sendto(0, pingbuf, 9, GATEWAY_PTR,3000);  // Ping Request
435
  close(0);
436
  printf("Route MAC Update Success");
437
  }
438
#endif
439
}
440
 
441
/*
442
****************************************************************************************************
443
*              Function to set subnet mask
444
*
445
* Description:
446
* Arguments  : addr--> Pointer that has the value to be set
447
* Returns    : None.
448
* Note       :
449
****************************************************************************************************
450
*/
451
void setsubmask(u_char * addr)
452
{
453
u_char i;
454
u_char far* sm_ptr = SUBNET_MASK_PTR;   // We can only convert to 'regular'
455
                                   // pointer if we're confident arithmetic
456
                                   // won't take us out of current window.
457
 
458
for (i = 0; i < 4; i++)
459
  {
460
  WRITE_VALUE(sm_ptr + SA_OFFSET(i), addr[i]);
461
  }
462
}
463
 
464
/*
465
****************************************************************************************************
466
*               Function to set gateway IP
467
*
468
* Description:
469
* Arguments  : addr--> Pointer that has Gateway IP to be set
470
* Returns    : None.
471
* Note       :
472
****************************************************************************************************
473
*/
474
void setgateway(u_char * addr)
475
{
476
u_char i;
477
u_char far* gw_ptr = GATEWAY_PTR;   // We can only convert to 'regular'
478
                                   // pointer if we're confident arithmetic
479
                                   // won't take us out of current window.
480
for (i = 0; i < 4; i++)
481
  {
482
  WRITE_VALUE(gw_ptr + SA_OFFSET(i), addr[i]);
483
  }
484
}
485
 
486
/*
487
****************************************************************************************************
488
*                 Function to set W3100A IP
489
*
490
* Description:
491
* Arguments  : addr--> Pointer that has Source IP to be set
492
* Returns    : None.
493
* Note       :
494
****************************************************************************************************
495
*/
496
void setIP(u_char * addr)
497
{
498
u_char i;
499
u_char far* src_ptr = SRC_IP_PTR;   // We can only convert to 'regular'
500
                                   // pointer if we're confident arithmetic
501
                                   // won't take us out of current window.
502
 
503
for (i = 0; i < 4; i++)
504
  {
505
  WRITE_VALUE(src_ptr + SA_OFFSET(i), addr[i]);
506
  }
507
}
508
 
509
// DEBUG
510
void getIP(u_char* addr)
511
{
512
u_char i;
513
u_char far* src_ptr = SRC_IP_PTR;   // We can only convert to 'regular'
514
                                   // pointer if we're confident arithmetic
515
                                   // won't take us out of current window.
516
 
517
for (i = 0; i < 4; i++)
518
        addr[i] = READ_VALUE(src_ptr + SA_OFFSET(i));
519
}
520
 
521
 
522
/*
523
****************************************************************************************************
524
*                Function to set MAC
525
*
526
* Description:
527
* Arguments  : addr--> Pointer that has MAC to be set
528
* Returns    : None.
529
* Note       :
530
****************************************************************************************************
531
*/
532
void setMACAddr(u_char * addr)
533
{
534
u_char i;
535
u_char far* ha_ptr = SRC_HA_PTR;   // We can only convert to 'regular'
536
                                   // pointer if we're confident arithmetic
537
                                   // won't take us out of current window.
538
 
539
for (i = 0; i < 6; i++)
540
  {
541
  WRITE_VALUE(ha_ptr + SA_OFFSET(i), addr[i]);
542
  }
543
}
544
 
545
/*
546
****************************************************************************************************
547
*                  Function to set TCP timeout
548
*
549
* Description: The function that used to adjust time to resend TCP
550
* Arguments  : val      --> Pointer that has the value to be set
551
*                                       Upper 2 byte:Initial timeout value
552
*                                       Last 1 byte:The count to retry till timeout
553
* Returns    : None.
554
* Note       :
555
****************************************************************************************************
556
*/
557
void settimeout(u_char * val)
558
{
559
u_char i;
560
u_char far* tout_ptr = TIMEOUT_PTR;   // We can only convert to 'regular'
561
                                   // pointer if we're confident arithmetic
562
                                   // won't take us out of current window.
563
 
564
for (i = 0; i < 3; i++)
565
  {
566
  WRITE_VALUE(tout_ptr + SA_OFFSET(i), val[i]);
567
  }
568
}
569
 
570
/*
571
****************************************************************************************************
572
*                 Function to set interrupt mask.
573
*
574
* Description:
575
* Arguments  : mask--> Mask value to be set ('1'-> interrupt )
576
* Returns    : None.
577
* Note       :
578
****************************************************************************************************
579
*/
580
void setINTMask(u_char mask)
581
{
582
WRITE_VALUE(INTMASK, mask);
583
}
584
 
585
/*
586
****************************************************************************************************
587
*                  Function to set enable in sending and receiving of broadcast data
588
*
589
* Description:  Enable to process of broadcating data in UDP or IP RAW mode.
590
* Arguments  : s        --> Channel No. to be set
591
* Returns    : None.
592
* Note       :
593
****************************************************************************************************
594
*/
595
void setbroadcast(SOCKET s)
596
{
597
u_char val = READ_VALUE(OPT_PROTOCOL(s));
598
WRITE_VALUE(OPT_PROTOCOL(s), val | SOCKOPT_BROADCAST);
599
}
600
 
601
/*
602
****************************************************************************************************
603
*                Function to set process protocol  in IP RAW mode.
604
*
605
* Description:
606
* Arguments  : s--> Channel No. to be set
607
*               tos-->Protocol Value to be set
608
* Returns    : None.
609
* Note       :
610
****************************************************************************************************
611
*/
612
void setTOS(SOCKET s, u_char tos)
613
{
614
WRITE_VALUE(TOS(s), tos);
615
}
616
 
617
/*
618
****************************************************************************************************
619
*               Upper layer protocol setup function in IP RAW Mode
620
*
621
* Description : Upper layer protocol setup function in protocol field of IP header when
622
*                    developing upper layer protocol like ICMP, IGMP, EGP etc. by using IP Protocol
623
* Arguments   : s          - Channel number
624
*               ipprotocol - Upper layer protocol setting value of IP Protocol
625
*                            (Possible to use designated IPPROTO_ in header file)
626
* Returns     : None
627
* Note        : API Function
628
*                  This function should be called before calling socket() that is, before
629
*                  socket initialization.
630
****************************************************************************************************
631
*/
632
void setIPprotocol(SOCKET s, u_char ipprotocol)
633
{
634
WRITE_VALUE(IP_PROTOCOL(s), ipprotocol);
635
}
636
 
637
/*
638
****************************************************************************************************
639
*              Initialization function to appropriate channel
640
*
641
* Description : Initialize designated channel and wait until W3100 has done.
642
* Arguments   : s - channel number
643
*               protocol - designate protocol for channel
644
*                          SOCK_STREAM(0x01) -> TCP.
645
*                          SOCK_DGRAM(0x02)  -> UDP.
646
*                          SOCK_IPL_RAW(0x03) -> IP LAYER RAW.
647
*                          SOCK_MACL_RAW(0x04) -> MAC LAYER RAW.
648
*               port     - designate source port for appropriate channel
649
*               flag     - designate option to be used in appropriate.
650
*                          SOCKOPT_BROADCAST(0x80) -> Send/receive broadcast message in UDP
651
*                          SOCKOPT_NDTIMEOUT(0x40) -> Use register value which designated TIMEOUT
652
*                            value
653
*                          SOCKOPT_NDACK(0x20)     -> When not using no delayed ack
654
*                          SOCKOPT_SWS(0x10)       -> When not using silly window syndrome
655
* Returns     : When succeeded : Channel number, failed :-1
656
* Note        : API Function
657
****************************************************************************************************
658
*/
659
char socket(SOCKET s, u_char protocol, u_int port, u_char flag)
660
{
661
u_char k;
662
 
663
//Designate socket protocol and option
664
WRITE_VALUE(OPT_PROTOCOL(s), protocol | flag);
665
 
666
// setup designated port number
667
if (port != 0)
668
  {
669
  k = (u_char)((port & 0xff00) >> 8);
670
  WRITE_VALUE(SRC_PORT_PTR(s), k);
671
  k = (u_char)(port & 0x00ff);
672
  WRITE_VALUE(SRC_PORT_PTR(s) + SA_OFFSET(1), k);
673
  }
674
else
675
  {
676
  // Designate random port number which is managed by local when you didn't designate source port
677
  Local_Port++;
678
 
679
  WRITE_VALUE(SRC_PORT_PTR(s), (u_char)((Local_Port & 0xff00) >> 8));
680
  WRITE_VALUE(SRC_PORT_PTR(s) + SA_OFFSET(1), (u_char)(Local_Port & 0x00ff));
681
  }
682
 
683
// SOCK_INIT
684
I_STATUS[s] = 0;
685
WRITE_VALUE(COMMAND(s), CSOCK_INIT);
686
 
687
// Waiting Interrupt to CSOCK_INIT
688
while (I_STATUS[s] == 0)
689
        I2CHIP_POLL_ISR(in4_isr_i2chip);
690
 
691
if (!(I_STATUS[s] & SSOCK_INIT_OK))
692
  return(-1);
693
 
694
initseqnum(s);                                                  //  Use initial seq# with random number
695
 
696
return(s);
697
}
698
 
699
/*
700
****************************************************************************************************
701
*               Connection establishing function to designated peer.
702
*
703
* Description : This function establish a connection to the peer by designated channel,
704
*     and wait until the connection is established successfully. (TCP client mode)
705
* Arguments   : s    - channel number
706
*               addr - destination IP Address
707
*               port - destination Port Number
708
* Returns     : when succeeded : 1, failed : -1
709
* Note        : API Function
710
****************************************************************************************************
711
*/
712
char connect(SOCKET s, u_char far * addr, u_int port)
713
{
714
 
715
if (port != 0)
716
  {                                             //designate destination port
717
  WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));
718
  WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));
719
  }
720
else
721
  return(-1);
722
 
723
  WRITE_VALUE(DST_IP_PTR(s), addr[0]);                           //designate destination IP address
724
  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);
725
  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);
726
  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);
727
 
728
I_STATUS[s] = 0;
729
 
730
  WRITE_VALUE(COMMAND(s), CCONNECT);                                    // CONNECT
731
  I2CHIP_POLL_ISR(in4_isr_i2chip);
732
 
733
// Wait until connection is established successfully
734
while (I_STATUS[s] == 0)
735
  {
736
  // When failed, appropriate channel will be closed and return an error
737
  if (select(s, SEL_CONTROL) == SOCK_CLOSED)
738
    return -1;
739
  }
740
 
741
if (!(I_STATUS[s] & SESTABLISHED))
742
  return(-1);
743
 
744
return(1);
745
}
746
 
747
/*
748
****************************************************************************************************
749
*               Connection establishing function to designated peer. (Non-blocking Mode)
750
*
751
* Description : This function establish a connection to the peer by designated channel.
752
*
753
* Arguments   : s    - channel number
754
*               addr - destination IP Address
755
*               port - destination Port Number
756
* Returns     : when succeeded : 1, failed : -1
757
* Note        : API Function
758
****************************************************************************************************
759
*/
760
char NBconnect(SOCKET s, u_char far * addr, u_int port)
761
{
762
 
763
if (port != 0)
764
  {                                             //designate destination port
765
        WRITE_VALUE(DST_PORT_PTR(s), (u_char) ((port & 0xff00) >> 8) );
766
   WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));
767
  }
768
else
769
  return(-1);
770
 
771
  WRITE_VALUE(DST_IP_PTR(s), addr[0]);                           //designate destination IP address
772
  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);
773
  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);
774
  WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);
775
 
776
I_STATUS[s] = 0;
777
 
778
WRITE_VALUE(COMMAND(s), CCONNECT);                                      // CONNECT
779
return(1);
780
}
781
 
782
/*
783
****************************************************************************************************
784
*            Waits for connection request from a peer (Blocking Mode)
785
*
786
* Description : Wait for connection request from a peer through designated channel (TCP Server mode)
787
* Arguments   : s    - channel number
788
*               addr - IP Address of the peer when a connection is established
789
*               port - Port number of the peer when a connection is established
790
* Returns     : When succeeded : 1, failed : -1
791
* Note        : API Function
792
****************************************************************************************************
793
*/
794
/*
795
char listen(SOCKET s, u_char far * addr, u_int far * port)
796
{
797
u_int i;
798
 
799
I_STATUS[s] = 0;
800
 
801
// LISTEN
802
COMMAND(s) = CLISTEN;
803
 
804
// Wait until connection is established
805
while (I_STATUS[s] == 0)
806
  {
807
  // When failed to connect, the designated channel will be closed and return an error.
808
  if (select(s, SEL_CONTROL) == SOCK_CLOSED)
809
    return -1;
810
  }
811
 
812
// Receive IP address and port number of the peer connected
813
if (I_STATUS[s] & SESTABLISHED)
814
  {
815
  i = *DST_PORT_PTR(s);
816
  *port = (u_int)((i & 0xff00) >> 8);
817
  i = *(DST_PORT_PTR(s) + 2);
818
  i = (u_int)(i & 0x00ff);
819
  *port += (i << 8);
820
 
821
  addr[0] = *DST_IP_PTR(s);
822
  addr[1] = *(DST_IP_PTR(s) + 2);
823
  addr[2] = *(DST_IP_PTR(s) + 4);
824
  addr[3] = *(DST_IP_PTR(s) + 6);
825
  }
826
else
827
  return(-1);
828
 
829
return(1);
830
}
831
*/
832
 
833
/*
834
****************************************************************************************************
835
*                Waits for connection request from a peer (Non-blocking Mode)
836
*
837
* Description : Wait for connection request from a peer through designated channel (TCP Server mode)
838
* Arguments   : s - channel number
839
* Returns     : None
840
* Note        : API Function
841
****************************************************************************************************
842
*/
843
char NBlisten(SOCKET s)
844
{
845
I_STATUS[s] = 0;
846
 
847
// LISTEN
848
WRITE_VALUE(COMMAND(s), CLISTEN);
849
 
850
return(1);
851
}
852
 
853
/*
854
****************************************************************************************************
855
*               Create random value for initial Seq# when establishing TCP connection
856
*
857
* Description : In this function, you can add some source codes to create random number for
858
*     initial Seq#. In real, TCP initial SEQ# should be random value.
859
*               (Currently, we're using static value in EVB/DK.)
860
* Arguments   : s - channel number
861
* Returns     : None
862
* Note        : API Function
863
****************************************************************************************************
864
*/
865
void initseqnum(SOCKET s)
866
{
867
// Designate initial seq#
868
// If you have random number generation function, assign random number instead of SEQ_NUM.lVal++.
869
SEQ_NUM.lVal++;
870
 
871
//randomize();
872
//SEQ_NUM.lVal = rand();
873
 
874
WRITE_VALUE(TX_WR_PTR(s), SEQ_NUM.cVal[0]);
875
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);
876
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);
877
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);
878
delay0(2);
879
 
880
WRITE_VALUE(TX_RD_PTR(s), SEQ_NUM.cVal[0]);
881
WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);
882
WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);
883
WRITE_VALUE(TX_RD_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);
884
delay0(2);
885
 
886
WRITE_VALUE(TX_ACK_PTR(s), SEQ_NUM.cVal[0]);
887
WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1), SEQ_NUM.cVal[1]);
888
WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2), SEQ_NUM.cVal[2]);
889
WRITE_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3), SEQ_NUM.cVal[3]);
890
delay0(2);
891
}
892
 
893
/*
894
****************************************************************************************************
895
*              Function for sending TCP data.
896
*
897
* Description : Function for sending TCP data and Composed of the send() and send_in() functions.
898
*     The send() function is an application I/F function.
899
*     It continues to call the send_in() function to complete the sending of the data up to the
900
*     size of the data to be sent when the application is called.
901
*     The send_in() function receives the return value (the size of the data sent), calculates
902
*     the size of the data to be sent, and calls the send_in() function again if there is any
903
*     data left to be sent.
904
* Arguments   : s   - channel number
905
*               buf - Pointer pointing data to send
906
*               len - data size to send
907
* Returns     : Succeed: sent data size, Failed:  -1;
908
* Note        : API Function
909
****************************************************************************************************
910
*/
911
int send(SOCKET s, u_char far * buf, u_int len)
912
{
913
int ptr, size;
914
u_char huge* huge_buf = (u_char huge*)buf;
915
u_char far*  local_buf = (u_char far*)huge_buf;
916
 
917
if (len <= 0)
918
  return (0);
919
else
920
  {
921
  ptr = 0;
922
  do
923
    {
924
         size = send_in(s, local_buf + ptr, len);
925
         if (size == -1)
926
      return -1;
927
         len = len - size;
928
         ptr += size;
929
         } while ( len > 0);
930
  }
931
return ptr;
932
}
933
 
934
/*
935
****************************************************************************************************
936
*              Internal function for sending TCP data.
937
*
938
* Description : Called by the send() function for TCP transmission.
939
*    It first calculates the free transmit buffer size
940
*    and compares it with the size of the data to be transmitted to determine the transmission size.
941
*    After calculating the data size, it copies data from TX_WR_PTR.
942
*    It waits if there is a previous send command in process.
943
*    When the send command is cleared, it updates the TX_WR_PTR up to the size to be transmitted
944
     and performs the send command.
945
* Arguments   : s   - channel number
946
*               buf - Pointer pointing data to send
947
*               len - data size to send
948
* Returns     : Succeeded: sent data size, Failed: -1
949
* Note        : Internal Function
950
****************************************************************************************************
951
*/
952
int send_in(SOCKET s, u_char far * buf, u_int len)
953
{
954
u_char k;
955
u_int size;
956
union un_l2cval wr_ptr, ack_ptr;
957
unsigned int offset;
958
 
959
S_START:
960
disable();            // CT: Shadow register access should not conflict with ISR.
961
k = READ_VALUE(SHADOW_TXWR_PTR(s));
962
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
963
delay0(2);
964
wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));
965
wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));
966
wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));
967
wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));
968
 
969
k = READ_VALUE(SHADOW_TXACK_PTR(s));
970
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
971
delay0(2);
972
ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));
973
ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));
974
ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));
975
ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));
976
enable();
977
 
978
// Suppress compiler errors that k is not used
979
k = k;
980
 
981
//  Calculate send free buffer size
982
if (wr_ptr.lVal >= ack_ptr.lVal)
983
  size = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));
984
else
985
  size = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));
986
 
987
// Recalulate after some delay because of error in pointer calculation
988
if (size > SSIZE[s])
989
  {
990
  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
991
    return -1;
992
  delay_ms(1);
993
         goto S_START;
994
  }
995
 
996
// Wait when previous sending has not finished yet and there's no free buffer
997
if (size == 0)
998
  {
999
  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
1000
    return -1;
1001
 
1002
  delay_ms(1);
1003
  goto S_START;
1004
  }
1005
else if (size < len)
1006
  {
1007
  len = size;
1008
  }
1009
 
1010
//  Calculate pointer to data copy
1011
offset = (UINT)(wr_ptr.lVal & SMASK[s]);
1012
 
1013
// copy data
1014
write_data(s, buf, offset, len);
1015
 
1016
while (READ_VALUE(COMMAND(s)) & CSEND)
1017
  {
1018
  // Confirm previous send command
1019
  if (select(s, SEL_CONTROL) != SOCK_ESTABLISHED)
1020
    return -1;
1021
  }
1022
 
1023
//  update tx_wr_ptr
1024
wr_ptr.lVal = wr_ptr.lVal + len;
1025
WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);
1026
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);
1027
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);
1028
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);
1029
 
1030
delay0(1);
1031
 
1032
// SEND
1033
WRITE_VALUE(COMMAND(s), CSEND);
1034
 
1035
return(len);
1036
}
1037
 
1038
/*
1039
****************************************************************************************************
1040
*              TCP data receiving function.
1041
*
1042
* Description : This function is to clear out any received TCP data.
1043
* Arguments   : s   - channel number
1044
* Returns     : None
1045
* Note        : API Fcuntion
1046
****************************************************************************************************
1047
*/
1048
void recv_clear(SOCKET s)
1049
{
1050
u_char k;
1051
u_int size;
1052
union un_l2cval wr_ptr, rd_ptr;
1053
 
1054
disable();
1055
k = READ_VALUE(SHADOW_RXWR_PTR(s));
1056
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1057
delay0(2);
1058
wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
1059
wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
1060
wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
1061
wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));
1062
 
1063
k = READ_VALUE(SHADOW_RXRD_PTR(s));
1064
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1065
delay0(2);
1066
rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
1067
rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
1068
rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
1069
rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
1070
enable();
1071
 
1072
// Suppress compiler errors that k is not used
1073
k = k;
1074
 
1075
//  calculate received data size
1076
if (wr_ptr.lVal >= rd_ptr.lVal)
1077
  size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);
1078
else
1079
  size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);
1080
 
1081
// Update rx_rd_ptr
1082
rd_ptr.lVal += size;
1083
WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);
1084
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);
1085
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);
1086
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);
1087
 
1088
// RECV
1089
 WRITE_VALUE(COMMAND(s), CRECV);
1090
}
1091
 
1092
/*
1093
****************************************************************************************************
1094
*              TCP data receiving function.
1095
*
1096
* Description : This function is for receiving TCP data.
1097
*     The recv() function is an application I/F function. It will read up to len chars if there are
1098
      enough characters in the buffer, otherwise will onl read the number of characters availiable
1099
* Arguments   : s   - channel number
1100
*               buf - Pointer where the data to be received is copied
1101
*               len - Size of the data to be received
1102
* Returns     : Succeeded: received data size, Failed: -1
1103
* Note        : API Fcuntion
1104
****************************************************************************************************
1105
*/
1106
int recv(SOCKET s, u_char far * buf, u_int len)
1107
{
1108
u_char k;
1109
u_int size;
1110
union un_l2cval wr_ptr, rd_ptr;
1111
unsigned int offset;
1112
 
1113
// If out length is 0, then we do not need to do anything
1114
if (len <= 0)
1115
  return (0);
1116
 
1117
disable();
1118
k = READ_VALUE(SHADOW_RXWR_PTR(s));
1119
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1120
delay0(2);
1121
wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
1122
wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
1123
wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
1124
wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));
1125
 
1126
k = READ_VALUE(SHADOW_RXRD_PTR(s));
1127
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1128
delay0(2);
1129
rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
1130
rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
1131
rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
1132
rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
1133
enable();
1134
 
1135
// Suppress compiler errors that k is not used
1136
k = k;
1137
 
1138
//  calculate IIM7010A received data size
1139
if (wr_ptr.lVal == rd_ptr.lVal)
1140
  return(0);
1141
else if (wr_ptr.lVal >= rd_ptr.lVal)
1142
  size = (u_int)(wr_ptr.lVal - rd_ptr.lVal);
1143
else
1144
  size = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);
1145
 
1146
// Make sure we do not try to read more characters than what is availiable in the IIM7010 buffer
1147
if (size < len)
1148
  len = size;
1149
 
1150
// Calculate pointer to be copied received data
1151
offset = ((UINT)(rd_ptr.lVal & RMASK[s]));
1152
 
1153
// Copy received data
1154
size = read_data(s, offset, buf, len);
1155
 
1156
// Update rx_rd_ptr
1157
rd_ptr.lVal += size;
1158
WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);
1159
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);
1160
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);
1161
WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);
1162
 
1163
// RECV
1164
 WRITE_VALUE(COMMAND(s), CRECV);
1165
return(size);
1166
}
1167
 
1168
 
1169
/*
1170
****************************************************************************************************
1171
*               UDP data sending function.
1172
*
1173
* Description : Composed of the sendto()and sendto_in() functions.
1174
*    The send() function is an application I/F function.
1175
*    It continues to call the send_in() function to complete the sending of the data up to the
1176
*    size of the data to be sent
1177
*    when the application is called.Unlike TCP transmission, it designates the destination address
1178
*    and the port.
1179
* Arguments   : s    - channel port
1180
*               buf  - Pointer pointing data to send
1181
*               len  - data size to send
1182
*               addr - destination IP address to send data
1183
*               port - destination port number to send data
1184
* Returns     : Sent data size
1185
* Note        : API Function
1186
****************************************************************************************************
1187
*/
1188
u_int sendto(SOCKET s, u_char far * buf, u_int len, u_char * addr, u_int port)
1189
{
1190
//char val;
1191
u_int ptr, size;
1192
 
1193
// Wait until previous send commnad has completed.
1194
while(READ_VALUE(COMMAND(s)) & CSEND)
1195
  {
1196
  if(select(s, SEL_CONTROL) == SOCK_CLOSED)
1197
    return -1;  // Error.
1198
  }
1199
 
1200
// Designate destination port number.
1201
if (port != 0)
1202
  {
1203
  WRITE_VALUE(DST_PORT_PTR(s), (u_char)((port & 0xff00) >> 8));
1204
  WRITE_VALUE(DST_PORT_PTR(s) + SA_OFFSET(1), (u_char)(port & 0x00ff));
1205
  }
1206
 
1207
//  Designate destination IP address
1208
WRITE_VALUE(DST_IP_PTR(s), addr[0]);
1209
WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(1), addr[1]);
1210
WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(2), addr[2]);
1211
WRITE_VALUE(DST_IP_PTR(s) + SA_OFFSET(3), addr[3]);
1212
 
1213
if (len <= 0)
1214
  return (0);
1215
else
1216
  {
1217
  ptr = 0;
1218
  do
1219
    {
1220
         size = sendto_in(s, buf + ptr, len);
1221
         len = len - size;
1222
         ptr += size;
1223
         } while ( len > 0);
1224
  }
1225
return ptr;
1226
}
1227
 
1228
/*
1229
****************************************************************************************************
1230
*            UDP data sending function.
1231
*
1232
* Description : An internal function that is the same as the send_in() function of the TCP.
1233
* Arguments   : s   - Channel number
1234
*               buf - Pointer indicating the data to send
1235
*               len - data size to send
1236
* Returns     : Sent data size
1237
* Note        : Internal Function
1238
****************************************************************************************************
1239
*/
1240
u_int sendto_in(SOCKET s, u_char far * buf, u_int len)
1241
{
1242
u_char k;
1243
u_int size;
1244
union un_l2cval wr_ptr, rd_ptr;
1245
unsigned int offset;
1246
 
1247
S2_START:
1248
disable();
1249
k = READ_VALUE(SHADOW_TXWR_PTR(s));
1250
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1251
delay0(2);
1252
wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));
1253
wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));
1254
wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));
1255
wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));
1256
 
1257
k = READ_VALUE(SHADOW_TXRD_PTR(s));
1258
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1259
delay0(2);
1260
rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));
1261
rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));
1262
rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));
1263
rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));
1264
enable();
1265
 
1266
// Suppress compiler errors that k is not used
1267
k = k;
1268
 
1269
//  Calculate free buffer size to send
1270
if (wr_ptr.lVal >= rd_ptr.lVal)
1271
  size = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));
1272
else
1273
  size = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));
1274
 
1275
//  Recalulate after some delay because of error in pointer caluation
1276
if (size > SSIZE[s])
1277
  {
1278
  delay_ms(1);
1279
  goto S2_START;
1280
  }
1281
 
1282
// Wait when previous sending has not finished yet and there's no free buffer
1283
if (size == 0)
1284
  {
1285
  delay_ms(1);
1286
  goto S2_START;
1287
 
1288
  }
1289
else if (size < len)
1290
  {
1291
  len = size;
1292
  }
1293
 
1294
// Calculate pointer to copy data pointer
1295
offset =(UINT)(wr_ptr.lVal & SMASK[s]);
1296
 
1297
// copy data
1298
write_data(s, buf, offset, len);
1299
 
1300
// Confirm previous send command
1301
while (READ_VALUE(COMMAND(s)) & CSEND)
1302
  {
1303
  if(select(s, SEL_CONTROL)==SOCK_CLOSED)
1304
    return -1;                  // Error
1305
  }
1306
 
1307
// update tx_wr_ptr
1308
wr_ptr.lVal = wr_ptr.lVal + len;
1309
WRITE_VALUE(TX_WR_PTR(s), wr_ptr.cVal[3]);
1310
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(1), wr_ptr.cVal[2]);
1311
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(2), wr_ptr.cVal[1]);
1312
WRITE_VALUE(TX_WR_PTR(s) + SA_OFFSET(3), wr_ptr.cVal[0]);
1313
 
1314
delay0(1);
1315
 
1316
// SEND
1317
WRITE_VALUE(COMMAND(s), CSEND);
1318
 
1319
return(len);
1320
}
1321
 
1322
/*
1323
****************************************************************************************************
1324
*             UDP data receiving function.
1325
*
1326
* Description : Function for receiving UDP and IP layer RAW mode data, and handling the data header.
1327
* Arguments   : s    - channel number
1328
*               buf  - Pointer where the data to be received is copied
1329
*               len  - Size of the data to be received
1330
*               addr - Peer IP address for receiving
1331
*               port - Peer port number for receiving
1332
* Returns     : Received data size
1333
* Note        : API Function
1334
****************************************************************************************************
1335
*/
1336
u_int recvfrom(SOCKET s, u_char far *buf, u_int len, u_char *addr, u_int *port)
1337
{
1338
struct _UDPHeader                                                                       // When receiving UDP data, header added by W3100A
1339
  {
1340
  union
1341
         {
1342
         struct
1343
                {
1344
                u_int size;
1345
                u_char addr[4];
1346
                u_int port;
1347
                } header;
1348
         u_char stream[8];
1349
    } u;
1350
  } UDPHeader;
1351
 
1352
u_int ret;
1353
union un_l2cval wr_ptr, rd_ptr;
1354
u_long size;
1355
u_char k;
1356
unsigned int offset;
1357
 
1358
if(select(s,SEL_CONTROL)==SOCK_CLOSED)
1359
  return -1;
1360
 
1361
disable();
1362
k = READ_VALUE(SHADOW_RXWR_PTR(s));
1363
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1364
delay0(2);
1365
wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
1366
wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
1367
wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
1368
wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));
1369
 
1370
k = READ_VALUE(SHADOW_RXRD_PTR(s));
1371
WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1372
delay0(2);
1373
rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
1374
rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
1375
rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
1376
rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
1377
enable();
1378
 
1379
// Suppress compiler errors that k is not used
1380
k = k;
1381
 
1382
// Calculate received data size
1383
if (len <= 0)
1384
  return (0);
1385
else if (wr_ptr.lVal >= rd_ptr.lVal)
1386
  size = wr_ptr.lVal - rd_ptr.lVal;
1387
else
1388
  size = 0 - rd_ptr.lVal + wr_ptr.lVal;
1389
 
1390
if (size == 0)
1391
  return 0;
1392
 
1393
  // Calulate received data pointer
1394
offset = ((UINT)(rd_ptr.lVal & RMASK[s]));
1395
 
1396
// When UDP data
1397
if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_DGRAM)
1398
  {
1399
  // Copy W3100A UDP header
1400
  read_data(s, offset, UDPHeader.u.stream, 8);
1401
 
1402
  // Read UDP Packet size
1403
  size = UDPHeader.u.stream[0];
1404
  size = (size << 8) + UDPHeader.u.stream[1];
1405
 
1406
  // Read IP address of the peer
1407
  addr[0] = UDPHeader.u.header.addr[0];
1408
  addr[1] = UDPHeader.u.header.addr[1];
1409
  addr[2] = UDPHeader.u.header.addr[2];
1410
  addr[3] = UDPHeader.u.header.addr[3];
1411
 
1412
  // Read Port number of the peer
1413
  *port = UDPHeader.u.stream[6];
1414
  *port = (*port << 8) + UDPHeader.u.stream[7];
1415
 
1416
  // Increase read pointer by 8, because already read as UDP header size
1417
  rd_ptr.lVal += 8;
1418
 
1419
  // Calculate UDP data copy pointer
1420
  offset = ((UINT)(rd_ptr.lVal & RMASK[s]));
1421
 
1422
  // Calculate data size of current UDP Packet from UDP header
1423
  size = size - 8;
1424
 
1425
  // Copy one UDP data packet to user-specific buffer
1426
  ret = read_data(s, offset, buf, (u_int)size);
1427
 
1428
  // Increase read pointer by UDP packet data size
1429
  rd_ptr.lVal += ret;
1430
  }
1431
else if ((READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_IPL_RAW)   // When IP layer RAW mode data
1432
  {
1433
  // Copy W3100A IP Raw header
1434
  read_data(s, offset, UDPHeader.u.stream, 6);
1435
 
1436
  // Read IP layer RAW Packet size
1437
  size = UDPHeader.u.stream[0];
1438
  size = (size << 8) + UDPHeader.u.stream[1];
1439
 
1440
  // Read IP address of the peer
1441
  addr[0] = UDPHeader.u.header.addr[0];
1442
  addr[1] = UDPHeader.u.header.addr[1];
1443
  addr[2] = UDPHeader.u.header.addr[2];
1444
  addr[3] = UDPHeader.u.header.addr[3];
1445
 
1446
  // Increase read pointer by 6, because already read as IP RAW header size
1447
  rd_ptr.lVal += 6;
1448
 
1449
  // Calculate IP layer raw mode data pointer
1450
  offset = ((UINT)(rd_ptr.lVal & RMASK[s]));
1451
 
1452
  // Copy one IP Raw data packet to user-specific buffer
1453
  ret = read_data(s, offset, buf, (u_int)size);
1454
  rd_ptr.lVal = rd_ptr.lVal + (ret - 4);
1455
  }
1456
 
1457
  // Update rx_rd_ptr
1458
  WRITE_VALUE(RX_RD_PTR(s), rd_ptr.cVal[3]);
1459
  WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(1), rd_ptr.cVal[2]);
1460
  WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(2), rd_ptr.cVal[1]);
1461
  WRITE_VALUE(RX_RD_PTR(s) + SA_OFFSET(3), rd_ptr.cVal[0]);
1462
 
1463
  // RECV
1464
  WRITE_VALUE(COMMAND(s), CRECV);
1465
 
1466
// Real received size return
1467
return(ret);
1468
}
1469
 
1470
/*
1471
****************************************************************************************************
1472
*              Channel closing function.
1473
*
1474
* Description : Function for closing the connection of the designated channel.
1475
* Arguments   : s - channel number
1476
* Returns     : None
1477
* Note        : API Function
1478
****************************************************************************************************
1479
*/
1480
void close(SOCKET s)
1481
{
1482
u_int len;
1483
short sAttempts = 0;
1484
 
1485
I_STATUS[s] = 0;
1486
 
1487
if (select(s, SEL_CONTROL) == SOCK_CLOSED)
1488
  return;          // Already closed
1489
 
1490
// When closing, if there's data which have not processed, Insert some source codes to handle this
1491
// Or before application call close(), handle those data first and call close() later.
1492
 
1493
len = select(s, SEL_SEND);
1494
if (len == SSIZE[s])
1495
  {
1496
  // CLOSE
1497
  WRITE_VALUE(COMMAND(s), CCLOSE);
1498
  // TODO: The 'SCLOSED' status value is only set briefly as part of the close,
1499
  // and will otherwise quickly return to normal.  That means your code might
1500
  // become 'stuck' at this point even if the packet has closed normally.
1501
  // Rather than a while() call, it might be preferred to time out on this
1502
  // close check and return to the application after some time.
1503
  while(!(I_STATUS[s] & SCLOSED))
1504
  {
1505
          sAttempts++;
1506
      if( sAttempts > 10 )
1507
      {
1508
        break;
1509
      }
1510
          I2CHIP_POLL_ISR(in4_isr_i2chip);
1511
  }
1512
  }
1513
}
1514
 
1515
u_char tx_empty(SOCKET s)
1516
{
1517
        return (select(s, SEL_SEND) == SSIZE[s]);
1518
}
1519
 
1520
/*
1521
****************************************************************************************************
1522
*              Channel closing function.
1523
*
1524
* Description : Function for closing the connection of the designated channel.
1525
* Arguments   : s - channel number
1526
* Returns     : None
1527
* Note        : API Function
1528
****************************************************************************************************
1529
*/
1530
char reset_sock(SOCKET s)
1531
{
1532
u_char c;
1533
 
1534
c = 1 << s;
1535
 
1536
// RESET
1537
WRITE_VALUE(RESETSOCK, c);
1538
return  (1);
1539
}
1540
 
1541
/*
1542
****************************************************************************************************
1543
*             Function handling the channel socket information.
1544
*
1545
* Description : Return socket information of designated channel
1546
* Arguments   : s    - channel number
1547
*               func - SEL_CONTROL(0x00) -> return socket status
1548
*                      SEL_SEND(0x01)    -> return free transmit buffer size
1549
*                      SEL_RECV(0x02)    -> return received data size
1550
* Returns     : socket status or free transmit buffer size or received data size
1551
* Note        : API Function
1552
****************************************************************************************************
1553
*/
1554
u_int select(SOCKET s, u_char func)
1555
{
1556
u_int val;
1557
union un_l2cval rd_ptr, wr_ptr, ack_ptr;
1558
u_char k;
1559
 
1560
switch (func)
1561
  {
1562
  // socket status information
1563
  case SEL_CONTROL :
1564
         val = READ_VALUE(SOCK_STATUS(s));
1565
         break;
1566
 
1567
  // Calculate send free buffer size
1568
  case SEL_SEND :
1569
         disable();
1570
         k = READ_VALUE(SHADOW_TXWR_PTR(s));
1571
         WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1572
         delay0(2);
1573
         wr_ptr.cVal[3] = READ_VALUE(TX_WR_PTR(s));
1574
         wr_ptr.cVal[2] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(1));
1575
         wr_ptr.cVal[1] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(2));
1576
         wr_ptr.cVal[0] = READ_VALUE(TX_WR_PTR(s) + SA_OFFSET(3));
1577
 
1578
         if (( READ_VALUE(OPT_PROTOCOL(s)) & 0x07) == SOCK_STREAM)      // TCP
1579
                {
1580
                k = READ_VALUE(SHADOW_TXACK_PTR(s));
1581
                WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1582
                delay0(2);
1583
                ack_ptr.cVal[3] = READ_VALUE(TX_ACK_PTR(s));
1584
                ack_ptr.cVal[2] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(1));
1585
                ack_ptr.cVal[1] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(2));
1586
                ack_ptr.cVal[0] = READ_VALUE(TX_ACK_PTR(s) + SA_OFFSET(3));
1587
                enable();
1588
 
1589
                if (wr_ptr.lVal >= ack_ptr.lVal)
1590
        val = (u_int)(SSIZE[s] - (wr_ptr.lVal - ack_ptr.lVal));
1591
                else
1592
        val = (u_int)(SSIZE[s] - (0 - ack_ptr.lVal + wr_ptr.lVal));
1593
                }
1594
         else                                                                                   // UDP, IP RAW ... (except TCP)
1595
                {
1596
                k = READ_VALUE(SHADOW_TXRD_PTR(s));
1597
                WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1598
                delay0(2);
1599
                rd_ptr.cVal[3] = READ_VALUE(TX_RD_PTR(s));
1600
                rd_ptr.cVal[2] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(1));
1601
                rd_ptr.cVal[1] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(2));
1602
                rd_ptr.cVal[0] = READ_VALUE(TX_RD_PTR(s) + SA_OFFSET(3));
1603
                enable();
1604
 
1605
                if (wr_ptr.lVal >= rd_ptr.lVal)
1606
        val = (u_int)(SSIZE[s] - (wr_ptr.lVal - rd_ptr.lVal));
1607
                else
1608
        val = (u_int)(SSIZE[s] - (0 - rd_ptr.lVal + wr_ptr.lVal));
1609
                }
1610
         break;
1611
 
1612
  //  Calculate received data size
1613
  case SEL_RECV :
1614
         disable();
1615
         k = READ_VALUE(SHADOW_RXWR_PTR(s));
1616
         WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1617
         delay0(2);
1618
         wr_ptr.cVal[3] = READ_VALUE(RX_WR_PTR(s));
1619
         wr_ptr.cVal[2] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(1));
1620
         wr_ptr.cVal[1] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(2));
1621
         wr_ptr.cVal[0] = READ_VALUE(RX_WR_PTR(s) + SA_OFFSET(3));
1622
 
1623
         k = READ_VALUE(SHADOW_RXRD_PTR(s));
1624
    WINDOW_RESTORE_BASE;  // Needed whenever we touch a shadow ptr; different window.
1625
         delay0(2);
1626
         rd_ptr.cVal[3] = READ_VALUE(RX_RD_PTR(s));
1627
         rd_ptr.cVal[2] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(1));
1628
         rd_ptr.cVal[1] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(2));
1629
         rd_ptr.cVal[0] = READ_VALUE(RX_RD_PTR(s) + SA_OFFSET(3));
1630
         enable();
1631
 
1632
         if (wr_ptr.lVal == rd_ptr.lVal)
1633
      val = 0;
1634
         else if (wr_ptr.lVal > rd_ptr.lVal)
1635
      val = (u_int)(wr_ptr.lVal - rd_ptr.lVal);
1636
         else
1637
      val = (u_int)(0 - rd_ptr.lVal + wr_ptr.lVal);
1638
         break;
1639
 
1640
  default :
1641
         val = -1;
1642
         break;
1643
  }
1644
// Suppress compiler errors that k is not used
1645
k = k;
1646
return(val);
1647
}
1648
 
1649
//
1650
//      unsigned char dma_read_i2chip (unsigned int i2_segm, unsigned int i2_offs,
1651
//      unsigned int cnt, unsigned int des_segm, unsigned int des_offs);
1652
//      Using DMA0 to read data from i2chip buffer into destination SRAM.
1653
//      where:
1654
//              unsigned int cnt = number of sectors, 512-byte per sector
1655
//              unsigned int des_segm = segment of destination SRAM data memory
1656
//              unsigned int des_offs = offset of destination SRAM data memory
1657
//              unsigned int i2_segm = segment of i2chip buffer mapped in memory
1658
//              unsigned int i2_offs = offset of i2chip buffer mapped in memory
1659
//       return DMA counter value
1660
//
1661
unsigned int dma_read_i2chip(u_char far* i2_src, u_char far* des, u_int cnt)
1662
{
1663
        u_int des_segm, des_offs;
1664
   u_int i2_segm, i2_offs;
1665
   u_long temp;
1666
 
1667
   temp = ((long)FP_SEG(des) << 4) + ((long)FP_OFF(des));
1668
   des_segm = (u_int)(temp >> 16);
1669
   des_offs = (u_int)(temp & 0xffff);
1670
 
1671
   temp = ((long)FP_SEG(i2_src) << 4) + ((long)FP_OFF(i2_src));
1672
   i2_segm = (u_int)(temp >> 16);
1673
   i2_offs = (u_int)(temp & 0xffff);
1674
 
1675
        outport(0xffc6, des_segm);   /* D0DSTH destination SRAM segment */
1676
        outport(0xffc4, des_offs);   /* D0DSTL destination SRAM offset */
1677
        outport(0xffc2, i2_segm);   /* D0SRCH=SP0RD */
1678
        outport(0xffc0, i2_offs);   /* D0SRCL=SP0RD */
1679
        outport(0xffc8, cnt);   // D0TC counter
1680
        outport(0xfff8,0x0504); // PLLCON, 0203=10M,050f=40M, 051f=80MHz
1681
// DMA0 mem-mem, 16-bit, unsync, Start moving data line below
1682
        outport(0xffca, 0xb60e);   /* D0CON 1011 0110 0000 1111 */
1683
//      outport(0xffca, 0xb42e);         // 1011 0100 0010 1110
1684
        while( inport(0xffc8) ); /* D0TC counter=0, DMA complete */
1685
        outport(0xfff8,0x051f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz
1686
return( inport(0xffc8) ); // counter
1687
}
1688
 
1689
//
1690
//      unsigned int dma_write_i2chip (unsigned int src_segm, unsigned int src_offs,
1691
//      unsigned int cnt, unsigned int i2_segm, unsigned int i2_offs);
1692
//      Using DMA0 to write data from memory into i2chip.
1693
//      where:
1694
//              unsigned int cnt = number of 16-bit DMA transfers
1695
//              unsigned int src_segm = segment of the source SRAM data memory
1696
//              unsigned int src_offs = offset of the source SRAM data memory
1697
//              unsigned int i2_segm = segment of i2chip buffer mapped in memory
1698
//              unsigned int i2_offs = offset of i2chip buffer mapped in memory
1699
//       return DMA counter value
1700
//
1701
unsigned int dma_write_i2chip(u_char far* src, u_char far* i2_dest, u_int cnt)
1702
{
1703
        u_int src_segm, src_offs;
1704
   u_int i2_segm, i2_offs;
1705
   u_long temp;
1706
 
1707
   temp = (FP_SEG(src) << 4) + (FP_OFF(src));
1708
   src_segm = (u_int)(temp >> 4);
1709
   src_offs = (u_int)(temp & 0xffff);
1710
 
1711
   temp = (FP_SEG(i2_dest) << 4) + (FP_OFF(i2_dest));
1712
   i2_segm = (u_int)(temp >> 4);
1713
   i2_offs = (u_int)(temp & 0xffff);
1714
 
1715
        outport(0xffc8, cnt);   // D0TC counter
1716
        outport(0xffc6, i2_segm); // D0DSTH=i2chip buffer segment
1717
        outport(0xffc4, i2_offs); // D0DSTL=i2chip buffer offset
1718
        outport(0xffc2, src_segm);   /* D0SRCH=SP0RD */
1719
        outport(0xffc0, src_offs);   /* D0SRCL=SP0RD */
1720
//      outport(0xfff8,0x050f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz
1721
// DMA0 mem-mem, 16-bit, unsync, Start moving data line below
1722
        outport(0xffca, 0xb60f);   /* D0CON 1011 0110 0000 1111 */
1723
        while( inport(0xffc8) ); /* D0TC counter=0, DMA complete */
1724
//      outport(0xfff8,0x051f); // PLLCON, 0203=10M,050f=40M, 051f=80MHz
1725
 
1726
return( inport(0xffc8) ); // counter
1727
}
1728
 
1729
/*
1730
****************************************************************************************************
1731
*              Copies the receive buffer data of the W3100A to the system buffer.
1732
*
1733
* Description : Copies the receive buffer data of the W3100A to the system buffer.
1734
*    It is called from the recv()or recvfrom() function.
1735
* Arguments   : s   - channel number
1736
*               src - receive buffer pointer of W3100A
1737
*               dst - system buffer pointer
1738
*               len - data size to copy
1739
* Returns     : copied data size
1740
* Note        : Internal Function
1741
****************************************************************************************************
1742
*/
1743
u_int read_data(SOCKET s, u_int offset, u_char far * dst, u_int len)
1744
{
1745
        u_int i, size, size1;
1746
   u_char far* src = (u_char far*)(MK_FP_WINDOW(RECV_DATA_BUF,
1747
                                        RBUFBASEADDRESS[s] + offset));
1748
//   src = (u_char far*)(MK_FP_WINDOW(RECV_DATA_BUF,
1749
//                                        0));
1750
 
1751
        if (len == 0)
1752
   {
1753
        WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.
1754
                return 0;
1755
   }
1756
 
1757
   if ((offset + len) > RSIZE[s])
1758
   {
1759
                size = (u_int)(RSIZE[s] - offset);
1760
 
1761
                if (size > TERN_RDMA_THRES)
1762
                {
1763
                        dma_read_i2chip(src, dst, size);
1764
                }
1765
                else
1766
      {
1767
                        for (i = 0; i < size; i++)
1768
                {
1769
                                *dst++ = READ_VALUE(src);
1770
            WINDOW_PTR_INC(src);
1771
 
1772
                        }
1773
                }
1774
 
1775
          size1 = len - size;
1776
     src = (u_char far *)(MK_FP_WINDOW(RECV_DATA_BUF, (RBUFBASEADDRESS[s])));
1777
 
1778
     if (size1 > TERN_RDMA_THRES)
1779
     {
1780
                dma_read_i2chip(src, dst, size);
1781
          }
1782
     else
1783
          {
1784
                        for (i = 0; i < size1; i++)
1785
                {
1786
                                *dst++ = READ_VALUE(src);
1787
            WINDOW_PTR_INC(src);
1788
                }
1789
                }
1790
        }
1791
   else
1792
   {
1793
         if (len > TERN_RDMA_THRES)
1794
    {
1795
                dma_read_i2chip(src, dst, size);
1796
    }
1797
    else
1798
    {
1799
                for (i = 0; i < len; i++)
1800
        {
1801
                        *dst++ = READ_VALUE(src);
1802
         WINDOW_PTR_INC(src);
1803
                }
1804
    }
1805
   }
1806
   WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.
1807
        return len;
1808
}
1809
 
1810
 
1811
/*
1812
****************************************************************************************************
1813
*              Copies the system buffer data to the transmit buffer of the W3100A.
1814
*
1815
* Description : Copies the system buffer data to the transmit buffer of the W3100A.
1816
*               It is called from the send_in()or sendto_in() function.
1817
* Arguments   : s   - channel number
1818
*               src - system buffer pointer
1819
*               dst - send buffer pointer of W3100A
1820
*               len - data size to copy
1821
* Returns     : copied data size
1822
* Note        : Internal Function
1823
****************************************************************************************************
1824
*/
1825
u_int write_data(SOCKET s, u_char far * src, u_int offset, u_int len)
1826
{
1827
        u_int i, size, size1;
1828
        u_char far* dst = (u_char far*)MK_FP_WINDOW(SEND_DATA_BUF,
1829
                                  SBUFBASEADDRESS[s] + offset);
1830
 
1831
        if (len == 0)
1832
   {
1833
        WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.
1834
                return 0;
1835
   }
1836
 
1837
        if ((offset + len) > SSIZE[s])
1838
   {
1839
                size = (u_int)(SSIZE[s] - offset);
1840
 
1841
                for (i = 0; i < size; i++)
1842
        {
1843
                        WRITE_VALUE(dst, *src++);
1844
         WINDOW_PTR_INC(dst);
1845
                }
1846
 
1847
                size1 = len - size;
1848
                dst = (u_char far *)(MK_FP_WINDOW(SEND_DATA_BUF, (SBUFBASEADDRESS[s])));
1849
 
1850
                for (i = 0; i < size1; i++)
1851
        {
1852
                        WRITE_VALUE(dst, *src++);
1853
         WINDOW_PTR_INC(dst);
1854
                }
1855
  }
1856
  else
1857
  {
1858
        for (i = 0; i < len; i++)
1859
        {
1860
                        WRITE_VALUE(dst, *src++);
1861
         WINDOW_PTR_INC(dst);
1862
                }
1863
        }
1864
   WINDOW_RESTORE_BASE;    // Needed whenever we do a call to MK_FP_WINDOW.
1865
        return len;
1866
}
1867
 
1868
 
1869
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.