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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [drivers/] [smc91111.c] - Blame information for rev 328

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 marcus.erl
/*------------------------------------------------------------------------
2
 . smc91111.c
3
 . This is a driver for SMSC's 91C111 single-chip Ethernet device.
4
 .
5
 . (C) Copyright 2005
6
 .
7
 . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
8
 .       Developed by Simple Network Magic Corporation (SNMC)
9
 . Copyright (C) 1996 by Erik Stahlman (ES)
10
 .
11
 . This program is free software; you can redistribute it and/or modify
12
 . it under the terms of the GNU General Public License as published by
13
 . the Free Software Foundation; either version 2 of the License, or
14
 . (at your option) any later version.
15
 .
16
 . This program is distributed in the hope that it will be useful,
17
 . but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 . GNU General Public License for more details.
20
 .
21
 . You should have received a copy of the GNU General Public License
22
 . along with this program; if not, write to the Free Software
23
 . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 .
25
 . Information contained in this file was obtained from the LAN91C111
26
 . manual from SMC.  To get a copy, if you really want one, you can find
27
 . information under www.smsc.com.
28
 .
29
 .
30
 . author:
31
 .      Javier Castillo                 ( javier.castillo@urjc.es )
32
 .
33
 . Sources:
34
 .    o   smc91111.c by Erik Stahlman
35
 .
36
 . History:
37
 . 06/05/05  Javier Castillo  Modified smc91111.c to work with OR1200
38
 ----------------------------------------------------------------------------*/
39
 
40
#include "board.h" 
41
 
42
#if SMC91111_LAN==1
43
 
44
#include "common.h"
45
#include "smc91111.h"
46
#include "support.h"
47
#include "net.h"
48
 
49
#ifndef CONFIG_SMC_AUTONEG_TIMEOUT
50
#define CONFIG_SMC_AUTONEG_TIMEOUT 10
51
#endif
52
 
53
#define ETH_ZLEN 60
54
#define MEMORY_WAIT_TIME 16
55
#define SMC_ALLOC_MAX_TRY 5
56
#define SMC_TX_TIMEOUT 30
57
#define SWAP16(x)  ((((x) & 0x00ff) << 8) | ( (x) >> 8))
58
 
59
 
60
typedef  unsigned char  byte;
61
typedef  unsigned short word;
62
 
63
//Do nothing but needed to compile
64
int tx_next;
65
int rx_next;
66
 
67
void (*receive)(volatile unsigned char *add, int len); /* Pointer to function to be called
68
                                        when frame is received */
69
 
70
static void __delay(unsigned long loops)
71
{
72
        __asm__ __volatile__ ("1: l.sfeqi %0,0; \
73
                                l.bnf   1b; \
74
                                l.addi %0,%0,-1;"
75
                                : "=r" (loops) : "0" (loops));
76
}
77
 
78
static void udelay(unsigned long usecs)
79
{
80
        /* Sigh */
81
        __delay(usecs);
82
}
83
 
84
static void smc_wait_ms(unsigned int ms){
85
        udelay(ms*1000);
86
}
87
 
88
static void
89
print_packet(unsigned long add, int len)
90
{
91
  int i;
92
 
93
  printf("ipacket: add = %lx len = %d\n", add, len);
94
  for(i = 0; i < len; i++) {
95
      if(!(i % 16))
96
          printf("\n");
97
      printf(" %.2x", *(((unsigned char *)add) + i));
98
  }
99
  printf("\n");
100
}
101
 
102
/*------------------------------------------------------------
103
 . Reads a register from the MII Management serial interface
104
 .-------------------------------------------------------------*/
