gonzui


Format: Advanced Search

t2ex/t2ex_source/driver/tef_em1d/netdrv/src/smsc9118.cbare sourcepermlink (0.08 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: /*
   15:  * This software package is available for use, modification, 
   16:  * and redistribution in accordance with the terms of the attached 
   17:  * T-License 2.x.
   18:  * If you want to redistribute the source code, you need to attach 
   19:  * the T-License 2.x document.
   20:  * There's no obligation to publish the content, and no obligation 
   21:  * to disclose it to the TRON Forum if you have modified the 
   22:  * software package.
   23:  * You can also distribute the modified source code. In this case, 
   24:  * please register the modification to T-Kernel traceability service.
   25:  * People can know the history of modifications by the service, 
   26:  * and can be sure that the version you have inherited some 
   27:  * modification of a particular version or not.
   28:  *
   29:  *    http://trace.tron.org/tk/?lang=en
   30:  *    http://trace.tron.org/tk/?lang=ja
   31:  *
   32:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   33:  * the portion of the software that is copyrighted by Ken Sakamura or 
   34:  * the TRON Forum does not infringe the copyrights of a third party.
   35:  * However, it does not make any warranty other than this.
   36:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   37:  * responsible for any consequences or damages caused directly or
   38:  * indirectly by the use of this software package.
   39:  *
   40:  * The source codes in bsd_source.tar.gz in this software package are 
   41:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   42:  * They need to be changed or redistributed according to the 
   43:  * representation of each source header.
   44:  */
   45: 
   46: /*
   47:  *      @(#)smsc9118.c
   48:  *
   49:  */
   50: 
   51: #include "netdrv.h"
   52: 
   53: /* Definitions of I/O Address and size */
   54: #define SMSC9118_IOSZ           0x100
   55: 
   56: /* Definitions of registers */
   57: #define RX_DATA                 0x00
   58: #define TX_DATA                 0x20
   59: #define RX_STS                  0x40
   60: #define TX_STS                  0x48
   61: #define ID_REV                  0x50
   62: #define IRQ_CFG                 0x54
   63: #define INT_STS                 0x58
   64: #define INT_EN                  0x5c
   65: #define BYTE_TEST               0x64
   66: #define FIFO_INT                0x68
   67: #define RX_CFG                  0x6c
   68: #define TX_CFG                  0x70
   69: #define HW_CFG                  0x74
   70: #define RX_DP_CTL               0x78
   71: #define RX_FIFO_INF             0x7c
   72: #define TX_FIFO_INF             0x80
   73: #define PMT_CTRL                0x84
   74: #define GPIO_CFG                0x88
   75: #define ENDIAN                  0x98
   76: #define RX_DROP                 0xa0
   77: #define MAC_CSR_CMD             0xa4
   78: #define MAC_CSR_DATA            0xa8
   79: #define AFC_CFG                 0xac
   80: #define E2P_CMD                 0xb0
   81: #define E2P_DATA                0xb4
   82: 
   83: /* IRQ_CFG */
   84: #define IRQ_CFG_INT_DEAS(x)     ((x) << 24)
   85: #define IRQ_CFG_IRQ_EN          (1 << 8)
   86: #define IRQ_CFG_IRQ_POL         (1 << 4)
   87: #define IRQ_CFG_IRQ_TYPE        (1 << 0)
   88: 
   89: /* INT_STS, INT_EN */
   90: #define INT_TXSTOP              (1 << 25)
   91: #define INT_RXSTOP              (1 << 24)
   92: #define INT_TSFF                (1 << 8)
   93: #define INT_TSFL                (1 << 7)
   94: #define INT_RSFF                (1 << 4)
   95: #define INT_RSFL                (1 << 3)
   96: 
   97: /* BYTE_TEST */
   98: #define BYTE_TEST_MAGIC         0x87654321
   99: 
  100: /* FIFO_INT */
  101: #define FIFO_INT_TSFL(x)        ((x) << 16)
  102: #define FIFO_INT_RSFL(x)        ((x) << 0)
  103: 
  104: /* RX_CFG */
  105: #define RX_CFG_ALIGN_4          (0 << 30)
  106: #define RX_CFG_DUMP             (1 << 15)
  107: #define RX_CFG_DOFF(x)          ((x) << 8)
  108: 
  109: /* TX_CFG */
  110: #define TX_CFG_SDUMP            (1 << 15)
  111: #define TX_CFG_DDUMP            (1 << 14)
  112: #define TX_CFG_ON               (1 << 1)
  113: #define TX_CFG_STOP             (1 << 0)
  114: 
  115: /* HW_CFG */
  116: #define HW_CFG_SF               (1 << 20)
  117: #define HW_CFG_TX_FIF_SZ(x)     ((x) << 16)
  118: #define HW_CFG_PHY_CLK_INT      (0 << 5)
  119: #define HW_CFG_SRST_TO          (1 << 1)
  120: #define HW_CFG_SRST             (1 << 0)
  121: 
  122: /* RX_DP_CTL */
  123: #define RX_DP_CTL_FFWD          (1 << 31)
  124: 
  125: /* PMT_CTRL */
  126: #define PMT_CTRL_PM_MODE(x)     ((x) << 12)
  127: #define PMT_CTRL_PHY_RST        (1 << 10)
  128: #define PMT_CTRL_READY          (1 << 0)
  129: 
  130: /* MAC_CSR_CMD */
  131: #define MAC_CSR_CMD_BUSY        (1 << 31)
  132: #define MAC_CSR_CMD_READ        (1 << 30)
  133: #define MAC_CSR_CMD_ADDR(x)     ((x) << 0)
  134: 
  135: /* E2P_CMD */
  136: #define E2P_CMD_BUSY            (1 << 31)
  137: #define E2P_CMD_READ            (0 << 28)
  138: #define E2P_CMD_TMO             (1 << 9)
  139: #define E2P_CMD_ADDR(x)         ((x) << 0)
  140: 
  141: /* MAC Control and Status Registers */
  142: #define MAC_CR                  0x01
  143: #define ADDRH                   0x02
  144: #define ADDRL                   0x03
  145: #define HASHH                   0x04
  146: #define HASHL                   0x05
  147: #define MII_ACC                 0x06
  148: #define MII_DATA                0x07
  149: #define FLOW                    0x08
  150: #define VLAN1                   0x09
  151: #define VLAN2                   0x0a
  152: #define WUFF                    0x0b
  153: #define WUCSR                   0x0c
  154: 
  155: /* MAC_CR */
  156: #define MAC_CR_FDPX             (1 << 20)
  157: #define MAC_CR_TXEN             (1 << 3)
  158: #define MAC_CR_RXEN             (1 << 2)
  159: 
  160: /* MII_ACC */
  161: #define MII_ACC_PHYADR(x)       ((x) << 11)
  162: #define MII_ACC_MIIRINDA(x)     ((x) << 6)
  163: #define MII_ACC_MIIWnR          (1 << 1)
  164: #define MII_ACC_MIIBZY          (1 << 0)
  165: 
  166: /* Parameters in NetInf */
  167: #define BadState                wrk.uw[0]
  168: #define ChipID                  wrk.uw[3]
  169: #define IntMask                 wrk.uw[6]
  170: 
  171: /* RX Status */
  172: #define RX_STS_ES               (1 << 15)
  173: 
  174: /* TX Command 'A' */
  175: #define TX_CMDA_ALIGN_4         (0 << 24)
  176: #define TX_CMDA_OFFSET(x)       ((x) << 16)
  177: #define TX_CMDA_FS              (1 << 13)
  178: #define TX_CMDA_LS              (1 << 12)
  179: #define TX_CMDA_BUFSZ(x)        ((x) << 0)
  180: 
  181: /* TX Command 'B' */
  182: #define TX_CMDB_PADDIS          (1 << 12)
  183: #define TX_CMDB_PKTSZ(x)        ((x) << 0)
  184: 
  185: /* TX Status */
  186: #define TX_STS_ES               (1 << 15)
  187: 
  188: /* I/O access offset */
  189: #define IOBase                  di.iobase
  190: 
  191: #define POLL_LIMIT              100000              /* x 45ns */
  192: #define DLY_LIMIT               100          /* x 10ms */
  193: 
  194: #define TX_FIFO_SIZE            5         // Tx FIFO size, kByte
  195: 
  196: /* Vendor Name, Product Name */
  197: LOCAL   const UB  *SMSC9118_PNAME1[] = {
  198:         "SMSC ",
  199: };
  200: 
  201: LOCAL   const UB  *SMSC9118_PNAME2[] = {
  202:         "LAN9118 family",
  203: };
  204: 
  205: 
  206: /*
  207:  *      Wait for not busy of register
  208:  */
  209: LOCAL   void      wait_reg(NetInf *inf, W reg, W mask, W val)
  210: {
  211:         UW     IOB = inf->IOBase;
  212:         W      i;
  213: 
  214:         for (i = POLL_LIMIT; i > 0; i--) {
  215:                 InW(BYTE_TEST);               /* needs delay of 1 read */
  216:                 if ((InW(reg) & mask) == val) goto fin0;
  217:         }
  218:         for (i = DLY_LIMIT; i > 0; i--) {
  219:                 if (tk_dly_tsk(10) < E_OK) InW(BYTE_TEST);
  220:                 if ((InW(reg) & mask) == val) goto fin0;
  221:         }
  222: 
  223:         inf->BadState = 1;
  224:         DP(("wait_reg: reg %#x mask %#x timeout\n", reg, mask));
  225:  fin0:
  226:         return;
  227: }
  228: 
  229: /*
  230:  *      Wait for not busy of MAC register
  231:  */
  232: #define wait_mac(inf)   wait_reg((inf), MAC_CSR_CMD, MAC_CSR_CMD_BUSY, 0)
  233: 
  234: /*
  235:  *      Write to MAC register
  236:  */
  237: LOCAL   void      poke_mac(NetInf *inf, W reg, W dat)
  238: {
  239:         UW     IOB = inf->IOBase;
  240: 
  241:         wait_mac(inf);
  242:         OutW(MAC_CSR_DATA, dat);
  243:         OutW(MAC_CSR_CMD, reg | MAC_CSR_CMD_BUSY);
  244:         wait_mac(inf);
  245: 
  246:         return;
  247: }
  248: 
  249: /*
  250:  *      Read from MAC register
  251:  */
  252: LOCAL   W peek_mac(NetInf *inf, W reg)
  253: {
  254:         UW     IOB = inf->IOBase;
  255: 
  256:         wait_mac(inf);
  257:         OutW(MAC_CSR_CMD, reg | MAC_CSR_CMD_BUSY | MAC_CSR_CMD_READ);
  258:         wait_mac(inf);
  259: 
  260:         return InW(MAC_CSR_DATA);
  261: }
  262: 
  263: /*
  264:  *      Wait for not busy of MII register
  265:  */
  266: LOCAL   void      wait_mii(NetInf *inf)
  267: {
  268:         W      i;
  269: 
  270:         for (i = POLL_LIMIT; i > 0; i--) {
  271:                 if (!(peek_mac(inf, MII_ACC) & MII_ACC_MIIBZY)) break;
  272:         }
  273: 
  274:         if (!i) {
  275:                 inf->BadState = 1;
  276:                 DP(("wait_mii: timeout\n"));
  277:         }
  278: 
  279:         return;
  280: }
  281: 
  282: /*
  283:  *      Write to MII register
  284:  */
  285: LOCAL   void      poke_mii(NetInf *inf, W adr, W reg, W dat)
  286: {
  287:         wait_mii(inf);
  288:         poke_mac(inf, MII_DATA, dat);
  289:         poke_mac(inf, MII_ACC, (MII_ACC_PHYADR(adr) | MII_ACC_MIIRINDA(reg) |
  290:                                 MII_ACC_MIIBZY | MII_ACC_MIIWnR));
  291:         wait_mii(inf);
  292: 
  293:         return;
  294: }
  295: 
  296: /*
  297:  *      Read from MII register
  298:  */
  299: LOCAL   UH        peek_mii(NetInf *inf, W adr, W reg)
  300: {
  301:         wait_mii(inf);
  302:         poke_mac(inf, MII_ACC, (MII_ACC_PHYADR(adr) | MII_ACC_MIIRINDA(reg) |
  303:                                 MII_ACC_MIIBZY));
  304:         wait_mii(inf);
  305: 
  306:         return peek_mac(inf, MII_DATA);
  307: }
  308: 
  309: /*
  310:  *      Wait for not busy of Serial EEPROM
  311:  */
  312: #define wait_srom(inf)  wait_reg((inf), E2P_CMD, E2P_CMD_BUSY, 0)
  313: 
  314: /*
  315:  *      Read from Serial EEPROM
  316:  */
  317: LOCAL   W peek_srom(NetInf *inf, W adr)
  318: {
  319:         UW     IOB = inf->IOBase;
  320: 
  321:         wait_srom(inf);
  322:         OutW(E2P_CMD, (E2P_CMD_BUSY | E2P_CMD_READ |
  323:                        E2P_CMD_TMO | E2P_CMD_ADDR(adr)));
  324:         wait_srom(inf);
  325: 
  326:         return (InW(E2P_CMD) & E2P_CMD_TMO) ? -1 : InW(E2P_DATA);
  327: }
  328: 
  329: /*
  330:  *      Wake-up from D1(WOL), D2(Energy detect)
  331:  */
  332: LOCAL   void      smsc9118_wakeup(NetInf *inf)
  333: {
  334:         UW     IOB = inf->IOBase;
  335: 
  336:         /* D1(WOL), D2(Energy detect) -> D0(Normal operation) */
  337:         if (InW(PMT_CTRL) & PMT_CTRL_PM_MODE(3)) {
  338:                 OutW(BYTE_TEST, BYTE_TEST_MAGIC);     /* wake-up! */
  339:                 wait_reg(inf, PMT_CTRL, PMT_CTRL_READY, PMT_CTRL_READY);
  340:         }
  341: 
  342:         /* Initialize PHY */
  343:         OutW(PMT_CTRL, PMT_CTRL_PHY_RST);
  344:         WaitUsec(100);
  345:         wait_reg(inf, PMT_CTRL, PMT_CTRL_PHY_RST, 0);
  346: 
  347:         return;
  348: }
  349: 
  350: /*
  351:  *      Power control of PHY
  352:  */
  353: LOCAL   void      smsc9118_phyen(NetInf *inf, BOOL power_on)
  354: {
  355: #define BMCR_PDN        (1 << 11)
  356: 
  357:         W      adr;
  358: 
  359:         adr = MIIfind(inf, 1);
  360:         if (adr >= 0) {
  361:                 if (power_on) {
  362:                         poke_mii(inf, adr, 0,
  363:                                  peek_mii(inf, adr, 0) & ~BMCR_PDN);
  364:                 } else {
  365:                         poke_mii(inf, adr, 0,
  366:                                  peek_mii(inf, adr, 0) | BMCR_PDN);
  367:                 }
  368:         }
  369: 
  370:         return;
  371: }
  372: 
  373: /*
  374:  *      Initialize controller
  375:  */
  376: LOCAL   void      smsc9118_reset(NetInf *inf, BOOL start)
  377: {
  378:         UW     IOB = inf->IOBase;
  379:         UW     cr;
  380: 
  381:         /* wake-up from sleep state */
  382:         smsc9118_wakeup(inf);
  383: 
  384:         /* Disable interrupt handler */
  385:         OutW(INT_EN, 0);
  386:         inf->IntMask = 0;
  387:         inf->BadState = 0;
  388:         inf->txbusy = FALSE;
  389: 
  390:         /* Power on of PHY */
  391:         smsc9118_phyen(inf, TRUE);
  392: 
  393:         /* Initialize */
  394:         OutW(HW_CFG, HW_CFG_SRST);
  395:         wait_reg(inf, HW_CFG, HW_CFG_SRST, 0);
  396:         wait_reg(inf, PMT_CTRL, PMT_CTRL_READY, PMT_CTRL_READY);
  397:         if (InW(HW_CFG) & HW_CFG_SRST_TO) inf->BadState = 1;
  398:         wait_srom(inf);                        // wait for EEPROM
  399:         if (start && inf->BadState) goto fin0;
  400: 
  401:         OutW(HW_CFG, HW_CFG_SF | HW_CFG_TX_FIF_SZ(TX_FIFO_SIZE) |
  402:              HW_CFG_PHY_CLK_INT);
  403:         OutW(AFC_CFG, 0x006e3740);
  404:         OutW(FIFO_INT, FIFO_INT_TSFL(0) | FIFO_INT_RSFL(0));
  405:         OutW(RX_CFG, RX_CFG_ALIGN_4 | RX_CFG_DUMP | RX_CFG_DOFF(0));
  406:         wait_reg(inf, RX_CFG, RX_CFG_DUMP, 0);
  407:         OutW(TX_CFG, TX_CFG_SDUMP | TX_CFG_DDUMP);
  408:         wait_reg(inf, TX_CFG, TX_CFG_SDUMP | TX_CFG_DDUMP, 0);
  409: #ifdef  GPIO_CFG_VAL
  410:         OutW(GPIO_CFG, GPIO_CFG_VAL);
  411: #else
  412:         OutW(GPIO_CFG, 0x70000000);    /* LED1-3 enable */
  413: #endif
  414:         InW(RX_DROP);  /* RX Dropped Frame Counter: clear */
  415: 
  416:         /* Setting of MAC address */
  417:         poke_mac(inf, ADDRH, *((UH *)&inf->eaddr.c[4]));
  418:         poke_mac(inf, ADDRL, *((UW *)&inf->eaddr.c[0]));
  419: 
  420:         /* Disable multicast filter */
  421:         poke_mac(inf, HASHH, 0);
  422:         poke_mac(inf, HASHL, 0);
  423: 
  424:         /* Initialize MII */
  425:         MIIinit(inf, 1);
  426: 
  427:         /* that's all, in case of operation stopped */
  428:         if (!start) {
  429:                 smsc9118_phyen(inf, FALSE);
  430:                 goto fin0;
  431:         }
  432: 
  433:         /* Wait for MII startup */
  434:         tk_dly_tsk(1500);
  435: 
  436:         /* Clear PHY status register */
  437:         peek_mii(inf, 1, 1);
  438: 
  439:         /* Enable both transmitter and receiver */
  440:         OutW(TX_CFG, TX_CFG_ON);
  441:         cr = MAC_CR_TXEN | MAC_CR_RXEN;
  442:         if (isFDX(inf)) cr |= MAC_CR_FDPX;
  443:         poke_mac(inf, MAC_CR, cr);
  444: 
  445:         /* Enable interrupt */
  446: #ifdef  IRQ_CFG_VAL
  447:         OutW(IRQ_CFG, IRQ_CFG_IRQ_EN | IRQ_CFG_VAL);
  448: #else
  449:         OutW(IRQ_CFG, (IRQ_CFG_INT_DEAS(22) |
  450:                        IRQ_CFG_IRQ_EN | IRQ_CFG_IRQ_TYPE)); /* Low/Push-Pull */
  451: #endif
  452:         inf->IntMask = (INT_TXSTOP | INT_RXSTOP |
  453:                         INT_TSFF | INT_TSFL | INT_RSFF | INT_RSFL);
  454:         OutW(INT_EN, inf->IntMask);
  455:  fin0:
  456:         return;
  457: }
  458: 
  459: /*
  460:  *      Read a packet from FIFO
  461:  */
  462: Inline  void     smsc9118_poprx(NetInf *inf, UB *bp, W len)
  463: {
  464:         UW     IOB = inf->IOBase;
  465:         UW     d;
  466: 
  467:         /* Write into memory according to byte align */
  468:         switch ((W)bp & 3) {
  469:         case   0:        /* W units */
  470:                 for (; len > 7; len -= 4) {
  471:                         *(UW *)bp = InW(RX_DATA);
  472:                         bp += 4;
  473:                 }
  474:                 break;
  475:         case   2:        /* H units */
  476:                 for (; len > 7; len -= 4) {
  477:                         d = InW(RX_DATA);
  478:                         *(UH *)bp = d;
  479:                         bp += 2;
  480:                         *(UH *)bp = d >> 16;
  481:                         bp += 2;
  482:                 }
  483:                 break;
  484:         default:       /* B units */
  485:                 for (; len > 7; len -= 4) {
  486:                         d = InW(RX_DATA);
  487:                         *bp++ = d;
  488:                         *bp++ = d >> 8;
  489:                         *bp++ = d >> 16;
  490:                         *bp++ = d >> 24;
  491:                 }
  492:                 break;
  493:         }
  494: 
  495:         /* Final effective data (before CRC) */
  496:         if (len >= 4) {
  497:                 d = InW(RX_DATA);
  498:                 switch (len) {
  499:                 case  7:       bp[2] = d >> 16;      /* fall-through */
  500:                 case  6:       bp[1] = d >> 8;               /* fall-through */
  501:                 case  5:       bp[0] = d;            /* fall-through */
  502:                 default:      break;
  503:                 }
  504:                 len -= 4;
  505:         }
  506: 
  507:         /* read out CRC */
  508:         if (len) InW(RX_DATA);
  509: 
  510:         return;
  511: }
  512: 
  513: /*
  514:  *      Completion of reception
  515:  */
  516: Inline  void     smsc9118_receive(NetInf *inf)
  517: {
  518:         UW     IOB = inf->IOBase;
  519:         UW     i, rxsused, sts, len, pktlen;
  520:         UB     *bp;
  521: 
  522:         /* Get number of waiting status */
  523:         rxsused = (InW(RX_FIFO_INF) >> 16) & 0xff;
  524: 
  525:         /* Process each waiting status */
  526:         for (i = 0; i < rxsused; i++) {
  527:                 sts = InW(RX_STS);
  528:                 len = (sts >> 16) & 0x3fff;   /* size including CRC */
  529:                 pktlen = len - 4;             /* size excluding CRC */
  530: 
  531:                 if (sts & RX_STS_ES) {
  532:                         inf->stinf.rxerr++;
  533:                         inf->stinf.other[2] |= sts;
  534: 
  535:                 } else if ((pktlen < inf->bufsz.minsz) ||
  536:                            (pktlen > inf->bufsz.maxsz)) {
  537:                         inf->stinf.invpkt++;
  538: 
  539:                 } else if (inf->mbfid > 0) {
  540:                         bp = GetRxBuf(inf);
  541: 
  542:                         if (bp == NULL) {
  543:                                 inf->stinf.misspkt++;
  544:                         } else {
  545:                                 /* Store received data into buffer */
  546:                                 smsc9118_poprx(inf, bp, len);
  547:                                 SendMsg(inf, bp, pktlen);
  548:                                 continue;
  549:                         }
  550:                 }
  551: 
  552:                 /* Abandon received data - FastForward can be used
  553:                                 when the length is greater equal to 4 words */
  554:                 len = (len + 3) / 4;
  555:                 if (len >= 4) {
  556:                         OutW(RX_DP_CTL, RX_DP_CTL_FFWD);
  557:                         wait_reg(inf, RX_DP_CTL, RX_DP_CTL_FFWD, 0);
  558:                 } else {
  559:                         for (; len > 0; len--) InW(RX_DATA);
  560:                 }
  561:         }
  562: 
  563:         return;
  564: }
  565: 
  566: /*
  567:  *      Check FIFO empty space - Max packet size and TxCommand A/B
  568:  */
  569: #define TXFIFOisReady   ((InW(TX_FIFO_INF) & 0xffff) >= MAXPKTLEN + 8)
  570: 
  571: /*
  572:  *      Completion of transmission
  573:  */
  574: Inline  void     smsc9118_sendcomplete(NetInf *inf)
  575: {
  576:         UW     IOB = inf->IOBase;
  577:         UW     i, txsused, sts;
  578: 
  579:         /* Get number of waiting status */
  580:         txsused = (InW(TX_FIFO_INF) >> 16) & 0xff;
  581: 
  582:         /* Process each waiting status */
  583:         for (i = 0; i < txsused; i++) {
  584:                 sts = InW(TX_STS);
  585:                 if (sts & TX_STS_ES) {
  586:                         inf->stinf.txerr++;
  587:                         inf->stinf.other[1] |= sts;
  588:                 }
  589:                 inf->stinf.collision += (sts >> 3) & 0x0f;
  590:         }
  591: 
  592:         /* When the empty space in the FIFO becomes sufficient,
  593:                                 notify the transmission permission. */
  594:         if (inf->txbusy && TXFIFOisReady) {
  595:                 inf->txbusy = FALSE;
  596:                 SendMsg(inf, NULL, 0);
  597:         }
  598: 
  599:         return;
  600: }
  601: 
  602: /*
  603:  *      Interrupt handling
  604:  */
  605: LOCAL   void      smsc9118_inthdr(NetInf *inf)
  606: {
  607:         UW     IOB = inf->IOBase;
  608:         UW     sts, limit;
  609: 
  610:         inf->stinf.nint++;
  611:         limit = 1000000;       /* Limit of interrupt counts */
  612: 
  613:         while (1) {
  614:                 /* Get interrupt status */
  615:                 sts = InW(INT_STS);
  616:                 OutW(INT_STS, sts & ~inf->IntMask);
  617: 
  618:                 /* Finish when no effective interrupt */
  619:                 if (!(sts & inf->IntMask)) break;
  620: 
  621:                 /* When too many interrupt occurs, finish as abnormal. */
  622:                 if (--limit < 0) {
  623:                         inf->stinf.hwerr++;
  624:                         smsc9118_reset(inf, FALSE);
  625:                         break;
  626:                 }
  627: 
  628:                 /* Receive interrupt*/
  629:                 if (sts & (INT_RSFF | INT_RSFL)) {
  630:                         inf->stinf.rxint++;
  631:                         smsc9118_receive(inf);
  632:                         OutW(INT_STS, sts & (INT_RSFF | INT_RSFL));
  633:                 }
  634: 
  635:                 /* Transmit interrupt */
  636:                 if (sts & (INT_TSFF | INT_TSFL)) {
  637:                         inf->stinf.txint++;
  638:                         smsc9118_sendcomplete(inf);
  639:                         OutW(INT_STS, sts & (INT_TSFF | INT_TSFL));
  640:                 }
  641: 
  642:                 /* Other interrupt */
  643:                 if (sts & (INT_TXSTOP | INT_RXSTOP)) {
  644:                         inf->stinf.hwerr++;
  645:                         smsc9118_reset(inf, TRUE);
  646:                         break;
  647:                 }
  648: 
  649:                 /* Wait for updating of interrupt status */
  650:                 InW(BYTE_TEST);
  651:         }
  652: 
  653:         return;
  654: }
  655: 
  656: /*
  657:  *      Transmit interrupt processing
  658:  */
  659: LOCAL   INT       smsc9118_send(NetInf *inf, UB *buf, W len)
  660: {
  661:         UW     IOB = inf->IOBase;
  662:         UW     i, d, ofs;
  663: 
  664:         /* In case of interrupt handler is inactive
  665:                                         or no space in transmit buffer. */
  666:         if (!inf->IntMask || inf->txbusy) {
  667:                 inf->stinf.txbusy++;
  668:                 return E_BUSY;
  669:         }
  670: 
  671:         /* Avoid conflict with the interrupt handler */
  672:         OutW(INT_EN, 0);
  673: 
  674:         /* Limit max length */
  675:         len = (len < MAXPKTLEN) ? len : MAXPKTLEN;
  676: 
  677:         /* Get offset in order to read by W units */
  678:         ofs = (W)buf & 3;
  679: 
  680:         /* Write TX Command A/B */
  681:         OutW(TX_DATA, (TX_CMDA_ALIGN_4 | TX_CMDA_OFFSET(ofs) |
  682:                        TX_CMDA_FS | TX_CMDA_LS | TX_CMDA_BUFSZ(len)));
  683:         OutW(TX_DATA, TX_CMDB_PADDIS | TX_CMDB_PKTSZ(len));
  684: 
  685:         /* Top of data (only when not aligned by 4-byte) */
  686:         if (ofs) {
  687:                 for (d = i = 0; i < 4 - ofs && len > 0; i++, len--, buf++) {
  688:                         d |= *buf << (((W)buf & 3) * 8);
  689:                 }
  690:                 OutW(TX_DATA, d);
  691:         }
  692: 
  693:         /* Middle of data (transfer by 4-byte units) */
  694:         for (; len > 3; len -= 4, buf += 4) OutW(TX_DATA, *(UW *)buf);
  695: 
  696:         /* Bottom of data (only when not aligned by 4-byte)  */
  697:         if (len) {
  698:                 d = 0;
  699:                 switch (len) {
  700:                 case  3:       d |= (buf[2] << 16);  /* fall-through */
  701:                 case  2:       d |= (buf[1] << 8);   /* fall-through */
  702:                 case  1:       d |=  buf[0];         /* fall-through */
  703:                 default:      break;
  704:                 }
  705:                 OutW(TX_DATA, d);
  706:         }
  707: 
  708:         /* When the empty space in the FIFO becomes sufficient,
  709:                                 notify the transmission permission. */
  710:         if (TXFIFOisReady) {
  711:                 SendMsg(inf, NULL, 0);
  712:         } else {
  713:                 inf->txbusy = TRUE;
  714:         }
  715: 
  716:         /* Enable interrupt */
  717:         OutW(INT_EN, inf->IntMask);
  718:         inf->stinf.txpkt++;
  719: 
  720:         return len;
  721: }
  722: 
  723: /*
  724:  *      Get controller status
  725:  */
  726: LOCAL   void      smsc9118_getstatus(NetInf *inf)
  727: {
  728:         UW     IOB = inf->IOBase;
  729: 
  730:         /* do nothing in close. */
  731:         if (!inf->opencnt) goto fin0;
  732: 
  733:         inf->stinf.overrun += InW(RX_DROP);
  734: 
  735:         /* Regards as Invalid, when the following cases:
  736:          * - Value of PMT_CTRL register is not READY.
  737:          * - Value of ENDIAN register is invalid (malfunction of controller).
  738:          * - Transmitter busy, or any status/data remains in transmit FIFO.
  739:          *   (at this time, transmission have been completed)
  740:          * - Can't read PHY Identifier (malfunction of PHY).
  741:          */
  742:         if (!(InW(PMT_CTRL) & PMT_CTRL_READY) ||
  743:             InW(BYTE_TEST) != BYTE_TEST_MAGIC ||
  744:             inf->txbusy || ((InW(TX_FIFO_INF) >> 16) & 0xff) ||
  745:             (InW(TX_FIFO_INF) & 0xffff) < (TX_FIFO_SIZE * 1024 - 512) ||
  746:             (peek_mii(inf, 1, 2) != 0x0007)) {
  747:                 inf->BadState = 1;
  748:         }
  749: 
  750:         /* Recover from the invalid state */
  751:         if (inf->BadState) {
  752:                 inf->stinf.other[0]++;
  753:                 DP(("smsc9118_getstatus: Bad state, try restart\n"));
  754: 
  755:                 smsc9118_reset(inf, TRUE);
  756:         }
  757: 
  758:  fin0:
  759:         return;
  760: }
  761: 
  762: /*
  763:  *      Probe the controller
  764:  */
  765: LOCAL   W smsc9118_probe(NetInf *inf)
  766: {
  767:         UW     IOB = inf->IOBase;
  768:         W      i, err;
  769: 
  770:         /* Disable interrupt handler */
  771:         inf->IntMask = 0;
  772: 
  773:         /* Wake-up from sleep state */
  774:         smsc9118_wakeup(inf);
  775: 
  776:         /* Read EndianCheck register */
  777:         if (InW(BYTE_TEST) != BYTE_TEST_MAGIC) {
  778:                 DP(("smsc9118_probe: LAN911x not found\n"));
  779:                 err = E_NOMDA;
  780:                 goto fin0;
  781:         }
  782: 
  783:         /* Invalid configuration, finish and return as OK */
  784:         if (inf->di.stat < E_OK) {
  785:                 err = E_OK;
  786:                 goto fin0;
  787:         }
  788: 
  789:         /* Disable interrupt, stop both transmitter and receiver */
  790:         OutW(INT_EN, 0);                               /* disable intr */
  791:         OutW(TX_CFG, TX_CFG_STOP);                     /* stop xmit */
  792:         wait_reg(inf, TX_CFG, TX_CFG_STOP, 0);
  793:         poke_mac(inf, MAC_CR,
  794:                  peek_mac(inf, MAC_CR) & ~(MAC_CR_TXEN | MAC_CR_RXEN));
  795: 
  796:         /* Power off PHY */
  797:         smsc9118_phyen(inf, FALSE);
  798: 
  799:         /* Set controller chip name */
  800:         inf->ChipID = InW(ID_REV);
  801:         DP(("smsc9118_probe: ID_REV %#x\n", inf->ChipID));
  802: 
  803:         /* Get MAC address */
  804:         for (i = 0; i < L_EADDR; i++) {
  805:                 inf->eaddr.c[i] = peek_srom(inf, i + 1);
  806:                 DP(("%02x ", inf->eaddr.c[i]));
  807:         }
  808:         DP(("\n"));
  809: 
  810:         /* Stay MAC on ( do not sleep) */
  811:         err = E_OK;
  812:  fin0:
  813:         return err;
  814: }
  815: 
  816: /*
  817:  *      Initialize SMSC LAN9118 driver
  818:  *
  819:  *      At return, the operation should not yet started, and the interrupt
  820:  *      should not occurred.
  821:  *
  822:  *      When the target device was detected, even if the normal operation
  823:  *      will not be expected, it should returns OK with error code in di.stat,
  824:  *      because when it returns error, the driver will be deleted.
  825:  *
  826:  *      PcCard
  827:  *              Performs only internal initialization. and set iosize.
  828:  *              Detection of the controller and hardware initialization will be
  829:  *              done in (*inf->cardchk)().
  830:  *              Always returns OK.
  831:  *
  832:  *      ISA
  833:  *              Performs detection of the controller, and hardware
  834:  *              initialization, then internal initialization.
  835:  *              The values of iob and irq are set by configuration, but when
  836:  *              the value is 0, it should detect automatically as much as
  837:  *              possible.
  838:  *              Returns error, only if detection of the controller was failed.
  839:  *
  840:  *      PCI
  841:  *              Performs hardware initialization and internal initialization.
  842:  *              the values of iob, iosize, irq, pciadr, and devix are set,
  843:  *              Always return OK, because the controller was detected.
  844:  *
  845:  *  <Processing of functions >
  846:  *
  847:  *      void inthdr(NetInf *inf) - Interrupt handler.
  848:  *              EndOfInt() does not needed.
  849:  *
  850:  *      INT sendfn(NetInf *inf, UB *buf, W len) - Transmit processing.
  851:  *              Transmits len bytes of data in the buf.
  852:  *              Returns len when the transmission is successful,
  853:  *              otherwise, returns E_BUSY.
  854:  *
  855:  *      void reset(NetInf *inf, BOOL start) - Reset processing.
  856:  *              start == TRUE : Start
  857:  *                       FALSE: Stop (No interrupt occurs)
  858:  *
  859:  *      ER cardchk(NetInf *inf) - Detection of PC card & initalization.
  860:  *              Returns OK when the detection of PC card is successful,
  861:  *              otherwise, returns error.
  862:  *              The values of iob, irq, devix, and name are set.
  863:  *              When returns OK, the controller should be in stop state 
  864:  *              (no interrupt occurs).
  865:  *              This function pointer may be NULL if no PC card supported.
  866:  */
  867: EXPORT  ER       InitSMSC9118(NetInf *inf, W init)
  868: {
  869:         ER     err;
  870: 
  871:         /* Finish processing */
  872:         if (init < 0) goto fin1;
  873: 
  874:         inf->di.iosize = SMSC9118_IOSZ;
  875: 
  876:         DP(("Net%c: InitSMSC9118 kind:%#x\n", NetUnit(inf), inf->di.kind));
  877: 
  878:         /* Set MII functions (should be set before probe) */
  879:         inf->mii_read  = peek_mii;
  880:         inf->mii_write = poke_mii;
  881: 
  882:         /* Probe controller */
  883:         err = smsc9118_probe(inf);
  884:         if (err < E_OK) goto fin0;
  885: 
  886:         /* Set product name */
  887:         SetProdName(inf, (UB **)SMSC9118_PNAME1, (UB **)SMSC9118_PNAME2);
  888: 
  889:         /* Set processing functions */
  890:         inf->inthdr  = smsc9118_inthdr;
  891:         inf->sendfn  = smsc9118_send;
  892:         inf->reset   = smsc9118_reset;
  893:         inf->cardchk = NULL;
  894:         inf->misc    = NULL;
  895:         inf->mcast   = NULL;
  896:         inf->tmout   = 10000;
  897:         inf->tmofn   = smsc9118_getstatus;
  898: 
  899:  fin1:
  900:         err = E_OK;
  901:  fin0:
  902:         return err;
  903: }
  904: