ether82563.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * Bootstrap driver for
  11. * Intel 82563, 82571, 82573, 82575, 82576
  12. * GbE PCI-Express Controllers.
  13. */
  14. #include "u.h"
  15. #include "lib.h"
  16. #include "mem.h"
  17. #include "dat.h"
  18. #include "fns.h"
  19. #include "io.h"
  20. #include "etherif.h"
  21. /* compatibility with cpu kernels */
  22. #define iallocb allocb
  23. #ifndef CACHELINESZ
  24. #define CACHELINESZ 32 /* pentium & later */
  25. #endif
  26. /* from pci.c */
  27. enum
  28. { /* command register pcidev->pcr */
  29. IOen = 1<<0,
  30. MEMen = 1<<1,
  31. MASen = 1<<2,
  32. MemWrInv = 1<<4,
  33. PErrEn = 1<<6,
  34. SErrEn = 1<<8,
  35. };
  36. /*
  37. * these are in the order they appear in the manual, not numeric order.
  38. * It was too hard to find them in the book. Ref 21489, rev 2.6
  39. */
  40. enum {
  41. /* General */
  42. Ctrl = 0x00000000, /* Device Control */
  43. Status = 0x00000008, /* Device Status */
  44. Eec = 0x00000010, /* EEPROM/Flash Control/Data */
  45. Eerd = 0x00000014, /* EEPROM Read */
  46. Ctrlext = 0x00000018, /* Extended Device Control */
  47. Fla = 0x0000001c, /* Flash Access */
  48. Mdic = 0x00000020, /* MDI Control */
  49. Seresctl = 0x00000024, /* Serdes ana */
  50. Fcal = 0x00000028, /* Flow Control Address Low */
  51. Fcah = 0x0000002C, /* Flow Control Address High */
  52. Fct = 0x00000030, /* Flow Control Type */
  53. Kumctrlsta = 0x00000034, /* MAC-PHY Interface */
  54. Vet = 0x00000038, /* VLAN EtherType */
  55. Fcttv = 0x00000170, /* Flow Control Transmit Timer Value */
  56. Txcw = 0x00000178, /* Transmit Configuration Word */
  57. Rxcw = 0x00000180, /* Receive Configuration Word */
  58. Ledctl = 0x00000E00, /* LED control */
  59. Pba = 0x00001000, /* Packet Buffer Allocation */
  60. Pbs = 0x00001008, /* Packet Buffer Size */
  61. /* Interrupt */
  62. Icr = 0x000000C0, /* Interrupt Cause Read */
  63. Ics = 0x000000C8, /* Interrupt Cause Set */
  64. Ims = 0x000000D0, /* Interrupt Mask Set/Read */
  65. Imc = 0x000000D8, /* Interrupt mask Clear */
  66. Iam = 0x000000E0, /* Interrupt acknowledge Auto Mask */
  67. /* Receive */
  68. Rctl = 0x00000100, /* Receive Control */
  69. Ert = 0x00002008, /* Early Receive Threshold (573[EVL] only) */
  70. Fcrtl = 0x00002160, /* Flow Control RX Threshold Low */
  71. Fcrth = 0x00002168, /* Flow Control Rx Threshold High */
  72. Psrctl = 0x00002170, /* Packet Split Receive Control */
  73. Rdbal = 0x00002800, /* Rdesc Base Address Low Queue 0 */
  74. Rdbah = 0x00002804, /* Rdesc Base Address High Queue 0 */
  75. Rdlen = 0x00002808, /* Receive Descriptor Length Queue 0 */
  76. Rdh = 0x00002810, /* Receive Descriptor Head Queue 0 */
  77. Rdt = 0x00002818, /* Receive Descriptor Tail Queue 0 */
  78. Rdtr = 0x00002820, /* Receive Descriptor Timer Ring */
  79. Rxdctl = 0x00002828, /* Receive Descriptor Control */
  80. Radv = 0x0000282C, /* Receive Interrupt Absolute Delay Timer */
  81. Rdbal1 = 0x00002900, /* Rdesc Base Address Low Queue 1 */
  82. Rdbah1 = 0x00002804, /* Rdesc Base Address High Queue 1 */
  83. Rdlen1 = 0x00002908, /* Receive Descriptor Length Queue 1 */
  84. Rdh1 = 0x00002910, /* Receive Descriptor Head Queue 1 */
  85. Rdt1 = 0x00002918, /* Receive Descriptor Tail Queue 1 */
  86. Rxdctl1 = 0x00002928, /* Receive Descriptor Control Queue 1 */
  87. Rsrpd = 0x00002c00, /* Receive Small Packet Detect */
  88. Raid = 0x00002c08, /* Receive ACK interrupt delay */
  89. Cpuvec = 0x00002c10, /* CPU Vector */
  90. Rxcsum = 0x00005000, /* Receive Checksum Control */
  91. Rfctl = 0x00005008, /* Receive Filter Control */
  92. Mta = 0x00005200, /* Multicast Table Array */
  93. Ral = 0x00005400, /* Receive Address Low */
  94. Rah = 0x00005404, /* Receive Address High */
  95. Vfta = 0x00005600, /* VLAN Filter Table Array */
  96. Mrqc = 0x00005818, /* Multiple Receive Queues Command */
  97. Rssim = 0x00005864, /* RSS Interrupt Mask */
  98. Rssir = 0x00005868, /* RSS Interrupt Request */
  99. Reta = 0x00005c00, /* Redirection Table */
  100. Rssrk = 0x00005c80, /* RSS Random Key */
  101. /* Transmit */
  102. Tctl = 0x00000400, /* Transmit Control */
  103. Tipg = 0x00000410, /* Transmit IPG */
  104. Tdbal = 0x00003800, /* Tdesc Base Address Low */
  105. Tdbah = 0x00003804, /* Tdesc Base Address High */
  106. Tdlen = 0x00003808, /* Transmit Descriptor Length */
  107. Tdh = 0x00003810, /* Transmit Descriptor Head */
  108. Tdt = 0x00003818, /* Transmit Descriptor Tail */
  109. Tidv = 0x00003820, /* Transmit Interrupt Delay Value */
  110. Txdctl = 0x00003828, /* Transmit Descriptor Control */
  111. Tadv = 0x0000382C, /* Transmit Interrupt Absolute Delay Timer */
  112. Tarc0 = 0x00003840, /* Transmit Arbitration Counter Queue 0 */
  113. Tdbal1 = 0x00003900, /* Transmit Descriptor Base Low Queue 1 */
  114. Tdbah1 = 0x00003904, /* Transmit Descriptor Base High Queue 1 */
  115. Tdlen1 = 0x00003908, /* Transmit Descriptor Length Queue 1 */
  116. Tdh1 = 0x00003910, /* Transmit Descriptor Head Queue 1 */
  117. Tdt1 = 0x00003918, /* Transmit Descriptor Tail Queue 1 */
  118. Txdctl1 = 0x00003928, /* Transmit Descriptor Control 1 */
  119. Tarc1 = 0x00003940, /* Transmit Arbitration Counter Queue 1 */
  120. /* Statistics */
  121. Statistics = 0x00004000, /* Start of Statistics Area */
  122. Gorcl = 0x88/4, /* Good Octets Received Count */
  123. Gotcl = 0x90/4, /* Good Octets Transmitted Count */
  124. Torl = 0xC0/4, /* Total Octets Received */
  125. Totl = 0xC8/4, /* Total Octets Transmitted */
  126. Nstatistics = 64,
  127. };
  128. enum { /* Ctrl */
  129. GIOmd = 1<<2, /* BIO master disable */
  130. Lrst = 1<<3, /* link reset */
  131. Slu = 1<<6, /* Set Link Up */
  132. SspeedMASK = 3<<8, /* Speed Selection */
  133. SspeedSHIFT = 8,
  134. Sspeed10 = 0x00000000, /* 10Mb/s */
  135. Sspeed100 = 0x00000100, /* 100Mb/s */
  136. Sspeed1000 = 0x00000200, /* 1000Mb/s */
  137. Frcspd = 1<<11, /* Force Speed */
  138. Frcdplx = 1<<12, /* Force Duplex */
  139. SwdpinsloMASK = 0x003C0000, /* Software Defined Pins - lo nibble */
  140. SwdpinsloSHIFT = 18,
  141. SwdpioloMASK = 0x03C00000, /* Software Defined Pins - I or O */
  142. SwdpioloSHIFT = 22,
  143. Devrst = 1<<26, /* Device Reset */
  144. Rfce = 1<<27, /* Receive Flow Control Enable */
  145. Tfce = 1<<28, /* Transmit Flow Control Enable */
  146. Vme = 1<<30, /* VLAN Mode Enable */
  147. Phy_rst = 1<<31, /* Phy Reset */
  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. SpeedMASK = 0x000000C0,
  155. Speed10 = 0x00000000, /* 10Mb/s */
  156. Speed100 = 0x00000040, /* 100Mb/s */
  157. Speed1000 = 0x00000080, /* 1000Mb/s */
  158. Phyra = 1<<10, /* PHY Reset Asserted */
  159. GIOme = 1<<19, /* GIO Master Enable Status */
  160. };
  161. enum { /* Ctrl and Status */
  162. Fd = 0x00000001, /* Full-Duplex */
  163. AsdvMASK = 0x00000300,
  164. Asdv10 = 0x00000000, /* 10Mb/s */
  165. Asdv100 = 0x00000100, /* 100Mb/s */
  166. Asdv1000 = 0x00000200, /* 1000Mb/s */
  167. };
  168. enum { /* Eec */
  169. Sk = 1<<0, /* Clock input to the EEPROM */
  170. Cs = 1<<1, /* Chip Select */
  171. Di = 1<<2, /* Data Input to the EEPROM */
  172. Do = 1<<3, /* Data Output from the EEPROM */
  173. Areq = 1<<6, /* EEPROM Access Request */
  174. Agnt = 1<<7, /* EEPROM Access Grant */
  175. };
  176. enum { /* Eerd */
  177. ee_start = 1<<0, /* Start Read */
  178. ee_done = 1<<1, /* Read done */
  179. ee_addr = 0xfff8<<2, /* Read address [15:2] */
  180. ee_data = 0xffff<<16, /* Read Data; Data returned from eeprom/nvm */
  181. };
  182. enum { /* Ctrlext */
  183. Asdchk = 1<<12, /* ASD Check */
  184. Eerst = 1<<13, /* EEPROM Reset */
  185. Spdbyps = 1<<15, /* Speed Select Bypass */
  186. };
  187. enum { /* EEPROM content offsets */
  188. Ea = 0x00, /* Ethernet Address */
  189. Cf = 0x03, /* Compatibility Field */
  190. Icw1 = 0x0A, /* Initialization Control Word 1 */
  191. Sid = 0x0B, /* Subsystem ID */
  192. Svid = 0x0C, /* Subsystem Vendor ID */
  193. Did = 0x0D, /* Device ID */
  194. Vid = 0x0E, /* Vendor ID */
  195. Icw2 = 0x0F, /* Initialization Control Word 2 */
  196. };
  197. enum { /* Mdic */
  198. MDIdMASK = 0x0000FFFF, /* Data */
  199. MDIdSHIFT = 0,
  200. MDIrMASK = 0x001F0000, /* PHY Register Address */
  201. MDIrSHIFT = 16,
  202. MDIpMASK = 0x03E00000, /* PHY Address */
  203. MDIpSHIFT = 21,
  204. MDIwop = 0x04000000, /* Write Operation */
  205. MDIrop = 0x08000000, /* Read Operation */
  206. MDIready = 0x10000000, /* End of Transaction */
  207. MDIie = 0x20000000, /* Interrupt Enable */
  208. MDIe = 0x40000000, /* Error */
  209. };
  210. enum { /* Icr, Ics, Ims, Imc */
  211. Txdw = 0x00000001, /* Transmit Descriptor Written Back */
  212. Txqe = 0x00000002, /* Transmit Queue Empty */
  213. Lsc = 0x00000004, /* Link Status Change */
  214. Rxseq = 0x00000008, /* Receive Sequence Error */
  215. Rxdmt0 = 0x00000010, /* Rdesc Minimum Threshold Reached */
  216. Rxo = 0x00000040, /* Receiver Overrun */
  217. Rxt0 = 0x00000080, /* Receiver Timer Interrupt */
  218. Mdac = 0x00000200, /* MDIO Access Completed */
  219. Rxcfg = 0x00000400, /* Receiving /C/ ordered sets */
  220. Gpi0 = 0x00000800, /* General Purpose Interrupts */
  221. Gpi1 = 0x00001000,
  222. Gpi2 = 0x00002000,
  223. Gpi3 = 0x00004000,
  224. Ack = 0x00020000, /* receive ACK frame */
  225. };
  226. enum { /* Txcw */
  227. TxcwFd = 0x00000020, /* Full Duplex */
  228. TxcwHd = 0x00000040, /* Half Duplex */
  229. TxcwPauseMASK = 0x00000180, /* Pause */
  230. TxcwPauseSHIFT = 7,
  231. TxcwPs = 1<<TxcwPauseSHIFT, /* Pause Supported */
  232. TxcwAs = 2<<TxcwPauseSHIFT, /* Asymmetric FC desired */
  233. TxcwRfiMASK = 0x00003000, /* Remote Fault Indication */
  234. TxcwRfiSHIFT = 12,
  235. TxcwNpr = 0x00008000, /* Next Page Request */
  236. TxcwConfig = 0x40000000, /* Transmit Config Control */
  237. TxcwAne = 0x80000000, /* Auto-Negotiation Enable */
  238. };
  239. enum { /* Rctl */
  240. Rrst = 0x00000001, /* Receiver Software Reset */
  241. Ren = 0x00000002, /* Receiver Enable */
  242. Sbp = 0x00000004, /* Store Bad Packets */
  243. Upe = 0x00000008, /* Unicast Promiscuous Enable */
  244. Mpe = 0x00000010, /* Multicast Promiscuous Enable */
  245. Lpe = 0x00000020, /* Long Packet Reception Enable */
  246. LbmMASK = 0x000000C0, /* Loopback Mode */
  247. LbmOFF = 0x00000000, /* No Loopback */
  248. LbmTBI = 0x00000040, /* TBI Loopback */
  249. LbmMII = 0x00000080, /* GMII/MII Loopback */
  250. LbmXCVR = 0x000000C0, /* Transceiver Loopback */
  251. RdtmsMASK = 0x00000300, /* Rdesc Minimum Threshold Size */
  252. RdtmsHALF = 0x00000000, /* Threshold is 1/2 Rdlen */
  253. RdtmsQUARTER = 0x00000100, /* Threshold is 1/4 Rdlen */
  254. RdtmsEIGHTH = 0x00000200, /* Threshold is 1/8 Rdlen */
  255. MoMASK = 0x00003000, /* Multicast Offset */
  256. Bam = 0x00008000, /* Broadcast Accept Mode */
  257. BsizeMASK = 0x00030000, /* Receive Buffer Size */
  258. Bsize2048 = 0x00000000,
  259. Bsize1024 = 0x00010000,
  260. Bsize512 = 0x00020000,
  261. Bsize256 = 0x00030000,
  262. Vfe = 0x00040000, /* VLAN Filter Enable */
  263. Cfien = 0x00080000, /* Canonical Form Indicator Enable */
  264. Cfi = 0x00100000, /* Canonical Form Indicator value */
  265. Dpf = 0x00400000, /* Discard Pause Frames */
  266. Pmcf = 0x00800000, /* Pass MAC Control Frames */
  267. Bsex = 0x02000000, /* Buffer Size Extension */
  268. Secrc = 0x04000000, /* Strip CRC from incoming packet */
  269. };
  270. enum { /* Tctl */
  271. Trst = 0x00000001, /* Transmitter Software Reset */
  272. Ten = 0x00000002, /* Transmit Enable */
  273. Psp = 0x00000008, /* Pad Short Packets */
  274. Mulr = 0x10000000, /* Allow multiple concurrent requests */
  275. CtMASK = 0x00000FF0, /* Collision Threshold */
  276. CtSHIFT = 4,
  277. ColdMASK = 0x003FF000, /* Collision Distance */
  278. ColdSHIFT = 12,
  279. Swxoff = 0x00400000, /* Sofware XOFF Transmission */
  280. Pbe = 0x00800000, /* Packet Burst Enable */
  281. Rtlc = 0x01000000, /* Re-transmit on Late Collision */
  282. Nrtu = 0x02000000, /* No Re-transmit on Underrrun */
  283. };
  284. enum { /* [RT]xdctl */
  285. PthreshMASK = 0x0000003F, /* Prefetch Threshold */
  286. PthreshSHIFT = 0,
  287. HthreshMASK = 0x00003F00, /* Host Threshold */
  288. HthreshSHIFT = 8,
  289. WthreshMASK = 0x003F0000, /* Writeback Threshold */
  290. WthreshSHIFT = 16,
  291. Gran = 0x01000000, /* Granularity */
  292. Qenable = 0x02000000, /* Queue Enable (82575eb) */
  293. };
  294. enum { /* Rxcsum */
  295. PcssMASK = 0x000000FF, /* Packet Checksum Start */
  296. PcssSHIFT = 0,
  297. Ipofl = 0x00000100, /* IP Checksum Off-load Enable */
  298. Tuofl = 0x00000200, /* TCP/UDP Checksum Off-load Enable */
  299. };
  300. typedef struct Rdesc { /* Receive Descriptor */
  301. uint addr[2];
  302. uint16_t length;
  303. uint16_t checksum;
  304. uint8_t status;
  305. uint8_t errors;
  306. uint16_t special;
  307. } Rdesc;
  308. enum { /* Rdesc status */
  309. Rdd = 0x01, /* Descriptor Done */
  310. Reop = 0x02, /* End of Packet */
  311. Ixsm = 0x04, /* Ignore Checksum Indication */
  312. Vp = 0x08, /* Packet is 802.1Q (matched VET) */
  313. Tcpcs = 0x20, /* TCP Checksum Calculated on Packet */
  314. Ipcs = 0x40, /* IP Checksum Calculated on Packet */
  315. Pif = 0x80, /* Passed in-exact filter */
  316. };
  317. enum { /* Rdesc errors */
  318. Ce = 0x01, /* CRC Error or Alignment Error */
  319. Se = 0x02, /* Symbol Error */
  320. Seq = 0x04, /* Sequence Error */
  321. Cxe = 0x10, /* Carrier Extension Error */
  322. Tcpe = 0x20, /* TCP/UDP Checksum Error */
  323. Ipe = 0x40, /* IP Checksum Error */
  324. Rxe = 0x80, /* RX Data Error */
  325. };
  326. typedef struct Tdesc { /* Legacy+Normal Transmit Descriptor */
  327. uint addr[2];
  328. uint control; /* varies with descriptor type */
  329. uint status; /* varies with descriptor type */
  330. } Tdesc;
  331. enum { /* Tdesc control */
  332. LenMASK = 0x000FFFFF, /* Data/Packet Length Field */
  333. LenSHIFT = 0,
  334. DtypeCD = 0x00000000, /* Data Type 'Context Descriptor' */
  335. DtypeDD = 0x00100000, /* Data Type 'Data Descriptor' */
  336. PtypeTCP = 0x01000000, /* TCP/UDP Packet Type (CD) */
  337. Teop = 0x01000000, /* End of Packet (DD) */
  338. PtypeIP = 0x02000000, /* IP Packet Type (CD) */
  339. Ifcs = 0x02000000, /* Insert FCS (DD) */
  340. Tse = 0x04000000, /* TCP Segmentation Enable */
  341. Rs = 0x08000000, /* Report Status */
  342. Rps = 0x10000000, /* Report Status Sent */
  343. Dext = 0x20000000, /* Descriptor Extension */
  344. Vle = 0x40000000, /* VLAN Packet Enable */
  345. Ide = 0x80000000, /* Interrupt Delay Enable */
  346. };
  347. enum { /* Tdesc status */
  348. Tdd = 0x00000001, /* Descriptor Done */
  349. Ec = 0x00000002, /* Excess Collisions */
  350. Lc = 0x00000004, /* Late Collision */
  351. Tu = 0x00000008, /* Transmit Underrun */
  352. CssMASK = 0x0000FF00, /* Checksum Start Field */
  353. CssSHIFT = 8,
  354. };
  355. typedef struct {
  356. uint16_t *reg;
  357. uint32_t *reg32;
  358. int sz;
  359. } Flash;
  360. enum {
  361. /* 16 and 32-bit flash registers for ich flash parts */
  362. Bfpr = 0x00/4, /* flash base 0:12; lim 16:28 */
  363. Fsts = 0x04/2, /* flash status; Hsfsts */
  364. Fctl = 0x06/2, /* flash control; Hsfctl */
  365. Faddr = 0x08/4, /* flash address to r/w */
  366. Fdata = 0x10/4, /* data @ address */
  367. /* status register */
  368. Fdone = 1<<0, /* flash cycle done */
  369. Fcerr = 1<<1, /* cycle error; write 1 to clear */
  370. Ael = 1<<2, /* direct access error log; 1 to clear */
  371. Scip = 1<<5, /* spi cycle in progress */
  372. Fvalid = 1<<14, /* flash descriptor valid */
  373. /* control register */
  374. Fgo = 1<<0, /* start cycle */
  375. Flcycle = 1<<1, /* two bits: r=0; w=2 */
  376. Fdbc = 1<<8, /* bytes to read; 5 bits */
  377. };
  378. enum {
  379. Nrdesc = 32, /* multiple of 8 */
  380. Ntdesc = 8, /* multiple of 8 */
  381. };
  382. enum {
  383. i82563,
  384. i82566,
  385. i82567,
  386. i82571,
  387. i82572,
  388. i82573,
  389. i82575,
  390. i82576,
  391. };
  392. static char *tname[] = {
  393. "i82563",
  394. "i82566",
  395. "i82567",
  396. "i82571",
  397. "i82572",
  398. "i82573",
  399. "i82575",
  400. "i82576",
  401. };
  402. typedef struct Ctlr Ctlr;
  403. struct Ctlr {
  404. int port;
  405. Pcidev *pcidev;
  406. Ctlr *next;
  407. int active;
  408. int cls;
  409. uint16_t eeprom[0x40];
  410. uint8_t ra[Eaddrlen]; /* receive address */
  411. int type;
  412. uint32_t* nic;
  413. Lock imlock;
  414. int im; /* interrupt mask */
  415. Lock slock;
  416. uint statistics[Nstatistics];
  417. Rdesc *rdba; /* receive descriptor base address */
  418. Block **rb; /* receive buffers */
  419. int rdh; /* receive descriptor head */
  420. int rdt; /* receive descriptor tail */
  421. Tdesc *tdba; /* transmit descriptor base address */
  422. Lock tdlock;
  423. Block **tb; /* transmit buffers */
  424. int tdh; /* transmit descriptor head */
  425. int tdt; /* transmit descriptor tail */
  426. int txcw;
  427. int fcrtl;
  428. int fcrth;
  429. /* bootstrap goo */
  430. Block *bqhead; /* transmission queue */
  431. Block *bqtail;
  432. };
  433. static Ctlr *ctlrhead;
  434. static Ctlr *ctlrtail;
  435. #define csr32r(c, r) (*((c)->nic+((r)/4)))
  436. #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  437. static void
  438. i82563im(Ctlr* ctlr, int im)
  439. {
  440. ilock(&ctlr->imlock);
  441. ctlr->im |= im;
  442. csr32w(ctlr, Ims, ctlr->im);
  443. iunlock(&ctlr->imlock);
  444. }
  445. static void
  446. i82563attach(Ether* edev)
  447. {
  448. int ctl;
  449. Ctlr *ctlr;
  450. ctlr = edev->ctlr;
  451. i82563im(ctlr, 0);
  452. ctl = csr32r(ctlr, Rctl)|Ren;
  453. csr32w(ctlr, Rctl, ctl);
  454. ctl = csr32r(ctlr, Tctl)|Ten;
  455. csr32w(ctlr, Tctl, ctl);
  456. }
  457. static void
  458. txstart(Ether *edev)
  459. {
  460. int tdh, tdt;
  461. Ctlr *ctlr = edev->ctlr;
  462. Block *bp;
  463. Tdesc *tdesc;
  464. /*
  465. * Try to fill the ring back up, moving buffers from the transmit q.
  466. */
  467. tdh = PREV(ctlr->tdh, Ntdesc);
  468. for(tdt = ctlr->tdt; tdt != tdh; tdt = NEXT(tdt, Ntdesc)){
  469. /* pull off the head of the transmission queue */
  470. if((bp = ctlr->bqhead) == nil) /* was qget(edev->oq) */
  471. break;
  472. ctlr->bqhead = bp->next;
  473. if (ctlr->bqtail == bp)
  474. ctlr->bqtail = nil;
  475. /* set up a descriptor for it */
  476. tdesc = &ctlr->tdba[tdt];
  477. tdesc->addr[0] = PCIWADDR(bp->rp);
  478. tdesc->addr[1] = 0;
  479. tdesc->control = /* Ide | */ Rs | Ifcs | Teop | BLEN(bp);
  480. ctlr->tb[tdt] = bp;
  481. }
  482. ctlr->tdt = tdt;
  483. csr32w(ctlr, Tdt, tdt);
  484. i82563im(ctlr, Txdw);
  485. }
  486. static Block *
  487. fromringbuf(Ether *ether)
  488. {
  489. RingBuf *tb = &ether->tb[ether->ti];
  490. Block *bp = allocb(tb->len);
  491. memmove(bp->wp, tb->pkt, tb->len);
  492. memmove(bp->wp+Eaddrlen, ether->ea, Eaddrlen);
  493. bp->wp += tb->len;
  494. return bp;
  495. }
  496. static void
  497. i82563transmit(Ether* edev)
  498. {
  499. Block *bp;
  500. Ctlr *ctlr;
  501. Tdesc *tdesc;
  502. RingBuf *tb;
  503. int tdh;
  504. ctlr = edev->ctlr;
  505. ilock(&ctlr->tdlock);
  506. /*
  507. * Free any completed packets
  508. * - try to get the soft tdh to catch the tdt;
  509. * - if the packet had an underrun bump the threshold
  510. * - the Tu bit doesn't seem to ever be set, perhaps
  511. * because Rs mode is used?
  512. */
  513. tdh = ctlr->tdh;
  514. for(;;){
  515. tdesc = &ctlr->tdba[tdh];
  516. if(!(tdesc->status & Tdd))
  517. break;
  518. if(ctlr->tb[tdh] != nil){
  519. freeb(ctlr->tb[tdh]);
  520. ctlr->tb[tdh] = nil;
  521. }
  522. tdesc->status = 0;
  523. tdh = NEXT(tdh, Ntdesc);
  524. }
  525. ctlr->tdh = tdh;
  526. /* copy packets from the software RingBuf to the transmission q */
  527. while((tb = &edev->tb[edev->ti])->owner == Interface){
  528. bp = fromringbuf(edev);
  529. // print("#l%d: tx %d %E %E\n", edev->ctlrno, edev->ti, bp->rp,
  530. // bp->rp+6);
  531. if(ctlr->bqhead)
  532. ctlr->bqtail->next = bp;
  533. else
  534. ctlr->bqhead = bp;
  535. ctlr->bqtail = bp;
  536. txstart(edev); /* kick transmitter */
  537. tb->owner = Host; /* give descriptor back */
  538. edev->ti = NEXT(edev->ti, edev->ntb);
  539. }
  540. iunlock(&ctlr->tdlock);
  541. }
  542. static void
  543. i82563replenish(Ctlr* ctlr)
  544. {
  545. int rdt;
  546. Block *bp;
  547. Rdesc *rdesc;
  548. rdt = ctlr->rdt;
  549. while(NEXT(rdt, Nrdesc) != ctlr->rdh){
  550. rdesc = &ctlr->rdba[rdt];
  551. if(ctlr->rb[rdt] != nil){
  552. /* nothing to do */
  553. }
  554. else if((bp = iallocb(2048)) != nil){
  555. ctlr->rb[rdt] = bp;
  556. rdesc->addr[0] = PCIWADDR(bp->rp);
  557. rdesc->addr[1] = 0;
  558. }
  559. else
  560. break;
  561. rdesc->status = 0;
  562. rdt = NEXT(rdt, Nrdesc);
  563. }
  564. ctlr->rdt = rdt;
  565. csr32w(ctlr, Rdt, rdt);
  566. }
  567. static void
  568. toringbuf(Ether *ether, Block *bp)
  569. {
  570. RingBuf *rb = &ether->rb[ether->ri];
  571. if (rb->owner == Interface) {
  572. rb->len = BLEN(bp);
  573. memmove(rb->pkt, bp->rp, rb->len);
  574. rb->owner = Host;
  575. ether->ri = NEXT(ether->ri, ether->nrb);
  576. } else if (debug)
  577. print("#l%d: toringbuf: dropping packets @ ri %d\n",
  578. ether->ctlrno, ether->ri);
  579. }
  580. int interesting(void*);
  581. static void
  582. i82563interrupt(Ureg*, void* arg)
  583. {
  584. int icr, im, rdh, txdw = 0, rxcnt;
  585. Block *bp;
  586. Ctlr *ctlr;
  587. Ether *edev;
  588. Rdesc *rdesc;
  589. edev = arg;
  590. ctlr = edev->ctlr;
  591. ilock(&ctlr->imlock);
  592. csr32w(ctlr, Imc, ~0);
  593. im = ctlr->im;
  594. rxcnt = 0;
  595. for(icr = csr32r(ctlr, Icr); icr & ctlr->im; icr = csr32r(ctlr, Icr)){
  596. if(icr & (Rxseq|Lsc)){
  597. /* should be more here */
  598. }
  599. rdh = ctlr->rdh;
  600. for (;;) {
  601. rdesc = &ctlr->rdba[rdh];
  602. if(!(rdesc->status & Rdd))
  603. break;
  604. if ((rdesc->status & Reop) && rdesc->errors == 0) {
  605. bp = ctlr->rb[rdh];
  606. if(0 && memcmp(bp->rp, broadcast, 6) != 0)
  607. print("#l%d: rx %d %E %E %d\n",
  608. edev->ctlrno, rdh, bp->rp,
  609. bp->rp+6, rdesc->length);
  610. ctlr->rb[rdh] = nil;
  611. bp->wp += rdesc->length;
  612. if (interesting(bp->rp))
  613. toringbuf(edev, bp);
  614. freeb(bp);
  615. } else if (rdesc->status & Reop && rdesc->errors)
  616. print("%s: input packet error %#ux\n",
  617. tname[ctlr->type], rdesc->errors);
  618. rdesc->status = 0;
  619. rdh = NEXT(rdh, Nrdesc);
  620. if (++rxcnt >= 16 && ctlr->type == i82576) {
  621. i82563replenish(ctlr);
  622. rxcnt = 0;
  623. }
  624. }
  625. ctlr->rdh = rdh;
  626. if(icr & Rxdmt0 || ctlr->type == i82576)
  627. i82563replenish(ctlr);
  628. if(icr & Txdw){
  629. im &= ~Txdw;
  630. txdw++;
  631. }
  632. }
  633. ctlr->im = im;
  634. csr32w(ctlr, Ims, im);
  635. iunlock(&ctlr->imlock);
  636. if(txdw)
  637. i82563transmit(edev);
  638. }
  639. static void
  640. i82563init(Ether* edev)
  641. {
  642. Ctlr *ctlr;
  643. uint32_t r, rctl;
  644. ctlr = edev->ctlr;
  645. rctl = Dpf | Bsize2048 | Bam | RdtmsHALF;
  646. if(ctlr->type == i82575 || ctlr->type == i82576){
  647. /*
  648. * Setting Qenable in Rxdctl does not
  649. * appear to stick unless Ren is on.
  650. */
  651. csr32w(ctlr, Rctl, Ren|rctl);
  652. r = csr32r(ctlr, Rxdctl);
  653. r |= Qenable;
  654. csr32w(ctlr, Rxdctl, r);
  655. }
  656. csr32w(ctlr, Rctl, rctl);
  657. ctlr->rdba = mallocalign(Nrdesc*sizeof(Rdesc), 256, 0, 0); /* 256 was 128 */
  658. csr32w(ctlr, Rdbal, PCIWADDR(ctlr->rdba));
  659. csr32w(ctlr, Rdbah, 0);
  660. csr32w(ctlr, Rdlen, Nrdesc*sizeof(Rdesc));
  661. ctlr->rdh = 0;
  662. csr32w(ctlr, Rdh, ctlr->rdh);
  663. ctlr->rdt = 0;
  664. csr32w(ctlr, Rdt, ctlr->rdt);
  665. ctlr->rb = malloc(sizeof(Block*)*Nrdesc);
  666. i82563replenish(ctlr);
  667. csr32w(ctlr, Rdtr, 0);
  668. csr32w(ctlr, Radv, 0);
  669. if(ctlr->type == i82573)
  670. csr32w(ctlr, Ert, 1024/8);
  671. if(ctlr->type == i82566 || ctlr->type == i82567)
  672. csr32w(ctlr, Pbs, 16);
  673. i82563im(ctlr, Rxt0 | Rxo | Rxdmt0 | Rxseq | Ack);
  674. csr32w(ctlr, Tctl, 0x0F<<CtSHIFT | Psp | 0x3f<<ColdSHIFT | Mulr);
  675. csr32w(ctlr, Tipg, 6<<20 | 8<<10 | 8);
  676. csr32w(ctlr, Tidv, 1);
  677. ctlr->tdba = mallocalign(Ntdesc*sizeof(Tdesc), 256, 0, 0); /* 256 was 128 */
  678. memset(ctlr->tdba, 0, Ntdesc*sizeof(Tdesc));
  679. csr32w(ctlr, Tdbal, PCIWADDR(ctlr->tdba));
  680. csr32w(ctlr, Tdbah, 0);
  681. csr32w(ctlr, Tdlen, Ntdesc*sizeof(Tdesc));
  682. ctlr->tdh = 0;
  683. csr32w(ctlr, Tdh, ctlr->tdh);
  684. ctlr->tdt = 0;
  685. csr32w(ctlr, Tdt, ctlr->tdt);
  686. ctlr->tb = malloc(sizeof(Block*)*Ntdesc);
  687. r = csr32r(ctlr, Txdctl);
  688. r &= ~(WthreshMASK|PthreshMASK);
  689. r |= 4<<WthreshSHIFT | 4<<PthreshSHIFT;
  690. if(ctlr->type == i82575 || ctlr->type == i82576)
  691. r |= Qenable;
  692. csr32w(ctlr, Txdctl, r);
  693. /*
  694. * Don't enable checksum offload. In practice, it interferes with
  695. * tftp booting on at least the 82575.
  696. */
  697. // csr32w(ctlr, Rxcsum, Tuofl | Ipofl | ETHERHDRSIZE<<PcssSHIFT);
  698. csr32w(ctlr, Rxcsum, 0);
  699. r = csr32r(ctlr, Tctl);
  700. r |= Ten;
  701. csr32w(ctlr, Tctl, r);
  702. }
  703. static uint16_t
  704. eeread(Ctlr* ctlr, int adr)
  705. {
  706. csr32w(ctlr, Eerd, ee_start | adr << 2);
  707. while ((csr32r(ctlr, Eerd) & ee_done) == 0)
  708. ;
  709. return csr32r(ctlr, Eerd) >> 16;
  710. }
  711. static int
  712. eeload(Ctlr* ctlr)
  713. {
  714. uint16_t sum;
  715. int data, adr;
  716. sum = 0;
  717. for (adr = 0; adr < 0x40; adr++) {
  718. data = eeread(ctlr, adr);
  719. ctlr->eeprom[adr] = data;
  720. sum += data;
  721. }
  722. return sum;
  723. }
  724. static void
  725. detach(Ctlr *ctlr)
  726. {
  727. int r;
  728. csr32w(ctlr, Imc, ~0);
  729. csr32w(ctlr, Rctl, 0);
  730. csr32w(ctlr, Tctl, 0);
  731. delay(10);
  732. r = csr32r(ctlr, Ctrl);
  733. if(ctlr->type == i82566 || ctlr->type == i82567)
  734. r |= Phy_rst;
  735. csr32w(ctlr, Ctrl, Devrst | r);
  736. /* apparently needed on multi-GHz processors to avoid infinite loops */
  737. delay(1);
  738. while(csr32r(ctlr, Ctrl) & Devrst)
  739. ;
  740. if(1 || ctlr->type != i82563){
  741. r = csr32r(ctlr, Ctrl);
  742. csr32w(ctlr, Ctrl, Slu | r);
  743. }
  744. csr32w(ctlr, Ctrlext, Eerst | csr32r(ctlr, Ctrlext));
  745. delay(1);
  746. while(csr32r(ctlr, Ctrlext) & Eerst)
  747. ;
  748. csr32w(ctlr, Imc, ~0);
  749. delay(1);
  750. while(csr32r(ctlr, Icr))
  751. ;
  752. }
  753. static void
  754. i82563detach(Ether *edev)
  755. {
  756. detach(edev->ctlr);
  757. }
  758. static void
  759. i82563shutdown(Ether* ether)
  760. {
  761. i82563detach(ether);
  762. }
  763. static int
  764. fcycle(Ctlr *, Flash *f)
  765. {
  766. uint16_t s, i;
  767. s = f->reg[Fsts];
  768. if((s&Fvalid) == 0)
  769. return -1;
  770. f->reg[Fsts] |= Fcerr | Ael;
  771. for(i = 0; i < 10; i++){
  772. if((s&Scip) == 0)
  773. return 0;
  774. delay(1);
  775. s = f->reg[Fsts];
  776. }
  777. return -1;
  778. }
  779. static int
  780. fread(Ctlr *c, Flash *f, int ladr)
  781. {
  782. uint16_t s;
  783. delay(1);
  784. if(fcycle(c, f) == -1)
  785. return -1;
  786. f->reg[Fsts] |= Fdone;
  787. f->reg32[Faddr] = ladr;
  788. /* setup flash control register */
  789. s = f->reg[Fctl];
  790. s &= ~(0x1f << 8);
  791. s |= (2-1) << 8; /* 2 bytes */
  792. s &= ~(2*Flcycle); /* read */
  793. f->reg[Fctl] = s | Fgo;
  794. while((f->reg[Fsts] & Fdone) == 0)
  795. ;
  796. if(f->reg[Fsts] & (Fcerr|Ael))
  797. return -1;
  798. return f->reg32[Fdata] & 0xffff;
  799. }
  800. static int
  801. fload(Ctlr *c)
  802. {
  803. uint32_t data, io, r, adr;
  804. uint16_t sum;
  805. Flash f;
  806. Pcidev *p;
  807. // io = c->pcidev->mem[1].bar & ~0x0f;
  808. // f.reg = vmap(io, c->pcidev->mem[1].size);
  809. // if(f.reg == nil)
  810. // return -1;
  811. p = c->pcidev;
  812. io = upamalloc(p->mem[1].bar & ~0x0F, p->mem[1].size, 0);
  813. if(io == 0){
  814. print("igbepcie: can't map flash @ 0x%8.8lux\n", p->mem[1].bar);
  815. return -1;
  816. }
  817. f.reg = KADDR(io);
  818. f.reg32 = (uint32_t*)f.reg;
  819. f.sz = f.reg32[Bfpr];
  820. r = f.sz & 0x1fff;
  821. if(csr32r(c, Eec) & (1<<22))
  822. ++r;
  823. r <<= 12;
  824. sum = 0;
  825. for (adr = 0; adr < 0x40; adr++) {
  826. data = fread(c, &f, r + adr*2);
  827. if(data == -1)
  828. break;
  829. c->eeprom[adr] = data;
  830. sum += data;
  831. }
  832. // vunmap(f.reg, c->pcidev->mem[1].size);
  833. return sum;
  834. }
  835. static int
  836. i82563reset(Ctlr* ctlr)
  837. {
  838. int i, r;
  839. detach(ctlr);
  840. if(ctlr->type == i82566 || ctlr->type == i82567)
  841. r = fload(ctlr);
  842. else
  843. r = eeload(ctlr);
  844. if (r != 0 && r != 0xBABA){
  845. print("%s: bad EEPROM checksum - 0x%4.4ux\n",
  846. tname[ctlr->type], r);
  847. return -1;
  848. }
  849. for(i = Ea; i < Eaddrlen/2; i++){
  850. ctlr->ra[2*i] = ctlr->eeprom[i];
  851. ctlr->ra[2*i+1] = ctlr->eeprom[i]>>8;
  852. }
  853. r = (csr32r(ctlr, Status) & Lanid) >> 2;
  854. ctlr->ra[5] += r; /* ea ctlr[1] = ea ctlr[0]+1 */
  855. r = ctlr->ra[3]<<24 | ctlr->ra[2]<<16 | ctlr->ra[1]<<8 | ctlr->ra[0];
  856. csr32w(ctlr, Ral, r);
  857. r = 0x80000000 | ctlr->ra[5]<<8 | ctlr->ra[4];
  858. csr32w(ctlr, Rah, r);
  859. for(i = 1; i < 16; i++){
  860. csr32w(ctlr, Ral+i*8, 0);
  861. csr32w(ctlr, Rah+i*8, 0);
  862. }
  863. for(i = 0; i < 128; i++)
  864. csr32w(ctlr, Mta+i*4, 0);
  865. csr32w(ctlr, Fcal, 0x00C28001);
  866. csr32w(ctlr, Fcah, 0x00000100);
  867. csr32w(ctlr, Fct, 0x00008808);
  868. csr32w(ctlr, Fcttv, 0x00000100);
  869. csr32w(ctlr, Fcrtl, ctlr->fcrtl);
  870. csr32w(ctlr, Fcrth, ctlr->fcrth);
  871. ilock(&ctlr->imlock);
  872. csr32w(ctlr, Imc, ~0);
  873. ctlr->im = 0; /* was = Lsc, which hangs some controllers */
  874. csr32w(ctlr, Ims, ctlr->im);
  875. iunlock(&ctlr->imlock);
  876. return 0;
  877. }
  878. static void
  879. i82563pci(void)
  880. {
  881. int port, type, cls;
  882. Pcidev *p;
  883. Ctlr *ctlr;
  884. static int first = 1;
  885. if (first)
  886. first = 0;
  887. else
  888. return;
  889. p = nil;
  890. while(p = pcimatch(p, 0x8086, 0)){
  891. if(p->ccrb != 0x02 || p->ccru != 0)
  892. continue;
  893. //print("i82563pci: did %4.4#x\n", p->did);
  894. switch(p->did){
  895. case 0x1096:
  896. case 0x10ba:
  897. type = i82563;
  898. break;
  899. case 0x1049: /* mm */
  900. case 0x104a: /* dm */
  901. case 0x104b: /* dc */
  902. case 0x104d: /* mc */
  903. case 0x10bd: /* dm */
  904. case 0x294c: /* dc-2 */
  905. type = i82566;
  906. break;
  907. case 0x10cd: /* lf */
  908. case 0x10ce: /* v-2 */
  909. case 0x10de: /* lm-3 */
  910. case 0x10f5: /* lm-2 */
  911. type = i82567;
  912. break;
  913. case 0x10a4:
  914. case 0x105e:
  915. type = i82571;
  916. break;
  917. case 0x10b9: /* sic, 82572gi */
  918. case 0x107d:
  919. type = i82572;
  920. break;
  921. case 0x108b: /* v */
  922. case 0x108c: /* e (iamt) */
  923. case 0x109a: /* l */
  924. type = i82573;
  925. break;
  926. // case 0x10d3: /* l */
  927. // type = i82574; /* never heard of it */
  928. // break;
  929. case 0x10a7: /* 82575eb */
  930. type = i82575;
  931. break;
  932. case 0x10c9: /* 82576 copper */
  933. case 0x10e6: /* 82576 fiber */
  934. case 0x10e7: /* 82576 serdes */
  935. type = i82576;
  936. break;
  937. default:
  938. continue;
  939. }
  940. port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
  941. if(port == 0){
  942. print("%s: can't map %d @ 0x%8.8lux\n", tname[type],
  943. p->mem[0].size, p->mem[0].bar);
  944. continue;
  945. }
  946. if(p->pcr & MemWrInv){
  947. cls = pcicfgr8(p, PciCLS) * 4;
  948. if(cls != CACHELINESZ)
  949. pcicfgw8(p, PciCLS, CACHELINESZ/4);
  950. }
  951. cls = pcicfgr8(p, PciCLS);
  952. switch(cls){
  953. default:
  954. print("%s: unexpected CLS - %d bytes\n",
  955. tname[type], cls*sizeof(int32_t));
  956. break;
  957. case 0x00:
  958. case 0xFF:
  959. /* alphapc 164lx returns 0 */
  960. print("%s: unusable PciCLS: %d, using %d longs\n",
  961. tname[type], cls, CACHELINESZ/sizeof(int32_t));
  962. cls = CACHELINESZ/sizeof(int32_t);
  963. pcicfgw8(p, PciCLS, cls);
  964. break;
  965. case 0x08:
  966. case 0x10:
  967. break;
  968. }
  969. ctlr = malloc(sizeof(Ctlr));
  970. ctlr->port = port;
  971. ctlr->pcidev = p;
  972. ctlr->cls = cls*4;
  973. ctlr->type = type;
  974. ctlr->nic = KADDR(ctlr->port);
  975. if(i82563reset(ctlr)){
  976. free(ctlr);
  977. continue;
  978. }
  979. pcisetbme(p);
  980. if(ctlrhead != nil)
  981. ctlrtail->next = ctlr;
  982. else
  983. ctlrhead = ctlr;
  984. ctlrtail = ctlr;
  985. }
  986. }
  987. static uint8_t nilea[Eaddrlen];
  988. int
  989. i82563pnp(Ether* edev)
  990. {
  991. Ctlr *ctlr;
  992. if(ctlrhead == nil)
  993. i82563pci();
  994. /*
  995. * Any adapter matches if no edev->port is supplied,
  996. * otherwise the ports must match.
  997. */
  998. for(ctlr = ctlrhead; ctlr != nil; ctlr = ctlr->next){
  999. if(ctlr->active)
  1000. continue;
  1001. if(edev->port == 0 || edev->port == ctlr->port){
  1002. ctlr->active = 1;
  1003. break;
  1004. }
  1005. }
  1006. if(ctlr == nil)
  1007. return -1;
  1008. edev->ctlr = ctlr;
  1009. edev->port = ctlr->port;
  1010. edev->irq = ctlr->pcidev->intl;
  1011. edev->tbdf = ctlr->pcidev->tbdf;
  1012. // edev->mbps = 1000;
  1013. if(memcmp(edev->ea, nilea, Eaddrlen) == 0)
  1014. memmove(edev->ea, ctlr->ra, Eaddrlen);
  1015. i82563init(edev);
  1016. /*
  1017. * Linkage to the generic ethernet driver.
  1018. */
  1019. edev->attach = i82563attach;
  1020. edev->transmit = i82563transmit;
  1021. edev->interrupt = i82563interrupt;
  1022. edev->detach = i82563detach;
  1023. /*
  1024. * with the current structure, there is no right place for this.
  1025. * ideally, we recognize the interface, note it's down and move on.
  1026. * currently either we can skip the interface or note it is down,
  1027. * but not both.
  1028. if((csr32r(ctlr, Status)&Lu) == 0){
  1029. print("ether#%d: 82563 (%s): link down\n",
  1030. edev->ctlrno, tname[ctlr->type]);
  1031. return -1;
  1032. }
  1033. */
  1034. return 0;
  1035. }