105
static word smc_read_phy_register(byte phyreg)
106
{
107
        int oldBank;
108
        int i;
109
        byte mask;
110
        word mii_reg;
111
        byte bits[64];
112
        int clk_idx = 0;
113
        int input_idx;
114
        word phydata;
115
        byte phyaddr=SMC_PHY_ADDR;
116
 
117
        // 32 consecutive ones on MDO to establish sync
118
        for (i = 0; i < 32; ++i)
119
                bits[clk_idx++] = MII_MDOE | MII_MDO;
120
 
121
        // Start code <01>
122
        bits[clk_idx++] = MII_MDOE;
123
        bits[clk_idx++] = MII_MDOE | MII_MDO;
124
 
125
        // Read command <10>
126
        bits[clk_idx++] = MII_MDOE | MII_MDO;
127
        bits[clk_idx++] = MII_MDOE;
128
 
129
        // Output the PHY address, msb first
130
        mask = (byte)0x10;
131
        for (i = 0; i < 5; ++i)
132
                {
133
                if (phyaddr & mask)
134
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
135
                else
136
                        bits[clk_idx++] = MII_MDOE;
137
 
138
                // Shift to next lowest bit
139
                mask >>= 1;
140
                }
141
 
142
        // Output the phy register number, msb first
143
        mask = (byte)0x10;
144
        for (i = 0; i < 5; ++i)
145
                {
146
                if (phyreg & mask)
147
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
148
                else
149
                        bits[clk_idx++] = MII_MDOE;
150
 
151
                // Shift to next lowest bit
152
                mask >>= 1;
153
                }
154
 
155
        // Tristate and turnaround (2 bit times)
156
        bits[clk_idx++] = 0;
157
        //bits[clk_idx++] = 0;
158
 
159
        // Input starts at this bit time
160
        input_idx = clk_idx;
161
 
162
        // Will input 16 bits
163
        for (i = 0; i < 16; ++i)
164
                bits[clk_idx++] = 0;
165
 
166
        // Final clock bit
167
        bits[clk_idx++] = 0;
168
 
169
        // Save the current bank
170
        oldBank = REG16(ETH_BASE+BANK_SELECT);
171
 
172
        // Select bank 3
173
        SMC_SELECT_BANK( 3 );
174
 
175
        // Get the current MII register value
176
        mii_reg = REG16(ETH_BASE+MII_REG);
177
 
178
        // Turn off all MII Interface bits
179
        mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
180
 
181
        // Clock all 64 cycles
182
        for (i = 0; i < sizeof bits; ++i)
183
                {
184
                // Clock Low - output data
185
                REG16(ETH_BASE+MII_REG)= mii_reg | bits[i];
186
                udelay(500);
187
 
188
 
189
                // Clock Hi - input data
190
                REG16(ETH_BASE+MII_REG)= mii_reg | bits[i] | MII_MCLK;
191
                udelay(500);
192
                bits[i] |= REG16(ETH_BASE+MII_REG) & MII_MDI;
193
                }
194
 
195
        // Return to idle state
196
        // Set clock to low, data to low, and output tristated
197
        REG16(ETH_BASE+MII_REG)=mii_reg;
198
        udelay(500);
199
 
200
        // Restore original bank select
201
        SMC_SELECT_BANK( oldBank );
202
 
203
        // Recover input data
204
        phydata = 0;
205
        for (i = 0; i < 16; ++i)
206
                {
207
                phydata <<= 1;
208
 
209
                if (bits[input_idx++] & MII_MDI)
210
                        phydata |= 0x0001;
211
                }
212
 
213
        return(phydata);
214
}
215
 
