The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/etherigbe.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Intel 8254[340]NN Gigabit Ethernet PCI Controllers
    3  * as found on the Intel PRO/1000 series of adapters:
    4  *      82543GC Intel PRO/1000 T
    5  *      82544EI Intel PRO/1000 XT
    6  *      82540EM Intel PRO/1000 MT
    7  *      82541[GP]I
    8  *      82547GI
    9  *      82546GB
   10  *      82546EB
   11  * To Do:
   12  *      finish autonegotiation code;
   13  *      integrate fiber stuff back in (this ONLY handles
   14  *      the CAT5 cards at the moment);
   15  *      add checksum-offload;
   16  *      add tuning control via ctl file;
   17  *      this driver is little-endian specific.
   18  */
   19 #include "u.h"
   20 #include "../port/lib.h"
   21 #include "mem.h"
   22 #include "dat.h"
   23 #include "fns.h"
   24 #include "io.h"
   25 #include "../port/error.h"
   26 #include "../port/netif.h"
   27 
   28 #include "etherif.h"
   29 #include "ethermii.h"
   30 
   31 enum {
   32         i82542          = (0x1000<<16)|0x8086,
   33         i82543gc        = (0x1004<<16)|0x8086,
   34         i82544ei        = (0x1008<<16)|0x8086,
   35         i82544eif       = (0x1009<<16)|0x8086,
   36         i82547ei        = (0x1019<<16)|0x8086,
   37         i82540em        = (0x100E<<16)|0x8086,
   38         i82540eplp      = (0x101E<<16)|0x8086,
   39         i82545em        = (0x100F<<16)|0x8086,
   40         i82545gmc       = (0x1026<<16)|0x8086,
   41         i82547gi        = (0x1075<<16)|0x8086,
   42         i82541gi        = (0x1076<<16)|0x8086,
   43         i82541gi2       = (0x1077<<16)|0x8086,
   44         i82546gb        = (0x1079<<16)|0x8086,
   45         i82541pi        = (0x107c<<16)|0x8086,
   46         i82546eb        = (0x1010<<16)|0x8086,
   47 };
   48 
   49 enum {
   50         Ctrl            = 0x00000000,   /* Device Control */
   51         Ctrldup         = 0x00000004,   /* Device Control Duplicate */
   52         Status          = 0x00000008,   /* Device Status */
   53         Eecd            = 0x00000010,   /* EEPROM/Flash Control/Data */
   54         Ctrlext         = 0x00000018,   /* Extended Device Control */
   55         Mdic            = 0x00000020,   /* MDI Control */
   56         Fcal            = 0x00000028,   /* Flow Control Address Low */
   57         Fcah            = 0x0000002C,   /* Flow Control Address High */
   58         Fct             = 0x00000030,   /* Flow Control Type */
   59         Icr             = 0x000000C0,   /* Interrupt Cause Read */
   60         Ics             = 0x000000C8,   /* Interrupt Cause Set */
   61         Ims             = 0x000000D0,   /* Interrupt Mask Set/Read */
   62         Imc             = 0x000000D8,   /* Interrupt mask Clear */
   63         Rctl            = 0x00000100,   /* Receive Control */
   64         Fcttv           = 0x00000170,   /* Flow Control Transmit Timer Value */
   65         Txcw            = 0x00000178,   /* Transmit Configuration Word */
   66         Rxcw            = 0x00000180,   /* Receive Configuration Word */
   67         /* on the oldest cards (8254[23]), the Mta register is at 0x200 */
   68         Tctl            = 0x00000400,   /* Transmit Control */
   69         Tipg            = 0x00000410,   /* Transmit IPG */
   70         Tbt             = 0x00000448,   /* Transmit Burst Timer */
   71         Ait             = 0x00000458,   /* Adaptive IFS Throttle */
   72         Fcrtl           = 0x00002160,   /* Flow Control RX Threshold Low */
   73         Fcrth           = 0x00002168,   /* Flow Control Rx Threshold High */
   74         Rdfh            = 0x00002410,   /* Receive data fifo head */
   75         Rdft            = 0x00002418,   /* Receive data fifo tail */
   76         Rdfhs           = 0x00002420,   /* Receive data fifo head saved */
   77         Rdfts           = 0x00002428,   /* Receive data fifo tail saved */
   78         Rdfpc           = 0x00002430,   /* Receive data fifo packet count */
   79         Rdbal           = 0x00002800,   /* Rd Base Address Low */
   80         Rdbah           = 0x00002804,   /* Rd Base Address High */
   81         Rdlen           = 0x00002808,   /* Receive Descriptor Length */
   82         Rdh             = 0x00002810,   /* Receive Descriptor Head */
   83         Rdt             = 0x00002818,   /* Receive Descriptor Tail */
   84         Rdtr            = 0x00002820,   /* Receive Descriptor Timer Ring */
   85         Rxdctl          = 0x00002828,   /* Receive Descriptor Control */
   86         Radv            = 0x0000282C,   /* Receive Interrupt Absolute Delay Timer */
   87         Txdmac          = 0x00003000,   /* Transfer DMA Control */
   88         Ett             = 0x00003008,   /* Early Transmit Control */
   89         Tdfh            = 0x00003410,   /* Transmit data fifo head */
   90         Tdft            = 0x00003418,   /* Transmit data fifo tail */
   91         Tdfhs           = 0x00003420,   /* Transmit data Fifo Head saved */
   92         Tdfts           = 0x00003428,   /* Transmit data fifo tail saved */
   93         Tdfpc           = 0x00003430,   /* Trasnmit data Fifo packet count */
   94         Tdbal           = 0x00003800,   /* Td Base Address Low */
   95         Tdbah           = 0x00003804,   /* Td Base Address High */
   96         Tdlen           = 0x00003808,   /* Transmit Descriptor Length */
   97         Tdh             = 0x00003810,   /* Transmit Descriptor Head */
   98         Tdt             = 0x00003818,   /* Transmit Descriptor Tail */
   99         Tidv            = 0x00003820,   /* Transmit Interrupt Delay Value */
  100         Txdctl          = 0x00003828,   /* Transmit Descriptor Control */
  101         Tadv            = 0x0000382C,   /* Transmit Interrupt Absolute Delay Timer */
  102 
  103         Statistics      = 0x00004000,   /* Start of Statistics Area */
  104         Gorcl           = 0x88/4,       /* Good Octets Received Count */
  105         Gotcl           = 0x90/4,       /* Good Octets Transmitted Count */
  106         Torl            = 0xC0/4,       /* Total Octets Received */
  107         Totl            = 0xC8/4,       /* Total Octets Transmitted */
  108         Nstatistics     = 64,
  109 
  110         Rxcsum          = 0x00005000,   /* Receive Checksum Control */
  111         Mta             = 0x00005200,   /* Multicast Table Array */
  112         Ral             = 0x00005400,   /* Receive Address Low */
  113         Rah             = 0x00005404,   /* Receive Address High */
  114         Manc            = 0x00005820,   /* Management Control */
  115 };
  116 
  117 enum {                                  /* Ctrl */
  118         Bem             = 0x00000002,   /* Big Endian Mode */
  119         Prior           = 0x00000004,   /* Priority on the PCI bus */
  120         Lrst            = 0x00000008,   /* Link Reset */
  121         Asde            = 0x00000020,   /* Auto-Speed Detection Enable */
  122         Slu             = 0x00000040,   /* Set Link Up */
  123         Ilos            = 0x00000080,   /* Invert Loss of Signal (LOS) */
  124         SspeedMASK      = 0x00000300,   /* Speed Selection */
  125         SspeedSHIFT     = 8,
  126         Sspeed10        = 0x00000000,   /* 10Mb/s */
  127         Sspeed100       = 0x00000100,   /* 100Mb/s */
  128         Sspeed1000      = 0x00000200,   /* 1000Mb/s */
  129         Frcspd          = 0x00000800,   /* Force Speed */
  130         Frcdplx         = 0x00001000,   /* Force Duplex */
  131         SwdpinsloMASK   = 0x003C0000,   /* Software Defined Pins - lo nibble */
  132         SwdpinsloSHIFT  = 18,
  133         SwdpioloMASK    = 0x03C00000,   /* Software Defined Pins - I or O */
  134         SwdpioloSHIFT   = 22,
  135         Devrst          = 0x04000000,   /* Device Reset */
  136         Rfce            = 0x08000000,   /* Receive Flow Control Enable */
  137         Tfce            = 0x10000000,   /* Transmit Flow Control Enable */
  138         Vme             = 0x40000000,   /* VLAN Mode Enable */
  139 };
  140 
  141 /*
  142  * can't find Tckok nor Rbcok in any Intel docs,
  143  * but even 82543gc docs define Lanid.
  144  */
  145 enum {                                  /* Status */
  146         Lu              = 0x00000002,   /* Link Up */
  147         Lanid           = 0x0000000C,   /* mask for Lan ID. (function id) */
  148 //      Tckok           = 0x00000004,   /* Transmit clock is running */
  149 //      Rbcok           = 0x00000008,   /* Receive clock is running */
  150         Txoff           = 0x00000010,   /* Transmission Paused */
  151         Tbimode         = 0x00000020,   /* TBI Mode Indication */
  152         LspeedMASK      = 0x000000C0,   /* Link Speed Setting */
  153         LspeedSHIFT     = 6,
  154         Lspeed10        = 0x00000000,   /* 10Mb/s */
  155         Lspeed100       = 0x00000040,   /* 100Mb/s */
  156         Lspeed1000      = 0x00000080,   /* 1000Mb/s */
  157         Mtxckok         = 0x00000400,   /* MTX clock is running */
  158         Pci66           = 0x00000800,   /* PCI Bus speed indication */
  159         Bus64           = 0x00001000,   /* PCI Bus width indication */
  160         Pcixmode        = 0x00002000,   /* PCI-X mode */
  161         PcixspeedMASK   = 0x0000C000,   /* PCI-X bus speed */
  162         PcixspeedSHIFT  = 14,
  163         Pcix66          = 0x00000000,   /* 50-66MHz */
  164         Pcix100         = 0x00004000,   /* 66-100MHz */
  165         Pcix133         = 0x00008000,   /* 100-133MHz */
  166 };
  167 
  168 enum {                                  /* Ctrl and Status */
  169         Fd              = 0x00000001,   /* Full-Duplex */
  170         AsdvMASK        = 0x00000300,
  171         AsdvSHIFT       = 8,
  172         Asdv10          = 0x00000000,   /* 10Mb/s */
  173         Asdv100         = 0x00000100,   /* 100Mb/s */
  174         Asdv1000        = 0x00000200,   /* 1000Mb/s */
  175 };
  176 
  177 enum {                                  /* Eecd */
  178         Sk              = 0x00000001,   /* Clock input to the EEPROM */
  179         Cs              = 0x00000002,   /* Chip Select */
  180         Di              = 0x00000004,   /* Data Input to the EEPROM */
  181         Do              = 0x00000008,   /* Data Output from the EEPROM */
  182         Areq            = 0x00000040,   /* EEPROM Access Request */
  183         Agnt            = 0x00000080,   /* EEPROM Access Grant */
  184         Eepresent       = 0x00000100,   /* EEPROM Present */
  185         Eesz256         = 0x00000200,   /* EEPROM is 256 words not 64 */
  186         Eeszaddr        = 0x00000400,   /* EEPROM size for 8254[17] */
  187         Spi             = 0x00002000,   /* EEPROM is SPI not Microwire */
  188 };
  189 
  190 enum {                                  /* Ctrlext */
  191         Gpien           = 0x0000000F,   /* General Purpose Interrupt Enables */
  192         SwdpinshiMASK   = 0x000000F0,   /* Software Defined Pins - hi nibble */
  193         SwdpinshiSHIFT  = 4,
  194         SwdpiohiMASK    = 0x00000F00,   /* Software Defined Pins - I or O */
  195         SwdpiohiSHIFT   = 8,
  196         Asdchk          = 0x00001000,   /* ASD Check */
  197         Eerst           = 0x00002000,   /* EEPROM Reset */
  198         Ips             = 0x00004000,   /* Invert Power State */
  199         Spdbyps         = 0x00008000,   /* Speed Select Bypass */
  200 };
  201 
  202 enum {                                  /* EEPROM content offsets */
  203         Ea              = 0x00,         /* Ethernet Address */
  204         Cf              = 0x03,         /* Compatibility Field */
  205         Pba             = 0x08,         /* Printed Board Assembly number */
  206         Icw1            = 0x0A,         /* Initialization Control Word 1 */
  207         Sid             = 0x0B,         /* Subsystem ID */
  208         Svid            = 0x0C,         /* Subsystem Vendor ID */
  209         Did             = 0x0D,         /* Device ID */
  210         Vid             = 0x0E,         /* Vendor ID */
  211         Icw2            = 0x0F,         /* Initialization Control Word 2 */
  212 };
  213 
  214 enum {                                  /* Mdic */
  215         MDIdMASK        = 0x0000FFFF,   /* Data */
  216         MDIdSHIFT       = 0,
  217         MDIrMASK        = 0x001F0000,   /* PHY Register Address */
  218         MDIrSHIFT       = 16,
  219         MDIpMASK        = 0x03E00000,   /* PHY Address */
  220         MDIpSHIFT       = 21,
  221         MDIwop          = 0x04000000,   /* Write Operation */
  222         MDIrop          = 0x08000000,   /* Read Operation */
  223         MDIready        = 0x10000000,   /* End of Transaction */
  224         MDIie           = 0x20000000,   /* Interrupt Enable */
  225         MDIe            = 0x40000000,   /* Error */
  226 };
  227 
  228 enum {                                  /* Icr, Ics, Ims, Imc */
  229         Txdw            = 0x00000001,   /* Transmit Descriptor Written Back */
  230         Txqe            = 0x00000002,   /* Transmit Queue Empty */
  231         Lsc             = 0x00000004,   /* Link Status Change */
  232         Rxseq           = 0x00000008,   /* Receive Sequence Error */
  233         Rxdmt0          = 0x00000010,   /* Rd Minimum Threshold Reached */
  234         Rxo             = 0x00000040,   /* Receiver Overrun */
  235         Rxt0            = 0x00000080,   /* Receiver Timer Interrupt */
  236         Mdac            = 0x00000200,   /* MDIO Access Completed */
  237         Rxcfg           = 0x00000400,   /* Receiving /C/ ordered sets */
  238         Gpi0            = 0x00000800,   /* General Purpose Interrupts */
  239         Gpi1            = 0x00001000,
  240         Gpi2            = 0x00002000,
  241         Gpi3            = 0x00004000,
  242 };
  243 
  244 /*
  245  * The Mdic register isn't implemented on the 82543GC,
  246  * the software defined pins are used instead.
  247  * These definitions work for the Intel PRO/1000 T Server Adapter.
  248  * The direction pin bits are read from the EEPROM.
  249  */
  250 enum {
  251         Mdd             = ((1<<2)<<SwdpinsloSHIFT),     /* data */
  252         Mddo            = ((1<<2)<<SwdpioloSHIFT),      /* pin direction */
  253         Mdc             = ((1<<3)<<SwdpinsloSHIFT),     /* clock */
  254         Mdco            = ((1<<3)<<SwdpioloSHIFT),      /* pin direction */
  255         Mdr             = ((1<<0)<<SwdpinshiSHIFT),     /* reset */
  256         Mdro            = ((1<<0)<<SwdpiohiSHIFT),      /* pin direction */
  257 };
  258 
  259 enum {                                  /* Txcw */
  260         TxcwFd          = 0x00000020,   /* Full Duplex */
  261         TxcwHd          = 0x00000040,   /* Half Duplex */
  262         TxcwPauseMASK   = 0x00000180,   /* Pause */
  263         TxcwPauseSHIFT  = 7,
  264         TxcwPs          = (1<<TxcwPauseSHIFT),  /* Pause Supported */
  265         TxcwAs          = (2<<TxcwPauseSHIFT),  /* Asymmetric FC desired */
  266         TxcwRfiMASK     = 0x00003000,   /* Remote Fault Indication */
  267         TxcwRfiSHIFT    = 12,
  268         TxcwNpr         = 0x00008000,   /* Next Page Request */
  269         TxcwConfig      = 0x40000000,   /* Transmit COnfig Control */
  270         TxcwAne         = 0x80000000,   /* Auto-Negotiation Enable */
  271 };
  272 
  273 enum {                                  /* Rxcw */
  274         Rxword          = 0x0000FFFF,   /* Data from auto-negotiation process */
  275         Rxnocarrier     = 0x04000000,   /* Carrier Sense indication */
  276         Rxinvalid       = 0x08000000,   /* Invalid Symbol during configuration */
  277         Rxchange        = 0x10000000,   /* Change to the Rxword indication */
  278         Rxconfig        = 0x20000000,   /* /C/ order set reception indication */
  279         Rxsync          = 0x40000000,   /* Lost bit synchronization indication */
  280         Anc             = 0x80000000,   /* Auto Negotiation Complete */
  281 };
  282 
  283 enum {                                  /* Rctl */
  284         Rrst            = 0x00000001,   /* Receiver Software Reset */
  285         Ren             = 0x00000002,   /* Receiver Enable */
  286         Sbp             = 0x00000004,   /* Store Bad Packets */
  287         Upe             = 0x00000008,   /* Unicast Promiscuous Enable */
  288         Mpe             = 0x00000010,   /* Multicast Promiscuous Enable */
  289         Lpe             = 0x00000020,   /* Long Packet Reception Enable */
  290         LbmMASK         = 0x000000C0,   /* Loopback Mode */
  291         LbmOFF          = 0x00000000,   /* No Loopback */
  292         LbmTBI          = 0x00000040,   /* TBI Loopback */
  293         LbmMII          = 0x00000080,   /* GMII/MII Loopback */
  294         LbmXCVR         = 0x000000C0,   /* Transceiver Loopback */
  295         RdtmsMASK       = 0x00000300,   /* Rd Minimum Threshold Size */
  296         RdtmsHALF       = 0x00000000,   /* Threshold is 1/2 Rdlen */
  297         RdtmsQUARTER    = 0x00000100,   /* Threshold is 1/4 Rdlen */
  298         RdtmsEIGHTH     = 0x00000200,   /* Threshold is 1/8 Rdlen */
  299         MoMASK          = 0x00003000,   /* Multicast Offset */
  300         Mo47b36         = 0x00000000,   /* bits [47:36] of received address */
  301         Mo46b35         = 0x00001000,   /* bits [46:35] of received address */
  302         Mo45b34         = 0x00002000,   /* bits [45:34] of received address */
  303         Mo43b32         = 0x00003000,   /* bits [43:32] of received address */
  304         Bam             = 0x00008000,   /* Broadcast Accept Mode */
  305         BsizeMASK       = 0x00030000,   /* Receive Buffer Size */
  306         Bsize2048       = 0x00000000,   /* Bsex = 0 */
  307         Bsize1024       = 0x00010000,   /* Bsex = 0 */
  308         Bsize512        = 0x00020000,   /* Bsex = 0 */
  309         Bsize256        = 0x00030000,   /* Bsex = 0 */
  310         Bsize16384      = 0x00010000,   /* Bsex = 1 */
  311         Vfe             = 0x00040000,   /* VLAN Filter Enable */
  312         Cfien           = 0x00080000,   /* Canonical Form Indicator Enable */
  313         Cfi             = 0x00100000,   /* Canonical Form Indicator value */
  314         Dpf             = 0x00400000,   /* Discard Pause Frames */
  315         Pmcf            = 0x00800000,   /* Pass MAC Control Frames */
  316         Bsex            = 0x02000000,   /* Buffer Size Extension */
  317         Secrc           = 0x04000000,   /* Strip CRC from incoming packet */
  318 };
  319 
  320 enum {                                  /* Tctl */
  321         Trst            = 0x00000001,   /* Transmitter Software Reset */
  322         Ten             = 0x00000002,   /* Transmit Enable */
  323         Psp             = 0x00000008,   /* Pad Short Packets */
  324         CtMASK          = 0x00000FF0,   /* Collision Threshold */
  325         CtSHIFT         = 4,
  326         ColdMASK        = 0x003FF000,   /* Collision Distance */
  327         ColdSHIFT       = 12,
  328         Swxoff          = 0x00400000,   /* Sofware XOFF Transmission */
  329         Pbe             = 0x00800000,   /* Packet Burst Enable */
  330         Rtlc            = 0x01000000,   /* Re-transmit on Late Collision */
  331         Nrtu            = 0x02000000,   /* No Re-transmit on Underrrun */
  332 };
  333 
  334 enum {                                  /* [RT]xdctl */
  335         PthreshMASK     = 0x0000003F,   /* Prefetch Threshold */
  336         PthreshSHIFT    = 0,
  337         HthreshMASK     = 0x00003F00,   /* Host Threshold */
  338         HthreshSHIFT    = 8,
  339         WthreshMASK     = 0x003F0000,   /* Writeback Threshold */
  340         WthreshSHIFT    = 16,
  341         Gran            = 0x01000000,   /* Granularity */
  342         LthreshMASK     = 0xFE000000,   /* Low Threshold */
  343         LthreshSHIFT    = 25,
  344 };
  345 
  346 enum {                                  /* Rxcsum */
  347         PcssMASK        = 0x000000FF,   /* Packet Checksum Start */
  348         PcssSHIFT       = 0,
  349         Ipofl           = 0x00000100,   /* IP Checksum Off-load Enable */
  350         Tuofl           = 0x00000200,   /* TCP/UDP Checksum Off-load Enable */
  351 };
  352 
  353 enum {                                  /* Manc */
  354         Arpen           = 0x00002000,   /* Enable ARP Request Filtering */
  355 };
  356 
  357 enum {                                  /* Receive Delay Timer Ring */
  358         DelayMASK       = 0x0000FFFF,   /* delay timer in 1.024nS increments */
  359         DelaySHIFT      = 0,
  360         Fpd             = 0x80000000,   /* Flush partial Descriptor Block */
  361 };
  362 
  363 typedef struct Rd {                     /* Receive Descriptor */
  364         uint    addr[2];
  365         ushort  length;
  366         ushort  checksum;
  367         uchar   status;
  368         uchar   errors;
  369         ushort  special;
  370 } Rd;
  371 
  372 enum {                                  /* Rd status */
  373         Rdd             = 0x01,         /* Descriptor Done */
  374         Reop            = 0x02,         /* End of Packet */
  375         Ixsm            = 0x04,         /* Ignore Checksum Indication */
  376         Vp              = 0x08,         /* Packet is 802.1Q (matched VET) */
  377         Tcpcs           = 0x20,         /* TCP Checksum Calculated on Packet */
  378         Ipcs            = 0x40,         /* IP Checksum Calculated on Packet */
  379         Pif             = 0x80,         /* Passed in-exact filter */
  380 };
  381 
  382 enum {                                  /* Rd errors */
  383         Ce              = 0x01,         /* CRC Error or Alignment Error */
  384         Se              = 0x02,         /* Symbol Error */
  385         Seq             = 0x04,         /* Sequence Error */
  386         Cxe             = 0x10,         /* Carrier Extension Error */
  387         Tcpe            = 0x20,         /* TCP/UDP Checksum Error */
  388         Ipe             = 0x40,         /* IP Checksum Error */
  389         Rxe             = 0x80,         /* RX Data Error */
  390 };
  391 
  392 typedef struct Td Td;
  393 struct Td {                             /* Transmit Descriptor */
  394         union {
  395                 uint    addr[2];        /* Data */
  396                 struct {                /* Context */
  397                         uchar   ipcss;
  398                         uchar   ipcso;
  399                         ushort  ipcse;
  400                         uchar   tucss;
  401                         uchar   tucso;
  402                         ushort  tucse;
  403                 };
  404         };
  405         uint    control;
  406         uint    status;
  407 };
  408 
  409 enum {                                  /* Td control */
  410         LenMASK         = 0x000FFFFF,   /* Data/Packet Length Field */
  411         LenSHIFT        = 0,
  412         DtypeCD         = 0x00000000,   /* Data Type 'Context Descriptor' */
  413         DtypeDD         = 0x00100000,   /* Data Type 'Data Descriptor' */
  414         PtypeTCP        = 0x01000000,   /* TCP/UDP Packet Type (CD) */
  415         Teop            = 0x01000000,   /* End of Packet (DD) */
  416         PtypeIP         = 0x02000000,   /* IP Packet Type (CD) */
  417         Ifcs            = 0x02000000,   /* Insert FCS (DD) */
  418         Tse             = 0x04000000,   /* TCP Segmentation Enable */
  419         Rs              = 0x08000000,   /* Report Status */
  420         Rps             = 0x10000000,   /* Report Status Sent */
  421         Dext            = 0x20000000,   /* Descriptor Extension */
  422         Vle             = 0x40000000,   /* VLAN Packet Enable */
  423         Ide             = 0x80000000,   /* Interrupt Delay Enable */
  424 };
  425 
  426 enum {                                  /* Td status */
  427         Tdd             = 0x00000001,   /* Descriptor Done */
  428         Ec              = 0x00000002,   /* Excess Collisions */
  429         Lc              = 0x00000004,   /* Late Collision */
  430         Tu              = 0x00000008,   /* Transmit Underrun */
  431         Iixsm           = 0x00000100,   /* Insert IP Checksum */
  432         Itxsm           = 0x00000200,   /* Insert TCP/UDP Checksum */
  433         HdrlenMASK      = 0x0000FF00,   /* Header Length (Tse) */
  434         HdrlenSHIFT     = 8,
  435         VlanMASK        = 0x0FFF0000,   /* VLAN Identifier */
  436         VlanSHIFT       = 16,
  437         Tcfi            = 0x10000000,   /* Canonical Form Indicator */
  438         PriMASK         = 0xE0000000,   /* User Priority */
  439         PriSHIFT        = 29,
  440         MssMASK         = 0xFFFF0000,   /* Maximum Segment Size (Tse) */
  441         MssSHIFT        = 16,
  442 };
  443 
  444 enum {
  445         Nrd             = 256,          /* multiple of 8 */
  446         Ntd             = 64,           /* multiple of 8 */
  447         Nrb             = 1024,         /* private receive buffers per Ctlr */
  448         Rbsz            = 2048,
  449 };
  450 
  451 typedef struct Ctlr Ctlr;
  452 typedef struct Ctlr {
  453         int     port;
  454         Pcidev* pcidev;
  455         Ctlr*   next;
  456         Ether*  edev;
  457         int     active;
  458         int     started;
  459         int     id;
  460         int     cls;
  461         ushort  eeprom[0x40];
  462 
  463         QLock   alock;                  /* attach */
  464         void*   alloc;                  /* receive/transmit descriptors */
  465         int     nrd;
  466         int     ntd;
  467         int     nrb;                    /* how many this Ctlr has in the pool */
  468 
  469         int*    nic;
  470         Lock    imlock;
  471         int     im;                     /* interrupt mask */
  472 
  473         Mii*    mii;
  474         Rendez  lrendez;
  475         int     lim;
  476 
  477         int     link;
  478 
  479         QLock   slock;
  480         uint    statistics[Nstatistics];
  481         uint    lsleep;
  482         uint    lintr;
  483         uint    rsleep;
  484         uint    rintr;
  485         uint    txdw;
  486         uint    tintr;
  487         uint    ixsm;
  488         uint    ipcs;
  489         uint    tcpcs;
  490 
  491         uchar   ra[Eaddrlen];           /* receive address */
  492         ulong   mta[128];               /* multicast table array */
  493 
  494         Rendez  rrendez;
  495         int     rim;
  496         int     rdfree;
  497         Rd*     rdba;                   /* receive descriptor base address */
  498         Block** rb;                     /* receive buffers */
  499         int     rdh;                    /* receive descriptor head */
  500         int     rdt;                    /* receive descriptor tail */
  501         int     rdtr;                   /* receive delay timer ring value */
  502 
  503         Lock    tlock;
  504         int     tbusy;
  505         int     tdfree;
  506         Td*     tdba;                   /* transmit descriptor base address */
  507         Block** tb;                     /* transmit buffers */
  508         int     tdh;                    /* transmit descriptor head */
  509         int     tdt;                    /* transmit descriptor tail */
  510 
  511         int     txcw;
  512         int     fcrtl;
  513         int     fcrth;
  514 } Ctlr;
  515 
  516 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
  517 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  518 
  519 static Ctlr* igbectlrhead;
  520 static Ctlr* igbectlrtail;
  521 
  522 static Lock igberblock;         /* free receive Blocks */
  523 static Block* igberbpool;       /* receive Blocks for all igbe controllers */
  524 
  525 static char* statistics[Nstatistics] = {
  526         "CRC Error",
  527         "Alignment Error",
  528         "Symbol Error",
  529         "RX Error",
  530         "Missed Packets",
  531         "Single Collision",
  532         "Excessive Collisions",
  533         "Multiple Collision",
  534         "Late Collisions",
  535         nil,
  536         "Collision",
  537         "Transmit Underrun",
  538         "Defer",
  539         "Transmit - No CRS",
  540         "Sequence Error",
  541         "Carrier Extension Error",
  542         "Receive Error Length",
  543         nil,
  544         "XON Received",
  545         "XON Transmitted",
  546         "XOFF Received",
  547         "XOFF Transmitted",
  548         "FC Received Unsupported",
  549         "Packets Received (64 Bytes)",
  550         "Packets Received (65-127 Bytes)",
  551         "Packets Received (128-255 Bytes)",
  552         "Packets Received (256-511 Bytes)",
  553         "Packets Received (512-1023 Bytes)",
  554         "Packets Received (1024-1522 Bytes)",
  555         "Good Packets Received",
  556         "Broadcast Packets Received",
  557         "Multicast Packets Received",
  558         "Good Packets Transmitted",
  559         nil,
  560         "Good Octets Received",
  561         nil,
  562         "Good Octets Transmitted",
  563         nil,
  564         nil,
  565         nil,
  566         "Receive No Buffers",
  567         "Receive Undersize",
  568         "Receive Fragment",
  569         "Receive Oversize",
  570         "Receive Jabber",
  571         nil,
  572         nil,
  573         nil,
  574         "Total Octets Received",
  575         nil,
  576         "Total Octets Transmitted",
  577         nil,
  578         "Total Packets Received",
  579         "Total Packets Transmitted",
  580         "Packets Transmitted (64 Bytes)",
  581         "Packets Transmitted (65-127 Bytes)",
  582         "Packets Transmitted (128-255 Bytes)",
  583         "Packets Transmitted (256-511 Bytes)",
  584         "Packets Transmitted (512-1023 Bytes)",
  585         "Packets Transmitted (1024-1522 Bytes)",
  586         "Multicast Packets Transmitted",
  587         "Broadcast Packets Transmitted",
  588         "TCP Segmentation Context Transmitted",
  589         "TCP Segmentation Context Fail",
  590 };
  591 
  592 static long
  593 igbeifstat(Ether* edev, void* a, long n, ulong offset)
  594 {
  595         Ctlr *ctlr;
  596         char *p, *s;
  597         int i, l, r;
  598         uvlong tuvl, ruvl;
  599 
  600         ctlr = edev->ctlr;
  601         qlock(&ctlr->slock);
  602         p = malloc(READSTR);
  603         l = 0;
  604         for(i = 0; i < Nstatistics; i++){
  605                 r = csr32r(ctlr, Statistics+i*4);
  606                 if((s = statistics[i]) == nil)
  607                         continue;
  608                 switch(i){
  609                 case Gorcl:
  610                 case Gotcl:
  611                 case Torl:
  612                 case Totl:
  613                         ruvl = r;
  614                         ruvl += ((uvlong)csr32r(ctlr, Statistics+(i+1)*4))<<32;
  615                         tuvl = ruvl;
  616                         tuvl += ctlr->statistics[i];
  617                         tuvl += ((uvlong)ctlr->statistics[i+1])<<32;
  618                         if(tuvl == 0)
  619                                 continue;
  620                         ctlr->statistics[i] = tuvl;
  621                         ctlr->statistics[i+1] = tuvl>>32;
  622                         l += snprint(p+l, READSTR-l, "%s: %llud %llud\n",
  623                                 s, tuvl, ruvl);
  624                         i++;
  625                         break;
  626 
  627                 default:
  628                         ctlr->statistics[i] += r;
  629                         if(ctlr->statistics[i] == 0)
  630                                 continue;
  631                         l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
  632                                 s, ctlr->statistics[i], r);
  633                         break;
  634                 }
  635         }
  636 
  637         l += snprint(p+l, READSTR-l, "lintr: %ud %ud\n",
  638                 ctlr->lintr, ctlr->lsleep);
  639         l += snprint(p+l, READSTR-l, "rintr: %ud %ud\n",
  640                 ctlr->rintr, ctlr->rsleep);
  641         l += snprint(p+l, READSTR-l, "tintr: %ud %ud\n",
  642                 ctlr->tintr, ctlr->txdw);
  643         l += snprint(p+l, READSTR-l, "ixcs: %ud %ud %ud\n",
  644                 ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
  645         l += snprint(p+l, READSTR-l, "rdtr: %ud\n", ctlr->rdtr);
  646         l += snprint(p+l, READSTR-l, "Ctrlext: %08x\n", csr32r(ctlr, Ctrlext));
  647 
  648         l += snprint(p+l, READSTR-l, "eeprom:");
  649         for(i = 0; i < 0x40; i++){
  650                 if(i && ((i & 0x07) == 0))
  651                         l += snprint(p+l, READSTR-l, "\n       ");
  652                 l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
  653         }
  654         l += snprint(p+l, READSTR-l, "\n");
  655 
  656         if(ctlr->mii != nil && ctlr->mii->curphy != nil){
  657                 l += snprint(p+l, READSTR, "phy:   ");
  658                 for(i = 0; i < NMiiPhyr; i++){
  659                         if(i && ((i & 0x07) == 0))
  660                                 l += snprint(p+l, READSTR-l, "\n       ");
  661                         r = miimir(ctlr->mii, i);
  662                         l += snprint(p+l, READSTR-l, " %4.4uX", r);
  663                 }
  664                 snprint(p+l, READSTR-l, "\n");
  665         }
  666         n = readstr(offset, a, n, p);
  667         free(p);
  668         qunlock(&ctlr->slock);
  669 
  670         return n;
  671 }
  672 
  673 enum {
  674         CMrdtr,
  675 };
  676 
  677 static Cmdtab igbectlmsg[] = {
  678         CMrdtr, "rdtr", 2,
  679 };
  680 
  681 static long
  682 igbectl(Ether* edev, void* buf, long n)
  683 {
  684         int v;
  685         char *p;
  686         Ctlr *ctlr;
  687         Cmdbuf *cb;
  688         Cmdtab *ct;
  689 
  690         if((ctlr = edev->ctlr) == nil)
  691                 error(Enonexist);
  692 
  693         cb = parsecmd(buf, n);
  694         if(waserror()){
  695                 free(cb);
  696                 nexterror();
  697         }
  698 
  699         ct = lookupcmd(cb, igbectlmsg, nelem(igbectlmsg));
  700         switch(ct->index){
  701         case CMrdtr:
  702                 v = strtol(cb->f[1], &p, 0);
  703                 if(v < 0 || p == cb->f[1] || v > 0xFFFF)
  704                         error(Ebadarg);
  705                 ctlr->rdtr = v;;
  706                 csr32w(ctlr, Rdtr, Fpd|v);
  707                 break;
  708         }
  709         free(cb);
  710         poperror();
  711 
  712         return n;
  713 }
  714 
  715 static void
  716 igbepromiscuous(void* arg, int on)
  717 {
  718         int rctl;
  719         Ctlr *ctlr;
  720         Ether *edev;
  721 
  722         edev = arg;
  723         ctlr = edev->ctlr;
  724 
  725         rctl = csr32r(ctlr, Rctl);
  726         rctl &= ~MoMASK;
  727         rctl |= Mo47b36;
  728         if(on)
  729                 rctl |= Upe|Mpe;
  730         else
  731                 rctl &= ~(Upe|Mpe);
  732         csr32w(ctlr, Rctl, rctl|Mpe);   /* temporarily keep Mpe on */
  733 }
  734 
  735 static void
  736 igbemulticast(void* arg, uchar* addr, int add)
  737 {
  738         int bit, x;
  739         Ctlr *ctlr;
  740         Ether *edev;
  741 
  742         edev = arg;
  743         ctlr = edev->ctlr;
  744 
  745         x = addr[5]>>1;
  746         bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
  747         /*
  748          * multiple ether addresses can hash to the same filter bit,
  749          * so it's never safe to clear a filter bit.
  750          * if we want to clear filter bits, we need to keep track of
  751          * all the multicast addresses in use, clear all the filter bits,
  752          * then set the ones corresponding to in-use addresses.
  753          */
  754         if(add)
  755                 ctlr->mta[x] |= 1<<bit;
  756 //      else
  757 //              ctlr->mta[x] &= ~(1<<bit);
  758 
  759         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
  760 }
  761 
  762 static Block*
  763 igberballoc(void)
  764 {
  765         Block *bp;
  766 
  767         ilock(&igberblock);
  768         if((bp = igberbpool) != nil){
  769                 igberbpool = bp->next;
  770                 bp->next = nil;
  771                 _xinc(&bp->ref);        /* prevent bp from being freed */
  772         }
  773         iunlock(&igberblock);
  774 
  775         return bp;
  776 }
  777 
  778 static void
  779 igberbfree(Block* bp)
  780 {
  781         bp->rp = bp->lim - Rbsz;
  782         bp->wp = bp->rp;
  783 
  784         ilock(&igberblock);
  785         bp->next = igberbpool;
  786         igberbpool = bp;
  787         iunlock(&igberblock);
  788 }
  789 
  790 static void
  791 igbeim(Ctlr* ctlr, int im)
  792 {
  793         ilock(&ctlr->imlock);
  794         ctlr->im |= im;
  795         csr32w(ctlr, Ims, ctlr->im);
  796         iunlock(&ctlr->imlock);
  797 }
  798 
  799 static int
  800 igbelim(void* ctlr)
  801 {
  802         return ((Ctlr*)ctlr)->lim != 0;
  803 }
  804 
  805 static void
  806 igbelproc(void* arg)
  807 {
  808         Ctlr *ctlr;
  809         Ether *edev;
  810         MiiPhy *phy;
  811         int ctrl, r;
  812 
  813         edev = arg;
  814         ctlr = edev->ctlr;
  815         for(;;){
  816                 if(ctlr->mii == nil || ctlr->mii->curphy == nil)
  817                         continue;
  818 
  819                 /*
  820                  * To do:
  821                  *      logic to manage status change,
  822                  *      this is incomplete but should work
  823                  *      one time to set up the hardware.
  824                  *
  825                  *      MiiPhy.speed, etc. should be in Mii.
  826                  */
  827                 if(miistatus(ctlr->mii) < 0)
  828                         //continue;
  829                         goto enable;
  830 
  831                 phy = ctlr->mii->curphy;
  832                 ctrl = csr32r(ctlr, Ctrl);
  833 
  834                 switch(ctlr->id){
  835                 case i82543gc:
  836                 case i82544ei:
  837                 case i82544eif:
  838                 default:
  839                         if(!(ctrl & Asde)){
  840                                 ctrl &= ~(SspeedMASK|Ilos|Fd);
  841                                 ctrl |= Frcdplx|Frcspd;
  842                                 if(phy->speed == 1000)
  843                                         ctrl |= Sspeed1000;
  844                                 else if(phy->speed == 100)
  845                                         ctrl |= Sspeed100;
  846                                 if(phy->fd)
  847                                         ctrl |= Fd;
  848                         }
  849                         break;
  850 
  851                 case i82540em:
  852                 case i82540eplp:
  853                 case i82547gi:
  854                 case i82541gi:
  855                 case i82541gi2:
  856                 case i82541pi:
  857                         break;
  858                 }
  859 
  860                 /*
  861                  * Collision Distance.
  862                  */
  863                 r = csr32r(ctlr, Tctl);
  864                 r &= ~ColdMASK;
  865                 if(phy->fd)
  866                         r |= 64<<ColdSHIFT;
  867                 else
  868                         r |= 512<<ColdSHIFT;
  869                 csr32w(ctlr, Tctl, r);
  870 
  871                 /*
  872                  * Flow control.
  873                  */
  874                 if(phy->rfc)
  875                         ctrl |= Rfce;
  876                 if(phy->tfc)
  877                         ctrl |= Tfce;
  878                 csr32w(ctlr, Ctrl, ctrl);
  879 
  880 enable:
  881                 ctlr->lim = 0;
  882                 igbeim(ctlr, Lsc);
  883 
  884                 ctlr->lsleep++;
  885                 sleep(&ctlr->lrendez, igbelim, ctlr);
  886         }
  887 }
  888 
  889 static void
  890 igbetxinit(Ctlr* ctlr)
  891 {
  892         int i, r;
  893         Block *bp;
  894 
  895         csr32w(ctlr, Tctl, (0x0F<<CtSHIFT)|Psp|(66<<ColdSHIFT));
  896         switch(ctlr->id){
  897         default:
  898                 r = 6;
  899                 break;
  900         case i82543gc:
  901         case i82544ei:
  902         case i82544eif:
  903         case i82547ei:
  904         case i82540em:
  905         case i82540eplp:
  906         case i82541gi:
  907         case i82541gi2:
  908         case i82541pi:
  909         case i82545em:
  910         case i82545gmc:
  911         case i82546gb:
  912         case i82546eb:
  913         case i82547gi:
  914                 r = 8;
  915                 break;
  916         }
  917         csr32w(ctlr, Tipg, (6<<20)|(8<<10)|r);
  918         csr32w(ctlr, Ait, 0);
  919         csr32w(ctlr, Txdmac, 0);
  920 
  921         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
  922         csr32w(ctlr, Tdbah, 0);
  923         csr32w(ctlr, Tdlen, ctlr->ntd*sizeof(Td));
  924         ctlr->tdh = PREV(0, ctlr->ntd);
  925         csr32w(ctlr, Tdh, 0);
  926         ctlr->tdt = 0;
  927         csr32w(ctlr, Tdt, 0);
  928 
  929         for(i = 0; i < ctlr->ntd; i++){
  930                 if((bp = ctlr->tb[i]) != nil){
  931                         ctlr->tb[i] = nil;
  932                         freeb(bp);
  933                 }
  934                 memset(&ctlr->tdba[i], 0, sizeof(Td));
  935         }
  936         ctlr->tdfree = ctlr->ntd;
  937 
  938         csr32w(ctlr, Tidv, 128);
  939         r = (4<<WthreshSHIFT)|(4<<HthreshSHIFT)|(8<<PthreshSHIFT);
  940 
  941         switch(ctlr->id){
  942         default:
  943                 break;
  944         case i82540em:
  945         case i82540eplp:
  946         case i82547gi:
  947         case i82545em:
  948         case i82545gmc:
  949         case i82546gb:
  950         case i82546eb:
  951         case i82541gi:
  952         case i82541gi2:
  953         case i82541pi:
  954                 r = csr32r(ctlr, Txdctl);
  955                 r &= ~WthreshMASK;
  956                 r |= Gran|(4<<WthreshSHIFT);
  957 
  958                 csr32w(ctlr, Tadv, 64);
  959                 break;
  960         }
  961 
  962         csr32w(ctlr, Txdctl, r);
  963 
  964         r = csr32r(ctlr, Tctl);
  965         r |= Ten;
  966         csr32w(ctlr, Tctl, r);
  967 }
  968 
  969 static void
  970 igbetransmit(Ether* edev)
  971 {
  972         Td *td;
  973         Block *bp;
  974         Ctlr *ctlr;
  975         int tdh, tdt;
  976 
  977         ctlr = edev->ctlr;
  978 
  979         ilock(&ctlr->tlock);
  980 
  981         /*
  982          * Free any completed packets
  983          */
  984         tdh = ctlr->tdh;
  985         while(NEXT(tdh, ctlr->ntd) != csr32r(ctlr, Tdh)){
  986                 if((bp = ctlr->tb[tdh]) != nil){
  987                         ctlr->tb[tdh] = nil;
  988                         freeb(bp);
  989                 }
  990                 memset(&ctlr->tdba[tdh], 0, sizeof(Td));
  991                 tdh = NEXT(tdh, ctlr->ntd);
  992         }
  993         ctlr->tdh = tdh;
  994 
  995         /*
  996          * Try to fill the ring back up.
  997          */
  998         tdt = ctlr->tdt;
  999         while(NEXT(tdt, ctlr->ntd) != tdh){
 1000                 if((bp = qget(edev->oq)) == nil)
 1001                         break;
 1002                 td = &ctlr->tdba[tdt];
 1003                 td->addr[0] = PCIWADDR(bp->rp);
 1004                 td->control = ((BLEN(bp) & LenMASK)<<LenSHIFT);
 1005                 td->control |= Dext|Ifcs|Teop|DtypeDD;
 1006                 ctlr->tb[tdt] = bp;
 1007                 tdt = NEXT(tdt, ctlr->ntd);
 1008                 if(NEXT(tdt, ctlr->ntd) == tdh){
 1009                         td->control |= Rs;
 1010                         ctlr->txdw++;
 1011                         ctlr->tdt = tdt;
 1012                         csr32w(ctlr, Tdt, tdt);
 1013                         igbeim(ctlr, Txdw);
 1014                         break;
 1015                 }
 1016                 ctlr->tdt = tdt;
 1017                 csr32w(ctlr, Tdt, tdt);
 1018         }
 1019 
 1020         iunlock(&ctlr->tlock);
 1021 }
 1022 
 1023 static void
 1024 igbereplenish(Ctlr* ctlr)
 1025 {
 1026         Rd *rd;
 1027         int rdt;
 1028         Block *bp;
 1029 
 1030         rdt = ctlr->rdt;
 1031         while(NEXT(rdt, ctlr->nrd) != ctlr->rdh){
 1032                 rd = &ctlr->rdba[rdt];
 1033                 if(ctlr->rb[rdt] == nil){
 1034                         bp = igberballoc();
 1035                         if(bp == nil){
 1036                                 iprint("#l%d: igbereplenish: no available buffers\n",
 1037                                         ctlr->edev->ctlrno);
 1038                                 break;
 1039                         }
 1040                         ctlr->rb[rdt] = bp;
 1041                         rd->addr[0] = PCIWADDR(bp->rp);
 1042                         rd->addr[1] = 0;
 1043                 }
 1044                 coherence();
 1045                 rd->status = 0;
 1046                 rdt = NEXT(rdt, ctlr->nrd);
 1047                 ctlr->rdfree++;
 1048         }
 1049         ctlr->rdt = rdt;
 1050         csr32w(ctlr, Rdt, rdt);
 1051 }
 1052 
 1053 static void
 1054 igberxinit(Ctlr* ctlr)
 1055 {
 1056         int i;
 1057         Block *bp;
 1058 
 1059         /* temporarily keep Mpe on */
 1060         csr32w(ctlr, Rctl, Dpf|Bsize2048|Bam|RdtmsHALF|Mpe);
 1061 
 1062         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
 1063         csr32w(ctlr, Rdbah, 0);
 1064         csr32w(ctlr, Rdlen, ctlr->nrd*sizeof(Rd));
 1065         ctlr->rdh = 0;
 1066         csr32w(ctlr, Rdh, 0);
 1067         ctlr->rdt = 0;
 1068         csr32w(ctlr, Rdt, 0);
 1069         ctlr->rdtr = 0;
 1070         csr32w(ctlr, Rdtr, Fpd|0);
 1071 
 1072         for(i = 0; i < ctlr->nrd; i++){
 1073                 if((bp = ctlr->rb[i]) != nil){
 1074                         ctlr->rb[i] = nil;
 1075                         freeb(bp);
 1076                 }
 1077         }
 1078         igbereplenish(ctlr);
 1079 
 1080         switch(ctlr->id){
 1081         case i82540em:
 1082         case i82540eplp:
 1083         case i82541gi:
 1084         case i82541gi2:
 1085         case i82541pi:
 1086         case i82545em:
 1087         case i82545gmc:
 1088         case i82546gb:
 1089         case i82546eb:
 1090         case i82547gi:
 1091                 csr32w(ctlr, Radv, 64);
 1092                 break;
 1093         }
 1094         csr32w(ctlr, Rxdctl, (8<<WthreshSHIFT)|(8<<HthreshSHIFT)|4);
 1095 
 1096         /*
 1097          * Enable checksum offload.
 1098          */
 1099         csr32w(ctlr, Rxcsum, Tuofl|Ipofl|(ETHERHDRSIZE<<PcssSHIFT));
 1100 }
 1101 
 1102 static int
 1103 igberim(void* ctlr)
 1104 {
 1105         return ((Ctlr*)ctlr)->rim != 0;
 1106 }
 1107 
 1108 static void
 1109 igberproc(void* arg)
 1110 {
 1111         Rd *rd;
 1112         Block *bp;
 1113         Ctlr *ctlr;
 1114         int r, rdh;
 1115         Ether *edev;
 1116 
 1117         edev = arg;
 1118         ctlr = edev->ctlr;
 1119 
 1120         igberxinit(ctlr);
 1121         r = csr32r(ctlr, Rctl);
 1122         r |= Ren;
 1123         csr32w(ctlr, Rctl, r);
 1124 
 1125         for(;;){
 1126                 ctlr->rim = 0;
 1127                 igbeim(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq);
 1128                 ctlr->rsleep++;
 1129                 sleep(&ctlr->rrendez, igberim, ctlr);
 1130 
 1131                 rdh = ctlr->rdh;
 1132                 for(;;){
 1133                         rd = &ctlr->rdba[rdh];
 1134 
 1135                         if(!(rd->status & Rdd))
 1136                                 break;
 1137 
 1138                         /*
 1139                          * Accept eop packets with no errors.
 1140                          * With no errors and the Ixsm bit set,
 1141                          * the descriptor status Tpcs and Ipcs bits give
 1142                          * an indication of whether the checksums were
 1143                          * calculated and valid.
 1144                          */
 1145                         if((rd->status & Reop) && rd->errors == 0){
 1146                                 bp = ctlr->rb[rdh];
 1147                                 ctlr->rb[rdh] = nil;
 1148                                 bp->wp += rd->length;
 1149                                 bp->next = nil;
 1150                                 if(!(rd->status & Ixsm)){
 1151                                         ctlr->ixsm++;
 1152                                         if(rd->status & Ipcs){
 1153                                                 /*
 1154                                                  * IP checksum calculated
 1155                                                  * (and valid as errors == 0).
 1156                                                  */
 1157                                                 ctlr->ipcs++;
 1158                                                 bp->flag |= Bipck;
 1159                                         }
 1160                                         if(rd->status & Tcpcs){
 1161                                                 /*
 1162                                                  * TCP/UDP checksum calculated
 1163                                                  * (and valid as errors == 0).
 1164                                                  */
 1165                                                 ctlr->tcpcs++;
 1166                                                 bp->flag |= Btcpck|Budpck;
 1167                                         }
 1168                                         bp->checksum = rd->checksum;
 1169                                         bp->flag |= Bpktck;
 1170                                 }
 1171                                 etheriq(edev, bp, 1);
 1172                         }
 1173                         else if(ctlr->rb[rdh] != nil){
 1174                                 freeb(ctlr->rb[rdh]);
 1175                                 ctlr->rb[rdh] = nil;
 1176                         }
 1177 
 1178                         memset(rd, 0, sizeof(Rd));
 1179                         coherence();
 1180                         ctlr->rdfree--;
 1181                         rdh = NEXT(rdh, ctlr->nrd);
 1182                 }
 1183                 ctlr->rdh = rdh;
 1184 
 1185                 if(ctlr->rdfree < ctlr->nrd/2 || (ctlr->rim & Rxdmt0))
 1186                         igbereplenish(ctlr);
 1187         }
 1188 }
 1189 
 1190 static void
 1191 igbeattach(Ether* edev)
 1192 {
 1193         Block *bp;
 1194         Ctlr *ctlr;
 1195         char name[KNAMELEN];
 1196 
 1197         ctlr = edev->ctlr;
 1198         ctlr->edev = edev;                      /* point back to Ether* */
 1199         qlock(&ctlr->alock);
 1200         if(ctlr->alloc != nil){                 /* already allocated? */
 1201                 qunlock(&ctlr->alock);
 1202                 return;
 1203         }
 1204 
 1205         ctlr->nrd = ROUND(Nrd, 8);
 1206         ctlr->ntd = ROUND(Ntd, 8);
 1207         ctlr->alloc = malloc(ctlr->nrd*sizeof(Rd)+ctlr->ntd*sizeof(Td) + 127);
 1208         if(ctlr->alloc == nil){
 1209                 print("igbe: can't allocate ctlr->alloc\n");
 1210                 qunlock(&ctlr->alock);
 1211                 return;
 1212         }
 1213         ctlr->rdba = (Rd*)ROUNDUP((uintptr)ctlr->alloc, 128);
 1214         ctlr->tdba = (Td*)(ctlr->rdba+ctlr->nrd);
 1215 
 1216         ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
 1217         ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
 1218         if (ctlr->rb == nil || ctlr->tb == nil) {
 1219                 print("igbe: can't allocate ctlr->rb or ctlr->tb\n");
 1220                 qunlock(&ctlr->alock);
 1221                 return;
 1222         }
 1223 
 1224         if(waserror()){
 1225                 while(ctlr->nrb > 0){
 1226                         bp = igberballoc();
 1227                         bp->free = nil;
 1228                         freeb(bp);
 1229                         ctlr->nrb--;
 1230                 }
 1231                 free(ctlr->tb);
 1232                 ctlr->tb = nil;
 1233                 free(ctlr->rb);
 1234                 ctlr->rb = nil;
 1235                 free(ctlr->alloc);
 1236                 ctlr->alloc = nil;
 1237                 qunlock(&ctlr->alock);
 1238                 nexterror();
 1239         }
 1240 
 1241         for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
 1242                 if((bp = allocb(Rbsz)) == nil)
 1243                         break;
 1244                 bp->free = igberbfree;
 1245                 freeb(bp);
 1246         }
 1247 
 1248         snprint(name, KNAMELEN, "#l%dlproc", edev->ctlrno);
 1249         kproc(name, igbelproc, edev);
 1250 
 1251         snprint(name, KNAMELEN, "#l%drproc", edev->ctlrno);
 1252         kproc(name, igberproc, edev);
 1253 
 1254         igbetxinit(ctlr);
 1255 
 1256         qunlock(&ctlr->alock);
 1257         poperror();
 1258 }
 1259 
 1260 static void
 1261 igbeinterrupt(Ureg*, void* arg)
 1262 {
 1263         Ctlr *ctlr;
 1264         Ether *edev;
 1265         int icr, im, txdw;
 1266 
 1267         edev = arg;
 1268         ctlr = edev->ctlr;
 1269 
 1270         ilock(&ctlr->imlock);
 1271         csr32w(ctlr, Imc, ~0);
 1272         im = ctlr->im;
 1273         txdw = 0;
 1274 
 1275         while((icr = csr32r(ctlr, Icr) & ctlr->im) != 0){
 1276                 if(icr & Lsc){
 1277                         im &= ~Lsc;
 1278                         ctlr->lim = icr & Lsc;
 1279                         wakeup(&ctlr->lrendez);
 1280                         ctlr->lintr++;
 1281                 }
 1282                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq)){
 1283                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq);
 1284                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq);
 1285                         wakeup(&ctlr->rrendez);
 1286                         ctlr->rintr++;
 1287                 }
 1288                 if(icr & Txdw){
 1289                         im &= ~Txdw;
 1290                         txdw++;
 1291                         ctlr->tintr++;
 1292                 }
 1293         }
 1294 
 1295         ctlr->im = im;
 1296         csr32w(ctlr, Ims, im);
 1297         iunlock(&ctlr->imlock);
 1298 
 1299         if(txdw)
 1300                 igbetransmit(edev);
 1301 }
 1302 
 1303 static int
 1304 i82543mdior(Ctlr* ctlr, int n)
 1305 {
 1306         int ctrl, data, i, r;
 1307 
 1308         /*
 1309          * Read n bits from the Management Data I/O Interface.
 1310          */
 1311         ctrl = csr32r(ctlr, Ctrl);
 1312         r = (ctrl & ~Mddo)|Mdco;
 1313         data = 0;
 1314         for(i = n-1; i >= 0; i--){
 1315                 if(csr32r(ctlr, Ctrl) & Mdd)
 1316                         data |= (1<<i);
 1317                 csr32w(ctlr, Ctrl, Mdc|r);
 1318                 csr32w(ctlr, Ctrl, r);
 1319         }
 1320         csr32w(ctlr, Ctrl, ctrl);
 1321 
 1322         return data;
 1323 }
 1324 
 1325 static int
 1326 i82543mdiow(Ctlr* ctlr, int bits, int n)
 1327 {
 1328         int ctrl, i, r;
 1329 
 1330         /*
 1331          * Write n bits to the Management Data I/O Interface.
 1332          */
 1333         ctrl = csr32r(ctlr, Ctrl);
 1334         r = Mdco|Mddo|ctrl;
 1335         for(i = n-1; i >= 0; i--){
 1336                 if(bits & (1<<i))
 1337                         r |= Mdd;
 1338                 else
 1339                         r &= ~Mdd;
 1340                 csr32w(ctlr, Ctrl, Mdc|r);
 1341                 csr32w(ctlr, Ctrl, r);
 1342         }
 1343         csr32w(ctlr, Ctrl, ctrl);
 1344 
 1345         return 0;
 1346 }
 1347 
 1348 static int
 1349 i82543miimir(Mii* mii, int pa, int ra)
 1350 {
 1351         int data;
 1352         Ctlr *ctlr;
 1353 
 1354         ctlr = mii->ctlr;
 1355 
 1356         /*
 1357          * MII Management Interface Read.
 1358          *
 1359          * Preamble;
 1360          * ST+OP+PHYAD+REGAD;
 1361          * TA + 16 data bits.
 1362          */
 1363         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
 1364         i82543mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
 1365         data = i82543mdior(ctlr, 18);
 1366 
 1367         if(data & 0x10000)
 1368                 return -1;
 1369 
 1370         return data & 0xFFFF;
 1371 }
 1372 
 1373 static int
 1374 i82543miimiw(Mii* mii, int pa, int ra, int data)
 1375 {
 1376         Ctlr *ctlr;
 1377 
 1378         ctlr = mii->ctlr;
 1379 
 1380         /*
 1381          * MII Management Interface Write.
 1382          *
 1383          * Preamble;
 1384          * ST+OP+PHYAD+REGAD+TA + 16 data bits;
 1385          * Z.
 1386          */
 1387         i82543mdiow(ctlr, 0xFFFFFFFF, 32);
 1388         data &= 0xFFFF;
 1389         data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
 1390         i82543mdiow(ctlr, data, 32);
 1391 
 1392         return 0;
 1393 }
 1394 
 1395 static int
 1396 igbemiimir(Mii* mii, int pa, int ra)
 1397 {
 1398         Ctlr *ctlr;
 1399         int mdic, timo;
 1400 
 1401         ctlr = mii->ctlr;
 1402 
 1403         csr32w(ctlr, Mdic, MDIrop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT));
 1404         mdic = 0;
 1405         for(timo = 64; timo; timo--){
 1406                 mdic = csr32r(ctlr, Mdic);
 1407                 if(mdic & (MDIe|MDIready))
 1408                         break;
 1409                 microdelay(1);
 1410         }
 1411 
 1412         if((mdic & (MDIe|MDIready)) == MDIready)
 1413                 return mdic & 0xFFFF;
 1414         return -1;
 1415 }
 1416 
 1417 static int
 1418 igbemiimiw(Mii* mii, int pa, int ra, int data)
 1419 {
 1420         Ctlr *ctlr;
 1421         int mdic, timo;
 1422 
 1423         ctlr = mii->ctlr;
 1424 
 1425         data &= MDIdMASK;
 1426         csr32w(ctlr, Mdic, MDIwop|(pa<<MDIpSHIFT)|(ra<<MDIrSHIFT)|data);
 1427         mdic = 0;
 1428         for(timo = 64; timo; timo--){
 1429                 mdic = csr32r(ctlr, Mdic);
 1430                 if(mdic & (MDIe|MDIready))
 1431                         break;
 1432                 microdelay(1);
 1433         }
 1434         if((mdic & (MDIe|MDIready)) == MDIready)
 1435                 return 0;
 1436         return -1;
 1437 }
 1438 
 1439 static int
 1440 igbemii(Ctlr* ctlr)
 1441 {
 1442         MiiPhy *phy;
 1443         int ctrl, p, r;
 1444 
 1445         r = csr32r(ctlr, Status);
 1446         if(r & Tbimode)
 1447                 return -1;
 1448         if((ctlr->mii = malloc(sizeof(Mii))) == nil)
 1449                 return -1;
 1450         ctlr->mii->ctlr = ctlr;
 1451 
 1452         ctrl = csr32r(ctlr, Ctrl);
 1453         ctrl |= Slu;
 1454 
 1455         switch(ctlr->id){
 1456         case i82543gc:
 1457                 ctrl |= Frcdplx|Frcspd;
 1458                 csr32w(ctlr, Ctrl, ctrl);
 1459 
 1460                 /*
 1461                  * The reset pin direction (Mdro) should already
 1462                  * be set from the EEPROM load.
 1463                  * If it's not set this configuration is unexpected
 1464                  * so bail.
 1465                  */
 1466                 r = csr32r(ctlr, Ctrlext);
 1467                 if(!(r & Mdro))
 1468                         return -1;
 1469                 csr32w(ctlr, Ctrlext, r);
 1470                 delay(20);
 1471                 r = csr32r(ctlr, Ctrlext);
 1472                 r &= ~Mdr;
 1473                 csr32w(ctlr, Ctrlext, r);
 1474                 delay(20);
 1475                 r = csr32r(ctlr, Ctrlext);
 1476                 r |= Mdr;
 1477                 csr32w(ctlr, Ctrlext, r);
 1478                 delay(20);
 1479 
 1480                 ctlr->mii->mir = i82543miimir;
 1481                 ctlr->mii->miw = i82543miimiw;
 1482                 break;
 1483         case i82544ei:
 1484         case i82544eif:
 1485         case i82547ei:
 1486         case i82540em:
 1487         case i82540eplp:
 1488         case i82547gi:
 1489         case i82541gi:
 1490         case i82541gi2:
 1491         case i82541pi:
 1492         case i82545em:
 1493         case i82545gmc:
 1494         case i82546gb:
 1495         case i82546eb:
 1496                 ctrl &= ~(Frcdplx|Frcspd);
 1497                 csr32w(ctlr, Ctrl, ctrl);
 1498                 ctlr->mii->mir = igbemiimir;
 1499                 ctlr->mii->miw = igbemiimiw;
 1500                 break;
 1501         default:
 1502                 free(ctlr->mii);
 1503                 ctlr->mii = nil;
 1504                 return -1;
 1505         }
 1506 
 1507         if(mii(ctlr->mii, ~0) == 0 || (phy = ctlr->mii->curphy) == nil){
 1508                 free(ctlr->mii);
 1509                 ctlr->mii = nil;
 1510                 return -1;
 1511         }
 1512         USED(phy);
 1513         // print("oui %X phyno %d\n", phy->oui, phy->phyno);
 1514 
 1515         /*
 1516          * 8254X-specific PHY registers not in 802.3:
 1517          *      0x10    PHY specific control
 1518          *      0x14    extended PHY specific control
 1519          * Set appropriate values then reset the PHY to have
 1520          * changes noted.
 1521          */
 1522         switch(ctlr->id){
 1523         case i82547gi:
 1524         case i82541gi:
 1525         case i82541gi2:
 1526         case i82541pi:
 1527         case i82545em:
 1528         case i82545gmc:
 1529         case i82546gb:
 1530         case i82546eb:
 1531                 break;
 1532         default:
 1533                 r = miimir(ctlr->mii, 16);
 1534                 r |= 0x0800;                    /* assert CRS on Tx */
 1535                 r |= 0x0060;                    /* auto-crossover all speeds */
 1536                 r |= 0x0002;                    /* polarity reversal enabled */
 1537                 miimiw(ctlr->mii, 16, r);
 1538 
 1539                 r = miimir(ctlr->mii, 20);
 1540                 r |= 0x0070;                    /* +25MHz clock */
 1541                 r &= ~0x0F00;
 1542                 r |= 0x0100;                    /* 1x downshift */
 1543                 miimiw(ctlr->mii, 20, r);
 1544 
 1545                 miireset(ctlr->mii);
 1546                 p = 0;
 1547                 if(ctlr->txcw & TxcwPs)
 1548                         p |= AnaP;
 1549                 if(ctlr->txcw & TxcwAs)
 1550                         p |= AnaAP;
 1551                 miiane(ctlr->mii, ~0, p, ~0);
 1552                 break;
 1553         }
 1554         return 0;
 1555 }
 1556 
 1557 static int
 1558 at93c46io(Ctlr* ctlr, char* op, int data)
 1559 {
 1560         char *lp, *p;
 1561         int i, loop, eecd, r;
 1562 
 1563         eecd = csr32r(ctlr, Eecd);
 1564 
 1565         r = 0;
 1566         loop = -1;
 1567         lp = nil;
 1568         for(p = op; *p != '\0'; p++){
 1569                 switch(*p){
 1570                 default:
 1571                         return -1;
 1572                 case ' ':
 1573                         continue;
 1574                 case ':':                       /* start of loop */
 1575                         loop = strtol(p+1, &lp, 0)-1;
 1576                         lp--;
 1577                         if(p == lp)
 1578                                 loop = 7;
 1579                         p = lp;
 1580                         continue;
 1581                 case ';':                       /* end of loop */
 1582                         if(lp == nil)
 1583                                 return -1;
 1584                         loop--;
 1585                         if(loop >= 0)
 1586                                 p = lp;
 1587                         else
 1588                                 lp = nil;
 1589                         continue;
 1590                 case 'C':                       /* assert clock */
 1591                         eecd |= Sk;
 1592                         break;
 1593                 case 'c':                       /* deassert clock */
 1594                         eecd &= ~Sk;
 1595                         break;
 1596                 case 'D':                       /* next bit in 'data' byte */
 1597                         if(loop < 0)
 1598                                 return -1;
 1599                         if(data & (1<<loop))
 1600                                 eecd |= Di;
 1601                         else
 1602                                 eecd &= ~Di;
 1603                         break;
 1604                 case 'O':                       /* collect data output */
 1605                         i = (csr32r(ctlr, Eecd) & Do) != 0;
 1606                         if(loop >= 0)
 1607                                 r |= (i<<loop);
 1608                         else
 1609                                 r = i;
 1610                         continue;
 1611                 case 'I':                       /* assert data input */
 1612                         eecd |= Di;
 1613                         break;
 1614                 case 'i':                       /* deassert data input */
 1615                         eecd &= ~Di;
 1616                         break;
 1617                 case 'S':                       /* enable chip select */
 1618                         eecd |= Cs;
 1619                         break;
 1620                 case 's':                       /* disable chip select */
 1621                         eecd &= ~Cs;
 1622                         break;
 1623                 }
 1624                 csr32w(ctlr, Eecd, eecd);
 1625                 microdelay(50);
 1626         }
 1627         if(loop >= 0)
 1628                 return -1;
 1629         return r;
 1630 }
 1631 
 1632 static int
 1633 at93c46r(Ctlr* ctlr)
 1634 {
 1635         ushort sum;
 1636         char rop[20];
 1637         int addr, areq, bits, data, eecd, i;
 1638 
 1639         eecd = csr32r(ctlr, Eecd);
 1640         if(eecd & Spi){
 1641                 print("igbe: SPI EEPROM access not implemented\n");
 1642                 return 0;
 1643         }
 1644         if(eecd & (Eeszaddr|Eesz256))
 1645                 bits = 8;
 1646         else
 1647                 bits = 6;
 1648 
 1649         sum = 0;
 1650 
 1651         switch(ctlr->id){
 1652         default:
 1653                 areq = 0;
 1654                 break;
 1655         case i82541gi:
 1656         case i82547gi:
 1657         case i82540em:
 1658         case i82540eplp:
 1659         case i82541pi:
 1660         case i82541gi2:
 1661         case i82545em:
 1662         case i82545gmc:
 1663         case i82546gb:
 1664         case i82546eb:
 1665         case i82547ei:
 1666                 areq = 1;
 1667                 csr32w(ctlr, Eecd, eecd|Areq);
 1668                 for(i = 0; i < 1000; i++){
 1669                         if((eecd = csr32r(ctlr, Eecd)) & Agnt)
 1670                                 break;
 1671                         microdelay(5);
 1672                 }
 1673                 if(!(eecd & Agnt)){
 1674                         print("igbe: not granted EEPROM access\n");
 1675                         goto release;
 1676                 }
 1677                 break;
 1678         }
 1679         snprint(rop, sizeof(rop), "S :%dDCc;", bits+3);
 1680 
 1681         for(addr = 0; addr < 0x40; addr++){
 1682                 /*
 1683                  * Read a word at address 'addr' from the Atmel AT93C46
 1684                  * 3-Wire Serial EEPROM or compatible. The EEPROM access is
 1685                  * controlled by 4 bits in Eecd. See the AT93C46 datasheet
 1686                  * for protocol details.
 1687                  */
 1688                 if(at93c46io(ctlr, rop, (0x06<<bits)|addr) != 0){
 1689                         print("igbe: can't set EEPROM address 0x%2.2X\n", addr);
 1690                         goto release;
 1691                 }
 1692                 data = at93c46io(ctlr, ":16COc;", 0);
 1693                 at93c46io(ctlr, "sic", 0);
 1694                 ctlr->eeprom[addr] = data;
 1695                 sum += data;
 1696         }
 1697 
 1698 release:
 1699         if(areq)
 1700                 csr32w(ctlr, Eecd, eecd & ~Areq);
 1701         return sum;
 1702 }
 1703 
 1704 static int
 1705 igbedetach(Ctlr* ctlr)
 1706 {
 1707         int r, timeo;
 1708 
 1709         /*
 1710          * Perform a device reset to get the chip back to the
 1711          * power-on state, followed by an EEPROM reset to read
 1712          * the defaults for some internal registers.
 1713          */
 1714         csr32w(ctlr, Imc, ~0);
 1715         csr32w(ctlr, Rctl, 0);
 1716         csr32w(ctlr, Tctl, 0);
 1717 
 1718         delay(10);
 1719 
 1720         csr32w(ctlr, Ctrl, Devrst);
 1721         delay(1);
 1722         for(timeo = 0; timeo < 1000; timeo++){
 1723                 if(!(csr32r(ctlr, Ctrl) & Devrst))
 1724                         break;
 1725                 delay(1);
 1726         }
 1727         if(csr32r(ctlr, Ctrl) & Devrst)
 1728                 return -1;
 1729         r = csr32r(ctlr, Ctrlext);
 1730         csr32w(ctlr, Ctrlext, r|Eerst);
 1731         delay(1);
 1732         for(timeo = 0; timeo < 1000; timeo++){
 1733                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
 1734                         break;
 1735                 delay(1);
 1736         }
 1737         if(csr32r(ctlr, Ctrlext) & Eerst)
 1738                 return -1;
 1739 
 1740         switch(ctlr->id){
 1741         default:
 1742                 break;
 1743         case i82540em:
 1744         case i82540eplp:
 1745         case i82541gi:
 1746         case i82541pi:
 1747         case i82547gi:
 1748         case i82541gi2:
 1749         case i82545em:
 1750         case i82545gmc:
 1751         case i82546gb:
 1752         case i82546eb:
 1753                 r = csr32r(ctlr, Manc);
 1754                 r &= ~Arpen;
 1755                 csr32w(ctlr, Manc, r);
 1756                 break;
 1757         }
 1758 
 1759         csr32w(ctlr, Imc, ~0);
 1760         delay(1);
 1761         for(timeo = 0; timeo < 1000; timeo++){
 1762                 if(!csr32r(ctlr, Icr))
 1763                         break;
 1764                 delay(1);
 1765         }
 1766         if(csr32r(ctlr, Icr))
 1767                 return -1;
 1768 
 1769         return 0;
 1770 }
 1771 
 1772 static void
 1773 igbeshutdown(Ether* ether)
 1774 {
 1775         igbedetach(ether->ctlr);
 1776 }
 1777 
 1778 static int
 1779 igbereset(Ctlr* ctlr)
 1780 {
 1781         int ctrl, i, pause, r, swdpio, txcw;
 1782 
 1783         if(igbedetach(ctlr))
 1784                 return -1;
 1785 
 1786         /*
 1787          * Read the EEPROM, validate the checksum
 1788          * then get the device back to a power-on state.
 1789          */
 1790         if((r = at93c46r(ctlr)) != 0xBABA){
 1791                 print("igbe: bad EEPROM checksum - 0x%4.4uX\n", r);
 1792                 return -1;
 1793         }
 1794 
 1795         /*
 1796          * Snarf and set up the receive addresses.
 1797          * There are 16 addresses. The first should be the MAC address.
 1798          * The others are cleared and not marked valid (MS bit of Rah).
 1799          */
 1800         if ((ctlr->id == i82546gb || ctlr->id == i82546eb) &&
 1801             BUSFNO(ctlr->pcidev->tbdf) == 1)
 1802                 ctlr->eeprom[Ea+2] += 0x100;            /* second interface */
 1803         if(ctlr->id == i82541gi && ctlr->eeprom[Ea] == 0xFFFF)
 1804                 ctlr->eeprom[Ea] = 0xD000;
 1805         for(i = Ea; i < Eaddrlen/2; i++){
 1806                 ctlr->ra[2*i] = ctlr->eeprom[i];
 1807                 ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
 1808         }
 1809         /* lan id seems to vary on 82543gc; don't use it */
 1810         if (ctlr->id != i82543gc) {
 1811                 r = (csr32r(ctlr, Status) & Lanid) >> 2;
 1812                 ctlr->ra[5] += r;               /* ea ctlr[1] = ea ctlr[0]+1 */
 1813         }
 1814 
 1815         r = (ctlr->ra[3]<<24)|(ctlr->ra[2]<<16)|(ctlr->ra[1]<<8)|ctlr->ra[0];
 1816         csr32w(ctlr, Ral, r);
 1817         r = 0x80000000|(ctlr->ra[5]<<8)|ctlr->ra[4];
 1818         csr32w(ctlr, Rah, r);
 1819         for(i = 1; i < 16; i++){
 1820                 csr32w(ctlr, Ral+i*8, 0);
 1821                 csr32w(ctlr, Rah+i*8, 0);
 1822         }
 1823 
 1824         /*
 1825          * Clear the Multicast Table Array.
 1826          * It's a 4096 bit vector accessed as 128 32-bit registers.
 1827          */
 1828         memset(ctlr->mta, 0, sizeof(ctlr->mta));
 1829         for(i = 0; i < 128; i++)
 1830                 csr32w(ctlr, Mta+i*4, 0);
 1831 
 1832         /*
 1833          * Just in case the Eerst didn't load the defaults
 1834          * (doesn't appear to fully on the 82543GC), do it manually.
 1835          */
 1836         if (ctlr->id == i82543gc) {
 1837                 txcw = csr32r(ctlr, Txcw);
 1838                 txcw &= ~(TxcwAne|TxcwPauseMASK|TxcwFd);
 1839                 ctrl = csr32r(ctlr, Ctrl);
 1840                 ctrl &= ~(SwdpioloMASK|Frcspd|Ilos|Lrst|Fd);
 1841 
 1842                 if(ctlr->eeprom[Icw1] & 0x0400){
 1843                         ctrl |= Fd;
 1844                         txcw |= TxcwFd;
 1845                 }
 1846                 if(ctlr->eeprom[Icw1] & 0x0200)
 1847                         ctrl |= Lrst;
 1848                 if(ctlr->eeprom[Icw1] & 0x0010)
 1849                         ctrl |= Ilos;
 1850                 if(ctlr->eeprom[Icw1] & 0x0800)
 1851                         ctrl |= Frcspd;
 1852                 swdpio = (ctlr->eeprom[Icw1] & 0x01E0)>>5;
 1853                 ctrl |= swdpio<<SwdpioloSHIFT;
 1854                 csr32w(ctlr, Ctrl, ctrl);
 1855 
 1856                 ctrl = csr32r(ctlr, Ctrlext);
 1857                 ctrl &= ~(Ips|SwdpiohiMASK);
 1858                 swdpio = (ctlr->eeprom[Icw2] & 0x00F0)>>4;
 1859                 if(ctlr->eeprom[Icw1] & 0x1000)
 1860                         ctrl |= Ips;
 1861                 ctrl |= swdpio<<SwdpiohiSHIFT;
 1862                 csr32w(ctlr, Ctrlext, ctrl);
 1863 
 1864                 if(ctlr->eeprom[Icw2] & 0x0800)
 1865                         txcw |= TxcwAne;
 1866                 pause = (ctlr->eeprom[Icw2] & 0x3000)>>12;
 1867                 txcw |= pause<<TxcwPauseSHIFT;
 1868                 switch(pause){
 1869                 default:
 1870                         ctlr->fcrtl = 0x00002000;
 1871                         ctlr->fcrth = 0x00004000;
 1872                         txcw |= TxcwAs|TxcwPs;
 1873                         break;
 1874                 case 0:
 1875                         ctlr->fcrtl = 0x00002000;
 1876                         ctlr->fcrth = 0x00004000;
 1877                         break;
 1878                 case 2:
 1879                         ctlr->fcrtl = 0;
 1880                         ctlr->fcrth = 0;
 1881                         txcw |= TxcwAs;
 1882                         break;
 1883                 }
 1884                 ctlr->txcw = txcw;
 1885                 csr32w(ctlr, Txcw, txcw);
 1886         }
 1887 
 1888 
 1889         /*
 1890          * Flow control - values from the datasheet.
 1891          */
 1892         csr32w(ctlr, Fcal, 0x00C28001);
 1893         csr32w(ctlr, Fcah, 0x00000100);
 1894         csr32w(ctlr, Fct, 0x00008808);
 1895         csr32w(ctlr, Fcttv, 0x00000100);
 1896 
 1897         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
 1898         csr32w(ctlr, Fcrth, ctlr->fcrth);
 1899 
 1900         if(!(csr32r(ctlr, Status) & Tbimode) && igbemii(ctlr) < 0)
 1901                 return -1;
 1902 
 1903         return 0;
 1904 }
 1905 
 1906 static void
 1907 igbepci(void)
 1908 {
 1909         int cls;
 1910         Pcidev *p;
 1911         Ctlr *ctlr;
 1912         void *mem;
 1913 
 1914         p = nil;
 1915         while(p = pcimatch(p, 0, 0)){
 1916                 if(p->ccrb != 0x02 || p->ccru != 0)
 1917                         continue;
 1918 
 1919                 switch((p->did<<16)|p->vid){
 1920                 default:
 1921                         continue;
 1922                 case i82543gc:
 1923                 case i82544ei:
 1924                 case i82544eif:
 1925                 case i82547ei:
 1926                 case i82540em:
 1927                 case i82540eplp:
 1928                 case i82541gi:
 1929                 case i82547gi:
 1930                 case i82541gi2:
 1931                 case i82541pi:
 1932                 case i82545em:
 1933                 case i82545gmc:
 1934                 case i82546gb:
 1935                 case i82546eb:
 1936                         break;
 1937                 }
 1938 
 1939                 mem = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
 1940                 if(mem == nil){
 1941                         print("igbe: can't map %8.8luX\n", p->mem[0].bar);
 1942                         continue;
 1943                 }
 1944                 cls = pcicfgr8(p, PciCLS);
 1945                 switch(cls){
 1946                         default:
 1947                                 print("igbe: unexpected CLS - %d\n", cls*4);
 1948                                 break;
 1949                         case 0x00:
 1950                         case 0xFF:
 1951                                 print("igbe: unusable CLS\n");
 1952                                 continue;
 1953                         case 0x08:
 1954                         case 0x10:
 1955                                 break;
 1956                 }
 1957                 ctlr = malloc(sizeof(Ctlr));
 1958                 ctlr->port = p->mem[0].bar & ~0x0F;
 1959                 ctlr->pcidev = p;
 1960                 ctlr->id = (p->did<<16)|p->vid;
 1961                 ctlr->cls = cls*4;
 1962                 ctlr->nic = mem;
 1963 
 1964                 if(igbereset(ctlr)){
 1965                         free(ctlr);
 1966                         vunmap(mem, p->mem[0].size);
 1967                         continue;
 1968                 }
 1969                 pcisetbme(p);
 1970 
 1971                 if(igbectlrhead != nil)
 1972                         igbectlrtail->next = ctlr;
 1973                 else
 1974                         igbectlrhead = ctlr;
 1975                 igbectlrtail = ctlr;
 1976         }
 1977 }
 1978 
 1979 static int
 1980 igbepnp(Ether* edev)
 1981 {
 1982         Ctlr *ctlr;
 1983 
 1984         if(igbectlrhead == nil)
 1985                 igbepci();
 1986 
 1987         /*
 1988          * Any adapter matches if no edev->port is supplied,
 1989          * otherwise the ports must match.
 1990          */
 1991         for(ctlr = igbectlrhead; ctlr != nil; ctlr = ctlr->next){
 1992                 if(ctlr->active)
 1993                         continue;
 1994                 if(edev->port == 0 || edev->port == ctlr->port){
 1995                         ctlr->active = 1;
 1996                         break;
 1997                 }
 1998         }
 1999         if(ctlr == nil)
 2000                 return -1;
 2001 
 2002         edev->ctlr = ctlr;
 2003         edev->port = ctlr->port;
 2004         edev->irq = ctlr->pcidev->intl;
 2005         edev->tbdf = ctlr->pcidev->tbdf;
 2006         edev->mbps = 1000;
 2007         memmove(edev->ea, ctlr->ra, Eaddrlen);
 2008 
 2009         /*
 2010          * Linkage to the generic ethernet driver.
 2011          */
 2012         edev->attach = igbeattach;
 2013         edev->transmit = igbetransmit;
 2014         edev->interrupt = igbeinterrupt;
 2015         edev->ifstat = igbeifstat;
 2016         edev->ctl = igbectl;
 2017 
 2018         edev->arg = edev;
 2019         edev->promiscuous = igbepromiscuous;
 2020         edev->shutdown = igbeshutdown;
 2021         edev->multicast = igbemulticast;
 2022 
 2023         return 0;
 2024 }
 2025 
 2026 void
 2027 etherigbelink(void)
 2028 {
 2029         addethercard("i82543", igbepnp);
 2030         addethercard("igbe", igbepnp);
 2031 }
 2032 

Cache object: ccb079131b78f50ef663a4a7bcfbe68e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.