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/ether82563.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 Gigabit Ethernet PCI-Express Controllers.
    3  *      8256[36], 8257[12], 82573[ev]
    4  *      82575eb
    5  * Pretty basic, does not use many of the chip smarts.
    6  * The interrupt mitigation tuning for each chip variant
    7  * is probably different. The reset/initialisation
    8  * sequence needs straightened out. Doubt the PHY code
    9  * for the 82575eb is right.
   10  */
   11 #include "u.h"
   12 #include "../port/lib.h"
   13 #include "mem.h"
   14 #include "dat.h"
   15 #include "fns.h"
   16 #include "io.h"
   17 #include "../port/error.h"
   18 #include "../port/netif.h"
   19 
   20 #include "etherif.h"
   21 
   22 /*
   23  * these are in the order they appear in the manual, not numeric order.
   24  * It was too hard to find them in the book. Ref 21489, rev 2.6
   25  */
   26 
   27 enum {
   28         /* General */
   29 
   30         Ctrl            = 0x0000,       /* Device Control */
   31         Status          = 0x0008,       /* Device Status */
   32         Eec             = 0x0010,       /* EEPROM/Flash Control/Data */
   33         Eerd            = 0x0014,       /* EEPROM Read */
   34         Ctrlext         = 0x0018,       /* Extended Device Control */
   35         Fla             = 0x001c,       /* Flash Access */
   36         Mdic            = 0x0020,       /* MDI Control */
   37         Seresctl        = 0x0024,       /* Serdes ana */
   38         Fcal            = 0x0028,       /* Flow Control Address Low */
   39         Fcah            = 0x002C,       /* Flow Control Address High */
   40         Fct             = 0x0030,       /* Flow Control Type */
   41         Kumctrlsta      = 0x0034,       /* MAC-PHY Interface */
   42         Vet             = 0x0038,       /* VLAN EtherType */
   43         Fcttv           = 0x0170,       /* Flow Control Transmit Timer Value */
   44         Txcw            = 0x0178,       /* Transmit Configuration Word */
   45         Rxcw            = 0x0180,       /* Receive Configuration Word */
   46         Ledctl          = 0x0E00,       /* LED control */
   47         Pba             = 0x1000,       /* Packet Buffer Allocation */
   48         Pbs             = 0x1008,       /* Packet Buffer Size */
   49 
   50         /* Interrupt */
   51 
   52         Icr             = 0x00C0,       /* Interrupt Cause Read */
   53         Itr             = 0x00c4,       /* Interrupt Throttling Rate */
   54         Ics             = 0x00C8,       /* Interrupt Cause Set */
   55         Ims             = 0x00D0,       /* Interrupt Mask Set/Read */
   56         Imc             = 0x00D8,       /* Interrupt mask Clear */
   57         Iam             = 0x00E0,       /* Interrupt acknowledge Auto Mask */
   58 
   59         /* Receive */
   60 
   61         Rctl            = 0x0100,       /* Control */
   62         Ert             = 0x2008,       /* Early Receive Threshold (573[EVL] only) */
   63         Fcrtl           = 0x2160,       /* Flow Control RX Threshold Low */
   64         Fcrth           = 0x2168,       /* Flow Control Rx Threshold High */
   65         Psrctl          = 0x2170,       /* Packet Split Receive Control */
   66         Rdbal           = 0x2800,       /* Rdesc Base Address Low Queue 0 */
   67         Rdbah           = 0x2804,       /* Rdesc Base Address High Queue 0 */
   68         Rdlen           = 0x2808,       /* Descriptor Length Queue 0 */
   69         Rdh             = 0x2810,       /* Descriptor Head Queue 0 */
   70         Rdt             = 0x2818,       /* Descriptor Tail Queue 0 */
   71         Rdtr            = 0x2820,       /* Descriptor Timer Ring */
   72         Rxdctl          = 0x2828,       /* Descriptor Control */
   73         Radv            = 0x282C,       /* Interrupt Absolute Delay Timer */
   74         Rdbal1          = 0x2900,       /* Rdesc Base Address Low Queue 1 */
   75         Rdbah1          = 0x2804,       /* Rdesc Base Address High Queue 1 */
   76         Rdlen1          = 0x2908,       /* Descriptor Length Queue 1 */
   77         Rdh1            = 0x2910,       /* Descriptor Head Queue 1 */
   78         Rdt1            = 0x2918,       /* Descriptor Tail Queue 1 */
   79         Rxdctl1         = 0x2928,       /* Descriptor Control Queue 1 */
   80         Rsrpd           = 0x2c00,       /* Small Packet Detect */
   81         Raid            = 0x2c08,       /* ACK interrupt delay */
   82         Cpuvec          = 0x2c10,       /* CPU Vector */
   83         Rxcsum          = 0x5000,       /* Checksum Control */
   84         Rfctl           = 0x5008,       /* Filter Control */
   85         Mta             = 0x5200,       /* Multicast Table Array */
   86         Ral             = 0x5400,       /* Receive Address Low */
   87         Rah             = 0x5404,       /* Receive Address High */
   88         Vfta            = 0x5600,       /* VLAN Filter Table Array */
   89         Mrqc            = 0x5818,       /* Multiple Receive Queues Command */
   90         Rssim           = 0x5864,       /* RSS Interrupt Mask */
   91         Rssir           = 0x5868,       /* RSS Interrupt Request */
   92         Reta            = 0x5c00,       /* Redirection Table */
   93         Rssrk           = 0x5c80,       /* RSS Random Key */
   94 
   95         /* Transmit */
   96 
   97         Tctl            = 0x0400,       /* Transmit Control */
   98         Tipg            = 0x0410,       /* Transmit IPG */
   99         Tkabgtxd        = 0x3004,       /* glci afe band gap transmit ref data, or something */
  100         Tdbal           = 0x3800,       /* Tdesc Base Address Low */
  101         Tdbah           = 0x3804,       /* Tdesc Base Address High */
  102         Tdlen           = 0x3808,       /* Descriptor Length */
  103         Tdh             = 0x3810,       /* Descriptor Head */
  104         Tdt             = 0x3818,       /* Descriptor Tail */
  105         Tidv            = 0x3820,       /* Interrupt Delay Value */
  106         Txdctl          = 0x3828,       /* Descriptor Control */
  107         Tadv            = 0x382C,       /* Interrupt Absolute Delay Timer */
  108         Tarc0           = 0x3840,       /* Arbitration Counter Queue 0 */
  109         Tdbal1          = 0x3900,       /* Descriptor Base Low Queue 1 */
  110         Tdbah1          = 0x3904,       /* Descriptor Base High Queue 1 */
  111         Tdlen1          = 0x3908,       /* Descriptor Length Queue 1 */
  112         Tdh1            = 0x3910,       /* Descriptor Head Queue 1 */
  113         Tdt1            = 0x3918,       /* Descriptor Tail Queue 1 */
  114         Txdctl1         = 0x3928,       /* Descriptor Control 1 */
  115         Tarc1           = 0x3940,       /* Arbitration Counter Queue 1 */
  116 
  117         /* Statistics */
  118 
  119         Statistics      = 0x4000,       /* Start of Statistics Area */
  120         Gorcl           = 0x88/4,       /* Good Octets Received Count */
  121         Gotcl           = 0x90/4,       /* Good Octets Transmitted Count */
  122         Torl            = 0xC0/4,       /* Total Octets Received */
  123         Totl            = 0xC8/4,       /* Total Octets Transmitted */
  124         Nstatistics     = 0x124/4,
  125 };
  126 
  127 enum {                                  /* Ctrl */
  128         GIOmd           = 1<<2,         /* BIO master disable */
  129         Lrst            = 1<<3,         /* link reset */
  130         Slu             = 1<<6,         /* Set Link Up */
  131         SspeedMASK      = 3<<8,         /* Speed Selection */
  132         SspeedSHIFT     = 8,
  133         Sspeed10        = 0x00000000,   /* 10Mb/s */
  134         Sspeed100       = 0x00000100,   /* 100Mb/s */
  135         Sspeed1000      = 0x00000200,   /* 1000Mb/s */
  136         Frcspd          = 1<<11,        /* Force Speed */
  137         Frcdplx         = 1<<12,        /* Force Duplex */
  138         SwdpinsloMASK   = 0x003C0000,   /* Software Defined Pins - lo nibble */
  139         SwdpinsloSHIFT  = 18,
  140         SwdpioloMASK    = 0x03C00000,   /* Software Defined Pins - I or O */
  141         SwdpioloSHIFT   = 22,
  142         Devrst          = 1<<26,        /* Device Reset */
  143         Rfce            = 1<<27,        /* Receive Flow Control Enable */
  144         Tfce            = 1<<28,        /* Transmit Flow Control Enable */
  145         Vme             = 1<<30,        /* VLAN Mode Enable */
  146         Phyrst          = 1<<31,        /* Phy Reset */
  147 };
  148 
  149 enum {                                  /* Status */
  150         Lu              = 1<<1,         /* Link Up */
  151         Lanid           = 3<<2,         /* mask for Lan ID. */
  152         Txoff           = 1<<4,         /* Transmission Paused */
  153         Tbimode         = 1<<5,         /* TBI Mode Indication */
  154         Phyra           = 1<<10,        /* PHY Reset Asserted */
  155         GIOme           = 1<<19,        /* GIO Master Enable Status */
  156 };
  157 
  158 enum {                                  /* Eerd */
  159         EEstart         = 1<<0,         /* Start Read */
  160         EEdone          = 1<<1,         /* Read done */
  161 };
  162 
  163 enum {                                  /* Ctrlext */
  164         Asdchk          = 1<<12,        /* ASD Check */
  165         Eerst           = 1<<13,        /* EEPROM Reset */
  166         Spdbyps         = 1<<15,        /* Speed Select Bypass */
  167 };
  168 
  169 enum {                                  /* EEPROM content offsets */
  170         Ea              = 0x00,         /* Ethernet Address */
  171         Cf              = 0x03,         /* Compatibility Field */
  172         Icw1            = 0x0A,         /* Initialization Control Word 1 */
  173         Sid             = 0x0B,         /* Subsystem ID */
  174         Svid            = 0x0C,         /* Subsystem Vendor ID */
  175         Did             = 0x0D,         /* Device ID */
  176         Vid             = 0x0E,         /* Vendor ID */
  177         Icw2            = 0x0F,         /* Initialization Control Word 2 */
  178 };
  179 
  180 enum {                                  /* Mdic */
  181         MDIdMASK        = 0x0000FFFF,   /* Data */
  182         MDIdSHIFT       = 0,
  183         MDIrMASK        = 0x001F0000,   /* PHY Register Address */
  184         MDIrSHIFT       = 16,
  185         MDIpMASK        = 0x03E00000,   /* PHY Address */
  186         MDIpSHIFT       = 21,
  187         MDIwop          = 0x04000000,   /* Write Operation */
  188         MDIrop          = 0x08000000,   /* Read Operation */
  189         MDIready        = 0x10000000,   /* End of Transaction */
  190         MDIie           = 0x20000000,   /* Interrupt Enable */
  191         MDIe            = 0x40000000,   /* Error */
  192 };
  193 
  194 enum {                                  /* phy interface registers */
  195         Phyctl          = 0,            /* phy ctl */
  196         Physsr          = 17,           /* phy secondary status */
  197         Phyier          = 18,           /* 82573 phy interrupt enable */
  198         Phyisr          = 19,           /* 82563 phy interrupt status */
  199         Phylhr          = 19,           /* 8257[12] link health */
  200 
  201         Rtlink          = 1<<10,        /* realtime link status */
  202         Phyan           = 1<<11,        /* phy has auto-negotiated */
  203 
  204         /* Phyctl bits */
  205         Ran             = 1<<9,         /* restart auto-negotiation */
  206         Ean             = 1<<12,        /* enable auto-negotiation */
  207 
  208         /* 82573 Phyier bits */
  209         Lscie           = 1<<10,        /* link status changed ie */
  210         Ancie           = 1<<11,        /* auto-negotiation complete ie */
  211         Spdie           = 1<<14,        /* speed changed ie */
  212         Panie           = 1<<15,        /* phy auto-negotiation error ie */
  213 
  214         /* Phylhr/Phyisr bits */
  215         Anf             = 1<<6,         /* lhr: auto-negotiation fault */
  216         Ane             = 1<<15,        /* isr: auto-negotiation error */
  217 };
  218 
  219 enum {                                  /* Icr, Ics, Ims, Imc */
  220         Txdw            = 0x00000001,   /* Transmit Descriptor Written Back */
  221         Txqe            = 0x00000002,   /* Transmit Queue Empty */
  222         Lsc             = 0x00000004,   /* Link Status Change */
  223         Rxseq           = 0x00000008,   /* Receive Sequence Error */
  224         Rxdmt0          = 0x00000010,   /* Rdesc Minimum Threshold Reached */
  225         Rxo             = 0x00000040,   /* Receiver Overrun */
  226         Rxt0            = 0x00000080,   /* Receiver Timer Interrupt */
  227         Mdac            = 0x00000200,   /* MDIO Access Completed */
  228         Rxcfg           = 0x00000400,   /* Receiving /C/ ordered sets */
  229         Gpi0            = 0x00000800,   /* General Purpose Interrupts */
  230         Gpi1            = 0x00001000,
  231         Gpi2            = 0x00002000,
  232         Gpi3            = 0x00004000,
  233         Ack             = 0x00020000,   /* Receive ACK frame */
  234 };
  235 
  236 enum {                                  /* Txcw */
  237         TxcwFd          = 0x00000020,   /* Full Duplex */
  238         TxcwHd          = 0x00000040,   /* Half Duplex */
  239         TxcwPauseMASK   = 0x00000180,   /* Pause */
  240         TxcwPauseSHIFT  = 7,
  241         TxcwPs          = 1<<TxcwPauseSHIFT,    /* Pause Supported */
  242         TxcwAs          = 2<<TxcwPauseSHIFT,    /* Asymmetric FC desired */
  243         TxcwRfiMASK     = 0x00003000,   /* Remote Fault Indication */
  244         TxcwRfiSHIFT    = 12,
  245         TxcwNpr         = 0x00008000,   /* Next Page Request */
  246         TxcwConfig      = 0x40000000,   /* Transmit Config Control */
  247         TxcwAne         = 0x80000000,   /* Auto-Negotiation Enable */
  248 };
  249 
  250 enum {                                  /* Rctl */
  251         Rrst            = 0x00000001,   /* Receiver Software Reset */
  252         Ren             = 0x00000002,   /* Receiver Enable */
  253         Sbp             = 0x00000004,   /* Store Bad Packets */
  254         Upe             = 0x00000008,   /* Unicast Promiscuous Enable */
  255         Mpe             = 0x00000010,   /* Multicast Promiscuous Enable */
  256         Lpe             = 0x00000020,   /* Long Packet Reception Enable */
  257         LbmMASK         = 0x000000C0,   /* Loopback Mode */
  258         LbmOFF          = 0x00000000,   /* No Loopback */
  259         LbmTBI          = 0x00000040,   /* TBI Loopback */
  260         LbmMII          = 0x00000080,   /* GMII/MII Loopback */
  261         LbmXCVR         = 0x000000C0,   /* Transceiver Loopback */
  262         RdtmsMASK       = 0x00000300,   /* Rdesc Minimum Threshold Size */
  263         RdtmsHALF       = 0x00000000,   /* Threshold is 1/2 Rdlen */
  264         RdtmsQUARTER    = 0x00000100,   /* Threshold is 1/4 Rdlen */
  265         RdtmsEIGHTH     = 0x00000200,   /* Threshold is 1/8 Rdlen */
  266         MoMASK          = 0x00003000,   /* Multicast Offset */
  267         Bam             = 0x00008000,   /* Broadcast Accept Mode */
  268         BsizeMASK       = 0x00030000,   /* Receive Buffer Size */
  269         Bsize16384      = 0x00010000,   /* Bsex = 1 */
  270         Bsize8192       = 0x00020000,   /* Bsex = 1 */
  271         Bsize2048       = 0x00000000,
  272         Bsize1024       = 0x00010000,
  273         Bsize512        = 0x00020000,
  274         Bsize256        = 0x00030000,
  275         BsizeFlex       = 0x08000000,   /* Flexible Bsize in 1KB increments */
  276         Vfe             = 0x00040000,   /* VLAN Filter Enable */
  277         Cfien           = 0x00080000,   /* Canonical Form Indicator Enable */
  278         Cfi             = 0x00100000,   /* Canonical Form Indicator value */
  279         Dpf             = 0x00400000,   /* Discard Pause Frames */
  280         Pmcf            = 0x00800000,   /* Pass MAC Control Frames */
  281         Bsex            = 0x02000000,   /* Buffer Size Extension */
  282         Secrc           = 0x04000000,   /* Strip CRC from incoming packet */
  283 };
  284 
  285 enum {                                  /* Tctl */
  286         Trst            = 0x00000001,   /* Transmitter Software Reset */
  287         Ten             = 0x00000002,   /* Transmit Enable */
  288         Psp             = 0x00000008,   /* Pad Short Packets */
  289         Mulr            = 0x10000000,   /* Allow multiple concurrent requests */
  290         CtMASK          = 0x00000FF0,   /* Collision Threshold */
  291         CtSHIFT         = 4,
  292         ColdMASK        = 0x003FF000,   /* Collision Distance */
  293         ColdSHIFT       = 12,
  294         Swxoff          = 0x00400000,   /* Sofware XOFF Transmission */
  295         Pbe             = 0x00800000,   /* Packet Burst Enable */
  296         Rtlc            = 0x01000000,   /* Re-transmit on Late Collision */
  297         Nrtu            = 0x02000000,   /* No Re-transmit on Underrrun */
  298 };
  299 
  300 enum {                                  /* [RT]xdctl */
  301         PthreshMASK     = 0x0000003F,   /* Prefetch Threshold */
  302         PthreshSHIFT    = 0,
  303         HthreshMASK     = 0x00003F00,   /* Host Threshold */
  304         HthreshSHIFT    = 8,
  305         WthreshMASK     = 0x003F0000,   /* Writeback Threshold */
  306         WthreshSHIFT    = 16,
  307         Gran            = 0x01000000,   /* Granularity */
  308         Qenable         = 0x02000000,   /* Queue Enable (82575) */
  309 };
  310 
  311 enum {                                  /* Rxcsum */
  312         PcssMASK        = 0x00FF,       /* Packet Checksum Start */
  313         PcssSHIFT       = 0,
  314         Ipofl           = 0x0100,       /* IP Checksum Off-load Enable */
  315         Tuofl           = 0x0200,       /* TCP/UDP Checksum Off-load Enable */
  316 };
  317 
  318 enum {                                  /* Receive Delay Timer Ring */
  319         DelayMASK       = 0xFFFF,       /* delay timer in 1.024nS increments */
  320         DelaySHIFT      = 0,
  321         Fpd             = 0x80000000,   /* Flush partial Descriptor Block */
  322 };
  323 
  324 typedef struct Rd {                     /* Receive Descriptor */
  325         u32int  addr[2];
  326         u16int  length;
  327         u16int  checksum;
  328         u8int   status;
  329         u8int   errors;
  330         u16int  special;
  331 } Rd;
  332 
  333 enum {                                  /* Rd status */
  334         Rdd             = 0x01,         /* Descriptor Done */
  335         Reop            = 0x02,         /* End of Packet */
  336         Ixsm            = 0x04,         /* Ignore Checksum Indication */
  337         Vp              = 0x08,         /* Packet is 802.1Q (matched VET) */
  338         Tcpcs           = 0x20,         /* TCP Checksum Calculated on Packet */
  339         Ipcs            = 0x40,         /* IP Checksum Calculated on Packet */
  340         Pif             = 0x80,         /* Passed in-exact filter */
  341 };
  342 
  343 enum {                                  /* Rd errors */
  344         Ce              = 0x01,         /* CRC Error or Alignment Error */
  345         Se              = 0x02,         /* Symbol Error */
  346         Seq             = 0x04,         /* Sequence Error */
  347         Cxe             = 0x10,         /* Carrier Extension Error */
  348         Tcpe            = 0x20,         /* TCP/UDP Checksum Error */
  349         Ipe             = 0x40,         /* IP Checksum Error */
  350         Rxe             = 0x80,         /* RX Data Error */
  351 };
  352 
  353 typedef struct {                        /* Transmit Descriptor */
  354         u32int  addr[2];                /* Data */
  355         u32int  control;
  356         u32int  status;
  357 } Td;
  358 
  359 enum {                                  /* Tdesc control */
  360         LenMASK         = 0x000FFFFF,   /* Data/Packet Length Field */
  361         LenSHIFT        = 0,
  362         DtypeCD         = 0x00000000,   /* Data Type 'Context Descriptor' */
  363         DtypeDD         = 0x00100000,   /* Data Type 'Data Descriptor' */
  364         PtypeTCP        = 0x01000000,   /* TCP/UDP Packet Type (CD) */
  365         Teop            = 0x01000000,   /* End of Packet (DD) */
  366         PtypeIP         = 0x02000000,   /* IP Packet Type (CD) */
  367         Ifcs            = 0x02000000,   /* Insert FCS (DD) */
  368         Tse             = 0x04000000,   /* TCP Segmentation Enable */
  369         Rs              = 0x08000000,   /* Report Status */
  370         Rps             = 0x10000000,   /* Report Status Sent */
  371         Dext            = 0x20000000,   /* Descriptor Extension */
  372         Vle             = 0x40000000,   /* VLAN Packet Enable */
  373         Ide             = 0x80000000,   /* Interrupt Delay Enable */
  374 };
  375 
  376 enum {                                  /* Tdesc status */
  377         Tdd             = 0x0001,       /* Descriptor Done */
  378         Ec              = 0x0002,       /* Excess Collisions */
  379         Lc              = 0x0004,       /* Late Collision */
  380         Tu              = 0x0008,       /* Transmit Underrun */
  381         CssMASK         = 0xFF00,       /* Checksum Start Field */
  382         CssSHIFT        = 8,
  383 };
  384 
  385 typedef struct {
  386         u16int  *reg;
  387         u32int  *reg32;
  388         int     sz;
  389 } Flash;
  390 
  391 enum {
  392         /* 16 and 32-bit flash registers for ich flash parts */
  393         Bfpr    = 0x00/4,               /* flash base 0:12; lim 16:28 */
  394         Fsts    = 0x04/2,               /* flash status;  Hsfsts */
  395         Fctl    = 0x06/2,               /* flash control; Hsfctl */
  396         Faddr   = 0x08/4,               /* flash address to r/w */
  397         Fdata   = 0x10/4,               /* data @ address */
  398 
  399         /* status register */
  400         Fdone   = 1<<0,                 /* flash cycle done */
  401         Fcerr   = 1<<1,                 /* cycle error; write 1 to clear */
  402         Ael     = 1<<2,                 /* direct access error log; 1 to clear */
  403         Scip    = 1<<5,                 /* spi cycle in progress */
  404         Fvalid  = 1<<14,                /* flash descriptor valid */
  405 
  406         /* control register */
  407         Fgo     = 1<<0,                 /* start cycle */
  408         Flcycle = 1<<1,                 /* two bits: r=0; w=2 */
  409         Fdbc    = 1<<8,                 /* bytes to read; 5 bits */
  410 };
  411 
  412 enum {
  413         Nrd             = 256,          /* power of two */
  414         Ntd             = 128,          /* power of two */
  415         Nrb             = 1024,         /* private receive buffers per Ctlr */
  416 };
  417 
  418 enum {
  419         Iany,
  420         i82563,
  421         i82566,
  422         i82571,
  423         i82572,
  424         i82573,
  425         i82575,
  426 };
  427 
  428 static int rbtab[] = {
  429         0,
  430         9014,
  431         1514,
  432         9234,
  433         9234,
  434         8192,                           /* terrible performance above 8k */
  435         1514,
  436 };
  437 
  438 static char *tname[] = {
  439         "any",
  440         "i82563",
  441         "i82566",
  442         "i82571",
  443         "i82572",
  444         "i82573",
  445         "i82575",
  446 };
  447 
  448 typedef struct Ctlr Ctlr;
  449 struct Ctlr {
  450         int     port;
  451         Pcidev  *pcidev;
  452         Ctlr    *next;
  453         Ether   *edev;
  454         int     active;
  455         int     type;
  456         ushort  eeprom[0x40];
  457 
  458         QLock   alock;                  /* attach */
  459         int     attached;
  460         int     nrd;
  461         int     ntd;
  462         int     nrb;                    /* how many this Ctlr has in the pool */
  463         unsigned rbsz;                  /* unsigned for % and / by 1024 */
  464 
  465         int     *nic;
  466         Lock    imlock;
  467         int     im;                     /* interrupt mask */
  468 
  469         Rendez  lrendez;
  470         int     lim;
  471 
  472         QLock   slock;
  473         uint    statistics[Nstatistics];
  474         uint    lsleep;
  475         uint    lintr;
  476         uint    rsleep;
  477         uint    rintr;
  478         uint    txdw;
  479         uint    tintr;
  480         uint    ixsm;
  481         uint    ipcs;
  482         uint    tcpcs;
  483         uint    speeds[4];
  484 
  485         uchar   ra[Eaddrlen];           /* receive address */
  486         ulong   mta[128];               /* multicast table array */
  487 
  488         Rendez  rrendez;
  489         int     rim;
  490         int     rdfree;
  491         Rd      *rdba;                  /* receive descriptor base address */
  492         Block   **rb;                   /* receive buffers */
  493         int     rdh;                    /* receive descriptor head */
  494         int     rdt;                    /* receive descriptor tail */
  495         int     rdtr;                   /* receive delay timer ring value */
  496         int     radv;                   /* receive interrupt absolute delay timer */
  497 
  498         Rendez  trendez;
  499         QLock   tlock;
  500         int     tbusy;
  501         Td      *tdba;                  /* transmit descriptor base address */
  502         Block   **tb;                   /* transmit buffers */
  503         int     tdh;                    /* transmit descriptor head */
  504         int     tdt;                    /* transmit descriptor tail */
  505 
  506         int     fcrtl;
  507         int     fcrth;
  508 
  509         uint    pba;                    /* packet buffer allocation */
  510 };
  511 
  512 #define csr32r(c, r)    (*((c)->nic+((r)/4)))
  513 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  514 
  515 static Ctlr* i82563ctlrhead;
  516 static Ctlr* i82563ctlrtail;
  517 
  518 static Lock i82563rblock;               /* free receive Blocks */
  519 static Block* i82563rbpool;
  520 
  521 static char* statistics[] = {
  522         "CRC Error",
  523         "Alignment Error",
  524         "Symbol Error",
  525         "RX Error",
  526         "Missed Packets",
  527         "Single Collision",
  528         "Excessive Collisions",
  529         "Multiple Collision",
  530         "Late Collisions",
  531         nil,
  532         "Collision",
  533         "Transmit Underrun",
  534         "Defer",
  535         "Transmit - No CRS",
  536         "Sequence Error",
  537         "Carrier Extension Error",
  538         "Receive Error Length",
  539         nil,
  540         "XON Received",
  541         "XON Transmitted",
  542         "XOFF Received",
  543         "XOFF Transmitted",
  544         "FC Received Unsupported",
  545         "Packets Received (64 Bytes)",
  546         "Packets Received (65-127 Bytes)",
  547         "Packets Received (128-255 Bytes)",
  548         "Packets Received (256-511 Bytes)",
  549         "Packets Received (512-1023 Bytes)",
  550         "Packets Received (1024-mtu Bytes)",
  551         "Good Packets Received",
  552         "Broadcast Packets Received",
  553         "Multicast Packets Received",
  554         "Good Packets Transmitted",
  555         nil,
  556         "Good Octets Received",
  557         nil,
  558         "Good Octets Transmitted",
  559         nil,
  560         nil,
  561         nil,
  562         "Receive No Buffers",
  563         "Receive Undersize",
  564         "Receive Fragment",
  565         "Receive Oversize",
  566         "Receive Jabber",
  567         "Management Packets Rx",
  568         "Management Packets Drop",
  569         "Management Packets Tx",
  570         "Total Octets Received",
  571         nil,
  572         "Total Octets Transmitted",
  573         nil,
  574         "Total Packets Received",
  575         "Total Packets Transmitted",
  576         "Packets Transmitted (64 Bytes)",
  577         "Packets Transmitted (65-127 Bytes)",
  578         "Packets Transmitted (128-255 Bytes)",
  579         "Packets Transmitted (256-511 Bytes)",
  580         "Packets Transmitted (512-1023 Bytes)",
  581         "Packets Transmitted (1024-mtu Bytes)",
  582         "Multicast Packets Transmitted",
  583         "Broadcast Packets Transmitted",
  584         "TCP Segmentation Context Transmitted",
  585         "TCP Segmentation Context Fail",
  586         "Interrupt Assertion",
  587         "Interrupt Rx Pkt Timer",
  588         "Interrupt Rx Abs Timer",
  589         "Interrupt Tx Pkt Timer",
  590         "Interrupt Tx Abs Timer",
  591         "Interrupt Tx Queue Empty",
  592         "Interrupt Tx Desc Low",
  593         "Interrupt Rx Min",
  594         "Interrupt Rx Overrun",
  595 };
  596 
  597 static long
  598 i82563ifstat(Ether* edev, void* a, long n, ulong offset)
  599 {
  600         Ctlr *ctlr;
  601         char *s, *p, *e, *stat;
  602         int i, r;
  603         uvlong tuvl, ruvl;
  604 
  605         ctlr = edev->ctlr;
  606         qlock(&ctlr->slock);
  607         p = s = malloc(READSTR);
  608         e = p + READSTR;
  609 
  610         for(i = 0; i < Nstatistics; i++){
  611                 r = csr32r(ctlr, Statistics + i*4);
  612                 if((stat = statistics[i]) == nil)
  613                         continue;
  614                 switch(i){
  615                 case Gorcl:
  616                 case Gotcl:
  617                 case Torl:
  618                 case Totl:
  619                         ruvl = r;
  620                         ruvl += (uvlong)csr32r(ctlr, Statistics+(i+1)*4) << 32;
  621                         tuvl = ruvl;
  622                         tuvl += ctlr->statistics[i];
  623                         tuvl += (uvlong)ctlr->statistics[i+1] << 32;
  624                         if(tuvl == 0)
  625                                 continue;
  626                         ctlr->statistics[i] = tuvl;
  627                         ctlr->statistics[i+1] = tuvl >> 32;
  628                         p = seprint(p, e, "%s: %llud %llud\n", stat, tuvl, ruvl);
  629                         i++;
  630                         break;
  631 
  632                 default:
  633                         ctlr->statistics[i] += r;
  634                         if(ctlr->statistics[i] == 0)
  635                                 continue;
  636                         p = seprint(p, e, "%s: %ud %ud\n", stat,
  637                                 ctlr->statistics[i], r);
  638                         break;
  639                 }
  640         }
  641 
  642         p = seprint(p, e, "lintr: %ud %ud\n", ctlr->lintr, ctlr->lsleep);
  643         p = seprint(p, e, "rintr: %ud %ud\n", ctlr->rintr, ctlr->rsleep);
  644         p = seprint(p, e, "tintr: %ud %ud\n", ctlr->tintr, ctlr->txdw);
  645         p = seprint(p, e, "ixcs: %ud %ud %ud\n", ctlr->ixsm, ctlr->ipcs, ctlr->tcpcs);
  646         p = seprint(p, e, "rdtr: %ud\n", ctlr->rdtr);
  647         p = seprint(p, e, "radv: %ud\n", ctlr->radv);
  648         p = seprint(p, e, "ctrl: %.8ux\n", csr32r(ctlr, Ctrl));
  649         p = seprint(p, e, "ctrlext: %.8ux\n", csr32r(ctlr, Ctrlext));
  650         p = seprint(p, e, "status: %.8ux\n", csr32r(ctlr, Status));
  651         p = seprint(p, e, "txcw: %.8ux\n", csr32r(ctlr, Txcw));
  652         p = seprint(p, e, "txdctl: %.8ux\n", csr32r(ctlr, Txdctl));
  653         p = seprint(p, e, "pba: %.8ux\n", ctlr->pba);
  654 
  655         p = seprint(p, e, "speeds: 10:%ud 100:%ud 1000:%ud ?:%ud\n",
  656                 ctlr->speeds[0], ctlr->speeds[1], ctlr->speeds[2], ctlr->speeds[3]);
  657         p = seprint(p, e, "type: %s\n", tname[ctlr->type]);
  658 
  659 //      p = seprint(p, e, "eeprom:");
  660 //      for(i = 0; i < 0x40; i++){
  661 //              if(i && ((i & 7) == 0))
  662 //                      p = seprint(p, e, "\n       ");
  663 //              p = seprint(p, e, " %4.4ux", ctlr->eeprom[i]);
  664 //      }
  665 //      p = seprint(p, e, "\n");
  666 
  667         USED(p);
  668         n = readstr(offset, a, n, s);
  669         free(s);
  670         qunlock(&ctlr->slock);
  671 
  672         return n;
  673 }
  674 
  675 enum {
  676         CMrdtr,
  677         CMradv,
  678 };
  679 
  680 static Cmdtab i82563ctlmsg[] = {
  681         CMrdtr, "rdtr", 2,
  682         CMradv, "radv", 2,
  683 };
  684 
  685 static long
  686 i82563ctl(Ether* edev, void* buf, long n)
  687 {
  688         ulong v;
  689         char *p;
  690         Ctlr *ctlr;
  691         Cmdbuf *cb;
  692         Cmdtab *ct;
  693 
  694         if((ctlr = edev->ctlr) == nil)
  695                 error(Enonexist);
  696 
  697         cb = parsecmd(buf, n);
  698         if(waserror()){
  699                 free(cb);
  700                 nexterror();
  701         }
  702 
  703         ct = lookupcmd(cb, i82563ctlmsg, nelem(i82563ctlmsg));
  704         switch(ct->index){
  705         case CMrdtr:
  706                 v = strtoul(cb->f[1], &p, 0);
  707                 if(p == cb->f[1] || v > 0xFFFF)
  708                         error(Ebadarg);
  709                 ctlr->rdtr = v;
  710                 csr32w(ctlr, Rdtr, v);
  711                 break;
  712         case CMradv:
  713                 v = strtoul(cb->f[1], &p, 0);
  714                 if(p == cb->f[1] || v > 0xFFFF)
  715                         error(Ebadarg);
  716                 ctlr->radv = v;
  717                 csr32w(ctlr, Radv, v);
  718         }
  719         free(cb);
  720         poperror();
  721 
  722         return n;
  723 }
  724 
  725 static void
  726 i82563promiscuous(void* arg, int on)
  727 {
  728         int rctl;
  729         Ctlr *ctlr;
  730         Ether *edev;
  731 
  732         edev = arg;
  733         ctlr = edev->ctlr;
  734 
  735         rctl = csr32r(ctlr, Rctl);
  736         rctl &= ~MoMASK;
  737         if(on)
  738                 rctl |= Upe|Mpe;
  739         else
  740                 rctl &= ~(Upe|Mpe);
  741         csr32w(ctlr, Rctl, rctl);
  742 }
  743 
  744 static void
  745 i82563multicast(void* arg, uchar* addr, int on)
  746 {
  747         int bit, x;
  748         Ctlr *ctlr;
  749         Ether *edev;
  750 
  751         edev = arg;
  752         ctlr = edev->ctlr;
  753 
  754         x = addr[5]>>1;
  755         if(ctlr->type == i82566)
  756                 x &= 31;
  757         bit = ((addr[5] & 1)<<4)|(addr[4]>>4);
  758         /*
  759          * multiple ether addresses can hash to the same filter bit,
  760          * so it's never safe to clear a filter bit.
  761          * if we want to clear filter bits, we need to keep track of
  762          * all the multicast addresses in use, clear all the filter bits,
  763          * then set the ones corresponding to in-use addresses.
  764          */
  765         if(on)
  766                 ctlr->mta[x] |= 1<<bit;
  767 //      else
  768 //              ctlr->mta[x] &= ~(1<<bit);
  769 
  770         csr32w(ctlr, Mta+x*4, ctlr->mta[x]);
  771 }
  772 
  773 static Block*
  774 i82563rballoc(void)
  775 {
  776         Block *bp;
  777 
  778         ilock(&i82563rblock);
  779         if((bp = i82563rbpool) != nil){
  780                 i82563rbpool = bp->next;
  781                 bp->next = nil;
  782                 _xinc(&bp->ref);        /* prevent bp from being freed */
  783         }
  784         iunlock(&i82563rblock);
  785 
  786         return bp;
  787 }
  788 
  789 static void
  790 i82563rbfree(Block* b)
  791 {
  792         b->rp = b->wp = (uchar*)PGROUND((uintptr)b->base);
  793         ilock(&i82563rblock);
  794         b->next = i82563rbpool;
  795         i82563rbpool = b;
  796         iunlock(&i82563rblock);
  797 }
  798 
  799 static void
  800 i82563im(Ctlr* ctlr, int im)
  801 {
  802         ilock(&ctlr->imlock);
  803         ctlr->im |= im;
  804         csr32w(ctlr, Ims, ctlr->im);
  805         iunlock(&ctlr->imlock);
  806 }
  807 
  808 static void
  809 i82563txinit(Ctlr* ctlr)
  810 {
  811         int i, r;
  812         Block *bp;
  813 
  814         csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 66<<ColdSHIFT | Mulr);
  815         csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8);          /* yb sez: 0x702008 */
  816         csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
  817         csr32w(ctlr, Tdbah, 0);
  818         csr32w(ctlr, Tdlen, ctlr->ntd * sizeof(Td));
  819         ctlr->tdh = PREV(0, ctlr->ntd);
  820         csr32w(ctlr, Tdh, 0);
  821         ctlr->tdt = 0;
  822         csr32w(ctlr, Tdt, 0);
  823         for(i = 0; i < ctlr->ntd; i++){
  824                 if((bp = ctlr->tb[i]) != nil){
  825                         ctlr->tb[i] = nil;
  826                         freeb(bp);
  827                 }
  828                 memset(&ctlr->tdba[i], 0, sizeof(Td));
  829         }
  830         csr32w(ctlr, Tidv, 128);
  831         r = csr32r(ctlr, Txdctl);
  832         r &= ~(WthreshMASK|PthreshSHIFT);
  833         r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
  834         if(ctlr->type == i82575)
  835                 r |= Qenable;
  836         csr32w(ctlr, Tadv, 64);
  837         csr32w(ctlr, Txdctl, r);
  838         r = csr32r(ctlr, Tctl);
  839         r |= Ten;
  840         csr32w(ctlr, Tctl, r);
  841 //      if(ctlr->type == i82671)
  842 //              csr32w(ctlr, Tarc0, csr32r(ctlr, Tarc0) | 7<<24); /* yb sez? */
  843 }
  844 
  845 #define Next(x, m)      (((x)+1) & (m))
  846 
  847 static int
  848 i82563cleanup(Ctlr *c)
  849 {
  850         Block *b;
  851         int tdh, m, n;
  852 
  853         tdh = c->tdh;
  854         m = c->ntd-1;
  855         while(c->tdba[n = Next(tdh, m)].status & Tdd){
  856                 tdh = n;
  857                 if((b = c->tb[tdh]) != nil){
  858                         c->tb[tdh] = nil;
  859                         freeb(b);
  860                 }else
  861                         iprint("82563 tx underrun!\n");
  862                 c->tdba[tdh].status = 0;
  863         }
  864 
  865         return c->tdh = tdh;
  866 }
  867 
  868 static void
  869 i82563transmit(Ether* edev)
  870 {
  871         Td *td;
  872         Block *bp;
  873         Ctlr *ctlr;
  874         int tdh, tdt, m;
  875 
  876         ctlr = edev->ctlr;
  877 
  878         qlock(&ctlr->tlock);
  879 
  880         /*
  881          * Free any completed packets
  882          */
  883         tdh = i82563cleanup(ctlr);
  884 
  885         /*
  886          * Try to fill the ring back up.
  887          */
  888         tdt = ctlr->tdt;
  889         m = ctlr->ntd-1;
  890         for(;;){
  891                 if(Next(tdt, m) == tdh){
  892                         ctlr->txdw++;
  893                         i82563im(ctlr, Txdw);
  894                         break;
  895                 }
  896                 if((bp = qget(edev->oq)) == nil)
  897                         break;
  898                 td = &ctlr->tdba[tdt];
  899                 td->addr[0] = PCIWADDR(bp->rp);
  900                 td->control = Ide|Rs|Ifcs|Teop|BLEN(bp);
  901                 ctlr->tb[tdt] = bp;
  902                 tdt = Next(tdt, m);
  903         }
  904         if(ctlr->tdt != tdt){
  905                 ctlr->tdt = tdt;
  906                 csr32w(ctlr, Tdt, tdt);
  907         }
  908         qunlock(&ctlr->tlock);
  909 }
  910 
  911 static void
  912 i82563replenish(Ctlr* ctlr)
  913 {
  914         Rd *rd;
  915         int rdt, m;
  916         Block *bp;
  917 
  918         rdt = ctlr->rdt;
  919         m = ctlr->nrd-1;
  920         while(Next(rdt, m) != ctlr->rdh){
  921                 rd = &ctlr->rdba[rdt];
  922                 if(ctlr->rb[rdt] != nil){
  923                         iprint("82563: tx overrun\n");
  924                         break;
  925                 }
  926                 bp = i82563rballoc();
  927                 if(bp == nil){
  928                         vlong now;
  929                         static vlong lasttime;
  930 
  931                         /* don't flood the console */
  932                         now = tk2ms(MACHP(0)->ticks);
  933                         if (now - lasttime > 2000)
  934                                 iprint("#l%d: 82563: all %d rx buffers in use\n",
  935                                         ctlr->edev->ctlrno, ctlr->nrb);
  936                         lasttime = now;
  937                         break;
  938                 }
  939                 ctlr->rb[rdt] = bp;
  940                 rd->addr[0] = PCIWADDR(bp->rp);
  941 //              rd->addr[1] = 0;
  942                 rd->status = 0;
  943                 ctlr->rdfree++;
  944                 rdt = Next(rdt, m);
  945         }
  946         ctlr->rdt = rdt;
  947         csr32w(ctlr, Rdt, rdt);
  948 }
  949 
  950 static void
  951 i82563rxinit(Ctlr* ctlr)
  952 {
  953         Block *bp;
  954         int i, r, rctl;
  955 
  956         if(ctlr->rbsz <= 2048)
  957                 rctl = Dpf|Bsize2048|Bam|RdtmsHALF;
  958         else if(ctlr->rbsz <= 8192)
  959                 rctl = Lpe|Dpf|Bsize8192|Bsex|Bam|RdtmsHALF|Secrc;
  960         else if(ctlr->rbsz <= 12*1024){
  961                 i = ctlr->rbsz / 1024;
  962                 if(ctlr->rbsz % 1024)
  963                         i++;
  964                 rctl = Lpe|Dpf|BsizeFlex*i|Bam|RdtmsHALF|Secrc;
  965         }
  966         else
  967                 rctl = Lpe|Dpf|Bsize16384|Bsex|Bam|RdtmsHALF|Secrc;
  968 
  969         if(ctlr->type == i82575){
  970                 /*
  971                  * Setting Qenable in Rxdctl does not
  972                  * appear to stick unless Ren is on.
  973                  */
  974                 csr32w(ctlr, Rctl, Ren|rctl);
  975                 r = csr32r(ctlr, Rxdctl);
  976                 r |= Qenable;
  977                 csr32w(ctlr, Rxdctl, r);
  978         }
  979         csr32w(ctlr, Rctl, rctl);
  980 
  981         if(ctlr->type == i82573)
  982                 csr32w(ctlr, Ert, 1024/8);
  983 
  984         if(ctlr->type == i82566)
  985                 csr32w(ctlr, Pbs, 16);
  986 
  987         csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
  988         csr32w(ctlr, Rdbah, 0);
  989         csr32w(ctlr, Rdlen, ctlr->nrd * sizeof(Rd));
  990         ctlr->rdh = 0;
  991         csr32w(ctlr, Rdh, 0);
  992         ctlr->rdt = 0;
  993         csr32w(ctlr, Rdt, 0);
  994         /* to hell with interrupt moderation, we've got fast cpus */
  995 //      ctlr->rdtr = 25;                /* µs units? */
  996 //      ctlr->radv = 500;               /* µs units? */
  997         ctlr->radv = ctlr->rdtr = 0;
  998         csr32w(ctlr, Rdtr, ctlr->rdtr);
  999         csr32w(ctlr, Radv, ctlr->radv);
 1000 
 1001         for(i = 0; i < ctlr->nrd; i++){
 1002                 if((bp = ctlr->rb[i]) != nil){
 1003                         ctlr->rb[i] = nil;
 1004                         freeb(bp);
 1005                 }
 1006         }
 1007         i82563replenish(ctlr);
 1008 
 1009         if(ctlr->type != i82575){
 1010                 /*
 1011                  * See comment above for Qenable.
 1012                  * Could shuffle the code?
 1013                  */
 1014                 r = csr32r(ctlr, Rxdctl);
 1015                 r &= ~(WthreshSHIFT|PthreshSHIFT);
 1016                 r |= (2<<WthreshSHIFT)|(2<<PthreshSHIFT);
 1017                 csr32w(ctlr, Rxdctl, r);
 1018         }
 1019 
 1020         /*
 1021          * Don't enable checksum offload.  In practice, it interferes with
 1022          * tftp booting on at least the 82575.
 1023          */
 1024 //      csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE<<PcssSHIFT);
 1025         csr32w(ctlr, Rxcsum, 0);
 1026 }
 1027 
 1028 static int
 1029 i82563rim(void* ctlr)
 1030 {
 1031         return ((Ctlr*)ctlr)->rim != 0;
 1032 }
 1033 
 1034 static void
 1035 i82563rproc(void* arg)
 1036 {
 1037         Rd *rd;
 1038         Block *bp;
 1039         Ctlr *ctlr;
 1040         int r, m, rdh, rim;
 1041         Ether *edev;
 1042 
 1043         edev = arg;
 1044         ctlr = edev->ctlr;
 1045 
 1046         i82563rxinit(ctlr);
 1047         r = csr32r(ctlr, Rctl);
 1048         r |= Ren;
 1049         csr32w(ctlr, Rctl, r);
 1050         m = ctlr->nrd-1;
 1051 
 1052         for(;;){
 1053                 i82563im(ctlr, Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
 1054                 ctlr->rsleep++;
 1055 //              coherence();
 1056                 sleep(&ctlr->rrendez, i82563rim, ctlr);
 1057 
 1058                 rdh = ctlr->rdh;
 1059                 for(;;){
 1060                         rd = &ctlr->rdba[rdh];
 1061                         rim = ctlr->rim;
 1062                         ctlr->rim = 0;
 1063                         if(!(rd->status & Rdd))
 1064                                 break;
 1065 
 1066                         /*
 1067                          * Accept eop packets with no errors.
 1068                          * With no errors and the Ixsm bit set,
 1069                          * the descriptor status Tpcs and Ipcs bits give
 1070                          * an indication of whether the checksums were
 1071                          * calculated and valid.
 1072                          */
 1073                         bp = ctlr->rb[rdh];
 1074                         if((rd->status & Reop) && rd->errors == 0){
 1075                                 bp->wp += rd->length;
 1076                                 bp->lim = bp->wp;       /* lie like a dog. */
 1077                                 if(!(rd->status & Ixsm)){
 1078                                         ctlr->ixsm++;
 1079                                         if(rd->status & Ipcs){
 1080                                                 /*
 1081                                                  * IP checksum calculated
 1082                                                  * (and valid as errors == 0).
 1083                                                  */
 1084                                                 ctlr->ipcs++;
 1085                                                 bp->flag |= Bipck;
 1086                                         }
 1087                                         if(rd->status & Tcpcs){
 1088                                                 /*
 1089                                                  * TCP/UDP checksum calculated
 1090                                                  * (and valid as errors == 0).
 1091                                                  */
 1092                                                 ctlr->tcpcs++;
 1093                                                 bp->flag |= Btcpck|Budpck;
 1094                                         }
 1095                                         bp->checksum = rd->checksum;
 1096                                         bp->flag |= Bpktck;
 1097                                 }
 1098                                 etheriq(edev, bp, 1);
 1099                         } else if (rd->status & Reop && rd->errors)
 1100                                 print("%s: input packet error %#ux\n",
 1101                                         tname[ctlr->type], rd->errors);
 1102                         else
 1103                                 freeb(bp);
 1104                         ctlr->rb[rdh] = nil;
 1105 
 1106                         rd->status = 0;
 1107                         ctlr->rdfree--;
 1108                         ctlr->rdh = rdh = Next(rdh, m);
 1109                         if(ctlr->nrd-ctlr->rdfree >= 32 || (rim & Rxdmt0))
 1110                                 i82563replenish(ctlr);
 1111                 }
 1112         }
 1113 }
 1114 
 1115 static int
 1116 i82563lim(void* c)
 1117 {
 1118         return ((Ctlr*)c)->lim != 0;
 1119 }
 1120 
 1121 static int speedtab[] = {
 1122         10, 100, 1000, 0
 1123 };
 1124 
 1125 static uint
 1126 phyread(Ctlr *c, int reg)
 1127 {
 1128         uint phy, i;
 1129 
 1130         csr32w(c, Mdic, MDIrop | 1<<MDIpSHIFT | reg<<MDIrSHIFT);
 1131         phy = 0;
 1132         for(i = 0; i < 64; i++){
 1133                 phy = csr32r(c, Mdic);
 1134                 if(phy & (MDIe|MDIready))
 1135                         break;
 1136                 microdelay(1);
 1137         }
 1138         if((phy & (MDIe|MDIready)) != MDIready)
 1139                 return ~0;
 1140         return phy & 0xffff;
 1141 }
 1142 
 1143 static uint
 1144 phywrite(Ctlr *c, int reg, ushort val)
 1145 {
 1146         uint phy, i;
 1147 
 1148         csr32w(c, Mdic, MDIwop | 1<<MDIpSHIFT | reg<<MDIrSHIFT | val);
 1149         phy = 0;
 1150         for(i = 0; i < 64; i++){
 1151                 phy = csr32r(c, Mdic);
 1152                 if(phy & (MDIe|MDIready))
 1153                         break;
 1154                 microdelay(1);
 1155         }
 1156         if((phy & (MDIe|MDIready)) != MDIready)
 1157                 return ~0;
 1158         return 0;
 1159 }
 1160 
 1161 /*
 1162  * watch for changes of link state
 1163  */
 1164 static void
 1165 i82563lproc(void *v)
 1166 {
 1167         uint phy, i, a;
 1168         Ctlr *c;
 1169         Ether *e;
 1170 
 1171         e = v;
 1172         c = e->ctlr;
 1173 
 1174         if(c->type == i82573 && (phy = phyread(c, Phyier)) != ~0)
 1175                 phywrite(c, Phyier, phy | Lscie | Ancie | Spdie | Panie);
 1176         for(;;){
 1177                 phy = phyread(c, Physsr);
 1178                 if(phy == ~0)
 1179                         goto next;
 1180                 i = (phy>>14) & 3;
 1181 
 1182                 switch(c->type){
 1183                 case i82563:
 1184                         a = phyread(c, Phyisr) & Ane;
 1185                         break;
 1186                 case i82571:
 1187                 case i82572:
 1188                         a = phyread(c, Phylhr) & Anf;
 1189                         i = (i-1) & 3;
 1190                         break;
 1191                 default:
 1192                         a = 0;
 1193                         break;
 1194                 }
 1195                 if(a)
 1196                         phywrite(c, Phyctl, phyread(c, Phyctl) | Ran | Ean);
 1197                 e->link = (phy & Rtlink) != 0;
 1198                 if(e->link){
 1199                         c->speeds[i]++;
 1200                         if (speedtab[i])
 1201                                 e->mbps = speedtab[i];
 1202                 }
 1203 next:
 1204                 c->lim = 0;
 1205                 i82563im(c, Lsc);
 1206                 c->lsleep++;
 1207                 sleep(&c->lrendez, i82563lim, c);
 1208         }
 1209 }
 1210 
 1211 static void
 1212 i82563tproc(void *v)
 1213 {
 1214         Ether *e;
 1215         Ctlr *c;
 1216 
 1217         e = v;
 1218         c = e->ctlr;
 1219         for(;;){
 1220                 sleep(&c->trendez, return0, 0);
 1221                 i82563transmit(e);
 1222         }
 1223 }
 1224 
 1225 static void
 1226 i82563attach(Ether* edev)
 1227 {
 1228         Block *bp;
 1229         Ctlr *ctlr;
 1230         char name[KNAMELEN];
 1231 
 1232         ctlr = edev->ctlr;
 1233         ctlr->edev = edev;                      /* point back to Ether* */
 1234         qlock(&ctlr->alock);
 1235         if(ctlr->attached){
 1236                 qunlock(&ctlr->alock);
 1237                 return;
 1238         }
 1239 
 1240         ctlr->nrd = Nrd;
 1241         ctlr->ntd = Ntd;
 1242 
 1243         if(waserror()){
 1244                 while(ctlr->nrb > 0){
 1245                         bp = i82563rballoc();
 1246                         bp->free = nil;
 1247                         freeb(bp);
 1248                         ctlr->nrb--;
 1249                 }
 1250                 free(ctlr->tb);
 1251                 ctlr->tb = nil;
 1252                 free(ctlr->rb);
 1253                 ctlr->rb = nil;
 1254                 free(ctlr->tdba);
 1255                 ctlr->tdba = nil;
 1256                 free(ctlr->rdba);
 1257                 ctlr->rdba = nil;
 1258                 qunlock(&ctlr->alock);
 1259                 nexterror();
 1260         }
 1261 
 1262         if((ctlr->rdba = mallocalign(ctlr->nrd*sizeof(Rd), 128, 0, 0)) == nil)
 1263                 error(Enomem);
 1264         if((ctlr->tdba = mallocalign(ctlr->ntd*sizeof(Td), 128, 0, 0)) == nil)
 1265                 error(Enomem);
 1266         if((ctlr->rb = malloc(ctlr->nrd*sizeof(Block*))) == nil)
 1267                 error(Enomem);
 1268         if((ctlr->tb = malloc(ctlr->ntd*sizeof(Block*))) == nil)
 1269                 error(Enomem);
 1270 
 1271         for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
 1272                 if((bp = allocb(ctlr->rbsz + BY2PG)) == nil)
 1273                         break;
 1274                 bp->free = i82563rbfree;
 1275                 freeb(bp);
 1276         }
 1277 
 1278         ctlr->attached = 1;
 1279 
 1280         snprint(name, sizeof name, "#l%dl", edev->ctlrno);
 1281         kproc(name, i82563lproc, edev);
 1282 
 1283         snprint(name, sizeof name, "#l%dr", edev->ctlrno);
 1284         kproc(name, i82563rproc, edev);
 1285 
 1286         snprint(name, sizeof name, "#l%dt", edev->ctlrno);
 1287         kproc(name, i82563tproc, edev);
 1288 
 1289         i82563txinit(ctlr);
 1290 
 1291         qunlock(&ctlr->alock);
 1292         poperror();
 1293 }
 1294 
 1295 static void
 1296 i82563interrupt(Ureg*, void* arg)
 1297 {
 1298         Ctlr *ctlr;
 1299         Ether *edev;
 1300         int icr, im;
 1301 
 1302         edev = arg;
 1303         ctlr = edev->ctlr;
 1304 
 1305         ilock(&ctlr->imlock);
 1306         csr32w(ctlr, Imc, ~0);
 1307         im = ctlr->im;
 1308 
 1309         for(icr = csr32r(ctlr, Icr); icr & ctlr->im; icr = csr32r(ctlr, Icr)){
 1310                 if(icr & Lsc){
 1311                         im &= ~Lsc;
 1312                         ctlr->lim = icr & Lsc;
 1313                         wakeup(&ctlr->lrendez);
 1314                         ctlr->lintr++;
 1315                 }
 1316                 if(icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack)){
 1317                         ctlr->rim = icr & (Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
 1318                         im &= ~(Rxt0|Rxo|Rxdmt0|Rxseq|Ack);
 1319                         wakeup(&ctlr->rrendez);
 1320                         ctlr->rintr++;
 1321                 }
 1322                 if(icr & Txdw){
 1323                         im &= ~Txdw;
 1324                         ctlr->tintr++;
 1325                         wakeup(&ctlr->trendez);
 1326                 }
 1327         }
 1328 
 1329         ctlr->im = im;
 1330         csr32w(ctlr, Ims, im);
 1331         iunlock(&ctlr->imlock);
 1332 }
 1333 
 1334 /* assume misrouted interrupts and check all controllers */
 1335 static void
 1336 i82575interrupt(Ureg*, void *)
 1337 {
 1338         Ctlr *ctlr;
 1339 
 1340         for (ctlr = i82563ctlrhead; ctlr != nil; ctlr = ctlr->next)
 1341                 i82563interrupt(nil, ctlr->edev);
 1342 }
 1343 
 1344 static int
 1345 i82563detach(Ctlr* ctlr)
 1346 {
 1347         int r, timeo;
 1348 
 1349         /*
 1350          * Perform a device reset to get the chip back to the
 1351          * power-on state, followed by an EEPROM reset to read
 1352          * the defaults for some internal registers.
 1353          */
 1354         csr32w(ctlr, Imc, ~0);
 1355         csr32w(ctlr, Rctl, 0);
 1356         csr32w(ctlr, Tctl, 0);
 1357 
 1358         delay(10);
 1359 
 1360         r = csr32r(ctlr, Ctrl);
 1361         if(ctlr->type == i82566)
 1362                 r |= Phyrst;
 1363         csr32w(ctlr, Ctrl, Devrst | r);
 1364         delay(1);
 1365         for(timeo = 0; timeo < 1000; timeo++){
 1366                 if(!(csr32r(ctlr, Ctrl) & Devrst))
 1367                         break;
 1368                 delay(1);
 1369         }
 1370         if(csr32r(ctlr, Ctrl) & Devrst)
 1371                 return -1;
 1372 
 1373         r = csr32r(ctlr, Ctrlext);
 1374         csr32w(ctlr, Ctrlext, r|Eerst);
 1375         delay(1);
 1376         for(timeo = 0; timeo < 1000; timeo++){
 1377                 if(!(csr32r(ctlr, Ctrlext) & Eerst))
 1378                         break;
 1379                 delay(1);
 1380         }
 1381         if(csr32r(ctlr, Ctrlext) & Eerst)
 1382                 return -1;
 1383 
 1384         csr32w(ctlr, Imc, ~0);
 1385         delay(1);
 1386         for(timeo = 0; timeo < 1000; timeo++){
 1387                 if(!csr32r(ctlr, Icr))
 1388                         break;
 1389                 delay(1);
 1390         }
 1391         if(csr32r(ctlr, Icr))
 1392                 return -1;
 1393 
 1394         /*
 1395          * Balance Rx/Tx packet buffer.
 1396          * No need to set PBA register unless using jumbo, defaults to 32KB
 1397          * for receive. If it is changed, then have to do a MAC reset,
 1398          * and need to do that at the the right time as it will wipe stuff.
 1399          */
 1400         if(ctlr->rbsz > 8192 && (ctlr->type == i82563 || ctlr->type == i82571 ||
 1401             ctlr->type == i82572)){
 1402                 ctlr->pba = csr32r(ctlr, Pba);
 1403                 r = ctlr->pba >> 16;
 1404                 r += ctlr->pba & 0xffff;
 1405                 r >>= 1;
 1406                 csr32w(ctlr, Pba, r);
 1407         } else if(ctlr->type == i82573 && ctlr->rbsz > 1514)
 1408                 csr32w(ctlr, Pba, 14);
 1409         ctlr->pba = csr32r(ctlr, Pba);
 1410 
 1411         r = csr32r(ctlr, Ctrl);
 1412         csr32w(ctlr, Ctrl, Slu|r);
 1413 
 1414         return 0;
 1415 }
 1416 
 1417 static void
 1418 i82563shutdown(Ether* ether)
 1419 {
 1420         i82563detach(ether->ctlr);
 1421 }
 1422 
 1423 static ushort
 1424 eeread(Ctlr *ctlr, int adr)
 1425 {
 1426         csr32w(ctlr, Eerd, EEstart | adr << 2);
 1427         while ((csr32r(ctlr, Eerd) & EEdone) == 0)
 1428                 ;
 1429         return csr32r(ctlr, Eerd) >> 16;
 1430 }
 1431 
 1432 static int
 1433 eeload(Ctlr *ctlr)
 1434 {
 1435         ushort sum;
 1436         int data, adr;
 1437 
 1438         sum = 0;
 1439         for (adr = 0; adr < 0x40; adr++) {
 1440                 data = eeread(ctlr, adr);
 1441                 ctlr->eeprom[adr] = data;
 1442                 sum += data;
 1443         }
 1444         return sum;
 1445 }
 1446 
 1447 static int
 1448 fcycle(Ctlr *, Flash *f)
 1449 {
 1450         ushort s, i;
 1451 
 1452         s = f->reg[Fsts];
 1453         if((s&Fvalid) == 0)
 1454                 return -1;
 1455         f->reg[Fsts] |= Fcerr | Ael;
 1456         for(i = 0; i < 10; i++){
 1457                 if((s&Scip) == 0)
 1458                         return 0;
 1459                 delay(1);
 1460                 s = f->reg[Fsts];
 1461         }
 1462         return -1;
 1463 }
 1464 
 1465 static int
 1466 fread(Ctlr *c, Flash *f, int ladr)
 1467 {
 1468         ushort s;
 1469 
 1470         delay(1);
 1471         if(fcycle(c, f) == -1)
 1472                 return -1;
 1473         f->reg[Fsts] |= Fdone;
 1474         f->reg32[Faddr] = ladr;
 1475 
 1476         /* setup flash control register */
 1477         s = f->reg[Fctl];
 1478         s &= ~(0x1f << 8);
 1479         s |= (2-1) << 8;                /* 2 bytes */
 1480         s &= ~(2*Flcycle);              /* read */
 1481         f->reg[Fctl] = s | Fgo;
 1482 
 1483         while((f->reg[Fsts] & Fdone) == 0)
 1484                 ;
 1485         if(f->reg[Fsts] & (Fcerr|Ael))
 1486                 return -1;
 1487         return f->reg32[Fdata] & 0xffff;
 1488 }
 1489 
 1490 static int
 1491 fload(Ctlr *c)
 1492 {
 1493         ulong data, io, r, adr;
 1494         ushort sum;
 1495         Flash f;
 1496 
 1497         io = c->pcidev->mem[1].bar & ~0x0f;
 1498         f.reg = vmap(io, c->pcidev->mem[1].size);
 1499         if(f.reg == nil)
 1500                 return -1;
 1501         f.reg32 = (void*)f.reg;
 1502         f.sz = f.reg32[Bfpr];
 1503         r = f.sz & 0x1fff;
 1504         if(csr32r(c, Eec) & (1<<22))
 1505                 ++r;
 1506         r <<= 12;
 1507 
 1508         sum = 0;
 1509         for (adr = 0; adr < 0x40; adr++) {
 1510                 data = fread(c, &f, r + adr*2);
 1511                 if(data == -1)
 1512                         break;
 1513                 c->eeprom[adr] = data;
 1514                 sum += data;
 1515         }
 1516         vunmap(f.reg, c->pcidev->mem[1].size);
 1517         return sum;
 1518 }
 1519 
 1520 static int
 1521 i82563reset(Ctlr *ctlr)
 1522 {
 1523         int i, r;
 1524 
 1525         if(i82563detach(ctlr))
 1526                 return -1;
 1527         if(ctlr->type == i82566)
 1528                 r = fload(ctlr);
 1529         else
 1530                 r = eeload(ctlr);
 1531         if (r != 0 && r != 0xBABA){
 1532                 print("%s: bad EEPROM checksum - %#.4ux\n",
 1533                         tname[ctlr->type], r);
 1534                 return -1;
 1535         }
 1536 
 1537         for(i = 0; i < Eaddrlen/2; i++){
 1538                 ctlr->ra[2*i]   = ctlr->eeprom[Ea+i];
 1539                 ctlr->ra[2*i+1] = ctlr->eeprom[Ea+i] >> 8;
 1540         }
 1541         r = (csr32r(ctlr, Status) & Lanid) >> 2;
 1542         ctlr->ra[5] += r;               /* ea ctlr[1] = ea ctlr[0]+1 */
 1543 
 1544         r = ctlr->ra[3]<<24 | ctlr->ra[2]<<16 | ctlr->ra[1]<<8 | ctlr->ra[0];
 1545         csr32w(ctlr, Ral, r);
 1546         r = 0x80000000 | ctlr->ra[5]<<8 | ctlr->ra[4];
 1547         csr32w(ctlr, Rah, r);
 1548         for(i = 1; i < 16; i++){
 1549                 csr32w(ctlr, Ral+i*8, 0);
 1550                 csr32w(ctlr, Rah+i*8, 0);
 1551         }
 1552         memset(ctlr->mta, 0, sizeof(ctlr->mta));
 1553         for(i = 0; i < 128; i++)
 1554                 csr32w(ctlr, Mta + i*4, 0);
 1555 
 1556         /*
 1557          * Does autonegotiation affect this manual setting?
 1558          * The correct values here should depend on the PBA value
 1559          * and maximum frame length, no?
 1560          * ctlr->fcrt[lh] are never set, so default to 0.
 1561          */
 1562         csr32w(ctlr, Fcal, 0x00C28001);
 1563         csr32w(ctlr, Fcah, 0x0100);
 1564         csr32w(ctlr, Fct, 0x8808);
 1565         csr32w(ctlr, Fcttv, 0x0100);
 1566 
 1567         ctlr->fcrtl = ctlr->fcrth = 0;
 1568         // ctlr->fcrtl = 0x00002000;
 1569         // ctlr->fcrth = 0x00004000;
 1570         csr32w(ctlr, Fcrtl, ctlr->fcrtl);
 1571         csr32w(ctlr, Fcrth, ctlr->fcrth);
 1572 
 1573         return 0;
 1574 }
 1575 
 1576 static void
 1577 i82563pci(void)
 1578 {
 1579         int type;
 1580         ulong io;
 1581         void *mem;
 1582         Pcidev *p;
 1583         Ctlr *ctlr;
 1584 
 1585         p = nil;
 1586         while(p = pcimatch(p, 0x8086, 0)){
 1587                 switch(p->did){
 1588                 default:
 1589                         continue;
 1590                 case 0x1096:
 1591                 case 0x10ba:
 1592                         type = i82563;
 1593                         break;
 1594                 case 0x1049:            /* mm */
 1595                 case 0x104a:            /* dm */
 1596                 case 0x104d:            /* v */
 1597                 case 0x10bd:            /* dm */
 1598                         type = i82566;
 1599                         break;
 1600                 case 0x10a4:
 1601                 case 0x105e:
 1602                         type = i82571;
 1603                         break;
 1604                 case 0x10b9:            /* sic, 82572 */
 1605                         type = i82572;
 1606                         break;
 1607                 case 0x108b:            /*  e */
 1608                 case 0x108c:            /*  e (iamt) */
 1609                 case 0x109a:            /*  l */
 1610                         type = i82573;
 1611                         break;
 1612                 case 0x10a7:    /* 82575eb: one of a pair of controllers */
 1613                         type = i82575;
 1614                         break;
 1615                 }
 1616 
 1617                 io = p->mem[0].bar & ~0x0F;
 1618                 mem = vmap(io, p->mem[0].size);
 1619                 if(mem == nil){
 1620                         print("%s: can't map %.8lux\n", tname[type], io);
 1621                         continue;
 1622                 }
 1623                 ctlr = malloc(sizeof(Ctlr));
 1624                 ctlr->port = io;
 1625                 ctlr->pcidev = p;
 1626                 ctlr->type = type;
 1627                 ctlr->rbsz = rbtab[type];
 1628                 ctlr->nic = mem;
 1629 
 1630                 if(i82563reset(ctlr)){
 1631                         vunmap(mem, p->mem[0].size);
 1632                         free(ctlr);
 1633                         continue;
 1634                 }
 1635                 pcisetbme(p);
 1636 
 1637                 if(i82563ctlrhead != nil)
 1638                         i82563ctlrtail->next = ctlr;
 1639                 else
 1640                         i82563ctlrhead = ctlr;
 1641                 i82563ctlrtail = ctlr;
 1642         }
 1643 }
 1644 
 1645 static int
 1646 pnp(Ether* edev, int type)
 1647 {
 1648         Ctlr *ctlr;
 1649         static int done;
 1650 
 1651         if(!done) {
 1652                 i82563pci();
 1653                 done = 1;
 1654         }
 1655 
 1656         /*
 1657          * Any adapter matches if no edev->port is supplied,
 1658          * otherwise the ports must match.
 1659          */
 1660         for(ctlr = i82563ctlrhead; ctlr != nil; ctlr = ctlr->next){
 1661                 if(ctlr->active)
 1662                         continue;
 1663                 if(type != Iany && ctlr->type != type)
 1664                         continue;
 1665                 if(edev->port == 0 || edev->port == ctlr->port){
 1666                         ctlr->active = 1;
 1667                         break;
 1668                 }
 1669         }
 1670         if(ctlr == nil)
 1671                 return -1;
 1672 
 1673         edev->ctlr = ctlr;
 1674         ctlr->edev = edev;                      /* point back to Ether* */
 1675         edev->port = ctlr->port;
 1676         edev->irq = ctlr->pcidev->intl;
 1677         edev->tbdf = ctlr->pcidev->tbdf;
 1678         edev->mbps = 1000;
 1679         edev->maxmtu = ctlr->rbsz;
 1680         memmove(edev->ea, ctlr->ra, Eaddrlen);
 1681 
 1682         /*
 1683          * Linkage to the generic ethernet driver.
 1684          */
 1685         edev->attach = i82563attach;
 1686         edev->transmit = i82563transmit;
 1687         edev->interrupt = (ctlr->type == i82575?
 1688                 i82575interrupt: i82563interrupt);
 1689         edev->ifstat = i82563ifstat;
 1690         edev->ctl = i82563ctl;
 1691 
 1692         edev->arg = edev;
 1693         edev->promiscuous = i82563promiscuous;
 1694         edev->shutdown = i82563shutdown;
 1695         edev->multicast = i82563multicast;
 1696 
 1697         return 0;
 1698 }
 1699 
 1700 static int
 1701 anypnp(Ether *e)
 1702 {
 1703         return pnp(e, Iany);
 1704 }
 1705 
 1706 static int
 1707 i82563pnp(Ether *e)
 1708 {
 1709         return pnp(e, i82563);
 1710 }
 1711 
 1712 static int
 1713 i82566pnp(Ether *e)
 1714 {
 1715         return pnp(e, i82566);
 1716 }
 1717 
 1718 static int
 1719 i82571pnp(Ether *e)
 1720 {
 1721         return pnp(e, i82571);
 1722 }
 1723 
 1724 static int
 1725 i82572pnp(Ether *e)
 1726 {
 1727         return pnp(e, i82572);
 1728 }
 1729 
 1730 static int
 1731 i82573pnp(Ether *e)
 1732 {
 1733         return pnp(e, i82573);
 1734 }
 1735 
 1736 static int
 1737 i82575pnp(Ether *e)
 1738 {
 1739         return pnp(e, i82575);
 1740 }
 1741 
 1742 void
 1743 ether82563link(void)
 1744 {
 1745         /* recognise lots of model numbers for debugging assistance */
 1746         addethercard("i82563", i82563pnp);
 1747         addethercard("i82566", i82566pnp);
 1748         addethercard("i82571", i82571pnp);
 1749         addethercard("i82572", i82572pnp);
 1750         addethercard("i82573", i82573pnp);
 1751         addethercard("i82575", i82575pnp);
 1752         addethercard("igbepcie", anypnp);
 1753 }

Cache object: 275be8361071f983acaea492fc0f5a15


[ 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.