216
static void smc_write_phy_register(byte phyreg, word phydata){
217
 
218
        int oldBank;
219
        int i;
220
        word mask;
221
        word mii_reg;
222
        byte bits[65];
223
        int clk_idx=0;
224
        byte phyaddr=SMC_PHY_ADDR;
225
 
226
        /*32 consecutives ones on MDO to establish sync*/
227
        for(i=0; i<32;i++)
228
                bits[clk_idx++]=MII_MDOE | MII_MDO;
229
 
230
        // Start code <01>
231
        bits[clk_idx++] = MII_MDOE;
232
        bits[clk_idx++] = MII_MDOE | MII_MDO;
233
 
234
        // Write command <01>
235
        bits[clk_idx++] = MII_MDOE;
236
        bits[clk_idx++] = MII_MDOE | MII_MDO;
237
 
238
        // Output the PHY address, msb first
239
        mask = (byte)0x10;
240
        for (i = 0; i < 5; ++i)
241
                {
242
                if (phyaddr & mask)
243
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
244
                else
245
                        bits[clk_idx++] = MII_MDOE;
246
 
247
                // Shift to next lowest bit
248
                mask >>= 1;
249
                }
250
 
251
        // Output the phy register number, msb first
252
        mask = (byte)0x10;
253
        for (i = 0; i < 5; ++i)
254
                {
255
                if (phyreg & mask)
256
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
257
                else
258
                        bits[clk_idx++] = MII_MDOE;
259
 
260
                // Shift to next lowest bit
261
                mask >>= 1;
262
                }
263
 
264
        // Tristate and turnaround (2 bit times)
265
        bits[clk_idx++] = 0;
266
        bits[clk_idx++] = 0;
267
 
268
        // Write out 16 bits of data, msb first
269
        mask = 0x8000;
270
        for (i = 0; i < 16; ++i)
271
                {
272
                if (phydata & mask)
273
                        bits[clk_idx++] = MII_MDOE | MII_MDO;
274
                else
275
                        bits[clk_idx++] = MII_MDOE;
276
 
277
                // Shift to next lowest bit
278
                mask >>= 1;
279
                }
280
 
281
        // Final clock bit (tristate)
282
        bits[clk_idx++] = 0;
283
 
284
        // Save the current bank
285
        oldBank = REG16(ETH_BASE+BANK_SELECT);
286
 
287
        // Select bank 3
288
        SMC_SELECT_BANK( 3 );
289
 
290
        // Get the current MII register value
291
        mii_reg = REG16(ETH_BASE+MII_REG);
292
 
293
        // Turn off all MII Interface bits
294
        mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
295
 
296
        // Clock all cycles
297
        for (i = 0; i < sizeof bits; ++i)
298
                {
299
                // Clock Low - output data
300
                REG16(ETH_BASE+MII_REG)= mii_reg | bits[i];
301
                udelay(50);
302
 
303
 
304
                // Clock Hi - input data
305
                REG16(ETH_BASE+MII_REG)= mii_reg | bits[i] | MII_MCLK;
306
                udelay(50);
307
                bits[i] |= REG16(ETH_BASE+MII_REG) & MII_MDI;
308
                }
309
 
310
        // Return to idle state
311
        // Set clock to low, data to low, and output tristated
312
        REG16(ETH_BASE+MII_REG)=mii_reg;
313
        udelay(50);
314
 
315
        // Restore original bank select
316
        SMC_SELECT_BANK( oldBank );
317
 
318
}
319
 
320
 
321
static void smc_phy_configure (void){
322
        int timeout;
323
        byte phyaddr;
324
        word my_phy_caps;       /* My PHY capabilities */
325
        word my_ad_caps;        /* My Advertised capabilities */
326
        word status = 0; /*;my status = 0 */
327
        int failed = 0;
328
 
329
        /* Get the detected phy address */
330
        phyaddr = SMC_PHY_ADDR;
331
 
332
        /* Reset the PHY, setting all other bits to zero */
333
        smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_RST);
334
 
335
        /* Wait for the reset to complete, or time out */
336
        timeout = 6;            /* Wait up to 3 seconds */
337
        while (timeout--) {
338
                if (!(smc_read_phy_register (PHY_CNTL_REG)
339
                      & PHY_CNTL_RST)) {
340
                        /* reset complete */
341
                        break;
342
                }
343
 
344
                smc_wait_ms (500);      /* wait 500 millisecs */
345
        }
346
 
347
        if (timeout < 1) {
348
                printf ("PHY reset timed out\n");
349
                goto smc_phy_configure_exit;
350
        }
351
 
352
        /* Read PHY Register 18, Status Output */
353
        /* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */
354
 
355
        /* Enable PHY Interrupts (for register 18) */
356
        /* Interrupts listed here are disabled */
357
        smc_write_phy_register (PHY_MASK_REG, 0xffff);
358
 
359
        /* Configure the Receive/Phy Control register */
360
        SMC_SELECT_BANK (0);
361
        REG16(ETH_BASE+RPC_REG)=RPC_DEFAULT;
362
 
363
        /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
364
        my_phy_caps = smc_read_phy_register (PHY_STAT_REG);
365
        my_ad_caps = PHY_AD_CSMA;       /* I am CSMA capable */
366
 
367
        if (my_phy_caps & PHY_STAT_CAP_T4)
368
                my_ad_caps |= PHY_AD_T4;
369
 
370
        if (my_phy_caps & PHY_STAT_CAP_TXF)
371
                my_ad_caps |= PHY_AD_TX_FDX;
372
 
373
        if (my_phy_caps & PHY_STAT_CAP_TXH)
