s6gmac.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. /*
  2. * Ethernet driver for S6105 on chip network device
  3. * (c)2008 emlix GmbH http://www.emlix.com
  4. * Authors: Oskar Schirmer <os@emlix.com>
  5. * Daniel Gloeckner <dg@emlix.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version
  10. * 2 of the License, or (at your option) any later version.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/types.h>
  16. #include <linux/delay.h>
  17. #include <linux/init.h>
  18. #include <linux/spinlock.h>
  19. #include <linux/netdevice.h>
  20. #include <linux/etherdevice.h>
  21. #include <linux/if.h>
  22. #include <linux/stddef.h>
  23. #include <linux/mii.h>
  24. #include <linux/phy.h>
  25. #include <linux/platform_device.h>
  26. #include <variant/hardware.h>
  27. #include <variant/dmac.h>
  28. #define DRV_NAME "s6gmac"
  29. #define DRV_PRMT DRV_NAME ": "
  30. /* register declarations */
  31. #define S6_GMAC_MACCONF1 0x000
  32. #define S6_GMAC_MACCONF1_TXENA 0
  33. #define S6_GMAC_MACCONF1_SYNCTX 1
  34. #define S6_GMAC_MACCONF1_RXENA 2
  35. #define S6_GMAC_MACCONF1_SYNCRX 3
  36. #define S6_GMAC_MACCONF1_TXFLOWCTRL 4
  37. #define S6_GMAC_MACCONF1_RXFLOWCTRL 5
  38. #define S6_GMAC_MACCONF1_LOOPBACK 8
  39. #define S6_GMAC_MACCONF1_RESTXFUNC 16
  40. #define S6_GMAC_MACCONF1_RESRXFUNC 17
  41. #define S6_GMAC_MACCONF1_RESTXMACCTRL 18
  42. #define S6_GMAC_MACCONF1_RESRXMACCTRL 19
  43. #define S6_GMAC_MACCONF1_SIMULRES 30
  44. #define S6_GMAC_MACCONF1_SOFTRES 31
  45. #define S6_GMAC_MACCONF2 0x004
  46. #define S6_GMAC_MACCONF2_FULL 0
  47. #define S6_GMAC_MACCONF2_CRCENA 1
  48. #define S6_GMAC_MACCONF2_PADCRCENA 2
  49. #define S6_GMAC_MACCONF2_LENGTHFCHK 4
  50. #define S6_GMAC_MACCONF2_HUGEFRAMENA 5
  51. #define S6_GMAC_MACCONF2_IFMODE 8
  52. #define S6_GMAC_MACCONF2_IFMODE_NIBBLE 1
  53. #define S6_GMAC_MACCONF2_IFMODE_BYTE 2
  54. #define S6_GMAC_MACCONF2_IFMODE_MASK 3
  55. #define S6_GMAC_MACCONF2_PREAMBLELEN 12
  56. #define S6_GMAC_MACCONF2_PREAMBLELEN_MASK 0x0F
  57. #define S6_GMAC_MACIPGIFG 0x008
  58. #define S6_GMAC_MACIPGIFG_B2BINTERPGAP 0
  59. #define S6_GMAC_MACIPGIFG_B2BINTERPGAP_MASK 0x7F
  60. #define S6_GMAC_MACIPGIFG_MINIFGENFORCE 8
  61. #define S6_GMAC_MACIPGIFG_B2BINTERPGAP2 16
  62. #define S6_GMAC_MACIPGIFG_B2BINTERPGAP1 24
  63. #define S6_GMAC_MACHALFDUPLEX 0x00C
  64. #define S6_GMAC_MACHALFDUPLEX_COLLISWIN 0
  65. #define S6_GMAC_MACHALFDUPLEX_COLLISWIN_MASK 0x3F
  66. #define S6_GMAC_MACHALFDUPLEX_RETXMAX 12
  67. #define S6_GMAC_MACHALFDUPLEX_RETXMAX_MASK 0x0F
  68. #define S6_GMAC_MACHALFDUPLEX_EXCESSDEF 16
  69. #define S6_GMAC_MACHALFDUPLEX_NOBACKOFF 17
  70. #define S6_GMAC_MACHALFDUPLEX_BPNOBCKOF 18
  71. #define S6_GMAC_MACHALFDUPLEX_ALTBEBENA 19
  72. #define S6_GMAC_MACHALFDUPLEX_ALTBEBTRN 20
  73. #define S6_GMAC_MACHALFDUPLEX_ALTBEBTR_MASK 0x0F
  74. #define S6_GMAC_MACMAXFRAMELEN 0x010
  75. #define S6_GMAC_MACMIICONF 0x020
  76. #define S6_GMAC_MACMIICONF_CSEL 0
  77. #define S6_GMAC_MACMIICONF_CSEL_DIV10 0
  78. #define S6_GMAC_MACMIICONF_CSEL_DIV12 1
  79. #define S6_GMAC_MACMIICONF_CSEL_DIV14 2
  80. #define S6_GMAC_MACMIICONF_CSEL_DIV18 3
  81. #define S6_GMAC_MACMIICONF_CSEL_DIV24 4
  82. #define S6_GMAC_MACMIICONF_CSEL_DIV34 5
  83. #define S6_GMAC_MACMIICONF_CSEL_DIV68 6
  84. #define S6_GMAC_MACMIICONF_CSEL_DIV168 7
  85. #define S6_GMAC_MACMIICONF_CSEL_MASK 7
  86. #define S6_GMAC_MACMIICONF_PREAMBLESUPR 4
  87. #define S6_GMAC_MACMIICONF_SCANAUTOINCR 5
  88. #define S6_GMAC_MACMIICMD 0x024
  89. #define S6_GMAC_MACMIICMD_READ 0
  90. #define S6_GMAC_MACMIICMD_SCAN 1
  91. #define S6_GMAC_MACMIIADDR 0x028
  92. #define S6_GMAC_MACMIIADDR_REG 0
  93. #define S6_GMAC_MACMIIADDR_REG_MASK 0x1F
  94. #define S6_GMAC_MACMIIADDR_PHY 8
  95. #define S6_GMAC_MACMIIADDR_PHY_MASK 0x1F
  96. #define S6_GMAC_MACMIICTRL 0x02C
  97. #define S6_GMAC_MACMIISTAT 0x030
  98. #define S6_GMAC_MACMIIINDI 0x034
  99. #define S6_GMAC_MACMIIINDI_BUSY 0
  100. #define S6_GMAC_MACMIIINDI_SCAN 1
  101. #define S6_GMAC_MACMIIINDI_INVAL 2
  102. #define S6_GMAC_MACINTERFSTAT 0x03C
  103. #define S6_GMAC_MACINTERFSTAT_LINKFAIL 3
  104. #define S6_GMAC_MACINTERFSTAT_EXCESSDEF 9
  105. #define S6_GMAC_MACSTATADDR1 0x040
  106. #define S6_GMAC_MACSTATADDR2 0x044
  107. #define S6_GMAC_FIFOCONF0 0x048
  108. #define S6_GMAC_FIFOCONF0_HSTRSTWT 0
  109. #define S6_GMAC_FIFOCONF0_HSTRSTSR 1
  110. #define S6_GMAC_FIFOCONF0_HSTRSTFR 2
  111. #define S6_GMAC_FIFOCONF0_HSTRSTST 3
  112. #define S6_GMAC_FIFOCONF0_HSTRSTFT 4
  113. #define S6_GMAC_FIFOCONF0_WTMENREQ 8
  114. #define S6_GMAC_FIFOCONF0_SRFENREQ 9
  115. #define S6_GMAC_FIFOCONF0_FRFENREQ 10
  116. #define S6_GMAC_FIFOCONF0_STFENREQ 11
  117. #define S6_GMAC_FIFOCONF0_FTFENREQ 12
  118. #define S6_GMAC_FIFOCONF0_WTMENRPLY 16
  119. #define S6_GMAC_FIFOCONF0_SRFENRPLY 17
  120. #define S6_GMAC_FIFOCONF0_FRFENRPLY 18
  121. #define S6_GMAC_FIFOCONF0_STFENRPLY 19
  122. #define S6_GMAC_FIFOCONF0_FTFENRPLY 20
  123. #define S6_GMAC_FIFOCONF1 0x04C
  124. #define S6_GMAC_FIFOCONF2 0x050
  125. #define S6_GMAC_FIFOCONF2_CFGLWM 0
  126. #define S6_GMAC_FIFOCONF2_CFGHWM 16
  127. #define S6_GMAC_FIFOCONF3 0x054
  128. #define S6_GMAC_FIFOCONF3_CFGFTTH 0
  129. #define S6_GMAC_FIFOCONF3_CFGHWMFT 16
  130. #define S6_GMAC_FIFOCONF4 0x058
  131. #define S6_GMAC_FIFOCONF_RSV_PREVDROP 0
  132. #define S6_GMAC_FIFOCONF_RSV_RUNT 1
  133. #define S6_GMAC_FIFOCONF_RSV_FALSECAR 2
  134. #define S6_GMAC_FIFOCONF_RSV_CODEERR 3
  135. #define S6_GMAC_FIFOCONF_RSV_CRCERR 4
  136. #define S6_GMAC_FIFOCONF_RSV_LENGTHERR 5
  137. #define S6_GMAC_FIFOCONF_RSV_LENRANGE 6
  138. #define S6_GMAC_FIFOCONF_RSV_OK 7
  139. #define S6_GMAC_FIFOCONF_RSV_MULTICAST 8
  140. #define S6_GMAC_FIFOCONF_RSV_BROADCAST 9
  141. #define S6_GMAC_FIFOCONF_RSV_DRIBBLE 10
  142. #define S6_GMAC_FIFOCONF_RSV_CTRLFRAME 11
  143. #define S6_GMAC_FIFOCONF_RSV_PAUSECTRL 12
  144. #define S6_GMAC_FIFOCONF_RSV_UNOPCODE 13
  145. #define S6_GMAC_FIFOCONF_RSV_VLANTAG 14
  146. #define S6_GMAC_FIFOCONF_RSV_LONGEVENT 15
  147. #define S6_GMAC_FIFOCONF_RSV_TRUNCATED 16
  148. #define S6_GMAC_FIFOCONF_RSV_MASK 0x3FFFF
  149. #define S6_GMAC_FIFOCONF5 0x05C
  150. #define S6_GMAC_FIFOCONF5_DROPLT64 18
  151. #define S6_GMAC_FIFOCONF5_CFGBYTM 19
  152. #define S6_GMAC_FIFOCONF5_RXDROPSIZE 20
  153. #define S6_GMAC_FIFOCONF5_RXDROPSIZE_MASK 0xF
  154. #define S6_GMAC_STAT_REGS 0x080
  155. #define S6_GMAC_STAT_SIZE_MIN 12
  156. #define S6_GMAC_STATTR64 0x080
  157. #define S6_GMAC_STATTR64_SIZE 18
  158. #define S6_GMAC_STATTR127 0x084
  159. #define S6_GMAC_STATTR127_SIZE 18
  160. #define S6_GMAC_STATTR255 0x088
  161. #define S6_GMAC_STATTR255_SIZE 18
  162. #define S6_GMAC_STATTR511 0x08C
  163. #define S6_GMAC_STATTR511_SIZE 18
  164. #define S6_GMAC_STATTR1K 0x090
  165. #define S6_GMAC_STATTR1K_SIZE 18
  166. #define S6_GMAC_STATTRMAX 0x094
  167. #define S6_GMAC_STATTRMAX_SIZE 18
  168. #define S6_GMAC_STATTRMGV 0x098
  169. #define S6_GMAC_STATTRMGV_SIZE 18
  170. #define S6_GMAC_STATRBYT 0x09C
  171. #define S6_GMAC_STATRBYT_SIZE 24
  172. #define S6_GMAC_STATRPKT 0x0A0
  173. #define S6_GMAC_STATRPKT_SIZE 18
  174. #define S6_GMAC_STATRFCS 0x0A4
  175. #define S6_GMAC_STATRFCS_SIZE 12
  176. #define S6_GMAC_STATRMCA 0x0A8
  177. #define S6_GMAC_STATRMCA_SIZE 18
  178. #define S6_GMAC_STATRBCA 0x0AC
  179. #define S6_GMAC_STATRBCA_SIZE 22
  180. #define S6_GMAC_STATRXCF 0x0B0
  181. #define S6_GMAC_STATRXCF_SIZE 18
  182. #define S6_GMAC_STATRXPF 0x0B4
  183. #define S6_GMAC_STATRXPF_SIZE 12
  184. #define S6_GMAC_STATRXUO 0x0B8
  185. #define S6_GMAC_STATRXUO_SIZE 12
  186. #define S6_GMAC_STATRALN 0x0BC
  187. #define S6_GMAC_STATRALN_SIZE 12
  188. #define S6_GMAC_STATRFLR 0x0C0
  189. #define S6_GMAC_STATRFLR_SIZE 16
  190. #define S6_GMAC_STATRCDE 0x0C4
  191. #define S6_GMAC_STATRCDE_SIZE 12
  192. #define S6_GMAC_STATRCSE 0x0C8
  193. #define S6_GMAC_STATRCSE_SIZE 12
  194. #define S6_GMAC_STATRUND 0x0CC
  195. #define S6_GMAC_STATRUND_SIZE 12
  196. #define S6_GMAC_STATROVR 0x0D0
  197. #define S6_GMAC_STATROVR_SIZE 12
  198. #define S6_GMAC_STATRFRG 0x0D4
  199. #define S6_GMAC_STATRFRG_SIZE 12
  200. #define S6_GMAC_STATRJBR 0x0D8
  201. #define S6_GMAC_STATRJBR_SIZE 12
  202. #define S6_GMAC_STATRDRP 0x0DC
  203. #define S6_GMAC_STATRDRP_SIZE 12
  204. #define S6_GMAC_STATTBYT 0x0E0
  205. #define S6_GMAC_STATTBYT_SIZE 24
  206. #define S6_GMAC_STATTPKT 0x0E4
  207. #define S6_GMAC_STATTPKT_SIZE 18
  208. #define S6_GMAC_STATTMCA 0x0E8
  209. #define S6_GMAC_STATTMCA_SIZE 18
  210. #define S6_GMAC_STATTBCA 0x0EC
  211. #define S6_GMAC_STATTBCA_SIZE 18
  212. #define S6_GMAC_STATTXPF 0x0F0
  213. #define S6_GMAC_STATTXPF_SIZE 12
  214. #define S6_GMAC_STATTDFR 0x0F4
  215. #define S6_GMAC_STATTDFR_SIZE 12
  216. #define S6_GMAC_STATTEDF 0x0F8
  217. #define S6_GMAC_STATTEDF_SIZE 12
  218. #define S6_GMAC_STATTSCL 0x0FC
  219. #define S6_GMAC_STATTSCL_SIZE 12
  220. #define S6_GMAC_STATTMCL 0x100
  221. #define S6_GMAC_STATTMCL_SIZE 12
  222. #define S6_GMAC_STATTLCL 0x104
  223. #define S6_GMAC_STATTLCL_SIZE 12
  224. #define S6_GMAC_STATTXCL 0x108
  225. #define S6_GMAC_STATTXCL_SIZE 12
  226. #define S6_GMAC_STATTNCL 0x10C
  227. #define S6_GMAC_STATTNCL_SIZE 13
  228. #define S6_GMAC_STATTPFH 0x110
  229. #define S6_GMAC_STATTPFH_SIZE 12
  230. #define S6_GMAC_STATTDRP 0x114
  231. #define S6_GMAC_STATTDRP_SIZE 12
  232. #define S6_GMAC_STATTJBR 0x118
  233. #define S6_GMAC_STATTJBR_SIZE 12
  234. #define S6_GMAC_STATTFCS 0x11C
  235. #define S6_GMAC_STATTFCS_SIZE 12
  236. #define S6_GMAC_STATTXCF 0x120
  237. #define S6_GMAC_STATTXCF_SIZE 12
  238. #define S6_GMAC_STATTOVR 0x124
  239. #define S6_GMAC_STATTOVR_SIZE 12
  240. #define S6_GMAC_STATTUND 0x128
  241. #define S6_GMAC_STATTUND_SIZE 12
  242. #define S6_GMAC_STATTFRG 0x12C
  243. #define S6_GMAC_STATTFRG_SIZE 12
  244. #define S6_GMAC_STATCARRY(n) (0x130 + 4*(n))
  245. #define S6_GMAC_STATCARRYMSK(n) (0x138 + 4*(n))
  246. #define S6_GMAC_STATCARRY1_RDRP 0
  247. #define S6_GMAC_STATCARRY1_RJBR 1
  248. #define S6_GMAC_STATCARRY1_RFRG 2
  249. #define S6_GMAC_STATCARRY1_ROVR 3
  250. #define S6_GMAC_STATCARRY1_RUND 4
  251. #define S6_GMAC_STATCARRY1_RCSE 5
  252. #define S6_GMAC_STATCARRY1_RCDE 6
  253. #define S6_GMAC_STATCARRY1_RFLR 7
  254. #define S6_GMAC_STATCARRY1_RALN 8
  255. #define S6_GMAC_STATCARRY1_RXUO 9
  256. #define S6_GMAC_STATCARRY1_RXPF 10
  257. #define S6_GMAC_STATCARRY1_RXCF 11
  258. #define S6_GMAC_STATCARRY1_RBCA 12
  259. #define S6_GMAC_STATCARRY1_RMCA 13
  260. #define S6_GMAC_STATCARRY1_RFCS 14
  261. #define S6_GMAC_STATCARRY1_RPKT 15
  262. #define S6_GMAC_STATCARRY1_RBYT 16
  263. #define S6_GMAC_STATCARRY1_TRMGV 25
  264. #define S6_GMAC_STATCARRY1_TRMAX 26
  265. #define S6_GMAC_STATCARRY1_TR1K 27
  266. #define S6_GMAC_STATCARRY1_TR511 28
  267. #define S6_GMAC_STATCARRY1_TR255 29
  268. #define S6_GMAC_STATCARRY1_TR127 30
  269. #define S6_GMAC_STATCARRY1_TR64 31
  270. #define S6_GMAC_STATCARRY2_TDRP 0
  271. #define S6_GMAC_STATCARRY2_TPFH 1
  272. #define S6_GMAC_STATCARRY2_TNCL 2
  273. #define S6_GMAC_STATCARRY2_TXCL 3
  274. #define S6_GMAC_STATCARRY2_TLCL 4
  275. #define S6_GMAC_STATCARRY2_TMCL 5
  276. #define S6_GMAC_STATCARRY2_TSCL 6
  277. #define S6_GMAC_STATCARRY2_TEDF 7
  278. #define S6_GMAC_STATCARRY2_TDFR 8
  279. #define S6_GMAC_STATCARRY2_TXPF 9
  280. #define S6_GMAC_STATCARRY2_TBCA 10
  281. #define S6_GMAC_STATCARRY2_TMCA 11
  282. #define S6_GMAC_STATCARRY2_TPKT 12
  283. #define S6_GMAC_STATCARRY2_TBYT 13
  284. #define S6_GMAC_STATCARRY2_TFRG 14
  285. #define S6_GMAC_STATCARRY2_TUND 15
  286. #define S6_GMAC_STATCARRY2_TOVR 16
  287. #define S6_GMAC_STATCARRY2_TXCF 17
  288. #define S6_GMAC_STATCARRY2_TFCS 18
  289. #define S6_GMAC_STATCARRY2_TJBR 19
  290. #define S6_GMAC_HOST_PBLKCTRL 0x140
  291. #define S6_GMAC_HOST_PBLKCTRL_TXENA 0
  292. #define S6_GMAC_HOST_PBLKCTRL_RXENA 1
  293. #define S6_GMAC_HOST_PBLKCTRL_TXSRES 2
  294. #define S6_GMAC_HOST_PBLKCTRL_RXSRES 3
  295. #define S6_GMAC_HOST_PBLKCTRL_TXBSIZ 8
  296. #define S6_GMAC_HOST_PBLKCTRL_RXBSIZ 12
  297. #define S6_GMAC_HOST_PBLKCTRL_SIZ_16 4
  298. #define S6_GMAC_HOST_PBLKCTRL_SIZ_32 5
  299. #define S6_GMAC_HOST_PBLKCTRL_SIZ_64 6
  300. #define S6_GMAC_HOST_PBLKCTRL_SIZ_128 7
  301. #define S6_GMAC_HOST_PBLKCTRL_SIZ_MASK 0xF
  302. #define S6_GMAC_HOST_PBLKCTRL_STATENA 16
  303. #define S6_GMAC_HOST_PBLKCTRL_STATAUTOZ 17
  304. #define S6_GMAC_HOST_PBLKCTRL_STATCLEAR 18
  305. #define S6_GMAC_HOST_PBLKCTRL_RGMII 19
  306. #define S6_GMAC_HOST_INTMASK 0x144
  307. #define S6_GMAC_HOST_INTSTAT 0x148
  308. #define S6_GMAC_HOST_INT_TXBURSTOVER 3
  309. #define S6_GMAC_HOST_INT_TXPREWOVER 4
  310. #define S6_GMAC_HOST_INT_RXBURSTUNDER 5
  311. #define S6_GMAC_HOST_INT_RXPOSTRFULL 6
  312. #define S6_GMAC_HOST_INT_RXPOSTRUNDER 7
  313. #define S6_GMAC_HOST_RXFIFOHWM 0x14C
  314. #define S6_GMAC_HOST_CTRLFRAMXP 0x150
  315. #define S6_GMAC_HOST_DSTADDRLO(n) (0x160 + 8*(n))
  316. #define S6_GMAC_HOST_DSTADDRHI(n) (0x164 + 8*(n))
  317. #define S6_GMAC_HOST_DSTMASKLO(n) (0x180 + 8*(n))
  318. #define S6_GMAC_HOST_DSTMASKHI(n) (0x184 + 8*(n))
  319. #define S6_GMAC_BURST_PREWR 0x1B0
  320. #define S6_GMAC_BURST_PREWR_LEN 0
  321. #define S6_GMAC_BURST_PREWR_LEN_MASK ((1 << 20) - 1)
  322. #define S6_GMAC_BURST_PREWR_CFE 20
  323. #define S6_GMAC_BURST_PREWR_PPE 21
  324. #define S6_GMAC_BURST_PREWR_FCS 22
  325. #define S6_GMAC_BURST_PREWR_PAD 23
  326. #define S6_GMAC_BURST_POSTRD 0x1D0
  327. #define S6_GMAC_BURST_POSTRD_LEN 0
  328. #define S6_GMAC_BURST_POSTRD_LEN_MASK ((1 << 20) - 1)
  329. #define S6_GMAC_BURST_POSTRD_DROP 20
  330. /* data handling */
  331. #define S6_NUM_TX_SKB 8 /* must be larger than TX fifo size */
  332. #define S6_NUM_RX_SKB 16
  333. #define S6_MAX_FRLEN 1536
  334. struct s6gmac {
  335. u32 reg;
  336. u32 tx_dma;
  337. u32 rx_dma;
  338. u32 io;
  339. u8 tx_chan;
  340. u8 rx_chan;
  341. spinlock_t lock;
  342. u8 tx_skb_i, tx_skb_o;
  343. u8 rx_skb_i, rx_skb_o;
  344. struct sk_buff *tx_skb[S6_NUM_TX_SKB];
  345. struct sk_buff *rx_skb[S6_NUM_RX_SKB];
  346. unsigned long carry[sizeof(struct net_device_stats) / sizeof(long)];
  347. unsigned long stats[sizeof(struct net_device_stats) / sizeof(long)];
  348. struct phy_device *phydev;
  349. struct {
  350. struct mii_bus *bus;
  351. int irq[PHY_MAX_ADDR];
  352. } mii;
  353. struct {
  354. unsigned int mbit;
  355. u8 giga;
  356. u8 isup;
  357. u8 full;
  358. } link;
  359. };
  360. static void s6gmac_rx_fillfifo(struct s6gmac *pd)
  361. {
  362. struct sk_buff *skb;
  363. while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB)
  364. && (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan))
  365. && (skb = dev_alloc_skb(S6_MAX_FRLEN + 2))) {
  366. pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb;
  367. s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan,
  368. pd->io, (u32)skb->data, S6_MAX_FRLEN);
  369. }
  370. }
  371. static void s6gmac_rx_interrupt(struct net_device *dev)
  372. {
  373. struct s6gmac *pd = netdev_priv(dev);
  374. u32 pfx;
  375. struct sk_buff *skb;
  376. while (((u8)(pd->rx_skb_i - pd->rx_skb_o)) >
  377. s6dmac_pending_count(pd->rx_dma, pd->rx_chan)) {
  378. skb = pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB];
  379. pfx = readl(pd->reg + S6_GMAC_BURST_POSTRD);
  380. if (pfx & (1 << S6_GMAC_BURST_POSTRD_DROP)) {
  381. dev_kfree_skb_irq(skb);
  382. } else {
  383. skb_put(skb, (pfx >> S6_GMAC_BURST_POSTRD_LEN)
  384. & S6_GMAC_BURST_POSTRD_LEN_MASK);
  385. skb->dev = dev;
  386. skb->protocol = eth_type_trans(skb, dev);
  387. skb->ip_summed = CHECKSUM_UNNECESSARY;
  388. netif_rx(skb);
  389. }
  390. }
  391. }
  392. static void s6gmac_tx_interrupt(struct net_device *dev)
  393. {
  394. struct s6gmac *pd = netdev_priv(dev);
  395. while (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >
  396. s6dmac_pending_count(pd->tx_dma, pd->tx_chan)) {
  397. dev_kfree_skb_irq(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]);
  398. }
  399. if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  400. netif_wake_queue(dev);
  401. }
  402. struct s6gmac_statinf {
  403. unsigned reg_size : 4; /* 0: unused */
  404. unsigned reg_off : 6;
  405. unsigned net_index : 6;
  406. };
  407. #define S6_STATS_B (8 * sizeof(u32))
  408. #define S6_STATS_C(b, r, f) [b] = { \
  409. BUILD_BUG_ON_ZERO(r##_SIZE < S6_GMAC_STAT_SIZE_MIN) + \
  410. BUILD_BUG_ON_ZERO((r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1)) \
  411. >= (1<<4)) + \
  412. r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1), \
  413. BUILD_BUG_ON_ZERO(((unsigned)((r - S6_GMAC_STAT_REGS) / sizeof(u32))) \
  414. >= ((1<<6)-1)) + \
  415. (r - S6_GMAC_STAT_REGS) / sizeof(u32), \
  416. BUILD_BUG_ON_ZERO((offsetof(struct net_device_stats, f)) \
  417. % sizeof(unsigned long)) + \
  418. BUILD_BUG_ON_ZERO((((unsigned)(offsetof(struct net_device_stats, f)) \
  419. / sizeof(unsigned long)) >= (1<<6))) + \
  420. BUILD_BUG_ON_ZERO((sizeof(((struct net_device_stats *)0)->f) \
  421. != sizeof(unsigned long))) + \
  422. (offsetof(struct net_device_stats, f)) / sizeof(unsigned long)},
  423. static const struct s6gmac_statinf statinf[2][S6_STATS_B] = { {
  424. S6_STATS_C(S6_GMAC_STATCARRY1_RBYT, S6_GMAC_STATRBYT, rx_bytes)
  425. S6_STATS_C(S6_GMAC_STATCARRY1_RPKT, S6_GMAC_STATRPKT, rx_packets)
  426. S6_STATS_C(S6_GMAC_STATCARRY1_RFCS, S6_GMAC_STATRFCS, rx_crc_errors)
  427. S6_STATS_C(S6_GMAC_STATCARRY1_RMCA, S6_GMAC_STATRMCA, multicast)
  428. S6_STATS_C(S6_GMAC_STATCARRY1_RALN, S6_GMAC_STATRALN, rx_frame_errors)
  429. S6_STATS_C(S6_GMAC_STATCARRY1_RFLR, S6_GMAC_STATRFLR, rx_length_errors)
  430. S6_STATS_C(S6_GMAC_STATCARRY1_RCDE, S6_GMAC_STATRCDE, rx_missed_errors)
  431. S6_STATS_C(S6_GMAC_STATCARRY1_RUND, S6_GMAC_STATRUND, rx_length_errors)
  432. S6_STATS_C(S6_GMAC_STATCARRY1_ROVR, S6_GMAC_STATROVR, rx_length_errors)
  433. S6_STATS_C(S6_GMAC_STATCARRY1_RFRG, S6_GMAC_STATRFRG, rx_crc_errors)
  434. S6_STATS_C(S6_GMAC_STATCARRY1_RJBR, S6_GMAC_STATRJBR, rx_crc_errors)
  435. S6_STATS_C(S6_GMAC_STATCARRY1_RDRP, S6_GMAC_STATRDRP, rx_dropped)
  436. }, {
  437. S6_STATS_C(S6_GMAC_STATCARRY2_TBYT, S6_GMAC_STATTBYT, tx_bytes)
  438. S6_STATS_C(S6_GMAC_STATCARRY2_TPKT, S6_GMAC_STATTPKT, tx_packets)
  439. S6_STATS_C(S6_GMAC_STATCARRY2_TEDF, S6_GMAC_STATTEDF, tx_aborted_errors)
  440. S6_STATS_C(S6_GMAC_STATCARRY2_TXCL, S6_GMAC_STATTXCL, tx_aborted_errors)
  441. S6_STATS_C(S6_GMAC_STATCARRY2_TNCL, S6_GMAC_STATTNCL, collisions)
  442. S6_STATS_C(S6_GMAC_STATCARRY2_TDRP, S6_GMAC_STATTDRP, tx_dropped)
  443. S6_STATS_C(S6_GMAC_STATCARRY2_TJBR, S6_GMAC_STATTJBR, tx_errors)
  444. S6_STATS_C(S6_GMAC_STATCARRY2_TFCS, S6_GMAC_STATTFCS, tx_errors)
  445. S6_STATS_C(S6_GMAC_STATCARRY2_TOVR, S6_GMAC_STATTOVR, tx_errors)
  446. S6_STATS_C(S6_GMAC_STATCARRY2_TUND, S6_GMAC_STATTUND, tx_errors)
  447. S6_STATS_C(S6_GMAC_STATCARRY2_TFRG, S6_GMAC_STATTFRG, tx_errors)
  448. } };
  449. static void s6gmac_stats_collect(struct s6gmac *pd,
  450. const struct s6gmac_statinf *inf)
  451. {
  452. int b;
  453. for (b = 0; b < S6_STATS_B; b++) {
  454. if (inf[b].reg_size) {
  455. pd->stats[inf[b].net_index] +=
  456. readl(pd->reg + S6_GMAC_STAT_REGS
  457. + sizeof(u32) * inf[b].reg_off);
  458. }
  459. }
  460. }
  461. static void s6gmac_stats_carry(struct s6gmac *pd,
  462. const struct s6gmac_statinf *inf, u32 mask)
  463. {
  464. int b;
  465. while (mask) {
  466. b = fls(mask) - 1;
  467. mask &= ~(1 << b);
  468. pd->carry[inf[b].net_index] += (1 << inf[b].reg_size);
  469. }
  470. }
  471. static inline u32 s6gmac_stats_pending(struct s6gmac *pd, int carry)
  472. {
  473. int r = readl(pd->reg + S6_GMAC_STATCARRY(carry)) &
  474. ~readl(pd->reg + S6_GMAC_STATCARRYMSK(carry));
  475. return r;
  476. }
  477. static inline void s6gmac_stats_interrupt(struct s6gmac *pd, int carry)
  478. {
  479. u32 mask;
  480. mask = s6gmac_stats_pending(pd, carry);
  481. if (mask) {
  482. writel(mask, pd->reg + S6_GMAC_STATCARRY(carry));
  483. s6gmac_stats_carry(pd, &statinf[carry][0], mask);
  484. }
  485. }
  486. static irqreturn_t s6gmac_interrupt(int irq, void *dev_id)
  487. {
  488. struct net_device *dev = (struct net_device *)dev_id;
  489. struct s6gmac *pd = netdev_priv(dev);
  490. if (!dev)
  491. return IRQ_NONE;
  492. spin_lock(&pd->lock);
  493. if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan))
  494. s6gmac_rx_interrupt(dev);
  495. s6gmac_rx_fillfifo(pd);
  496. if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan))
  497. s6gmac_tx_interrupt(dev);
  498. s6gmac_stats_interrupt(pd, 0);
  499. s6gmac_stats_interrupt(pd, 1);
  500. spin_unlock(&pd->lock);
  501. return IRQ_HANDLED;
  502. }
  503. static inline void s6gmac_set_dstaddr(struct s6gmac *pd, int n,
  504. u32 addrlo, u32 addrhi, u32 masklo, u32 maskhi)
  505. {
  506. writel(addrlo, pd->reg + S6_GMAC_HOST_DSTADDRLO(n));
  507. writel(addrhi, pd->reg + S6_GMAC_HOST_DSTADDRHI(n));
  508. writel(masklo, pd->reg + S6_GMAC_HOST_DSTMASKLO(n));
  509. writel(maskhi, pd->reg + S6_GMAC_HOST_DSTMASKHI(n));
  510. }
  511. static inline void s6gmac_stop_device(struct net_device *dev)
  512. {
  513. struct s6gmac *pd = netdev_priv(dev);
  514. writel(0, pd->reg + S6_GMAC_MACCONF1);
  515. }
  516. static inline void s6gmac_init_device(struct net_device *dev)
  517. {
  518. struct s6gmac *pd = netdev_priv(dev);
  519. int is_rgmii = !!(pd->phydev->supported
  520. & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half));
  521. #if 0
  522. writel(1 << S6_GMAC_MACCONF1_SYNCTX |
  523. 1 << S6_GMAC_MACCONF1_SYNCRX |
  524. 1 << S6_GMAC_MACCONF1_TXFLOWCTRL |
  525. 1 << S6_GMAC_MACCONF1_RXFLOWCTRL |
  526. 1 << S6_GMAC_MACCONF1_RESTXFUNC |
  527. 1 << S6_GMAC_MACCONF1_RESRXFUNC |
  528. 1 << S6_GMAC_MACCONF1_RESTXMACCTRL |
  529. 1 << S6_GMAC_MACCONF1_RESRXMACCTRL,
  530. pd->reg + S6_GMAC_MACCONF1);
  531. #endif
  532. writel(1 << S6_GMAC_MACCONF1_SOFTRES, pd->reg + S6_GMAC_MACCONF1);
  533. udelay(1000);
  534. writel(1 << S6_GMAC_MACCONF1_TXENA | 1 << S6_GMAC_MACCONF1_RXENA,
  535. pd->reg + S6_GMAC_MACCONF1);
  536. writel(1 << S6_GMAC_HOST_PBLKCTRL_TXSRES |
  537. 1 << S6_GMAC_HOST_PBLKCTRL_RXSRES,
  538. pd->reg + S6_GMAC_HOST_PBLKCTRL);
  539. writel(S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ |
  540. S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ |
  541. 1 << S6_GMAC_HOST_PBLKCTRL_STATENA |
  542. 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR |
  543. is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII,
  544. pd->reg + S6_GMAC_HOST_PBLKCTRL);
  545. writel(1 << S6_GMAC_MACCONF1_TXENA |
  546. 1 << S6_GMAC_MACCONF1_RXENA |
  547. (dev->flags & IFF_LOOPBACK ? 1 : 0)
  548. << S6_GMAC_MACCONF1_LOOPBACK,
  549. pd->reg + S6_GMAC_MACCONF1);
  550. writel(dev->mtu && (dev->mtu < (S6_MAX_FRLEN - ETH_HLEN-ETH_FCS_LEN)) ?
  551. dev->mtu+ETH_HLEN+ETH_FCS_LEN : S6_MAX_FRLEN,
  552. pd->reg + S6_GMAC_MACMAXFRAMELEN);
  553. writel((pd->link.full ? 1 : 0) << S6_GMAC_MACCONF2_FULL |
  554. 1 << S6_GMAC_MACCONF2_PADCRCENA |
  555. 1 << S6_GMAC_MACCONF2_LENGTHFCHK |
  556. (pd->link.giga ?
  557. S6_GMAC_MACCONF2_IFMODE_BYTE :
  558. S6_GMAC_MACCONF2_IFMODE_NIBBLE)
  559. << S6_GMAC_MACCONF2_IFMODE |
  560. 7 << S6_GMAC_MACCONF2_PREAMBLELEN,
  561. pd->reg + S6_GMAC_MACCONF2);
  562. writel(0, pd->reg + S6_GMAC_MACSTATADDR1);
  563. writel(0, pd->reg + S6_GMAC_MACSTATADDR2);
  564. writel(1 << S6_GMAC_FIFOCONF0_WTMENREQ |
  565. 1 << S6_GMAC_FIFOCONF0_SRFENREQ |
  566. 1 << S6_GMAC_FIFOCONF0_FRFENREQ |
  567. 1 << S6_GMAC_FIFOCONF0_STFENREQ |
  568. 1 << S6_GMAC_FIFOCONF0_FTFENREQ,
  569. pd->reg + S6_GMAC_FIFOCONF0);
  570. writel(128 << S6_GMAC_FIFOCONF3_CFGFTTH |
  571. 128 << S6_GMAC_FIFOCONF3_CFGHWMFT,
  572. pd->reg + S6_GMAC_FIFOCONF3);
  573. writel((S6_GMAC_FIFOCONF_RSV_MASK & ~(
  574. 1 << S6_GMAC_FIFOCONF_RSV_RUNT |
  575. 1 << S6_GMAC_FIFOCONF_RSV_CRCERR |
  576. 1 << S6_GMAC_FIFOCONF_RSV_OK |
  577. 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE |
  578. 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME |
  579. 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL |
  580. 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE |
  581. 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED)) |
  582. 1 << S6_GMAC_FIFOCONF5_DROPLT64 |
  583. pd->link.giga << S6_GMAC_FIFOCONF5_CFGBYTM |
  584. 1 << S6_GMAC_FIFOCONF5_RXDROPSIZE,
  585. pd->reg + S6_GMAC_FIFOCONF5);
  586. writel(1 << S6_GMAC_FIFOCONF_RSV_RUNT |
  587. 1 << S6_GMAC_FIFOCONF_RSV_CRCERR |
  588. 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE |
  589. 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME |
  590. 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL |
  591. 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE |
  592. 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED,
  593. pd->reg + S6_GMAC_FIFOCONF4);
  594. s6gmac_set_dstaddr(pd, 0,
  595. 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0x0000FFFF);
  596. s6gmac_set_dstaddr(pd, 1,
  597. dev->dev_addr[5] |
  598. dev->dev_addr[4] << 8 |
  599. dev->dev_addr[3] << 16 |
  600. dev->dev_addr[2] << 24,
  601. dev->dev_addr[1] |
  602. dev->dev_addr[0] << 8,
  603. 0xFFFFFFFF, 0x0000FFFF);
  604. s6gmac_set_dstaddr(pd, 2,
  605. 0x00000000, 0x00000100, 0x00000000, 0x00000100);
  606. s6gmac_set_dstaddr(pd, 3,
  607. 0x00000000, 0x00000000, 0x00000000, 0x00000000);
  608. writel(1 << S6_GMAC_HOST_PBLKCTRL_TXENA |
  609. 1 << S6_GMAC_HOST_PBLKCTRL_RXENA |
  610. S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ |
  611. S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ |
  612. 1 << S6_GMAC_HOST_PBLKCTRL_STATENA |
  613. 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR |
  614. is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII,
  615. pd->reg + S6_GMAC_HOST_PBLKCTRL);
  616. }
  617. static void s6mii_enable(struct s6gmac *pd)
  618. {
  619. writel(readl(pd->reg + S6_GMAC_MACCONF1) &
  620. ~(1 << S6_GMAC_MACCONF1_SOFTRES),
  621. pd->reg + S6_GMAC_MACCONF1);
  622. writel((readl(pd->reg + S6_GMAC_MACMIICONF)
  623. & ~(S6_GMAC_MACMIICONF_CSEL_MASK << S6_GMAC_MACMIICONF_CSEL))
  624. | (S6_GMAC_MACMIICONF_CSEL_DIV168 << S6_GMAC_MACMIICONF_CSEL),
  625. pd->reg + S6_GMAC_MACMIICONF);
  626. }
  627. static int s6mii_busy(struct s6gmac *pd, int tmo)
  628. {
  629. while (readl(pd->reg + S6_GMAC_MACMIIINDI)) {
  630. if (--tmo == 0)
  631. return -ETIME;
  632. udelay(64);
  633. }
  634. return 0;
  635. }
  636. static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum)
  637. {
  638. struct s6gmac *pd = bus->priv;
  639. s6mii_enable(pd);
  640. if (s6mii_busy(pd, 256))
  641. return -ETIME;
  642. writel(phy_addr << S6_GMAC_MACMIIADDR_PHY |
  643. regnum << S6_GMAC_MACMIIADDR_REG,
  644. pd->reg + S6_GMAC_MACMIIADDR);
  645. writel(1 << S6_GMAC_MACMIICMD_READ, pd->reg + S6_GMAC_MACMIICMD);
  646. writel(0, pd->reg + S6_GMAC_MACMIICMD);
  647. if (s6mii_busy(pd, 256))
  648. return -ETIME;
  649. return (u16)readl(pd->reg + S6_GMAC_MACMIISTAT);
  650. }
  651. static int s6mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
  652. {
  653. struct s6gmac *pd = bus->priv;
  654. s6mii_enable(pd);
  655. if (s6mii_busy(pd, 256))
  656. return -ETIME;
  657. writel(phy_addr << S6_GMAC_MACMIIADDR_PHY |
  658. regnum << S6_GMAC_MACMIIADDR_REG,
  659. pd->reg + S6_GMAC_MACMIIADDR);
  660. writel(value, pd->reg + S6_GMAC_MACMIICTRL);
  661. if (s6mii_busy(pd, 256))
  662. return -ETIME;
  663. return 0;
  664. }
  665. static int s6mii_reset(struct mii_bus *bus)
  666. {
  667. struct s6gmac *pd = bus->priv;
  668. s6mii_enable(pd);
  669. if (s6mii_busy(pd, PHY_INIT_TIMEOUT))
  670. return -ETIME;
  671. return 0;
  672. }
  673. static void s6gmac_set_rgmii_txclock(struct s6gmac *pd)
  674. {
  675. u32 pllsel = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL);
  676. pllsel &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC);
  677. switch (pd->link.mbit) {
  678. case 10:
  679. pllsel |= S6_GREG1_PLLSEL_GMAC_2500KHZ << S6_GREG1_PLLSEL_GMAC;
  680. break;
  681. case 100:
  682. pllsel |= S6_GREG1_PLLSEL_GMAC_25MHZ << S6_GREG1_PLLSEL_GMAC;
  683. break;
  684. case 1000:
  685. pllsel |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC;
  686. break;
  687. default:
  688. return;
  689. }
  690. writel(pllsel, S6_REG_GREG1 + S6_GREG1_PLLSEL);
  691. }
  692. static inline void s6gmac_linkisup(struct net_device *dev, int isup)
  693. {
  694. struct s6gmac *pd = netdev_priv(dev);
  695. struct phy_device *phydev = pd->phydev;
  696. pd->link.full = phydev->duplex;
  697. pd->link.giga = (phydev->speed == 1000);
  698. if (pd->link.mbit != phydev->speed) {
  699. pd->link.mbit = phydev->speed;
  700. s6gmac_set_rgmii_txclock(pd);
  701. }
  702. pd->link.isup = isup;
  703. if (isup)
  704. netif_carrier_on(dev);
  705. phy_print_status(phydev);
  706. }
  707. static void s6gmac_adjust_link(struct net_device *dev)
  708. {
  709. struct s6gmac *pd = netdev_priv(dev);
  710. struct phy_device *phydev = pd->phydev;
  711. if (pd->link.isup &&
  712. (!phydev->link ||
  713. (pd->link.mbit != phydev->speed) ||
  714. (pd->link.full != phydev->duplex))) {
  715. pd->link.isup = 0;
  716. netif_tx_disable(dev);
  717. if (!phydev->link) {
  718. netif_carrier_off(dev);
  719. phy_print_status(phydev);
  720. }
  721. }
  722. if (!pd->link.isup && phydev->link) {
  723. if (pd->link.full != phydev->duplex) {
  724. u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2);
  725. if (phydev->duplex)
  726. maccfg |= 1 << S6_GMAC_MACCONF2_FULL;
  727. else
  728. maccfg &= ~(1 << S6_GMAC_MACCONF2_FULL);
  729. writel(maccfg, pd->reg + S6_GMAC_MACCONF2);
  730. }
  731. if (pd->link.giga != (phydev->speed == 1000)) {
  732. u32 fifocfg = readl(pd->reg + S6_GMAC_FIFOCONF5);
  733. u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2);
  734. maccfg &= ~(S6_GMAC_MACCONF2_IFMODE_MASK
  735. << S6_GMAC_MACCONF2_IFMODE);
  736. if (phydev->speed == 1000) {
  737. fifocfg |= 1 << S6_GMAC_FIFOCONF5_CFGBYTM;
  738. maccfg |= S6_GMAC_MACCONF2_IFMODE_BYTE
  739. << S6_GMAC_MACCONF2_IFMODE;
  740. } else {
  741. fifocfg &= ~(1 << S6_GMAC_FIFOCONF5_CFGBYTM);
  742. maccfg |= S6_GMAC_MACCONF2_IFMODE_NIBBLE
  743. << S6_GMAC_MACCONF2_IFMODE;
  744. }
  745. writel(fifocfg, pd->reg + S6_GMAC_FIFOCONF5);
  746. writel(maccfg, pd->reg + S6_GMAC_MACCONF2);
  747. }
  748. if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  749. netif_wake_queue(dev);
  750. s6gmac_linkisup(dev, 1);
  751. }
  752. }
  753. static inline int s6gmac_phy_start(struct net_device *dev)
  754. {
  755. struct s6gmac *pd = netdev_priv(dev);
  756. int i = 0;
  757. struct phy_device *p = NULL;
  758. while ((!(p = pd->mii.bus->phy_map[i])) && (i < PHY_MAX_ADDR))
  759. i++;
  760. p = phy_connect(dev, dev_name(&p->dev), &s6gmac_adjust_link, 0,
  761. PHY_INTERFACE_MODE_RGMII);
  762. if (IS_ERR(p)) {
  763. printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
  764. return PTR_ERR(p);
  765. }
  766. p->supported &= PHY_GBIT_FEATURES;
  767. p->advertising = p->supported;
  768. pd->phydev = p;
  769. return 0;
  770. }
  771. static inline void s6gmac_init_stats(struct net_device *dev)
  772. {
  773. struct s6gmac *pd = netdev_priv(dev);
  774. u32 mask;
  775. mask = 1 << S6_GMAC_STATCARRY1_RDRP |
  776. 1 << S6_GMAC_STATCARRY1_RJBR |
  777. 1 << S6_GMAC_STATCARRY1_RFRG |
  778. 1 << S6_GMAC_STATCARRY1_ROVR |
  779. 1 << S6_GMAC_STATCARRY1_RUND |
  780. 1 << S6_GMAC_STATCARRY1_RCDE |
  781. 1 << S6_GMAC_STATCARRY1_RFLR |
  782. 1 << S6_GMAC_STATCARRY1_RALN |
  783. 1 << S6_GMAC_STATCARRY1_RMCA |
  784. 1 << S6_GMAC_STATCARRY1_RFCS |
  785. 1 << S6_GMAC_STATCARRY1_RPKT |
  786. 1 << S6_GMAC_STATCARRY1_RBYT;
  787. writel(mask, pd->reg + S6_GMAC_STATCARRY(0));
  788. writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(0));
  789. mask = 1 << S6_GMAC_STATCARRY2_TDRP |
  790. 1 << S6_GMAC_STATCARRY2_TNCL |
  791. 1 << S6_GMAC_STATCARRY2_TXCL |
  792. 1 << S6_GMAC_STATCARRY2_TEDF |
  793. 1 << S6_GMAC_STATCARRY2_TPKT |
  794. 1 << S6_GMAC_STATCARRY2_TBYT |
  795. 1 << S6_GMAC_STATCARRY2_TFRG |
  796. 1 << S6_GMAC_STATCARRY2_TUND |
  797. 1 << S6_GMAC_STATCARRY2_TOVR |
  798. 1 << S6_GMAC_STATCARRY2_TFCS |
  799. 1 << S6_GMAC_STATCARRY2_TJBR;
  800. writel(mask, pd->reg + S6_GMAC_STATCARRY(1));
  801. writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(1));
  802. }
  803. static inline void s6gmac_init_dmac(struct net_device *dev)
  804. {
  805. struct s6gmac *pd = netdev_priv(dev);
  806. s6dmac_disable_chan(pd->tx_dma, pd->tx_chan);
  807. s6dmac_disable_chan(pd->rx_dma, pd->rx_chan);
  808. s6dmac_disable_error_irqs(pd->tx_dma, 1 << S6_HIFDMA_GMACTX);
  809. s6dmac_disable_error_irqs(pd->rx_dma, 1 << S6_HIFDMA_GMACRX);
  810. }
  811. static int s6gmac_tx(struct sk_buff *skb, struct net_device *dev)
  812. {
  813. struct s6gmac *pd = netdev_priv(dev);
  814. unsigned long flags;
  815. spin_lock_irqsave(&pd->lock, flags);
  816. dev->trans_start = jiffies;
  817. writel(skb->len << S6_GMAC_BURST_PREWR_LEN |
  818. 0 << S6_GMAC_BURST_PREWR_CFE |
  819. 1 << S6_GMAC_BURST_PREWR_PPE |
  820. 1 << S6_GMAC_BURST_PREWR_FCS |
  821. ((skb->len < ETH_ZLEN) ? 1 : 0) << S6_GMAC_BURST_PREWR_PAD,
  822. pd->reg + S6_GMAC_BURST_PREWR);
  823. s6dmac_put_fifo_cache(pd->tx_dma, pd->tx_chan,
  824. (u32)skb->data, pd->io, skb->len);
  825. if (s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  826. netif_stop_queue(dev);
  827. if (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >= S6_NUM_TX_SKB) {
  828. printk(KERN_ERR "GMAC BUG: skb tx ring overflow [%x, %x]\n",
  829. pd->tx_skb_o, pd->tx_skb_i);
  830. BUG();
  831. }
  832. pd->tx_skb[(pd->tx_skb_i++) % S6_NUM_TX_SKB] = skb;
  833. spin_unlock_irqrestore(&pd->lock, flags);
  834. return 0;
  835. }
  836. static void s6gmac_tx_timeout(struct net_device *dev)
  837. {
  838. struct s6gmac *pd = netdev_priv(dev);
  839. unsigned long flags;
  840. spin_lock_irqsave(&pd->lock, flags);
  841. s6gmac_tx_interrupt(dev);
  842. spin_unlock_irqrestore(&pd->lock, flags);
  843. }
  844. static int s6gmac_open(struct net_device *dev)
  845. {
  846. struct s6gmac *pd = netdev_priv(dev);
  847. unsigned long flags;
  848. phy_read_status(pd->phydev);
  849. spin_lock_irqsave(&pd->lock, flags);
  850. pd->link.mbit = 0;
  851. s6gmac_linkisup(dev, pd->phydev->link);
  852. s6gmac_init_device(dev);
  853. s6gmac_init_stats(dev);
  854. s6gmac_init_dmac(dev);
  855. s6gmac_rx_fillfifo(pd);
  856. s6dmac_enable_chan(pd->rx_dma, pd->rx_chan,
  857. 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1);
  858. s6dmac_enable_chan(pd->tx_dma, pd->tx_chan,
  859. 2, 0, 1, 0, 0, 0, 0, 7, -1, 2, 0, 1);
  860. writel(0 << S6_GMAC_HOST_INT_TXBURSTOVER |
  861. 0 << S6_GMAC_HOST_INT_TXPREWOVER |
  862. 0 << S6_GMAC_HOST_INT_RXBURSTUNDER |
  863. 0 << S6_GMAC_HOST_INT_RXPOSTRFULL |
  864. 0 << S6_GMAC_HOST_INT_RXPOSTRUNDER,
  865. pd->reg + S6_GMAC_HOST_INTMASK);
  866. spin_unlock_irqrestore(&pd->lock, flags);
  867. phy_start(pd->phydev);
  868. netif_start_queue(dev);
  869. return 0;
  870. }
  871. static int s6gmac_stop(struct net_device *dev)
  872. {
  873. struct s6gmac *pd = netdev_priv(dev);
  874. unsigned long flags;
  875. netif_stop_queue(dev);
  876. phy_stop(pd->phydev);
  877. spin_lock_irqsave(&pd->lock, flags);
  878. s6gmac_init_dmac(dev);
  879. s6gmac_stop_device(dev);
  880. while (pd->tx_skb_i != pd->tx_skb_o)
  881. dev_kfree_skb(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]);
  882. while (pd->rx_skb_i != pd->rx_skb_o)
  883. dev_kfree_skb(pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]);
  884. spin_unlock_irqrestore(&pd->lock, flags);
  885. return 0;
  886. }
  887. static struct net_device_stats *s6gmac_stats(struct net_device *dev)
  888. {
  889. struct s6gmac *pd = netdev_priv(dev);
  890. struct net_device_stats *st = (struct net_device_stats *)&pd->stats;
  891. int i;
  892. do {
  893. unsigned long flags;
  894. spin_lock_irqsave(&pd->lock, flags);
  895. for (i = 0; i < sizeof(pd->stats) / sizeof(unsigned long); i++)
  896. pd->stats[i] =
  897. pd->carry[i] << (S6_GMAC_STAT_SIZE_MIN - 1);
  898. s6gmac_stats_collect(pd, &statinf[0][0]);
  899. s6gmac_stats_collect(pd, &statinf[1][0]);
  900. i = s6gmac_stats_pending(pd, 0) |
  901. s6gmac_stats_pending(pd, 1);
  902. spin_unlock_irqrestore(&pd->lock, flags);
  903. } while (i);
  904. st->rx_errors = st->rx_crc_errors +
  905. st->rx_frame_errors +
  906. st->rx_length_errors +
  907. st->rx_missed_errors;
  908. st->tx_errors += st->tx_aborted_errors;
  909. return st;
  910. }
  911. static int __devinit s6gmac_probe(struct platform_device *pdev)
  912. {
  913. struct net_device *dev;
  914. struct s6gmac *pd;
  915. int res;
  916. unsigned long i;
  917. struct mii_bus *mb;
  918. dev = alloc_etherdev(sizeof(*pd));
  919. if (!dev) {
  920. printk(KERN_ERR DRV_PRMT "etherdev alloc failed, aborting.\n");
  921. return -ENOMEM;
  922. }
  923. dev->open = s6gmac_open;
  924. dev->stop = s6gmac_stop;
  925. dev->hard_start_xmit = s6gmac_tx;
  926. dev->tx_timeout = s6gmac_tx_timeout;
  927. dev->watchdog_timeo = HZ;
  928. dev->get_stats = s6gmac_stats;
  929. dev->irq = platform_get_irq(pdev, 0);
  930. pd = netdev_priv(dev);
  931. memset(pd, 0, sizeof(*pd));
  932. spin_lock_init(&pd->lock);
  933. pd->reg = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start;
  934. i = platform_get_resource(pdev, IORESOURCE_DMA, 0)->start;
  935. pd->tx_dma = DMA_MASK_DMAC(i);
  936. pd->tx_chan = DMA_INDEX_CHNL(i);
  937. i = platform_get_resource(pdev, IORESOURCE_DMA, 1)->start;
  938. pd->rx_dma = DMA_MASK_DMAC(i);
  939. pd->rx_chan = DMA_INDEX_CHNL(i);
  940. pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
  941. res = request_irq(dev->irq, &s6gmac_interrupt, 0, dev->name, dev);
  942. if (res) {
  943. printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq);
  944. goto errirq;
  945. }
  946. res = register_netdev(dev);
  947. if (res) {
  948. printk(KERN_ERR DRV_PRMT "error registering device %s\n",
  949. dev->name);
  950. goto errdev;
  951. }
  952. mb = mdiobus_alloc();
  953. if (!mb) {
  954. printk(KERN_ERR DRV_PRMT "error allocating mii bus\n");
  955. goto errmii;
  956. }
  957. mb->name = "s6gmac_mii";
  958. mb->read = s6mii_read;
  959. mb->write = s6mii_write;
  960. mb->reset = s6mii_reset;
  961. mb->priv = pd;
  962. snprintf(mb->id, MII_BUS_ID_SIZE, "0");
  963. mb->phy_mask = ~(1 << 0);
  964. mb->irq = &pd->mii.irq[0];
  965. for (i = 0; i < PHY_MAX_ADDR; i++) {
  966. int n = platform_get_irq(pdev, i + 1);
  967. if (n < 0)
  968. n = PHY_POLL;
  969. pd->mii.irq[i] = n;
  970. }
  971. mdiobus_register(mb);
  972. pd->mii.bus = mb;
  973. res = s6gmac_phy_start(dev);
  974. if (res)
  975. return res;
  976. platform_set_drvdata(pdev, dev);
  977. return 0;
  978. errmii:
  979. unregister_netdev(dev);
  980. errdev:
  981. free_irq(dev->irq, dev);
  982. errirq:
  983. free_netdev(dev);
  984. return res;
  985. }
  986. static int __devexit s6gmac_remove(struct platform_device *pdev)
  987. {
  988. struct net_device *dev = platform_get_drvdata(pdev);
  989. if (dev) {
  990. struct s6gmac *pd = netdev_priv(dev);
  991. mdiobus_unregister(pd->mii.bus);
  992. unregister_netdev(dev);
  993. free_irq(dev->irq, dev);
  994. free_netdev(dev);
  995. platform_set_drvdata(pdev, NULL);
  996. }
  997. return 0;
  998. }
  999. static struct platform_driver s6gmac_driver = {
  1000. .probe = s6gmac_probe,
  1001. .remove = __devexit_p(s6gmac_remove),
  1002. .driver = {
  1003. .name = "s6gmac",
  1004. .owner = THIS_MODULE,
  1005. },
  1006. };
  1007. static int __init s6gmac_init(void)
  1008. {
  1009. printk(KERN_INFO DRV_PRMT "S6 GMAC ethernet driver\n");
  1010. return platform_driver_register(&s6gmac_driver);
  1011. }
  1012. static void __exit s6gmac_exit(void)
  1013. {
  1014. platform_driver_unregister(&s6gmac_driver);
  1015. }
  1016. module_init(s6gmac_init);
  1017. module_exit(s6gmac_exit);
  1018. MODULE_LICENSE("GPL");
  1019. MODULE_DESCRIPTION("S6105 on chip Ethernet driver");
  1020. MODULE_AUTHOR("Oskar Schirmer <os@emlix.com>");