etherdp83820.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322
  1. /*
  2. * National Semiconductor DP83820 & DP83821
  3. * 10/100/1000 Mb/s Ethernet Network Interface Controller
  4. * (Gig-NIC).
  5. * Driver assumes little-endian and 32-bit host throughout.
  6. */
  7. #ifdef FS
  8. #include "all.h"
  9. #include "io.h"
  10. #include "mem.h"
  11. #include "../ip/ip.h"
  12. #else
  13. #include "u.h"
  14. #include "../port/lib.h"
  15. #include "mem.h"
  16. #include "dat.h"
  17. #include "fns.h"
  18. #include "io.h"
  19. #include "../port/error.h"
  20. #include "../port/netif.h"
  21. #endif /* FS */
  22. #include "etherif.h"
  23. #include "ethermii.h"
  24. #include "compat.h"
  25. enum { /* Registers */
  26. Cr = 0x00, /* Command */
  27. Cfg = 0x04, /* Configuration and Media Status */
  28. Mear = 0x08, /* MII/EEPROM Access */
  29. Ptscr = 0x0C, /* PCI Test Control */
  30. Isr = 0x10, /* Interrupt Status */
  31. Imr = 0x14, /* Interrupt Mask */
  32. Ier = 0x18, /* Interrupt Enable */
  33. Ihr = 0x1C, /* Interrupt Holdoff */
  34. Txdp = 0x20, /* Transmit Descriptor Pointer */
  35. Txdphi = 0x24, /* Transmit Descriptor Pointer Hi */
  36. Txcfg = 0x28, /* Transmit Configuration */
  37. Gpior = 0x2C, /* General Purpose I/O Control */
  38. Rxdp = 0x30, /* Receive Descriptor Pointer */
  39. Rxdphi = 0x34, /* Receive Descriptor Pointer Hi */
  40. Rxcfg = 0x38, /* Receive Configuration */
  41. Pqcr = 0x3C, /* Priority Queueing Control */
  42. Wcsr = 0x40, /* Wake on LAN Control/Status */
  43. Pcr = 0x44, /* Pause Control/Status */
  44. Rfcr = 0x48, /* Receive Filter/Match Control */
  45. Rfdr = 0x4C, /* Receive Filter/Match Data */
  46. Brar = 0x50, /* Boot ROM Address */
  47. Brdr = 0x54, /* Boot ROM Data */
  48. Srr = 0x58, /* Silicon Revision */
  49. Mibc = 0x5C, /* MIB Control */
  50. Mibd = 0x60, /* MIB Data */
  51. Txdp1 = 0xA0, /* Txdp Priority 1 */
  52. Txdp2 = 0xA4, /* Txdp Priority 2 */
  53. Txdp3 = 0xA8, /* Txdp Priority 3 */
  54. Rxdp1 = 0xB0, /* Rxdp Priority 1 */
  55. Rxdp2 = 0xB4, /* Rxdp Priority 2 */
  56. Rxdp3 = 0xB8, /* Rxdp Priority 3 */
  57. Vrcr = 0xBC, /* VLAN/IP Receive Control */
  58. Vtcr = 0xC0, /* VLAN/IP Transmit Control */
  59. Vdr = 0xC4, /* VLAN Data */
  60. Ccsr = 0xCC, /* Clockrun Control/Status */
  61. Tbicr = 0xE0, /* TBI Control */
  62. Tbisr = 0xE4, /* TBI Status */
  63. Tanar = 0xE8, /* TBI ANAR */
  64. Tanlpar = 0xEC, /* TBI ANLPAR */
  65. Taner = 0xF0, /* TBI ANER */
  66. Tesr = 0xF4, /* TBI ESR */
  67. };
  68. enum { /* Cr */
  69. Txe = 0x00000001, /* Transmit Enable */
  70. Txd = 0x00000002, /* Transmit Disable */
  71. Rxe = 0x00000004, /* Receiver Enable */
  72. Rxd = 0x00000008, /* Receiver Disable */
  73. Txr = 0x00000010, /* Transmitter Reset */
  74. Rxr = 0x00000020, /* Receiver Reset */
  75. Swien = 0x00000080, /* Software Interrupt Enable */
  76. Rst = 0x00000100, /* Reset */
  77. TxpriSHFT = 9, /* Tx Priority Queue Select */
  78. TxpriMASK = 0x00001E00,
  79. RxpriSHFT = 13, /* Rx Priority Queue Select */
  80. RxpriMASK = 0x0001E000,
  81. };
  82. enum { /* Configuration and Media Status */
  83. Bem = 0x00000001, /* Big Endian Mode */
  84. Ext125 = 0x00000002, /* External 125MHz reference Select */
  85. Bromdis = 0x00000004, /* Disable Boot ROM interface */
  86. Pesel = 0x00000008, /* Parity Error Detection Action */
  87. Exd = 0x00000010, /* Excessive Deferral Abort */
  88. Pow = 0x00000020, /* Program Out of Window Timer */
  89. Sb = 0x00000040, /* Single Back-off */
  90. Reqalg = 0x00000080, /* PCI Bus Request Algorithm */
  91. Extstsen = 0x00000100, /* Extended Status Enable */
  92. Phydis = 0x00000200, /* Disable PHY */
  93. Phyrst = 0x00000400, /* Reset PHY */
  94. M64addren = 0x00000800, /* Master 64-bit Addressing Enable */
  95. Data64en = 0x00001000, /* 64-bit Data Enable */
  96. Pci64det = 0x00002000, /* PCI 64-bit Bus Detected */
  97. T64addren = 0x00004000, /* Target 64-bit Addressing Enable */
  98. Mwidis = 0x00008000, /* MWI Disable */
  99. Mrmdis = 0x00010000, /* MRM Disable */
  100. Tmrtest = 0x00020000, /* Timer Test Mode */
  101. Spdstsien = 0x00040000, /* PHY Spdsts Interrupt Enable */
  102. Lnkstsien = 0x00080000, /* PHY Lnksts Interrupt Enable */
  103. Dupstsien = 0x00100000, /* PHY Dupsts Interrupt Enable */
  104. Mode1000 = 0x00400000, /* 1000Mb/s Mode Control */
  105. Tbien = 0x01000000, /* Ten-Bit Interface Enable */
  106. Dupsts = 0x10000000, /* Full Duplex Status */
  107. Spdsts100 = 0x20000000, /* SPEED100 Input Pin Status */
  108. Spdsts1000 = 0x40000000, /* SPEED1000 Input Pin Status */
  109. Lnksts = 0x80000000, /* Link Status */
  110. };
  111. enum { /* MII/EEPROM Access */
  112. Eedi = 0x00000001, /* EEPROM Data In */
  113. Eedo = 0x00000002, /* EEPROM Data Out */
  114. Eeclk = 0x00000004, /* EEPROM Serial Clock */
  115. Eesel = 0x00000008, /* EEPROM Chip Select */
  116. Mdio = 0x00000010, /* MII Management Data */
  117. Mddir = 0x00000020, /* MII Management Direction */
  118. Mdc = 0x00000040, /* MII Management Clock */
  119. };
  120. enum { /* Interrupts */
  121. Rxok = 0x00000001, /* Rx OK */
  122. Rxdesc = 0x00000002, /* Rx Descriptor */
  123. Rxerr = 0x00000004, /* Rx Packet Error */
  124. Rxearly = 0x00000008, /* Rx Early Threshold */
  125. Rxidle = 0x00000010, /* Rx Idle */
  126. Rxorn = 0x00000020, /* Rx Overrun */
  127. Txok = 0x00000040, /* Tx Packet OK */
  128. Txdesc = 0x00000080, /* Tx Descriptor */
  129. Txerr = 0x00000100, /* Tx Packet Error */
  130. Txidle = 0x00000200, /* Tx Idle */
  131. Txurn = 0x00000400, /* Tx Underrun */
  132. Mib = 0x00000800, /* MIB Service */
  133. Swi = 0x00001000, /* Software Interrupt */
  134. Pme = 0x00002000, /* Power Management Event */
  135. Phy = 0x00004000, /* PHY Interrupt */
  136. Hibint = 0x00008000, /* High Bits Interrupt Set */
  137. Rxsovr = 0x00010000, /* Rx Status FIFO Overrun */
  138. Rtabt = 0x00020000, /* Received Target Abort */
  139. Rmabt = 0x00040000, /* Received Master Abort */
  140. Sserr = 0x00080000, /* Signalled System Error */
  141. Dperr = 0x00100000, /* Detected Parity Error */
  142. Rxrcmp = 0x00200000, /* Receive Reset Complete */
  143. Txrcmp = 0x00400000, /* Transmit Reset Complete */
  144. Rxdesc0 = 0x00800000, /* Rx Descriptor for Priority Queue 0 */
  145. Rxdesc1 = 0x01000000, /* Rx Descriptor for Priority Queue 1 */
  146. Rxdesc2 = 0x02000000, /* Rx Descriptor for Priority Queue 2 */
  147. Rxdesc3 = 0x04000000, /* Rx Descriptor for Priority Queue 3 */
  148. Txdesc0 = 0x08000000, /* Tx Descriptor for Priority Queue 0 */
  149. Txdesc1 = 0x10000000, /* Tx Descriptor for Priority Queue 1 */
  150. Txdesc2 = 0x20000000, /* Tx Descriptor for Priority Queue 2 */
  151. Txdesc3 = 0x40000000, /* Tx Descriptor for Priority Queue 3 */
  152. };
  153. enum { /* Interrupt Enable */
  154. Ien = 0x00000001, /* Interrupt Enable */
  155. };
  156. enum { /* Interrupt Holdoff */
  157. IhSHFT = 0, /* Interrupt Holdoff */
  158. IhMASK = 0x000000FF,
  159. Ihctl = 0x00000100, /* Interrupt Holdoff Control */
  160. };
  161. enum { /* Transmit Configuration */
  162. TxdrthSHFT = 0, /* Tx Drain Threshold */
  163. TxdrthMASK = 0x000000FF,
  164. FlthSHFT = 16, /* Tx Fill Threshold */
  165. FlthMASK = 0x0000FF00,
  166. Brstdis = 0x00080000, /* 1000Mb/s Burst Disable */
  167. MxdmaSHFT = 20, /* Max Size per Tx DMA Burst */
  168. MxdmaMASK = 0x00700000,
  169. Ecretryen = 0x00800000, /* Excessive Collision Retry Enable */
  170. Atp = 0x10000000, /* Automatic Transmit Padding */
  171. Mlb = 0x20000000, /* MAC Loopback */
  172. Hbi = 0x40000000, /* Heartbeat Ignore */
  173. Csi = 0x80000000, /* Carrier Sense Ignore */
  174. };
  175. enum { /* Receive Configuration */
  176. RxdrthSHFT = 1, /* Rx Drain Threshold */
  177. RxdrthMASK = 0x0000003E,
  178. Airl = 0x04000000, /* Accept In-Range Length Errored */
  179. Alp = 0x08000000, /* Accept Long Packets */
  180. Rxfd = 0x10000000, /* Receive Full Duplex */
  181. Stripcrc = 0x20000000, /* Strip CRC */
  182. Arp = 0x40000000, /* Accept Runt Packets */
  183. Aep = 0x80000000, /* Accept Errored Packets */
  184. };
  185. enum { /* Priority Queueing Control */
  186. Txpqen = 0x00000001, /* Transmit Priority Queuing Enable */
  187. Txfairen = 0x00000002, /* Transmit Fairness Enable */
  188. RxpqenSHFT = 2, /* Receive Priority Queue Enable */
  189. RxpqenMASK = 0x0000000C,
  190. };
  191. enum { /* Pause Control/Status */
  192. PscntSHFT = 0, /* Pause Counter Value */
  193. PscntMASK = 0x0000FFFF,
  194. Pstx = 0x00020000, /* Transmit Pause Frame */
  195. PsffloSHFT = 18, /* Rx Data FIFO Lo Threshold */
  196. PsffloMASK = 0x000C0000,
  197. PsffhiSHFT = 20, /* Rx Data FIFO Hi Threshold */
  198. PsffhiMASK = 0x00300000,
  199. PsstloSHFT = 22, /* Rx Stat FIFO Hi Threshold */
  200. PsstloMASK = 0x00C00000,
  201. PssthiSHFT = 24, /* Rx Stat FIFO Hi Threshold */
  202. PssthiMASK = 0x03000000,
  203. Psrcvd = 0x08000000, /* Pause Frame Received */
  204. Psact = 0x10000000, /* Pause Active */
  205. Psda = 0x20000000, /* Pause on Destination Address */
  206. Psmcast = 0x40000000, /* Pause on Multicast */
  207. Psen = 0x80000000, /* Pause Enable */
  208. };
  209. enum { /* Receive Filter/Match Control */
  210. RfaddrSHFT = 0, /* Extended Register Address */
  211. RfaddrMASK = 0x000003FF,
  212. Ulm = 0x00080000, /* U/L bit mask */
  213. Uhen = 0x00100000, /* Unicast Hash Enable */
  214. Mhen = 0x00200000, /* Multicast Hash Enable */
  215. Aarp = 0x00400000, /* Accept ARP Packets */
  216. ApatSHFT = 23, /* Accept on Pattern Match */
  217. ApatMASK = 0x07800000,
  218. Apm = 0x08000000, /* Accept on Perfect Match */
  219. Aau = 0x10000000, /* Accept All Unicast */
  220. Aam = 0x20000000, /* Accept All Multicast */
  221. Aab = 0x40000000, /* Accept All Broadcast */
  222. Rfen = 0x80000000, /* Rx Filter Enable */
  223. };
  224. enum { /* Receive Filter/Match Data */
  225. RfdataSHFT = 0, /* Receive Filter Data */
  226. RfdataMASK = 0x0000FFFF,
  227. BmaskSHFT = 16, /* Byte Mask */
  228. BmaskMASK = 0x00030000,
  229. };
  230. enum { /* MIB Control */
  231. Wrn = 0x00000001, /* Warning Test Indicator */
  232. Frz = 0x00000002, /* Freeze All Counters */
  233. Aclr = 0x00000004, /* Clear All Counters */
  234. Mibs = 0x00000008, /* MIB Counter Strobe */
  235. };
  236. enum { /* MIB Data */
  237. Nmibd = 11, /* Number of MIB Data Registers */
  238. };
  239. enum { /* VLAN/IP Receive Control */
  240. Vtden = 0x00000001, /* VLAN Tag Detection Enable */
  241. Vtren = 0x00000002, /* VLAN Tag Removal Enable */
  242. Dvtf = 0x00000004, /* Discard VLAN Tagged Frames */
  243. Dutf = 0x00000008, /* Discard Untagged Frames */
  244. Ipen = 0x00000010, /* IP Checksum Enable */
  245. Ripe = 0x00000020, /* Reject IP Checksum Errors */
  246. Rtcpe = 0x00000040, /* Reject TCP Checksum Errors */
  247. Rudpe = 0x00000080, /* Reject UDP Checksum Errors */
  248. };
  249. enum { /* VLAN/IP Transmit Control */
  250. Vgti = 0x00000001, /* VLAN Global Tag Insertion */
  251. Vppti = 0x00000002, /* VLAN Per-Packet Tag Insertion */
  252. Gchk = 0x00000004, /* Global Checksum Generation */
  253. Ppchk = 0x00000008, /* Per-Packet Checksum Generation */
  254. };
  255. enum { /* VLAN Data */
  256. VtypeSHFT = 0, /* VLAN Type Field */
  257. VtypeMASK = 0x0000FFFF,
  258. VtciSHFT = 16, /* VLAN Tag Control Information */
  259. VtciMASK = 0xFFFF0000,
  260. };
  261. enum { /* Clockrun Control/Status */
  262. Clkrunen = 0x00000001, /* CLKRUN Enable */
  263. Pmeen = 0x00000100, /* PME Enable */
  264. Pmests = 0x00008000, /* PME Status */
  265. };
  266. typedef struct {
  267. u32int link; /* Link to the next descriptor */
  268. u32int bufptr; /* pointer to data Buffer */
  269. int cmdsts; /* Command/Status */
  270. int extsts; /* optional Extended Status */
  271. Block* bp; /* Block containing bufptr */
  272. u32int unused; /* pad to 64-bit */
  273. } Desc;
  274. enum { /* Common cmdsts bits */
  275. SizeMASK = 0x0000FFFF, /* Descriptor Byte Count */
  276. SizeSHFT = 0,
  277. Ok = 0x08000000, /* Packet OK */
  278. Crc = 0x10000000, /* Suppress/Include CRC */
  279. Intr = 0x20000000, /* Interrupt on ownership transfer */
  280. More = 0x40000000, /* not last descriptor in a packet */
  281. Own = 0x80000000, /* Descriptor Ownership */
  282. };
  283. enum { /* Transmit cmdsts bits */
  284. CcntMASK = 0x000F0000, /* Collision Count */
  285. CcntSHFT = 16,
  286. Ec = 0x00100000, /* Excessive Collisions */
  287. Owc = 0x00200000, /* Out of Window Collision */
  288. Ed = 0x00400000, /* Excessive Deferral */
  289. Td = 0x00800000, /* Transmit Deferred */
  290. Crs = 0x01000000, /* Carrier Sense Lost */
  291. Tfu = 0x02000000, /* Transmit FIFO Underrun */
  292. Txa = 0x04000000, /* Transmit Abort */
  293. };
  294. enum { /* Receive cmdsts bits */
  295. Irl = 0x00010000, /* In-Range Length Error */
  296. Lbp = 0x00020000, /* Loopback Packet */
  297. Fae = 0x00040000, /* Frame Alignment Error */
  298. Crce = 0x00080000, /* CRC Error */
  299. Ise = 0x00100000, /* Invalid Symbol Error */
  300. Runt = 0x00200000, /* Runt Packet Received */
  301. Long = 0x00400000, /* Too Long Packet Received */
  302. DestMASK = 0x01800000, /* Destination Class */
  303. DestSHFT = 23,
  304. Rxo = 0x02000000, /* Receive Overrun */
  305. Rxa = 0x04000000, /* Receive Aborted */
  306. };
  307. enum { /* extsts bits */
  308. EvtciMASK = 0x0000FFFF, /* VLAN Tag Control Information */
  309. EvtciSHFT = 0,
  310. Vpkt = 0x00010000, /* VLAN Packet */
  311. /* Ippkt, Udppkt are struct types in the fs kernel */
  312. Ippacket = 0x00020000, /* IP Packet */
  313. Iperr = 0x00040000, /* IP Checksum Error */
  314. Tcppkt = 0x00080000, /* TCP Packet */
  315. Tcperr = 0x00100000, /* TCP Checksum Error */
  316. Udppacket = 0x00200000, /* UDP Packet */
  317. Udperr = 0x00400000, /* UDP Checksum Error */
  318. };
  319. /*
  320. * adjust these, keeping in mind that at 1Gb/s, a 1514-byte packet is
  321. * sent or received in 12µs. Ignoring mandatory inter-packet gaps,
  322. * a ring of 32 buffers will take 388µs to fill or empty; 64 buffers
  323. * will take 775µs; 256 will take 3.1ms.
  324. */
  325. enum {
  326. Nrd = 64, // was 64 then 450
  327. Nrb = 4*Nrd,
  328. Rbsz = ROUNDUP(sizeof(Etherpkt)+8, 8),
  329. Ntd = Nrd, // was 32 then 450
  330. };
  331. typedef struct Ctlr Ctlr;
  332. typedef struct Ctlr {
  333. int port;
  334. Pcidev* pcidev;
  335. Ctlr* next;
  336. int active;
  337. int id;
  338. int eepromsz; /* address size in bits */
  339. ushort* eeprom;
  340. int* nic;
  341. int cfg;
  342. int imr;
  343. QLock alock; /* attach */
  344. Lock ilock; /* init */
  345. void* alloc; /* base of per-Ctlr allocated data */
  346. Mii* mii;
  347. Lock rdlock; /* receive */
  348. Desc* rd;
  349. int nrd;
  350. int nrb;
  351. int rdx;
  352. int rxcfg;
  353. Lock tlock; /* transmit */
  354. Desc* td;
  355. int ntd;
  356. int tdh;
  357. int tdt;
  358. int ntq;
  359. int txcfg;
  360. int rxidle;
  361. uint mibd[Nmibd];
  362. int ec;
  363. int owc;
  364. int ed;
  365. int crs;
  366. int tfu;
  367. int txa;
  368. } Ctlr;
  369. #define csr32r(c, r) (*((c)->nic+((r)/4)))
  370. #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))
  371. static Ctlr* dp83820ctlrhead;
  372. static Ctlr* dp83820ctlrtail;
  373. static Lock dp83820rblock; /* free receive Blocks */
  374. static Block* dp83820rbpool;
  375. static char* dp83820mibs[Nmibd] = {
  376. "RXErroredPkts",
  377. "RXFCSErrors",
  378. "RXMsdPktErrors",
  379. "RXFAErrors",
  380. "RXSymbolErrors",
  381. "RXFrameToLong",
  382. "RXIRLErrors",
  383. "RXBadOpcodes",
  384. "RXPauseFrames",
  385. "TXPauseFrames",
  386. "TXSQEErrors",
  387. };
  388. static int
  389. mdior(Ctlr* ctlr, int n)
  390. {
  391. int data, i, mear, r;
  392. mear = csr32r(ctlr, Mear);
  393. r = ~(Mdc|Mddir) & mear;
  394. data = 0;
  395. for(i = n-1; i >= 0; i--){
  396. if(csr32r(ctlr, Mear) & Mdio)
  397. data |= (1<<i);
  398. csr32w(ctlr, Mear, Mdc|r);
  399. csr32w(ctlr, Mear, r);
  400. }
  401. csr32w(ctlr, Mear, mear);
  402. return data;
  403. }
  404. static void
  405. mdiow(Ctlr* ctlr, int bits, int n)
  406. {
  407. int i, mear, r;
  408. mear = csr32r(ctlr, Mear);
  409. r = Mddir|(~Mdc & mear);
  410. for(i = n-1; i >= 0; i--){
  411. if(bits & (1<<i))
  412. r |= Mdio;
  413. else
  414. r &= ~Mdio;
  415. csr32w(ctlr, Mear, r);
  416. csr32w(ctlr, Mear, Mdc|r);
  417. }
  418. csr32w(ctlr, Mear, mear);
  419. }
  420. static int
  421. dp83820miimir(Mii* mii, int pa, int ra)
  422. {
  423. int data;
  424. Ctlr *ctlr;
  425. ctlr = mii->ctlr;
  426. /*
  427. * MII Management Interface Read.
  428. *
  429. * Preamble;
  430. * ST+OP+PA+RA;
  431. * LT + 16 data bits.
  432. */
  433. mdiow(ctlr, 0xFFFFFFFF, 32);
  434. mdiow(ctlr, 0x1800|(pa<<5)|ra, 14);
  435. data = mdior(ctlr, 18);
  436. if(data & 0x10000)
  437. return -1;
  438. return data & 0xFFFF;
  439. }
  440. static int
  441. dp83820miimiw(Mii* mii, int pa, int ra, int data)
  442. {
  443. Ctlr *ctlr;
  444. ctlr = mii->ctlr;
  445. /*
  446. * MII Management Interface Write.
  447. *
  448. * Preamble;
  449. * ST+OP+PA+RA+LT + 16 data bits;
  450. * Z.
  451. */
  452. mdiow(ctlr, 0xFFFFFFFF, 32);
  453. data &= 0xFFFF;
  454. data |= (0x05<<(5+5+2+16))|(pa<<(5+2+16))|(ra<<(2+16))|(0x02<<16);
  455. mdiow(ctlr, data, 32);
  456. return data & 0xFFFF; /* TODO: what's the caller expect here? */
  457. }
  458. /*
  459. * return free Block+buffer ready for input of up to MTU bytes.
  460. * desc->bp is also set to the return value.
  461. */
  462. static Block *
  463. dp83820rballoc(Desc* desc)
  464. {
  465. Block *bp;
  466. if(desc->bp == nil){
  467. ilock(&dp83820rblock);
  468. if((bp = dp83820rbpool) == nil){
  469. iunlock(&dp83820rblock);
  470. desc->bp = nil;
  471. desc->cmdsts = Own;
  472. iprint("dp83820rballoc: out of buffers\n");
  473. return nil;
  474. }
  475. dp83820rbpool = bp->next;
  476. bp->next = nil;
  477. iunlock(&dp83820rblock);
  478. desc->bufptr = PCIWADDR(bp->rp);
  479. desc->bp = bp;
  480. }
  481. else{
  482. bp = desc->bp;
  483. BLKRESET(bp);
  484. }
  485. coherence();
  486. desc->cmdsts = Intr|Rbsz;
  487. return bp;
  488. }
  489. /* should be called via freeb() */
  490. static void
  491. dp83820rbfree(Block *bp)
  492. {
  493. BLKRESET(bp);
  494. ilock(&dp83820rblock);
  495. bp->next = dp83820rbpool;
  496. dp83820rbpool = bp;
  497. iunlock(&dp83820rblock);
  498. }
  499. static void
  500. dp83820halt(Ctlr* ctlr)
  501. {
  502. int i, timeo;
  503. ilock(&ctlr->ilock);
  504. csr32w(ctlr, Imr, 0);
  505. csr32w(ctlr, Ier, 0);
  506. csr32w(ctlr, Cr, Rxd|Txd);
  507. for(timeo = 0; timeo < 1000; timeo++){
  508. if(!(csr32r(ctlr, Cr) & (Rxe|Txe)))
  509. break;
  510. microdelay(1);
  511. }
  512. csr32w(ctlr, Mibc, Frz);
  513. iunlock(&ctlr->ilock);
  514. if(ctlr->rd != nil){
  515. for(i = 0; i < ctlr->nrd; i++){
  516. if(ctlr->rd[i].bp == nil)
  517. continue;
  518. freeb(ctlr->rd[i].bp);
  519. ctlr->rd[i].bp = nil;
  520. }
  521. }
  522. if(ctlr->td != nil){
  523. for(i = 0; i < ctlr->ntd; i++){
  524. if(ctlr->td[i].bp == nil)
  525. continue;
  526. freeb(ctlr->td[i].bp);
  527. ctlr->td[i].bp = nil;
  528. }
  529. }
  530. }
  531. static void
  532. dp83820cfg(Ctlr* ctlr)
  533. {
  534. int cfg;
  535. /*
  536. * Don't know how to deal with a TBI yet.
  537. */
  538. if(ctlr->mii == nil) {
  539. iprint("83820: got tbi, not phy\n");
  540. return;
  541. }
  542. /*
  543. * The polarity of these bits is at the mercy
  544. * of the board designer.
  545. * The correct answer for all speed and duplex questions
  546. * should be to query the phy.
  547. */
  548. cfg = csr32r(ctlr, Cfg);
  549. if(!(cfg & Dupsts)){
  550. ctlr->rxcfg |= Rxfd;
  551. ctlr->txcfg |= Csi|Hbi;
  552. iprint("83820: full duplex, ");
  553. }
  554. else{
  555. ctlr->rxcfg &= ~Rxfd;
  556. ctlr->txcfg &= ~(Csi|Hbi);
  557. iprint("83820: half duplex, ");
  558. }
  559. csr32w(ctlr, Rxcfg, ctlr->rxcfg);
  560. csr32w(ctlr, Txcfg, ctlr->txcfg);
  561. switch(cfg & (Spdsts1000|Spdsts100)){
  562. case Spdsts1000: /* 100Mbps */
  563. default: /* 10Mbps */
  564. ctlr->cfg &= ~Mode1000;
  565. if ((cfg & (Spdsts1000|Spdsts100)) == Spdsts1000)
  566. iprint("100Mb/s\n");
  567. else
  568. iprint("10Mb/s\n");
  569. break;
  570. case Spdsts100: /* 1Gbps */
  571. ctlr->cfg |= Mode1000;
  572. iprint("1Gb/s\n");
  573. break;
  574. }
  575. csr32w(ctlr, Cfg, ctlr->cfg);
  576. }
  577. static void
  578. dp83820init(Ether* edev)
  579. {
  580. int i;
  581. Ctlr *ctlr;
  582. Desc *desc;
  583. uchar *alloc;
  584. ctlr = edev->ctlr;
  585. dp83820halt(ctlr);
  586. /*
  587. * Receiver
  588. */
  589. alloc = (uchar*)ROUNDUP((ulong)ctlr->alloc, 8);
  590. ctlr->rd = (Desc*)alloc;
  591. alloc += ctlr->nrd*sizeof(Desc);
  592. memset(ctlr->rd, 0, ctlr->nrd*sizeof(Desc));
  593. ctlr->rdx = 0;
  594. for(i = 0; i < ctlr->nrd; i++){
  595. desc = &ctlr->rd[i];
  596. desc->link = PCIWADDR(&ctlr->rd[NEXT(i, ctlr->nrd)]);
  597. if(dp83820rballoc(desc) == nil) {
  598. print("dp83820init: out of buffers\n");
  599. continue;
  600. }
  601. }
  602. csr32w(ctlr, Rxdphi, 0);
  603. csr32w(ctlr, Rxdp, PCIWADDR(ctlr->rd));
  604. for(i = 0; i < Eaddrlen; i += 2){
  605. csr32w(ctlr, Rfcr, i);
  606. csr32w(ctlr, Rfdr, (edev->ea[i+1]<<8)|edev->ea[i]);
  607. }
  608. /* for now, accept all multicast packets */
  609. csr32w(ctlr, Rfcr, Rfen|Aab|Apm|Aam);
  610. ctlr->rxcfg = Stripcrc|(((2*(ETHERMINTU+4))/8)<<RxdrthSHFT);
  611. ctlr->imr |= Rxorn|Rxidle|Rxearly|Rxdesc|Rxok;
  612. /*
  613. * Transmitter.
  614. */
  615. ctlr->td = (Desc*)alloc;
  616. memset(ctlr->td, 0, ctlr->ntd*sizeof(Desc));
  617. ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
  618. for(i = 0; i < ctlr->ntd; i++){
  619. desc = &ctlr->td[i];
  620. desc->link = PCIWADDR(&ctlr->td[NEXT(i, ctlr->ntd)]);
  621. }
  622. csr32w(ctlr, Txdphi, 0);
  623. csr32w(ctlr, Txdp, PCIWADDR(ctlr->td));
  624. ctlr->txcfg = Atp|(((2*(ETHERMINTU+4))/32)<<FlthSHFT)|((4096/32)<<TxdrthSHFT);
  625. ctlr->imr |= Txurn|Txidle|Txdesc|Txok;
  626. ilock(&ctlr->ilock);
  627. dp83820cfg(ctlr);
  628. csr32w(ctlr, Mibc, Aclr);
  629. ctlr->imr |= Mib;
  630. csr32w(ctlr, Imr, ctlr->imr);
  631. /* try coalescing adjacent interrupts; use hold-off interval of 100µs */
  632. csr32w(ctlr, Ihr, Ihctl|(1<<IhSHFT));
  633. csr32w(ctlr, Ier, Ien);
  634. csr32w(ctlr, Cr, Rxe|Txe);
  635. iunlock(&ctlr->ilock);
  636. }
  637. /* multicast already on, don't need to do anything */
  638. static void
  639. multicast(void*, uchar*, int)
  640. {
  641. }
  642. static void
  643. dp83820attach(Ether* edev)
  644. {
  645. Block *bp;
  646. Ctlr *ctlr;
  647. ctlr = edev->ctlr;
  648. qlock(&ctlr->alock);
  649. if(ctlr->alloc != nil){
  650. qunlock(&ctlr->alock);
  651. return;
  652. }
  653. if(waserror()){
  654. err:
  655. if(ctlr->mii != nil){
  656. free(ctlr->mii);
  657. ctlr->mii = nil;
  658. }
  659. if(ctlr->alloc != nil){
  660. free(ctlr->alloc);
  661. ctlr->alloc = nil;
  662. }
  663. qunlock(&ctlr->alock);
  664. nexterror();
  665. }
  666. if(!(ctlr->cfg & Tbien)){
  667. if((ctlr->mii = malloc(sizeof(Mii))) == nil)
  668. error(Enomem);
  669. ctlr->mii->ctlr = ctlr;
  670. ctlr->mii->mir = dp83820miimir;
  671. ctlr->mii->miw = dp83820miimiw;
  672. if(mii(ctlr->mii, ~0) == 0)
  673. error("no PHY");
  674. ctlr->cfg |= Dupstsien|Lnkstsien|Spdstsien;
  675. ctlr->imr |= Phy;
  676. }
  677. /* allocate all Descs */
  678. ctlr->nrd = Nrd;
  679. ctlr->nrb = Nrb;
  680. ctlr->ntd = Ntd;
  681. ctlr->alloc = mallocz((ctlr->nrd+ctlr->ntd)*sizeof(Desc) + 7, 0);
  682. if(ctlr->alloc == nil)
  683. error(Enomem);
  684. /*
  685. * allocate receive Blocks+buffers, add all to receive Block+buffer pool
  686. */
  687. for(ctlr->nrb = 0; ctlr->nrb < Nrb; ctlr->nrb++){
  688. if((bp = iallocb(Rbsz)) == nil) {
  689. print(
  690. "dp83820attach: iallocb failed with %d rcv bufs allocated\n",
  691. ctlr->nrb);
  692. error(Enomem);
  693. }
  694. #ifdef FS
  695. bp->flags |= Mbrcvbuf;
  696. #endif
  697. bp->free = dp83820rbfree; /* to be called via freeb() */
  698. dp83820rbfree(bp);
  699. }
  700. /* attaches a receive Block+buffer to each receive Desc */
  701. dp83820init(edev);
  702. qunlock(&ctlr->alock);
  703. poperror();
  704. }
  705. static void
  706. dp83820transmit(Ether* edev)
  707. {
  708. Block *bp;
  709. Ctlr *ctlr;
  710. Desc *desc;
  711. int cmdsts, r, x;
  712. ctlr = edev->ctlr;
  713. ilock(&ctlr->tlock);
  714. bp = nil;
  715. for(x = ctlr->tdh; ctlr->ntq; x = NEXT(x, ctlr->ntd)){
  716. desc = &ctlr->td[x];
  717. if((cmdsts = desc->cmdsts) & Own)
  718. break;
  719. if(!(cmdsts & Ok)){
  720. if(cmdsts & Ec)
  721. ctlr->ec++;
  722. if(cmdsts & Owc)
  723. ctlr->owc++;
  724. if(cmdsts & Ed)
  725. ctlr->ed++;
  726. if(cmdsts & Crs)
  727. ctlr->crs++;
  728. if(cmdsts & Tfu)
  729. ctlr->tfu++;
  730. if(cmdsts & Txa)
  731. ctlr->txa++;
  732. #ifndef FS
  733. edev->oerrs++;
  734. #endif
  735. }
  736. desc->bp->next = bp; /* chain transmitted Blocks together */
  737. bp = desc->bp;
  738. desc->bp = nil; /* unlink them from Descs */
  739. ctlr->ntq--;
  740. }
  741. /* free Blocks+buffers comprising the packets just sent */
  742. ctlr->tdh = x;
  743. if(bp != nil)
  744. freeblist(bp);
  745. x = ctlr->tdt;
  746. while(ctlr->ntq < (ctlr->ntd-1)){
  747. bp = etheroq(edev); /* get head of transmit q */
  748. if(bp == nil)
  749. break;
  750. desc = &ctlr->td[x];
  751. desc->bufptr = PCIWADDR(bp->rp);
  752. desc->bp = bp; /* attach to Desc */
  753. ctlr->ntq++;
  754. coherence();
  755. desc->cmdsts = Own|Intr|BLEN(bp); /* fire! */
  756. x = NEXT(x, ctlr->ntd);
  757. }
  758. if (ctlr->ntq >= ctlr->ntd-1)
  759. iprint("83820: xmit q full, Ntd=%d\n", Ntd);
  760. if(x != ctlr->tdt){
  761. ctlr->tdt = x;
  762. r = csr32r(ctlr, Cr);
  763. csr32w(ctlr, Cr, Txe|r);
  764. }
  765. iunlock(&ctlr->tlock);
  766. }
  767. static void
  768. dp83820interrupt(Ureg*, void* arg)
  769. {
  770. Block *bp;
  771. Ctlr *ctlr;
  772. Desc *desc;
  773. Ether *edev;
  774. int cmdsts, i, isr, r, x, rcvd = 0;
  775. edev = arg;
  776. ctlr = edev->ctlr;
  777. for(isr = csr32r(ctlr, Isr); isr & ctlr->imr; isr = csr32r(ctlr, Isr)){
  778. if(isr & (Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok)){
  779. x = ctlr->rdx;
  780. desc = &ctlr->rd[x];
  781. while((cmdsts = desc->cmdsts) & Own){
  782. if((cmdsts & Ok) && desc->bp != nil){
  783. /* unlink rcv. Block from Desc */
  784. bp = desc->bp;
  785. desc->bp = nil;
  786. /* store its length, add to input q */
  787. INCRPTR(bp, desc->cmdsts & SizeMASK);
  788. ETHERIQ(edev, bp, 1);
  789. rcvd++;
  790. }
  791. /* replace rcv. Block just detached from Desc */
  792. if (dp83820rballoc(desc) == nil)
  793. iprint(
  794. "dp83820interrupt: rballoc failed\n");
  795. x = NEXT(x, ctlr->nrd);
  796. desc = &ctlr->rd[x];
  797. }
  798. ctlr->rdx = x;
  799. if (rcvd >= ctlr->nrd-1)
  800. iprint("83820: rcv q full, Nrd=%d\n", Nrd);
  801. if(isr & Rxidle){
  802. /* resume reading packets */
  803. r = csr32r(ctlr, Cr);
  804. csr32w(ctlr, Cr, Rxe|r);
  805. ctlr->rxidle++;
  806. }
  807. isr &= ~(Rxorn|Rxidle|Rxearly|Rxerr|Rxdesc|Rxok);
  808. }
  809. if(isr & Txurn){
  810. x = (ctlr->txcfg & TxdrthMASK)>>TxdrthSHFT;
  811. r = (ctlr->txcfg & FlthMASK)>>FlthSHFT;
  812. if(x < ((TxdrthMASK)>>TxdrthSHFT)
  813. && x < (2048/32 - r)){
  814. ctlr->txcfg &= ~TxdrthMASK;
  815. x++;
  816. ctlr->txcfg |= x<<TxdrthSHFT;
  817. csr32w(ctlr, Txcfg, ctlr->txcfg);
  818. }
  819. }
  820. if(isr & (Txurn|Txidle|Txdesc|Txok)){
  821. /* toss completed packets, q new ones, fire */
  822. dp83820transmit(edev);
  823. isr &= ~(Txurn|Txidle|Txdesc|Txok);
  824. }
  825. if(isr & Mib){
  826. for(i = 0; i < Nmibd; i++){
  827. r = csr32r(ctlr, Mibd+(i*sizeof(int)));
  828. ctlr->mibd[i] += r & 0xFFFF;
  829. }
  830. isr &= ~Mib;
  831. }
  832. if((isr & Phy) && ctlr->mii != nil){
  833. ctlr->mii->mir(ctlr->mii, 1, Bmsr);
  834. print("phy: cfg %8.8ux bmsr %4.4ux\n",
  835. csr32r(ctlr, Cfg),
  836. ctlr->mii->mir(ctlr->mii, 1, Bmsr));
  837. dp83820cfg(ctlr);
  838. isr &= ~Phy;
  839. }
  840. if(isr)
  841. iprint("dp83820: isr %8.8ux\n", isr);
  842. }
  843. }
  844. #ifndef FS
  845. static long
  846. dp83820ifstat(Ether* edev, void* a, long n, ulong offset)
  847. {
  848. char *p;
  849. Ctlr *ctlr;
  850. int i, l, r;
  851. MiiPhy *phy;
  852. ctlr = edev->ctlr;
  853. edev->crcs = ctlr->mibd[1];
  854. edev->frames = ctlr->mibd[3];
  855. edev->buffs = ctlr->mibd[5];
  856. edev->overflows = ctlr->mibd[2];
  857. if(n == 0)
  858. return 0;
  859. p = malloc(READSTR);
  860. l = 0;
  861. for(i = 0; i < Nmibd; i++){
  862. r = csr32r(ctlr, Mibd+(i*sizeof(int)));
  863. ctlr->mibd[i] += r & 0xFFFF;
  864. if(ctlr->mibd[i] != 0 && dp83820mibs[i] != nil)
  865. l += snprint(p+l, READSTR-l, "%s: %ud %ud\n",
  866. dp83820mibs[i], ctlr->mibd[i], r);
  867. }
  868. l += snprint(p+l, READSTR-l, "rxidle %d\n", ctlr->rxidle);
  869. l += snprint(p+l, READSTR-l, "ec %d\n", ctlr->ec);
  870. l += snprint(p+l, READSTR-l, "owc %d\n", ctlr->owc);
  871. l += snprint(p+l, READSTR-l, "ed %d\n", ctlr->ed);
  872. l += snprint(p+l, READSTR-l, "crs %d\n", ctlr->crs);
  873. l += snprint(p+l, READSTR-l, "tfu %d\n", ctlr->tfu);
  874. l += snprint(p+l, READSTR-l, "txa %d\n", ctlr->txa);
  875. l += snprint(p+l, READSTR, "rom:");
  876. for(i = 0; i < 0x10; i++){
  877. if(i && ((i & 0x07) == 0))
  878. l += snprint(p+l, READSTR-l, "\n ");
  879. l += snprint(p+l, READSTR-l, " %4.4uX", ctlr->eeprom[i]);
  880. }
  881. l += snprint(p+l, READSTR-l, "\n");
  882. USED(l);
  883. if(0 && ctlr->mii != nil && (phy = ctlr->mii->curphy) != nil){
  884. l += snprint(p+l, READSTR, "phy:");
  885. for(i = 0; i < NMiiPhyr; i++){
  886. if(i && ((i & 0x07) == 0))
  887. l += snprint(p+l, READSTR-l, "\n ");
  888. /* phy->r no longer exists */
  889. // l += snprint(p+l, READSTR-l, " %4.4uX", phy->r[i]);
  890. }
  891. snprint(p+l, READSTR-l, "\n");
  892. }
  893. n = readstr(offset, a, n, p);
  894. free(p);
  895. return n;
  896. }
  897. #endif /* FS */
  898. static void
  899. dp83820promiscuous(void* arg, int on)
  900. {
  901. USED(arg, on);
  902. }
  903. static int
  904. atc93c46r(Ctlr* ctlr, int address)
  905. {
  906. int data, i, mear, r, size;
  907. /*
  908. * Analog Technology, Inc. ATC93C46
  909. * or equivalent serial EEPROM.
  910. */
  911. mear = csr32r(ctlr, Mear);
  912. mear &= ~(Eesel|Eeclk|Eedo|Eedi);
  913. r = Eesel|mear;
  914. reread:
  915. csr32w(ctlr, Mear, r);
  916. data = 0x06;
  917. for(i = 3-1; i >= 0; i--){
  918. if(data & (1<<i))
  919. r |= Eedi;
  920. else
  921. r &= ~Eedi;
  922. csr32w(ctlr, Mear, r);
  923. csr32w(ctlr, Mear, Eeclk|r);
  924. microdelay(1);
  925. csr32w(ctlr, Mear, r);
  926. microdelay(1);
  927. }
  928. /*
  929. * First time through must work out the EEPROM size.
  930. */
  931. if((size = ctlr->eepromsz) == 0)
  932. size = 8;
  933. for(size = size-1; size >= 0; size--){
  934. if(address & (1<<size))
  935. r |= Eedi;
  936. else
  937. r &= ~Eedi;
  938. csr32w(ctlr, Mear, r);
  939. csr32w(ctlr, Mear, Eeclk|r);
  940. microdelay(1);
  941. csr32w(ctlr, Mear, r);
  942. microdelay(1);
  943. if(!(csr32r(ctlr, Mear) & Eedo))
  944. break;
  945. }
  946. r &= ~Eedi;
  947. data = 0;
  948. for(i = 16-1; i >= 0; i--){
  949. csr32w(ctlr, Mear, Eeclk|r);
  950. microdelay(1);
  951. if(csr32r(ctlr, Mear) & Eedo)
  952. data |= (1<<i);
  953. csr32w(ctlr, Mear, r);
  954. microdelay(1);
  955. }
  956. csr32w(ctlr, Mear, mear);
  957. if(ctlr->eepromsz == 0){
  958. ctlr->eepromsz = 8-size;
  959. ctlr->eeprom = malloc((1<<ctlr->eepromsz)*sizeof(ushort));
  960. goto reread;
  961. }
  962. return data;
  963. }
  964. static void
  965. resetctlr(Ctlr *ctlr)
  966. {
  967. csr32w(ctlr, Cr, Rst);
  968. delay(1);
  969. /* TODO: limit this; don't wait forever */
  970. while(csr32r(ctlr, Cr) & Rst)
  971. delay(1);
  972. atc93c46r(ctlr, 0);
  973. }
  974. static void
  975. shutdown(Ether* ether)
  976. {
  977. Ctlr *ctlr = ether->ctlr;
  978. print("ether83820 shutting down\n");
  979. csr32w(ctlr, Cr, Txd|Rxd); /* disable transceiver */
  980. resetctlr(ctlr);
  981. }
  982. int
  983. dp83820reset(Ctlr* ctlr)
  984. {
  985. int i, r;
  986. unsigned char sum;
  987. /*
  988. * Soft reset the controller;
  989. * read the EEPROM to get the initial settings
  990. * of the Cfg and Gpior bits which should be cleared by
  991. * the reset.
  992. */
  993. resetctlr(ctlr);
  994. sum = 0;
  995. for(i = 0; i < 0x0E; i++){
  996. r = atc93c46r(ctlr, i);
  997. ctlr->eeprom[i] = r;
  998. sum += r;
  999. sum += r>>8;
  1000. }
  1001. if(sum != 0){
  1002. print("dp83820reset: bad EEPROM checksum\n");
  1003. return -1;
  1004. }
  1005. #ifdef notdef
  1006. csr32w(ctlr, Gpior, ctlr->eeprom[4]);
  1007. cfg = Extstsen|Exd;
  1008. r = csr32r(ctlr, Cfg);
  1009. if(ctlr->eeprom[5] & 0x0001)
  1010. cfg |= Ext125;
  1011. if(ctlr->eeprom[5] & 0x0002)
  1012. cfg |= M64addren;
  1013. if((ctlr->eeprom[5] & 0x0004) && (r & Pci64det))
  1014. cfg |= Data64en;
  1015. if(ctlr->eeprom[5] & 0x0008)
  1016. cfg |= T64addren;
  1017. if(!(pcicfgr16(ctlr->pcidev, PciPCR) & 0x10))
  1018. cfg |= Mwidis;
  1019. if(ctlr->eeprom[5] & 0x0020)
  1020. cfg |= Mrmdis;
  1021. if(ctlr->eeprom[5] & 0x0080)
  1022. cfg |= Mode1000;
  1023. if(ctlr->eeprom[5] & 0x0200)
  1024. cfg |= Tbien|Mode1000;
  1025. /*
  1026. * What about RO bits we might have destroyed with Rst?
  1027. * What about Exd, Tmrtest, Extstsen, Pintctl?
  1028. * Why does it think it has detected a 64-bit bus when
  1029. * it hasn't?
  1030. */
  1031. #else
  1032. //r = csr32r(ctlr, Cfg);
  1033. //r &= ~(Mode1000|T64addren|Data64en|M64addren);
  1034. //csr32w(ctlr, Cfg, r);
  1035. //csr32w(ctlr, Cfg, 0x2000);
  1036. #endif /* notdef */
  1037. ctlr->cfg = csr32r(ctlr, Cfg);
  1038. print("cfg %8.8ux pcicfg %8.8ux\n", ctlr->cfg, pcicfgr32(ctlr->pcidev, PciPCR));
  1039. ctlr->cfg &= ~(T64addren|Data64en|M64addren);
  1040. csr32w(ctlr, Cfg, ctlr->cfg);
  1041. csr32w(ctlr, Mibc, Aclr|Frz);
  1042. return 0;
  1043. }
  1044. // from pci.c
  1045. enum {
  1046. Pcinetctlr = 0x02, /* network controller */
  1047. // PciCCRp = 0x09, /* programming interface class code */
  1048. // PciCCRu = 0x0A, /* sub-class code */
  1049. // PciCCRb = 0x0B, /* base class code */
  1050. };
  1051. static void
  1052. dp83820pci(void)
  1053. {
  1054. void *mem;
  1055. Pcidev *p;
  1056. Ctlr *ctlr;
  1057. p = nil;
  1058. while(p = pcimatch(p, 0, 0)){
  1059. /* ccru is a short in the FS kernel, thus the cast to uchar */
  1060. if(p->ccrb != Pcinetctlr || (uchar)p->ccru != 0)
  1061. continue;
  1062. switch((p->did<<16)|p->vid){
  1063. default:
  1064. continue;
  1065. case (0x0022<<16)|0x100B: /* NS DP83820 (Gig-NIC) */
  1066. /* case (0x1032<<16)|0x1737: /* linksys eg1032 */
  1067. break;
  1068. }
  1069. /* cast for FS */
  1070. mem = (void *)vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
  1071. if(mem == 0){
  1072. print("DP83820: can't map %8.8lux\n", p->mem[1].bar);
  1073. continue;
  1074. }
  1075. /* malloc only zeroes storage if Npadlong!=0, so use mallocz */
  1076. ctlr = mallocz(sizeof(Ctlr), 1);
  1077. ctlr->port = p->mem[1].bar & ~0x0F;
  1078. ctlr->pcidev = p;
  1079. ctlr->id = (p->did<<16)|p->vid;
  1080. #ifdef notdef
  1081. /*
  1082. * bar[0] is the I/O port register address and
  1083. * bar[1] is the memory-mapped register address.
  1084. */
  1085. if (ioalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0, "dp83820")
  1086. < 0) {
  1087. print("dp83820: port 0x%uX in use\n", ctlr->port);
  1088. free(ctlr);
  1089. continue;
  1090. }
  1091. #endif
  1092. ctlr->nic = mem;
  1093. if(dp83820reset(ctlr)){
  1094. free(ctlr);
  1095. continue;
  1096. }
  1097. pcisetbme(p);
  1098. if(dp83820ctlrhead != nil)
  1099. dp83820ctlrtail->next = ctlr;
  1100. else
  1101. dp83820ctlrhead = ctlr;
  1102. dp83820ctlrtail = ctlr;
  1103. }
  1104. }
  1105. int
  1106. dp83820pnp(Ether* edev)
  1107. {
  1108. int i;
  1109. Ctlr *ctlr;
  1110. uchar ea[Eaddrlen];
  1111. if(dp83820ctlrhead == nil)
  1112. dp83820pci();
  1113. /*
  1114. * Any adapter matches if no edev->port is supplied,
  1115. * otherwise the ports must match.
  1116. */
  1117. for(ctlr = dp83820ctlrhead; ctlr != nil; ctlr = ctlr->next){
  1118. if(ctlr->active)
  1119. continue;
  1120. if(edev->port == 0 || edev->port == ctlr->port){
  1121. ctlr->active = 1;
  1122. break;
  1123. }
  1124. }
  1125. if(ctlr == nil)
  1126. return -1;
  1127. edev->ctlr = ctlr;
  1128. edev->port = ctlr->port;
  1129. edev->irq = ctlr->pcidev->intl;
  1130. edev->tbdf = ctlr->pcidev->tbdf;
  1131. edev->mbps = 1000;
  1132. /*
  1133. * Check if the adapter's station address is to be overridden.
  1134. * If not, read it from the EEPROM and set in ether->ea prior to
  1135. * loading the station address in the hardware.
  1136. */
  1137. memset(ea, 0, Eaddrlen);
  1138. if(memcmp(ea, edev->ea, Eaddrlen) == 0){
  1139. for(i = 0; i < Eaddrlen/2; i++){
  1140. edev->ea[2*i] = ctlr->eeprom[0x0C-i];
  1141. edev->ea[2*i+1] = ctlr->eeprom[0x0C-i]>>8;
  1142. }
  1143. }
  1144. edev->attach = dp83820attach;
  1145. edev->transmit = dp83820transmit;
  1146. edev->interrupt = dp83820interrupt;
  1147. #ifndef FS
  1148. edev->ifstat = dp83820ifstat;
  1149. edev->arg = edev;
  1150. edev->shutdown = shutdown;
  1151. edev->multicast = multicast;
  1152. edev->promiscuous = dp83820promiscuous;
  1153. #endif
  1154. return 0;
  1155. }
  1156. #ifndef FS
  1157. void
  1158. etherdp83820link(void)
  1159. {
  1160. addethercard("DP83820", dp83820pnp);
  1161. }
  1162. void
  1163. etherdp83820bothlink(void)
  1164. {
  1165. etherdp83820link();
  1166. }
  1167. #endif