374
                my_ad_caps |= PHY_AD_TX_HDX;
375
 
376
        if (my_phy_caps & PHY_STAT_CAP_TF)
377
                my_ad_caps |= PHY_AD_10_FDX;
378
 
379
        if (my_phy_caps & PHY_STAT_CAP_TH)
380
                my_ad_caps |= PHY_AD_10_HDX;
381
 
382
        /* Update our Auto-Neg Advertisement Register */
383
        smc_write_phy_register (PHY_AD_REG, my_ad_caps);
384
 
385
        /* Read the register back.  Without this, it appears that when */
386
        /* auto-negotiation is restarted, sometimes it isn't ready and */
387
        /* the link does not come up. */
388
        smc_read_phy_register(PHY_AD_REG);
389
 
390
        /* Restart auto-negotiation process in order to advertise my caps */
391
        smc_write_phy_register (PHY_CNTL_REG,
392
                                PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);
393
 
394
        /* Wait for the auto-negotiation to complete.  This may take from */
395
        /* 2 to 3 seconds. */
396
        /* Wait for the reset to complete, or time out */
397
        timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2;
398
        while (timeout--) {
399
 
400
                status = smc_read_phy_register (PHY_STAT_REG);
401
                if (status & PHY_STAT_ANEG_ACK) {
402
                        /* auto-negotiate complete */
403
                        break;
404
                }
405
 
406
                smc_wait_ms (500);      /* wait 500 millisecs */
407
 
408
                /* Restart auto-negotiation if remote fault */
409
                if (status & PHY_STAT_REM_FLT) {
410
                        printf ("PHY remote fault detected\n");
411
 
412
                        /* Restart auto-negotiation */
413
                        printf ("PHY restarting auto-negotiation\n");
414
                        smc_write_phy_register (PHY_CNTL_REG,
415
                                                PHY_CNTL_ANEG_EN |
416
                                                PHY_CNTL_ANEG_RST |
417
                                                PHY_CNTL_SPEED |
418
                                                PHY_CNTL_DPLX);
419
                }
420
        }
421
 
422
        if (timeout < 1) {
423
                printf ("PHY auto-negotiate timed out\n");
424
                failed = 1;
425
        }
426
 
427
        /* Fail if we detected an auto-negotiate remote fault */
428
        if (status & PHY_STAT_REM_FLT) {
429
                printf ("PHY remote fault detected\n");
430
                failed = 1;
431
        }
432
 
433
        /* Re-Configure the Receive/Phy Control register */
434
        REG16(ETH_BASE+RPC_REG)=RPC_DEFAULT;
435
 
436
smc_phy_configure_exit: ;
437
 
438
}
439
 
440
static inline void smc_wait_mmu_release_complete (void)
441
{
442
        int count = 0;
443
 
444
        /* assume bank 2 selected */
445
        while (REG16(ETH_BASE+MMU_CMD_REG) & MC_BUSY) {
446
                udelay (1);     /* Wait until not busy */
447
                if (++count > 200)
448
                        break;
449
        }
450
}
451
 
452
static void eth_reset(){
453
 
454
        /* This resets the registers mostly to defaults, but doesn't
455
           affect EEPROM.  That seems unnecessary */
456
        SMC_SELECT_BANK (0);
457
        REG16(ETH_BASE+RCR_REG)=RCR_SOFTRST;
458
 
459
        /* Setup the Configuration Register */
460
        /* This is necessary because the CONFIG_REG is not affected */
461
        /* by a soft reset */
462
 
463
        SMC_SELECT_BANK (1);
464
        REG16(ETH_BASE+CONFIG_REG)=CONFIG_DEFAULT;
465
 
466
        /* Release from possible power-down state */
467
        /* Configuration register is not affected by Soft Reset */
468
        REG16(ETH_BASE+CONFIG_REG)=REG16(ETH_BASE+CONFIG_REG) | CONFIG_EPH_POWER_EN;
469
 
470
        SMC_SELECT_BANK (0);
471
 
472
        /* this should pause enough for the chip to be happy */
473
        udelay (100);
474
 
475
        /* Disable transmit and receive functionality */
476
        REG16(ETH_BASE+RCR_REG)=RCR_CLEAR;
477
        REG16(ETH_BASE+TCR_REG)=TCR_CLEAR;
478
 
479
        /* set the control register */
480
        SMC_SELECT_BANK (1);
481
        REG16(ETH_BASE+CTL_REG)=CTL_DEFAULT;
482
 
483
        /* Reset the MMU */
484
        SMC_SELECT_BANK (2);
485
        smc_wait_mmu_release_complete ();
486
        REG16(ETH_BASE+MMU_CMD_REG)=MC_RESET;
487
        while (REG16(ETH_BASE+MMU_CMD_REG) & MC_BUSY)
488
                udelay (1);     /* Wait until not busy */
489
 
490
        /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
491
           but this is a place where future chipsets _COULD_ break.  Be wary
492
           of issuing another MMU command right after this */
493
 
494
        /* Disable all interrupts */
495
        REG8(ETH_BASE+IM_REG)=0;
496
}
497
 
