Annotation of qemu/roms/ipxe/src/drivers/net/ns83820.c, revision 1.1.1.1

1.1       root        1: /**************************************************************************
                      2: *    ns83820.c: Etherboot device driver for the National Semiconductor 83820
                      3: *    Written 2004 by Timothy Legge <[email protected]>
                      4: *
                      5: *    This program is free software; you can redistribute it and/or modify
                      6: *    it under the terms of the GNU General Public License as published by
                      7: *    the Free Software Foundation; either version 2 of the License, or
                      8: *    (at your option) any later version.
                      9: *
                     10: *    This program is distributed in the hope that it will be useful,
                     11: *    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12: *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13: *    GNU General Public License for more details.
                     14: *
                     15: *    You should have received a copy of the GNU General Public License
                     16: *    along with this program; if not, write to the Free Software
                     17: *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     18: *
                     19: *    Portions of this code based on:
                     20: *      ns83820.c by Benjamin LaHaise with contributions
                     21: *              for Linux kernel 2.4.x.
                     22: *      
                     23: *    Linux Driver Version 0.20, 20020610
                     24: * 
                     25: *    This development of this Etherboot driver was funded by:
                     26: *
                     27: *    NXTV: http://www.nxtv.com/
                     28: *      
                     29: *    REVISION HISTORY:
                     30: *    ================
                     31: *
                     32: *    v1.0      02-16-2004      timlegge        Initial port of Linux driver
                     33: *    v1.1      02-19-2004      timlegge        More rohbust transmit and poll
                     34: *    
                     35: *    Indent Options: indent -kr -i8
                     36: ***************************************************************************/
                     37: 
                     38: FILE_LICENCE ( GPL2_OR_LATER );
                     39: 
                     40: /* to get some global routines like printf */
                     41: #include "etherboot.h"
                     42: /* to get the interface to the body of the program */
                     43: #include "nic.h"
                     44: /* to get the PCI support functions, if this is a PCI NIC */
                     45: #include <ipxe/pci.h>
                     46: 
                     47: #if ARCH == ia64               /* Support 64-bit addressing */
                     48: #define USE_64BIT_ADDR
                     49: #endif
                     50: 
                     51: #define HZ 100
                     52: 
                     53: /* Condensed operations for readability. */
                     54: #define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
                     55: #define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
                     56: 
                     57: /* NIC specific static variables go here */
                     58: 
                     59: /* Global parameters.  See MODULE_PARM near the bottom. */
                     60: // static int ihr = 2;
                     61: static int reset_phy = 0;
                     62: static int lnksts = 0;         /* CFG_LNKSTS bit polarity */
                     63: 
                     64: #if defined(CONFIG_HIGHMEM64G) || defined(__ia64__)
                     65: #define USE_64BIT_ADDR "+"
                     66: #endif
                     67: 
                     68: #if defined(USE_64BIT_ADDR)
                     69: #define TRY_DAC        1
                     70: #else
                     71: #define TRY_DAC        0
                     72: #endif
                     73: 
                     74: /* tunables */
                     75: #define RX_BUF_SIZE    1500    /* 8192 */
                     76: 
                     77: /* Must not exceed ~65000. */
                     78: #define NR_RX_DESC     64
                     79: #define NR_TX_DESC     1
                     80: 
                     81:                   /* not tunable *//* Extra 6 bytes for 64 bit alignment (divisable by 8) */
                     82: #define REAL_RX_BUF_SIZE (RX_BUF_SIZE + 14 + 6)        /* rx/tx mac addr + type */
                     83: 
                     84: #define MIN_TX_DESC_FREE       8
                     85: 
                     86: /* register defines */
                     87: #define CFGCS          0x04
                     88: 
                     89: #define CR_TXE         0x00000001
                     90: #define CR_TXD         0x00000002
                     91: /* Ramit : Here's a tip, don't do a RXD immediately followed by an RXE
                     92:  * The Receive engine skips one descriptor and moves
                     93:  * onto the next one!! */
                     94: #define CR_RXE         0x00000004
                     95: #define CR_RXD         0x00000008
                     96: #define CR_TXR         0x00000010
                     97: #define CR_RXR         0x00000020
                     98: #define CR_SWI         0x00000080
                     99: #define CR_RST         0x00000100
                    100: 
                    101: #define PTSCR_EEBIST_FAIL       0x00000001
                    102: #define PTSCR_EEBIST_EN         0x00000002
                    103: #define PTSCR_EELOAD_EN         0x00000004
                    104: #define PTSCR_RBIST_FAIL        0x000001b8
                    105: #define PTSCR_RBIST_DONE        0x00000200
                    106: #define PTSCR_RBIST_EN          0x00000400
                    107: #define PTSCR_RBIST_RST         0x00002000
                    108: 
                    109: #define MEAR_EEDI              0x00000001
                    110: #define MEAR_EEDO              0x00000002
                    111: #define MEAR_EECLK             0x00000004
                    112: #define MEAR_EESEL             0x00000008
                    113: #define MEAR_MDIO              0x00000010
                    114: #define MEAR_MDDIR             0x00000020
                    115: #define MEAR_MDC               0x00000040
                    116: 
                    117: #define ISR_TXDESC3    0x40000000
                    118: #define ISR_TXDESC2    0x20000000
                    119: #define ISR_TXDESC1    0x10000000
                    120: #define ISR_TXDESC0    0x08000000
                    121: #define ISR_RXDESC3    0x04000000
                    122: #define ISR_RXDESC2    0x02000000
                    123: #define ISR_RXDESC1    0x01000000
                    124: #define ISR_RXDESC0    0x00800000
                    125: #define ISR_TXRCMP     0x00400000
                    126: #define ISR_RXRCMP     0x00200000
                    127: #define ISR_DPERR      0x00100000
                    128: #define ISR_SSERR      0x00080000
                    129: #define ISR_RMABT      0x00040000
                    130: #define ISR_RTABT      0x00020000
                    131: #define ISR_RXSOVR     0x00010000
                    132: #define ISR_HIBINT     0x00008000
                    133: #define ISR_PHY                0x00004000
                    134: #define ISR_PME                0x00002000
                    135: #define ISR_SWI                0x00001000
                    136: #define ISR_MIB                0x00000800
                    137: #define ISR_TXURN      0x00000400
                    138: #define ISR_TXIDLE     0x00000200
                    139: #define ISR_TXERR      0x00000100
                    140: #define ISR_TXDESC     0x00000080
                    141: #define ISR_TXOK       0x00000040
                    142: #define ISR_RXORN      0x00000020
                    143: #define ISR_RXIDLE     0x00000010
                    144: #define ISR_RXEARLY    0x00000008
                    145: #define ISR_RXERR      0x00000004
                    146: #define ISR_RXDESC     0x00000002
                    147: #define ISR_RXOK       0x00000001
                    148: 
                    149: #define TXCFG_CSI      0x80000000
                    150: #define TXCFG_HBI      0x40000000
                    151: #define TXCFG_MLB      0x20000000
                    152: #define TXCFG_ATP      0x10000000
                    153: #define TXCFG_ECRETRY  0x00800000
                    154: #define TXCFG_BRST_DIS 0x00080000
                    155: #define TXCFG_MXDMA1024        0x00000000
                    156: #define TXCFG_MXDMA512 0x00700000
                    157: #define TXCFG_MXDMA256 0x00600000
                    158: #define TXCFG_MXDMA128 0x00500000
                    159: #define TXCFG_MXDMA64  0x00400000
                    160: #define TXCFG_MXDMA32  0x00300000
                    161: #define TXCFG_MXDMA16  0x00200000
                    162: #define TXCFG_MXDMA8   0x00100000
                    163: 
                    164: #define CFG_LNKSTS     0x80000000
                    165: #define CFG_SPDSTS     0x60000000
                    166: #define CFG_SPDSTS1    0x40000000
                    167: #define CFG_SPDSTS0    0x20000000
                    168: #define CFG_DUPSTS     0x10000000
                    169: #define CFG_TBI_EN     0x01000000
                    170: #define CFG_MODE_1000  0x00400000
                    171: /* Ramit : Dont' ever use AUTO_1000, it never works and is buggy.
                    172:  * Read the Phy response and then configure the MAC accordingly */
                    173: #define CFG_AUTO_1000  0x00200000
                    174: #define CFG_PINT_CTL   0x001c0000
                    175: #define CFG_PINT_DUPSTS        0x00100000
                    176: #define CFG_PINT_LNKSTS        0x00080000
                    177: #define CFG_PINT_SPDSTS        0x00040000
                    178: #define CFG_TMRTEST    0x00020000
                    179: #define CFG_MRM_DIS    0x00010000
                    180: #define CFG_MWI_DIS    0x00008000
                    181: #define CFG_T64ADDR    0x00004000
                    182: #define CFG_PCI64_DET  0x00002000
                    183: #define CFG_DATA64_EN  0x00001000
                    184: #define CFG_M64ADDR    0x00000800
                    185: #define CFG_PHY_RST    0x00000400
                    186: #define CFG_PHY_DIS    0x00000200
                    187: #define CFG_EXTSTS_EN  0x00000100
                    188: #define CFG_REQALG     0x00000080
                    189: #define CFG_SB         0x00000040
                    190: #define CFG_POW                0x00000020
                    191: #define CFG_EXD                0x00000010
                    192: #define CFG_PESEL      0x00000008
                    193: #define CFG_BROM_DIS   0x00000004
                    194: #define CFG_EXT_125    0x00000002
                    195: #define CFG_BEM                0x00000001
                    196: 
                    197: #define EXTSTS_UDPPKT  0x00200000
                    198: #define EXTSTS_TCPPKT  0x00080000
                    199: #define EXTSTS_IPPKT   0x00020000
                    200: 
                    201: #define SPDSTS_POLARITY        (CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0))
                    202: 
                    203: #define MIBC_MIBS      0x00000008
                    204: #define MIBC_ACLR      0x00000004
                    205: #define MIBC_FRZ       0x00000002
                    206: #define MIBC_WRN       0x00000001
                    207: 
                    208: #define PCR_PSEN       (1 << 31)
                    209: #define PCR_PS_MCAST   (1 << 30)
                    210: #define PCR_PS_DA      (1 << 29)
                    211: #define PCR_STHI_8     (3 << 23)
                    212: #define PCR_STLO_4     (1 << 23)
                    213: #define PCR_FFHI_8K    (3 << 21)
                    214: #define PCR_FFLO_4K    (1 << 21)
                    215: #define PCR_PAUSE_CNT  0xFFFE
                    216: 
                    217: #define RXCFG_AEP      0x80000000
                    218: #define RXCFG_ARP      0x40000000
                    219: #define RXCFG_STRIPCRC 0x20000000
                    220: #define RXCFG_RX_FD    0x10000000
                    221: #define RXCFG_ALP      0x08000000
                    222: #define RXCFG_AIRL     0x04000000
                    223: #define RXCFG_MXDMA512 0x00700000
                    224: #define RXCFG_DRTH     0x0000003e
                    225: #define RXCFG_DRTH0    0x00000002
                    226: 
                    227: #define RFCR_RFEN      0x80000000
                    228: #define RFCR_AAB       0x40000000
                    229: #define RFCR_AAM       0x20000000
                    230: #define RFCR_AAU       0x10000000
                    231: #define RFCR_APM       0x08000000
                    232: #define RFCR_APAT      0x07800000
                    233: #define RFCR_APAT3     0x04000000
                    234: #define RFCR_APAT2     0x02000000
                    235: #define RFCR_APAT1     0x01000000
                    236: #define RFCR_APAT0     0x00800000
                    237: #define RFCR_AARP      0x00400000
                    238: #define RFCR_MHEN      0x00200000
                    239: #define RFCR_UHEN      0x00100000
                    240: #define RFCR_ULM       0x00080000
                    241: 
                    242: #define VRCR_RUDPE     0x00000080
                    243: #define VRCR_RTCPE     0x00000040
                    244: #define VRCR_RIPE      0x00000020
                    245: #define VRCR_IPEN      0x00000010
                    246: #define VRCR_DUTF      0x00000008
                    247: #define VRCR_DVTF      0x00000004
                    248: #define VRCR_VTREN     0x00000002
                    249: #define VRCR_VTDEN     0x00000001
                    250: 
                    251: #define VTCR_PPCHK     0x00000008
                    252: #define VTCR_GCHK      0x00000004
                    253: #define VTCR_VPPTI     0x00000002
                    254: #define VTCR_VGTI      0x00000001
                    255: 
                    256: #define CR             0x00
                    257: #define CFG            0x04
                    258: #define MEAR           0x08
                    259: #define PTSCR          0x0c
                    260: #define        ISR             0x10
                    261: #define        IMR             0x14
                    262: #define        IER             0x18
                    263: #define        IHR             0x1c
                    264: #define TXDP           0x20
                    265: #define TXDP_HI                0x24
                    266: #define TXCFG          0x28
                    267: #define GPIOR          0x2c
                    268: #define RXDP           0x30
                    269: #define RXDP_HI                0x34
                    270: #define RXCFG          0x38
                    271: #define PQCR           0x3c
                    272: #define WCSR           0x40
                    273: #define PCR            0x44
                    274: #define RFCR           0x48
                    275: #define RFDR           0x4c
                    276: 
                    277: #define SRR            0x58
                    278: 
                    279: #define VRCR           0xbc
                    280: #define VTCR           0xc0
                    281: #define VDR            0xc4
                    282: #define CCSR           0xcc
                    283: 
                    284: #define TBICR          0xe0
                    285: #define TBISR          0xe4
                    286: #define TANAR          0xe8
                    287: #define TANLPAR                0xec
                    288: #define TANER          0xf0
                    289: #define TESR           0xf4
                    290: 
                    291: #define TBICR_MR_AN_ENABLE     0x00001000
                    292: #define TBICR_MR_RESTART_AN    0x00000200
                    293: 
                    294: #define TBISR_MR_LINK_STATUS   0x00000020
                    295: #define TBISR_MR_AN_COMPLETE   0x00000004
                    296: 
                    297: #define TANAR_PS2              0x00000100
                    298: #define TANAR_PS1              0x00000080
                    299: #define TANAR_HALF_DUP                 0x00000040
                    300: #define TANAR_FULL_DUP                 0x00000020
                    301: 
                    302: #define GPIOR_GP5_OE           0x00000200
                    303: #define GPIOR_GP4_OE           0x00000100
                    304: #define GPIOR_GP3_OE           0x00000080
                    305: #define GPIOR_GP2_OE           0x00000040
                    306: #define GPIOR_GP1_OE           0x00000020
                    307: #define GPIOR_GP3_OUT          0x00000004
                    308: #define GPIOR_GP1_OUT          0x00000001
                    309: 
                    310: #define LINK_AUTONEGOTIATE     0x01
                    311: #define LINK_DOWN              0x02
                    312: #define LINK_UP                        0x04
                    313: 
                    314: 
                    315: #define __kick_rx()    writel(CR_RXE, ns->base + CR)
                    316: 
                    317: #define kick_rx() do { \
                    318:        DBG("kick_rx: maybe kicking\n"); \
                    319:                writel(virt_to_le32desc(&rx_ring[ns->cur_rx]), ns->base + RXDP); \
                    320:                if (ns->next_rx == ns->next_empty) \
                    321:                        printf("uh-oh: next_rx == next_empty???\n"); \
                    322:                __kick_rx(); \
                    323: } while(0)
                    324: 
                    325: 
                    326: #ifdef USE_64BIT_ADDR
                    327: #define HW_ADDR_LEN    8
                    328: #else
                    329: #define HW_ADDR_LEN    4
                    330: #endif
                    331: 
                    332: #define CMDSTS_OWN     0x80000000
                    333: #define CMDSTS_MORE    0x40000000
                    334: #define CMDSTS_INTR    0x20000000
                    335: #define CMDSTS_ERR     0x10000000
                    336: #define CMDSTS_OK      0x08000000
                    337: #define CMDSTS_LEN_MASK        0x0000ffff
                    338: 
                    339: #define CMDSTS_DEST_MASK       0x01800000
                    340: #define CMDSTS_DEST_SELF       0x00800000
                    341: #define CMDSTS_DEST_MULTI      0x01000000
                    342: 
                    343: #define DESC_SIZE      8       /* Should be cache line sized */
                    344: 
                    345: #ifdef USE_64BIT_ADDR
                    346: struct ring_desc {
                    347:        uint64_t link;
                    348:        uint64_t bufptr;
                    349:        u32 cmdsts;
                    350:        u32 extsts;             /* Extended status field */
                    351: };
                    352: #else
                    353: struct ring_desc {
                    354:        u32 link;
                    355:        u32 bufptr;
                    356:        u32 cmdsts;
                    357:        u32 extsts;             /* Extended status field */
                    358: };
                    359: #endif
                    360: 
                    361: /* Private Storage for the NIC */
                    362: static struct ns83820_private {
                    363:        u8 *base;
                    364:        int up;
                    365:        long idle;
                    366:        u32 *next_rx_desc;
                    367:        u16 next_rx, next_empty;
                    368:        u32 cur_rx;
                    369:        u32 *descs;
                    370:        unsigned ihr;
                    371:        u32 CFG_cache;
                    372:        u32 MEAR_cache;
                    373:        u32 IMR_cache;
                    374:        int linkstate;
                    375:        u16 tx_done_idx;
                    376:        u16 tx_idx;
                    377:        u16 tx_intr_idx;
                    378:        u32 phy_descs;
                    379:        u32 *tx_descs;
                    380: 
                    381: } nsx;
                    382: static struct ns83820_private *ns;
                    383: 
                    384: /* Define the TX and RX Descriptor and Buffers */
                    385: struct {
                    386:        struct ring_desc tx_ring[NR_TX_DESC] __attribute__ ((aligned(8)));
                    387:        unsigned char txb[NR_TX_DESC * REAL_RX_BUF_SIZE];
                    388:        struct ring_desc rx_ring[NR_RX_DESC] __attribute__ ((aligned(8)));
                    389:        unsigned char rxb[NR_RX_DESC * REAL_RX_BUF_SIZE]
                    390:        __attribute__ ((aligned(8)));
                    391: } ns83820_bufs __shared;
                    392: #define tx_ring ns83820_bufs.tx_ring
                    393: #define rx_ring ns83820_bufs.rx_ring
                    394: #define txb ns83820_bufs.txb
                    395: #define rxb ns83820_bufs.rxb
                    396: 
                    397: static void phy_intr(struct nic *nic __unused)
                    398: {
                    399:        static char *speeds[] =
                    400:            { "10", "100", "1000", "1000(?)", "1000F" };
                    401:        u32 cfg, new_cfg;
                    402:        u32 tbisr, tanar, tanlpar;
                    403:        int speed, fullduplex, newlinkstate;
                    404: 
                    405:        cfg = readl(ns->base + CFG) ^ SPDSTS_POLARITY;
                    406:        if (ns->CFG_cache & CFG_TBI_EN) {
                    407:                /* we have an optical transceiver */
                    408:                tbisr = readl(ns->base + TBISR);
                    409:                tanar = readl(ns->base + TANAR);
                    410:                tanlpar = readl(ns->base + TANLPAR);
                    411:                DBG("phy_intr: tbisr=%hX, tanar=%hX, tanlpar=%hX\n",
                    412:                    tbisr, tanar, tanlpar);
                    413: 
                    414:                if ((fullduplex = (tanlpar & TANAR_FULL_DUP)
                    415:                     && (tanar & TANAR_FULL_DUP))) {
                    416: 
                    417:                        /* both of us are full duplex */
                    418:                        writel(readl(ns->base + TXCFG)
                    419:                               | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
                    420:                               ns->base + TXCFG);
                    421:                        writel(readl(ns->base + RXCFG) | RXCFG_RX_FD,
                    422:                               ns->base + RXCFG);
                    423:                        /* Light up full duplex LED */
                    424:                        writel(readl(ns->base + GPIOR) | GPIOR_GP1_OUT,
                    425:                               ns->base + GPIOR);
                    426: 
                    427:                } else if (((tanlpar & TANAR_HALF_DUP)
                    428:                            && (tanar & TANAR_HALF_DUP))
                    429:                           || ((tanlpar & TANAR_FULL_DUP)
                    430:                               && (tanar & TANAR_HALF_DUP))
                    431:                           || ((tanlpar & TANAR_HALF_DUP)
                    432:                               && (tanar & TANAR_FULL_DUP))) {
                    433: 
                    434:                        /* one or both of us are half duplex */
                    435:                        writel((readl(ns->base + TXCFG)
                    436:                                & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
                    437:                               ns->base + TXCFG);
                    438:                        writel(readl(ns->base + RXCFG) & ~RXCFG_RX_FD,
                    439:                               ns->base + RXCFG);
                    440:                        /* Turn off full duplex LED */
                    441:                        writel(readl(ns->base + GPIOR) & ~GPIOR_GP1_OUT,
                    442:                               ns->base + GPIOR);
                    443:                }
                    444: 
                    445:                speed = 4;      /* 1000F */
                    446: 
                    447:        } else {
                    448:                /* we have a copper transceiver */
                    449:                new_cfg =
                    450:                    ns->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
                    451: 
                    452:                if (cfg & CFG_SPDSTS1)
                    453:                        new_cfg |= CFG_MODE_1000;
                    454:                else
                    455:                        new_cfg &= ~CFG_MODE_1000;
                    456: 
                    457:                speed = ((cfg / CFG_SPDSTS0) & 3);
                    458:                fullduplex = (cfg & CFG_DUPSTS);
                    459: 
                    460:                if (fullduplex)
                    461:                        new_cfg |= CFG_SB;
                    462: 
                    463:                if ((cfg & CFG_LNKSTS) &&
                    464:                    ((new_cfg ^ ns->CFG_cache) & CFG_MODE_1000)) {
                    465:                        writel(new_cfg, ns->base + CFG);
                    466:                        ns->CFG_cache = new_cfg;
                    467:                }
                    468: 
                    469:                ns->CFG_cache &= ~CFG_SPDSTS;
                    470:                ns->CFG_cache |= cfg & CFG_SPDSTS;
                    471:        }
                    472: 
                    473:        newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
                    474: 
                    475:        if (newlinkstate & LINK_UP && ns->linkstate != newlinkstate) {
                    476:                printf("link now %s mbps, %s duplex and up.\n",
                    477:                       speeds[speed], fullduplex ? "full" : "half");
                    478:        } else if (newlinkstate & LINK_DOWN
                    479:                   && ns->linkstate != newlinkstate) {
                    480:                printf("link now down.\n");
                    481:        }
                    482:        ns->linkstate = newlinkstate;
                    483: }
                    484: static void ns83820_set_multicast(struct nic *nic __unused);
                    485: static void ns83820_setup_rx(struct nic *nic)
                    486: {
                    487:        unsigned i;
                    488:        ns->idle = 1;
                    489:        ns->next_rx = 0;
                    490:        ns->next_rx_desc = ns->descs;
                    491:        ns->next_empty = 0;
                    492:        ns->cur_rx = 0;
                    493: 
                    494: 
                    495:        for (i = 0; i < NR_RX_DESC; i++) {
                    496:                rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]);
                    497:                rx_ring[i].bufptr =
                    498:                    virt_to_le32desc(&rxb[i * REAL_RX_BUF_SIZE]);
                    499:                rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE);
                    500:                rx_ring[i].extsts = cpu_to_le32(0);
                    501:        }
                    502: //      No need to wrap the ring 
                    503: //      rx_ring[i].link = virt_to_le32desc(&rx_ring[0]);
                    504:        writel(0, ns->base + RXDP_HI);
                    505:        writel(virt_to_le32desc(&rx_ring[0]), ns->base + RXDP);
                    506: 
                    507:        DBG("starting receiver\n");
                    508: 
                    509:        writel(0x0001, ns->base + CCSR);
                    510:        writel(0, ns->base + RFCR);
                    511:        writel(0x7fc00000, ns->base + RFCR);
                    512:        writel(0xffc00000, ns->base + RFCR);
                    513: 
                    514:        ns->up = 1;
                    515: 
                    516:        phy_intr(nic);
                    517: 
                    518:        /* Okay, let it rip */
                    519:        ns->IMR_cache |= ISR_PHY;
                    520:        ns->IMR_cache |= ISR_RXRCMP;
                    521:        //dev->IMR_cache |= ISR_RXERR;
                    522:        //dev->IMR_cache |= ISR_RXOK;
                    523:        ns->IMR_cache |= ISR_RXORN;
                    524:        ns->IMR_cache |= ISR_RXSOVR;
                    525:        ns->IMR_cache |= ISR_RXDESC;
                    526:        ns->IMR_cache |= ISR_RXIDLE;
                    527:        ns->IMR_cache |= ISR_TXDESC;
                    528:        ns->IMR_cache |= ISR_TXIDLE;
                    529: 
                    530:        // No reason to enable interupts...
                    531:        // writel(ns->IMR_cache, ns->base + IMR);
                    532:        // writel(1, ns->base + IER);
                    533:        ns83820_set_multicast(nic);
                    534:        kick_rx();
                    535: }
                    536: 
                    537: 
                    538: static void ns83820_do_reset(struct nic *nic __unused, u32 which)
                    539: {
                    540:        DBG("resetting chip...\n");
                    541:        writel(which, ns->base + CR);
                    542:        do {
                    543: 
                    544:        } while (readl(ns->base + CR) & which);
                    545:        DBG("okay!\n");
                    546: }
                    547: 
                    548: static void ns83820_reset(struct nic *nic)
                    549: {
                    550:        unsigned i;
                    551:        DBG("ns83820_reset\n");
                    552: 
                    553:        writel(0, ns->base + PQCR);
                    554: 
                    555:        ns83820_setup_rx(nic);
                    556: 
                    557:        for (i = 0; i < NR_TX_DESC; i++) {
                    558:                tx_ring[i].link = 0;
                    559:                tx_ring[i].bufptr = 0;
                    560:                tx_ring[i].cmdsts = cpu_to_le32(0);
                    561:                tx_ring[i].extsts = cpu_to_le32(0);
                    562:        }
                    563: 
                    564:        ns->tx_idx = 0;
                    565:        ns->tx_done_idx = 0;
                    566:        writel(0, ns->base + TXDP_HI);
                    567:        return;
                    568: }
                    569: static void ns83820_getmac(struct nic *nic __unused, u8 * mac)
                    570: {
                    571:        unsigned i;
                    572:        for (i = 0; i < 3; i++) {
                    573:                u32 data;
                    574:                /* Read from the perfect match memory: this is loaded by
                    575:                 * the chip from the EEPROM via the EELOAD self test.
                    576:                 */
                    577:                writel(i * 2, ns->base + RFCR);
                    578:                data = readl(ns->base + RFDR);
                    579:                *mac++ = data;
                    580:                *mac++ = data >> 8;
                    581:        }
                    582: }
                    583: 
                    584: static void ns83820_set_multicast(struct nic *nic __unused)
                    585: {
                    586:        u8 *rfcr = ns->base + RFCR;
                    587:        u32 and_mask = 0xffffffff;
                    588:        u32 or_mask = 0;
                    589:        u32 val;
                    590: 
                    591:        /* Support Multicast */
                    592:        and_mask &= ~(RFCR_AAU | RFCR_AAM);
                    593:        or_mask |= RFCR_AAM;
                    594:        val = (readl(rfcr) & and_mask) | or_mask;
                    595:        /* Ramit : RFCR Write Fix doc says RFEN must be 0 modify other bits */
                    596:        writel(val & ~RFCR_RFEN, rfcr);
                    597:        writel(val, rfcr);
                    598: 
                    599: }
                    600: static void ns83820_run_bist(struct nic *nic __unused, const char *name,
                    601:                             u32 enable, u32 done, u32 fail)
                    602: {
                    603:        int timed_out = 0;
                    604:        long start;
                    605:        u32 status;
                    606:        int loops = 0;
                    607: 
                    608:        DBG("start %s\n", name);
                    609: 
                    610:            start = currticks();
                    611: 
                    612:        writel(enable, ns->base + PTSCR);
                    613:        for (;;) {
                    614:                loops++;
                    615:                status = readl(ns->base + PTSCR);
                    616:                if (!(status & enable))
                    617:                        break;
                    618:                if (status & done)
                    619:                        break;
                    620:                if (status & fail)
                    621:                        break;
                    622:                if ((currticks() - start) >= HZ) {
                    623:                        timed_out = 1;
                    624:                        break;
                    625:                }
                    626:        }
                    627: 
                    628:        if (status & fail)
                    629:          printf("%s failed! (0x%hX & 0x%hX)\n", name, (unsigned int) status, 
                    630:                 (unsigned int) fail);
                    631:        else if (timed_out)
                    632:                printf("run_bist %s timed out! (%hX)\n", name, (unsigned int) status);
                    633:        DBG("done %s in %d loops\n", name, loops);
                    634: }
                    635: 
                    636: /*************************************
                    637: Check Link
                    638: *************************************/
                    639: static void ns83820_check_intr(struct nic *nic) {
                    640:        int i;
                    641:        u32 isr = readl(ns->base + ISR);
                    642:        if(ISR_PHY & isr)
                    643:                phy_intr(nic);
                    644:        if(( ISR_RXIDLE | ISR_RXDESC | ISR_RXERR) & isr)
                    645:                kick_rx();
                    646:        for (i = 0; i < NR_RX_DESC; i++) {
                    647:                if (rx_ring[i].cmdsts == CMDSTS_OWN) {
                    648: //                     rx_ring[i].link = virt_to_le32desc(&rx_ring[i + 1]);
                    649:                        rx_ring[i].cmdsts = cpu_to_le32(REAL_RX_BUF_SIZE);
                    650:                }
                    651:        }
                    652: }
                    653: /**************************************************************************
                    654: POLL - Wait for a frame
                    655: ***************************************************************************/
                    656: static int ns83820_poll(struct nic *nic, int retrieve)
                    657: {
                    658:        /* return true if there's an ethernet packet ready to read */
                    659:        /* nic->packet should contain data on return */
                    660:        /* nic->packetlen should contain length of data */
                    661:        u32 cmdsts;
                    662:        int entry = ns->cur_rx;
                    663: 
                    664:        ns83820_check_intr(nic);
                    665: 
                    666:        cmdsts = le32_to_cpu(rx_ring[entry].cmdsts);
                    667: 
                    668:        if ( ! ( (CMDSTS_OWN & (cmdsts)) && (cmdsts != (CMDSTS_OWN)) ) )
                    669:          return 0;
                    670: 
                    671:        if ( ! retrieve ) return 1;
                    672: 
                    673:        if (! (CMDSTS_OK & cmdsts) )
                    674:          return 0;
                    675: 
                    676:        nic->packetlen = cmdsts & 0xffff;
                    677:        memcpy(nic->packet,
                    678:               rxb + (entry * REAL_RX_BUF_SIZE),
                    679:               nic->packetlen);
                    680:        //                      rx_ring[entry].link = 0;
                    681:        rx_ring[entry].cmdsts = cpu_to_le32(CMDSTS_OWN);
                    682: 
                    683:        ns->cur_rx = (ns->cur_rx + 1) % NR_RX_DESC;
                    684: 
                    685:        if (ns->cur_rx == 0)    /* We have wrapped the ring */
                    686:          kick_rx();
                    687: 
                    688:        return 1;
                    689: }
                    690: 
                    691: static inline void kick_tx(struct nic *nic __unused)
                    692: {
                    693:        DBG("kick_tx\n");
                    694:        writel(CR_TXE, ns->base + CR);
                    695: }
                    696: 
                    697: /**************************************************************************
                    698: TRANSMIT - Transmit a frame
                    699: ***************************************************************************/
                    700: static void ns83820_transmit(struct nic *nic, const char *d,   /* Destination */
                    701:                             unsigned int t,    /* Type */
                    702:                             unsigned int s,    /* size */
                    703:                             const char *p)
                    704: {                              /* Packet */
                    705:        /* send the packet to destination */
                    706: 
                    707:        u16 nstype;
                    708:        u32 cmdsts, extsts;
                    709:        int cur_tx = 0;
                    710:        u32 isr = readl(ns->base + ISR);
                    711:        if (ISR_TXIDLE & isr)
                    712:                kick_tx(nic);
                    713:        /* point to the current txb incase multiple tx_rings are used */
                    714:        memcpy(txb, d, ETH_ALEN);
                    715:        memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
                    716:        nstype = htons((u16) t);
                    717:        memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
                    718:        memcpy(txb + ETH_HLEN, p, s);
                    719:        s += ETH_HLEN;
                    720:        s &= 0x0FFF;
                    721:        while (s < ETH_ZLEN)
                    722:                txb[s++] = '\0';
                    723: 
                    724:        /* Setup the transmit descriptor */
                    725:        extsts = 0;
                    726:        extsts |= EXTSTS_UDPPKT;
                    727: 
                    728:        tx_ring[cur_tx].bufptr = virt_to_le32desc(&txb);
                    729:        tx_ring[cur_tx].extsts = cpu_to_le32(extsts);
                    730: 
                    731:        cmdsts = cpu_to_le32(0);
                    732:        cmdsts |= cpu_to_le32(CMDSTS_OWN | s);
                    733:        tx_ring[cur_tx].cmdsts = cpu_to_le32(cmdsts);
                    734: 
                    735:        writel(virt_to_le32desc(&tx_ring[0]), ns->base + TXDP);
                    736:        kick_tx(nic);
                    737: }
                    738: 
                    739: /**************************************************************************
                    740: DISABLE - Turn off ethernet interface
                    741: ***************************************************************************/
                    742: static void ns83820_disable ( struct nic *nic ) {
                    743: 
                    744:        /* put the card in its initial state */
                    745:        /* This function serves 3 purposes.
                    746:         * This disables DMA and interrupts so we don't receive
                    747:         *  unexpected packets or interrupts from the card after
                    748:         *  etherboot has finished. 
                    749:         * This frees resources so etherboot may use
                    750:         *  this driver on another interface
                    751:         * This allows etherboot to reinitialize the interface
                    752:         *  if something is something goes wrong.
                    753:         */
                    754:        /* disable interrupts */
                    755:        writel(0, ns->base + IMR);
                    756:        writel(0, ns->base + IER);
                    757:        readl(ns->base + IER);
                    758: 
                    759:        ns->up = 0;
                    760: 
                    761:        ns83820_do_reset(nic, CR_RST);
                    762: 
                    763:        ns->IMR_cache &=
                    764:            ~(ISR_RXOK | ISR_RXDESC | ISR_RXERR | ISR_RXEARLY |
                    765:              ISR_RXIDLE);
                    766:        writel(ns->IMR_cache, ns->base + IMR);
                    767: 
                    768:        /* touch the pci bus... */
                    769:        readl(ns->base + IMR);
                    770: 
                    771:        /* assumes the transmitter is already disabled and reset */
                    772:        writel(0, ns->base + RXDP_HI);
                    773:        writel(0, ns->base + RXDP);
                    774: }
                    775: 
                    776: /**************************************************************************
                    777: IRQ - Enable, Disable, or Force interrupts
                    778: ***************************************************************************/
                    779: static void ns83820_irq(struct nic *nic __unused, irq_action_t action __unused)
                    780: {
                    781:   switch ( action ) {
                    782:   case DISABLE :
                    783:     break;
                    784:   case ENABLE :
                    785:     break;
                    786:   case FORCE :
                    787:     break;
                    788:   }
                    789: }
                    790: 
                    791: static struct nic_operations ns83820_operations = {
                    792:        .connect        = dummy_connect,
                    793:        .poll           = ns83820_poll,
                    794:        .transmit       = ns83820_transmit,
                    795:        .irq            = ns83820_irq,
                    796: 
                    797: };
                    798: 
                    799: static struct pci_device_id ns83820_nics[] = {
                    800:        PCI_ROM(0x100b, 0x0022, "ns83820", "National Semiconductor 83820", 0),
                    801: };
                    802: 
                    803: PCI_DRIVER ( ns83820_driver, ns83820_nics, PCI_NO_CLASS );
                    804: 
                    805: /**************************************************************************
                    806: PROBE - Look for an adapter, this routine's visible to the outside
                    807: ***************************************************************************/
                    808: 
                    809: #define board_found 1
                    810: #define valid_link 0
                    811: static int ns83820_probe ( struct nic *nic, struct pci_device *pci ) {
                    812: 
                    813:        long addr;
                    814:        int using_dac = 0;
                    815: 
                    816:        if (pci->ioaddr == 0)
                    817:                return 0;
                    818: 
                    819:        printf("ns83820.c: Found %s, vendor=0x%hX, device=0x%hX\n",
                    820:               pci->id->name, pci->vendor, pci->device);
                    821: 
                    822:        /* point to private storage */
                    823:        ns = &nsx;
                    824: 
                    825:        adjust_pci_device(pci);
                    826: 
                    827:        addr = pci_bar_start(pci, PCI_BASE_ADDRESS_1);
                    828: 
                    829:        ns->base = ioremap(addr, (1UL << 12));
                    830: 
                    831:        if (!ns->base)
                    832:                return 0;
                    833: 
                    834:        nic->irqno  = 0;
                    835:        nic->ioaddr = pci->ioaddr & ~3;
                    836: 
                    837:        /* disable interrupts */
                    838:        writel(0, ns->base + IMR);
                    839:        writel(0, ns->base + IER);
                    840:        readl(ns->base + IER);
                    841: 
                    842:        ns->IMR_cache = 0;
                    843: 
                    844:        ns83820_do_reset(nic, CR_RST);
                    845: 
                    846:        /* Must reset the ram bist before running it */
                    847:        writel(PTSCR_RBIST_RST, ns->base + PTSCR);
                    848:        ns83820_run_bist(nic, "sram bist", PTSCR_RBIST_EN,
                    849:                         PTSCR_RBIST_DONE, PTSCR_RBIST_FAIL);
                    850:        ns83820_run_bist(nic, "eeprom bist", PTSCR_EEBIST_EN, 0,
                    851:                         PTSCR_EEBIST_FAIL);
                    852:        ns83820_run_bist(nic, "eeprom load", PTSCR_EELOAD_EN, 0, 0);
                    853: 
                    854:        /* I love config registers */
                    855:        ns->CFG_cache = readl(ns->base + CFG);
                    856: 
                    857:        if ((ns->CFG_cache & CFG_PCI64_DET)) {
                    858:                printf("%s: detected 64 bit PCI data bus.\n", pci->id->name);
                    859:                /*dev->CFG_cache |= CFG_DATA64_EN; */
                    860:                if (!(ns->CFG_cache & CFG_DATA64_EN))
                    861:                        printf
                    862:                            ("%s: EEPROM did not enable 64 bit bus.  Disabled.\n",
                    863:                             pci->id->name);
                    864:        } else
                    865:                ns->CFG_cache &= ~(CFG_DATA64_EN);
                    866: 
                    867:        ns->CFG_cache &= (CFG_TBI_EN | CFG_MRM_DIS | CFG_MWI_DIS |
                    868:                          CFG_T64ADDR | CFG_DATA64_EN | CFG_EXT_125 |
                    869:                          CFG_M64ADDR);
                    870:        ns->CFG_cache |=
                    871:            CFG_PINT_DUPSTS | CFG_PINT_LNKSTS | CFG_PINT_SPDSTS |
                    872:            CFG_EXTSTS_EN | CFG_EXD | CFG_PESEL;
                    873:        ns->CFG_cache |= CFG_REQALG;
                    874:        ns->CFG_cache |= CFG_POW;
                    875:        ns->CFG_cache |= CFG_TMRTEST;
                    876: 
                    877:        /* When compiled with 64 bit addressing, we must always enable
                    878:         * the 64 bit descriptor format.
                    879:         */
                    880: #ifdef USE_64BIT_ADDR
                    881:        ns->CFG_cache |= CFG_M64ADDR;
                    882: #endif
                    883: 
                    884: //FIXME: Enable section on dac or remove this
                    885:        if (using_dac)
                    886:                ns->CFG_cache |= CFG_T64ADDR;
                    887: 
                    888:        /* Big endian mode does not seem to do what the docs suggest */
                    889:        ns->CFG_cache &= ~CFG_BEM;
                    890: 
                    891:        /* setup optical transceiver if we have one */
                    892:        if (ns->CFG_cache & CFG_TBI_EN) {
                    893:                DBG("%s: enabling optical transceiver\n", pci->id->name);
                    894:                writel(readl(ns->base + GPIOR) | 0x3e8, ns->base + GPIOR);
                    895: 
                    896:                /* setup auto negotiation feature advertisement */
                    897:                writel(readl(ns->base + TANAR)
                    898:                       | TANAR_HALF_DUP | TANAR_FULL_DUP,
                    899:                       ns->base + TANAR);
                    900: 
                    901:                /* start auto negotiation */
                    902:                writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN,
                    903:                       ns->base + TBICR);
                    904:                writel(TBICR_MR_AN_ENABLE, ns->base + TBICR);
                    905:                ns->linkstate = LINK_AUTONEGOTIATE;
                    906: 
                    907:                ns->CFG_cache |= CFG_MODE_1000;
                    908:        }
                    909:        writel(ns->CFG_cache, ns->base + CFG);
                    910:        DBG("CFG: %hX\n", ns->CFG_cache);
                    911: 
                    912:        /* FIXME: reset_phy is defaulted to 0, should we reset anyway? */
                    913:        if (reset_phy) {
                    914:                DBG("%s: resetting phy\n", pci->id->name);
                    915:                writel(ns->CFG_cache | CFG_PHY_RST, ns->base + CFG);
                    916:                writel(ns->CFG_cache, ns->base + CFG);
                    917:        }
                    918: #if 0                          /* Huh?  This sets the PCI latency register.  Should be done via 
                    919:                                 * the PCI layer.  FIXME.
                    920:                                 */
                    921:        if (readl(dev->base + SRR))
                    922:                writel(readl(dev->base + 0x20c) | 0xfe00,
                    923:                       dev->base + 0x20c);
                    924: #endif
                    925: 
                    926:        /* Note!  The DMA burst size interacts with packet
                    927:         * transmission, such that the largest packet that
                    928:         * can be transmitted is 8192 - FLTH - burst size.
                    929:         * If only the transmit fifo was larger...
                    930:         */
                    931:        /* Ramit : 1024 DMA is not a good idea, it ends up banging 
                    932:         * some DELL and COMPAQ SMP systems */
                    933:        writel(TXCFG_CSI | TXCFG_HBI | TXCFG_ATP | TXCFG_MXDMA512
                    934:               | ((1600 / 32) * 0x100), ns->base + TXCFG);
                    935: 
                    936:        /* Set Rx to full duplex, don't accept runt, errored, long or length
                    937:         * range errored packets.  Use 512 byte DMA.
                    938:         */
                    939:        /* Ramit : 1024 DMA is not a good idea, it ends up banging 
                    940:         * some DELL and COMPAQ SMP systems 
                    941:         * Turn on ALP, only we are accpeting Jumbo Packets */
                    942:        writel(RXCFG_AEP | RXCFG_ARP | RXCFG_AIRL | RXCFG_RX_FD
                    943:               | RXCFG_STRIPCRC
                    944:               //| RXCFG_ALP
                    945:               | (RXCFG_MXDMA512) | 0, ns->base + RXCFG);
                    946: 
                    947:        /* Disable priority queueing */
                    948:        writel(0, ns->base + PQCR);
                    949: 
                    950:        /* Enable IP checksum validation and detetion of VLAN headers.
                    951:         * Note: do not set the reject options as at least the 0x102
                    952:         * revision of the chip does not properly accept IP fragments
                    953:         * at least for UDP.
                    954:         */
                    955:        /* Ramit : Be sure to turn on RXCFG_ARP if VLAN's are enabled, since
                    956:         * the MAC it calculates the packetsize AFTER stripping the VLAN
                    957:         * header, and if a VLAN Tagged packet of 64 bytes is received (like
                    958:         * a ping with a VLAN header) then the card, strips the 4 byte VLAN
                    959:         * tag and then checks the packet size, so if RXCFG_ARP is not enabled,
                    960:         * it discrards it!.  These guys......
                    961:         */
                    962:        writel(VRCR_IPEN | VRCR_VTDEN, ns->base + VRCR);
                    963: 
                    964:        /* Enable per-packet TCP/UDP/IP checksumming */
                    965:        writel(VTCR_PPCHK, ns->base + VTCR);
                    966: 
                    967:        /* Ramit : Enable async and sync pause frames */
                    968: //      writel(0, ns->base + PCR); 
                    969:        writel((PCR_PS_MCAST | PCR_PS_DA | PCR_PSEN | PCR_FFLO_4K |
                    970:                PCR_FFHI_8K | PCR_STLO_4 | PCR_STHI_8 | PCR_PAUSE_CNT),
                    971:               ns->base + PCR);
                    972: 
                    973:        /* Disable Wake On Lan */
                    974:        writel(0, ns->base + WCSR);
                    975: 
                    976:        ns83820_getmac(nic, nic->node_addr);
                    977: 
                    978:        if (using_dac) {
                    979:                DBG("%s: using 64 bit addressing.\n", pci->id->name);
                    980:        }
                    981: 
                    982:        DBG("%s: DP83820 %d.%d: io=%#04lx\n",
                    983:            pci->id->name,
                    984:            (unsigned) readl(ns->base + SRR) >> 8,
                    985:            (unsigned) readl(ns->base + SRR) & 0xff,
                    986:            pci->ioaddr);
                    987: 
                    988: #ifdef PHY_CODE_IS_FINISHED
                    989:        ns83820_probe_phy(dev);
                    990: #endif
                    991: 
                    992:        ns83820_reset(nic);
                    993:        /* point to NIC specific routines */
                    994:        nic->nic_op     = &ns83820_operations;
                    995:        return 1;
                    996: }
                    997: 
                    998: DRIVER ( "NS83820/PCI", nic_driver, pci_driver, ns83820_driver,
                    999:         ns83820_probe, ns83820_disable );
                   1000: 
                   1001: /*
                   1002:  * Local variables:
                   1003:  *  c-basic-offset: 8
                   1004:  *  c-indent-level: 8
                   1005:  *  tab-width: 8
                   1006:  * End:
                   1007:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.