498
void eth_init (void (*rec)(volatile unsigned char *, int)){
499
 
500
        receive = rec;
501
 
502
        /*First make a SW reset of the chip*/
503
        eth_reset();
504
 
505
        /*Enable TX and Rx*/
506
        SMC_SELECT_BANK(0x0);
507
        REG16(ETH_BASE+TCR_REG)=TCR_DEFAULT;
508
        REG16(ETH_BASE+RCR_REG)=RCR_DEFAULT;
509
        REG16(ETH_BASE+RPC_REG)=RPC_DEFAULT;
510
 
511
        /*Configure PHY with autoneg*/
512
        smc_phy_configure();
513
 
514
        /*Set MAC address*/
515
        SMC_SELECT_BANK(0x1);
516
        REG8(ETH_BASE+ADDR0_REG)=ETH_MACADDR0;
517
        REG8(ETH_BASE+ADDR0_REG+1)=ETH_MACADDR1;
518
        REG8(ETH_BASE+ADDR0_REG+2)=ETH_MACADDR2;
519
        REG8(ETH_BASE+ADDR0_REG+3)=ETH_MACADDR3;
520
        REG8(ETH_BASE+ADDR0_REG+4)=ETH_MACADDR4;
521
        REG8(ETH_BASE+ADDR0_REG+5)=ETH_MACADDR5;
522
 
523
}
524
 
525
void eth_halt(void) {
526
        /* no more interrupts for me */
527
        SMC_SELECT_BANK( 2 );
528
        REG8(ETH_BASE+IM_REG)=0;
529
 
530
        /* and tell the card to stay away from that nasty outside world */
531
        SMC_SELECT_BANK( 0 );
532
        REG8(ETH_BASE+RCR_REG)=RCR_CLEAR;
533
        REG8(ETH_BASE+TCR_REG)=TCR_CLEAR;
534
}
535
 
536
unsigned long eth_rx (void){
537
 
538
        int     packet_number;
539
        word    status;
540
        word    packet_length;
541
        word    packet_length_loop;
542
        int     is_error = 0;
543
        byte saved_pnr;
544
        word saved_ptr;
545
        word word_readed;
546
        byte *data;
547
 
548
        SMC_SELECT_BANK(2);
549
        /* save PTR and PTR registers */
550
        saved_pnr = REG8(ETH_BASE+PN_REG );
551
        saved_ptr = REG16(ETH_BASE+PTR_REG );
552
 
553
        packet_number = REG16(ETH_BASE+RXFIFO_REG );
554
 
555
        if ( packet_number & RXFIFO_REMPTY ) {
556
                return 0;
557
        }
558
 
559
        /*  start reading from the start of the packet */
560
        REG16(ETH_BASE+PTR_REG)=PTR_READ | PTR_RCV | PTR_AUTOINC;
561
 
562
        /* First two words are status and packet_length */
563
        status          = REG16(ETH_BASE+SMC91111_DATA_REG );
564
        packet_length   = REG16(ETH_BASE+SMC91111_DATA_REG );
565
 
566
        packet_length &= 0x07ff;  /* mask off top bits */
567
 
568
        #ifdef DEBUG
569
        printf("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );
570
        #endif
571
        if ( !(status & RS_ERRORS ) ){
572
                /* Adjust for having already read the first two words */
573
                packet_length -= 4; /*4; */
574
 
575
                /* set odd length for bug in LAN91C111, */
576
                /* which never sets RS_ODDFRAME */
577
                /* TODO ? */
578
                #ifdef DEBUG
579
                printf(" Reading %d words and %d byte(s) \n",(packet_length >> 1 ), packet_length & 1 );
580
                #endif
581
                packet_length_loop=packet_length>>1;
582
 
583
                data=(byte*)NetRxPackets[0];
584
                while(packet_length_loop-->0){
585
                  word_readed=REG16(ETH_BASE+SMC91111_DATA_REG);
586
                  *((word*)data)=SWAP16(word_readed);
587
                  data+=sizeof(word);
588
                }
589
 
590
        } else {
591
                /* error ... */
592
                /* TODO ? */
593
                is_error = 1;
594
        }
595
 
596
        while ( REG16(ETH_BASE+MMU_CMD_REG) & MC_BUSY )
597
                udelay(1); /* Wait until not busy */
598
 
599
        /*  error or good, tell the card to get rid of this packet */
600
        REG16(ETH_BASE+MMU_CMD_REG)=MC_RELEASE;
601
 
602
        while ( REG16(ETH_BASE+MMU_CMD_REG) & MC_BUSY )
603
                udelay(1); /* Wait until not busy */
604
 
605
        /* restore saved registers */
606
 
607
        REG8(ETH_BASE+PN_REG)=saved_pnr;
608
 
609
        REG16(ETH_BASE+PTR_REG)=saved_ptr;
610
 
611
        if (!is_error) {
612
                /* Pass the packet up to the protocol layers. */
613
                receive(NetRxPackets[0], packet_length);
614
                return packet_length;
615
        } else {
616
                return 0;
617
        }
618
}
619
 
620
#define CFG_HZ 1000
621
static int poll4int (byte mask, int timeout)
622
{
623
        int tmo = get_timer (0) + timeout * CFG_HZ;
624
        int is_timeout = 0;
625
        word old_bank = REG16(ETH_BASE+BSR_REG);
626
        #ifdef DEBUG
627
        printf ("Polling...\n");
628
        #endif
629
        SMC_SELECT_BANK (2);
630
        while ((REG16(ETH_BASE+SMC91111_INT_REG) & mask) == 0) {
631
                if (get_timer (0) >= tmo) {
632
                        is_timeout = 1;
633
                        break;
634
                }
635
        }
636
 
637
        /* restore old bank selection */
638
        SMC_SELECT_BANK (old_bank);
639
 
640
        if (is_timeout)
641
                return 1;
642
        else
643
                return 0;
644
}
645
 
646
void eth_send(void *buf, unsigned long len) {
647
 
648
        byte packet_no;
649
        byte *bufb;
650
        int length;
651
        int lengtht;
652
        int numPages;
653
        int try = 0;
654
        int time_out;
655
        byte status;
656
        byte saved_pnr;
657
        word saved_ptr;
658
 
659
        /* save PTR and PNR registers before manipulation */
660
        SMC_SELECT_BANK (2);
661
        saved_pnr = REG8( ETH_BASE+PN_REG );
662
        saved_ptr = REG16( ETH_BASE+PTR_REG );
663
        #ifdef DEBUG
664
        printf ("smc_hardware_send_packet\n");
665
        #endif
666
        length = ETH_ZLEN < len ? len : ETH_ZLEN;
667
 
668
        /* allocate memory
669
         ** The MMU wants the number of pages to be the number of 256 bytes
670
         ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
671
         **
672
         ** The 91C111 ignores the size bits, but the code is left intact
673
         ** for backwards and future compatibility.
674
         **
675
         ** Pkt size for allocating is data length +6 (for additional status
676
         ** words, length and ctl!)
677
         **
678
         ** If odd size then last byte is included in this header.
679
         */
680
        numPages = ((length & 0xfffe) + 6);
681
        numPages >>= 8;         /* Divide by 256 */
682
 
683
        if (numPages > 7) {
684
                printf ("Far too big packet error. \n");
685
                return;
686
        }
687
 
688
        /* now, try to allocate the memory */
689
        SMC_SELECT_BANK (2);
690
        REG16( ETH_BASE+MMU_CMD_REG)=MC_ALLOC | numPages;
691
 
692
        /* FIXME: the ALLOC_INT bit never gets set *
693
         * so the following will always give a     *
694
         * memory allocation error.                *
695
         * same code works in armboot though       *
696
         * -ro
697
         */
698
 
699
again:
700
        try++;
701
        time_out = MEMORY_WAIT_TIME;
702
        do {
703
                status = REG8( ETH_BASE+SMC91111_INT_REG);
704
                if (status & IM_ALLOC_INT) {
705
                        /* acknowledge the interrupt */
706
                        REG8( ETH_BASE+SMC91111_INT_REG)=IM_ALLOC_INT;
707
                        break;
708
                }
709
        } while (--time_out);
710
 
711
        if (!time_out) {
712
                if (try < SMC_ALLOC_MAX_TRY)
713
                        goto again;
714
                else
715
                        return;
716
        }
717
 
718
        /* I can send the packet now.. */
719
 
720
        bufb = (byte *) buf;
721
 
722
        /* If I get here, I _know_ there is a packet slot waiting for me */
723
        packet_no = REG8( ETH_BASE+AR_REG);
724
        if (packet_no & AR_FAILED) {
725
                /* or isn't there?  BAD CHIP! */
726
                printf ("Memory allocation failed. \n");
727
                return;
728
        }
729
 
730
        /* we have a packet address, so tell the card to use it */
731
        REG8( ETH_BASE+PN_REG)=packet_no;
732
        /* do not write new ptr value if Write data fifo not empty */
733
        while ( saved_ptr & PTR_NOTEMPTY )
734
                printf ("Write data fifo not empty!\n");
735
 
736
        /* point to the beginning of the packet */
737
        REG16( ETH_BASE+PTR_REG)=PTR_AUTOINC;
738
 
739
 
740
        /* send the packet length ( +6 for status, length and ctl byte )
741
           and the status word ( set to zeros ) */
742
        REG16(ETH_BASE+SMC91111_DATA_REG)=0;
743
        /* send the packet length ( +6 for status words, length, and ctl */
744
        REG16(ETH_BASE+SMC91111_DATA_REG)=length + 6;
745
 
746
 
747
        /* send the actual data */
748
        lengtht=length>>1;
749
        while(lengtht-->0){
750
          REG16(ETH_BASE+SMC91111_DATA_REG)=SWAP16(*((word*)bufb));
751
          bufb+=sizeof(word);
752
        }
753
 
754
 
755
        /* Send the last byte, if there is one.   */
756
        if ((length & 1) == 0) {
757
                REG16(ETH_BASE+SMC91111_DATA_REG)=0;
758
        } else {
759
                REG16(ETH_BASE+SMC91111_DATA_REG)=bufb[length - 1] | 0x2000;
760
        }
761
 
762
        /* and let the chipset deal with it */
763
        REG16(ETH_BASE+MMU_CMD_REG)=MC_ENQUEUE;
764
 
765
        /* poll for TX INT */
766
        /* if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) { */
767
        /* poll for TX_EMPTY INT - autorelease enabled */
768
        if (poll4int(IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
769
                /* sending failed */
770
                printf ("TX timeout, sending failed...\n");
771
 
772
                /* release packet */
773
                /* no need to release, MMU does that now */
774
 
775
                /* wait for MMU getting ready (low) */
776
                while (REG16(ETH_BASE+MMU_CMD_REG) & MC_BUSY) {
777
                        udelay (10);
778
                }
779
 
780
                printf ("MMU ready\n");
781
 
782
 
783
                return;
784
        } else {
785
                /* ack. int */
786
                REG8(ETH_BASE+SMC91111_INT_REG)=IM_TX_EMPTY_INT;
787
                /* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
788
                #ifdef DEBUG
789
                printf ("Sent packet of length %u\n",length);
790
                #endif
791
 
792
                /* release packet */
793
                /* no need to release, MMU does that now */
794
 
795
                /* wait for MMU getting ready (low) */
796
                while (REG16(ETH_BASE+MMU_CMD_REG) & MC_BUSY) {
797
                        udelay (10);
798
                }
799
 
800
        }
801
 
802
        /* restore previously saved registers */
803
        REG8(ETH_BASE+PN_REG)=saved_pnr;
804
        REG16(ETH_BASE+PTR_REG)=saved_ptr, PTR_REG;
805
 
806
        return;
807
 
808
}
809
 
810
#endif

powered by: WebSVN 2.1.0

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