s6gmac.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  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->protocol = eth_type_trans(skb, dev);
  386. skb->ip_summed = CHECKSUM_UNNECESSARY;
  387. netif_rx(skb);
  388. }
  389. }
  390. }
  391. static void s6gmac_tx_interrupt(struct net_device *dev)
  392. {
  393. struct s6gmac *pd = netdev_priv(dev);
  394. while (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >
  395. s6dmac_pending_count(pd->tx_dma, pd->tx_chan)) {
  396. dev_kfree_skb_irq(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]);
  397. }
  398. if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  399. netif_wake_queue(dev);
  400. }
  401. struct s6gmac_statinf {
  402. unsigned reg_size : 4; /* 0: unused */
  403. unsigned reg_off : 6;
  404. unsigned net_index : 6;
  405. };
  406. #define S6_STATS_B (8 * sizeof(u32))
  407. #define S6_STATS_C(b, r, f) [b] = { \
  408. BUILD_BUG_ON_ZERO(r##_SIZE < S6_GMAC_STAT_SIZE_MIN) + \
  409. BUILD_BUG_ON_ZERO((r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1)) \
  410. >= (1<<4)) + \
  411. r##_SIZE - (S6_GMAC_STAT_SIZE_MIN - 1), \
  412. BUILD_BUG_ON_ZERO(((unsigned)((r - S6_GMAC_STAT_REGS) / sizeof(u32))) \
  413. >= ((1<<6)-1)) + \
  414. (r - S6_GMAC_STAT_REGS) / sizeof(u32), \
  415. BUILD_BUG_ON_ZERO((offsetof(struct net_device_stats, f)) \
  416. % sizeof(unsigned long)) + \
  417. BUILD_BUG_ON_ZERO((((unsigned)(offsetof(struct net_device_stats, f)) \
  418. / sizeof(unsigned long)) >= (1<<6))) + \
  419. BUILD_BUG_ON_ZERO((sizeof(((struct net_device_stats *)0)->f) \
  420. != sizeof(unsigned long))) + \
  421. (offsetof(struct net_device_stats, f)) / sizeof(unsigned long)},
  422. static const struct s6gmac_statinf statinf[2][S6_STATS_B] = { {
  423. S6_STATS_C(S6_GMAC_STATCARRY1_RBYT, S6_GMAC_STATRBYT, rx_bytes)
  424. S6_STATS_C(S6_GMAC_STATCARRY1_RPKT, S6_GMAC_STATRPKT, rx_packets)
  425. S6_STATS_C(S6_GMAC_STATCARRY1_RFCS, S6_GMAC_STATRFCS, rx_crc_errors)
  426. S6_STATS_C(S6_GMAC_STATCARRY1_RMCA, S6_GMAC_STATRMCA, multicast)
  427. S6_STATS_C(S6_GMAC_STATCARRY1_RALN, S6_GMAC_STATRALN, rx_frame_errors)
  428. S6_STATS_C(S6_GMAC_STATCARRY1_RFLR, S6_GMAC_STATRFLR, rx_length_errors)
  429. S6_STATS_C(S6_GMAC_STATCARRY1_RCDE, S6_GMAC_STATRCDE, rx_missed_errors)
  430. S6_STATS_C(S6_GMAC_STATCARRY1_RUND, S6_GMAC_STATRUND, rx_length_errors)
  431. S6_STATS_C(S6_GMAC_STATCARRY1_ROVR, S6_GMAC_STATROVR, rx_length_errors)
  432. S6_STATS_C(S6_GMAC_STATCARRY1_RFRG, S6_GMAC_STATRFRG, rx_crc_errors)
  433. S6_STATS_C(S6_GMAC_STATCARRY1_RJBR, S6_GMAC_STATRJBR, rx_crc_errors)
  434. S6_STATS_C(S6_GMAC_STATCARRY1_RDRP, S6_GMAC_STATRDRP, rx_dropped)
  435. }, {
  436. S6_STATS_C(S6_GMAC_STATCARRY2_TBYT, S6_GMAC_STATTBYT, tx_bytes)
  437. S6_STATS_C(S6_GMAC_STATCARRY2_TPKT, S6_GMAC_STATTPKT, tx_packets)
  438. S6_STATS_C(S6_GMAC_STATCARRY2_TEDF, S6_GMAC_STATTEDF, tx_aborted_errors)
  439. S6_STATS_C(S6_GMAC_STATCARRY2_TXCL, S6_GMAC_STATTXCL, tx_aborted_errors)
  440. S6_STATS_C(S6_GMAC_STATCARRY2_TNCL, S6_GMAC_STATTNCL, collisions)
  441. S6_STATS_C(S6_GMAC_STATCARRY2_TDRP, S6_GMAC_STATTDRP, tx_dropped)
  442. S6_STATS_C(S6_GMAC_STATCARRY2_TJBR, S6_GMAC_STATTJBR, tx_errors)
  443. S6_STATS_C(S6_GMAC_STATCARRY2_TFCS, S6_GMAC_STATTFCS, tx_errors)
  444. S6_STATS_C(S6_GMAC_STATCARRY2_TOVR, S6_GMAC_STATTOVR, tx_errors)
  445. S6_STATS_C(S6_GMAC_STATCARRY2_TUND, S6_GMAC_STATTUND, tx_errors)
  446. S6_STATS_C(S6_GMAC_STATCARRY2_TFRG, S6_GMAC_STATTFRG, tx_errors)
  447. } };
  448. static void s6gmac_stats_collect(struct s6gmac *pd,
  449. const struct s6gmac_statinf *inf)
  450. {
  451. int b;
  452. for (b = 0; b < S6_STATS_B; b++) {
  453. if (inf[b].reg_size) {
  454. pd->stats[inf[b].net_index] +=
  455. readl(pd->reg + S6_GMAC_STAT_REGS
  456. + sizeof(u32) * inf[b].reg_off);
  457. }
  458. }
  459. }
  460. static void s6gmac_stats_carry(struct s6gmac *pd,
  461. const struct s6gmac_statinf *inf, u32 mask)
  462. {
  463. int b;
  464. while (mask) {
  465. b = fls(mask) - 1;
  466. mask &= ~(1 << b);
  467. pd->carry[inf[b].net_index] += (1 << inf[b].reg_size);
  468. }
  469. }
  470. static inline u32 s6gmac_stats_pending(struct s6gmac *pd, int carry)
  471. {
  472. int r = readl(pd->reg + S6_GMAC_STATCARRY(carry)) &
  473. ~readl(pd->reg + S6_GMAC_STATCARRYMSK(carry));
  474. return r;
  475. }
  476. static inline void s6gmac_stats_interrupt(struct s6gmac *pd, int carry)
  477. {
  478. u32 mask;
  479. mask = s6gmac_stats_pending(pd, carry);
  480. if (mask) {
  481. writel(mask, pd->reg + S6_GMAC_STATCARRY(carry));
  482. s6gmac_stats_carry(pd, &statinf[carry][0], mask);
  483. }
  484. }
  485. static irqreturn_t s6gmac_interrupt(int irq, void *dev_id)
  486. {
  487. struct net_device *dev = (struct net_device *)dev_id;
  488. struct s6gmac *pd = netdev_priv(dev);
  489. if (!dev)
  490. return IRQ_NONE;
  491. spin_lock(&pd->lock);
  492. if (s6dmac_termcnt_irq(pd->rx_dma, pd->rx_chan))
  493. s6gmac_rx_interrupt(dev);
  494. s6gmac_rx_fillfifo(pd);
  495. if (s6dmac_termcnt_irq(pd->tx_dma, pd->tx_chan))
  496. s6gmac_tx_interrupt(dev);
  497. s6gmac_stats_interrupt(pd, 0);
  498. s6gmac_stats_interrupt(pd, 1);
  499. spin_unlock(&pd->lock);
  500. return IRQ_HANDLED;
  501. }
  502. static inline void s6gmac_set_dstaddr(struct s6gmac *pd, int n,
  503. u32 addrlo, u32 addrhi, u32 masklo, u32 maskhi)
  504. {
  505. writel(addrlo, pd->reg + S6_GMAC_HOST_DSTADDRLO(n));
  506. writel(addrhi, pd->reg + S6_GMAC_HOST_DSTADDRHI(n));
  507. writel(masklo, pd->reg + S6_GMAC_HOST_DSTMASKLO(n));
  508. writel(maskhi, pd->reg + S6_GMAC_HOST_DSTMASKHI(n));
  509. }
  510. static inline void s6gmac_stop_device(struct net_device *dev)
  511. {
  512. struct s6gmac *pd = netdev_priv(dev);
  513. writel(0, pd->reg + S6_GMAC_MACCONF1);
  514. }
  515. static inline void s6gmac_init_device(struct net_device *dev)
  516. {
  517. struct s6gmac *pd = netdev_priv(dev);
  518. int is_rgmii = !!(pd->phydev->supported
  519. & (SUPPORTED_1000baseT_Full | SUPPORTED_1000baseT_Half));
  520. #if 0
  521. writel(1 << S6_GMAC_MACCONF1_SYNCTX |
  522. 1 << S6_GMAC_MACCONF1_SYNCRX |
  523. 1 << S6_GMAC_MACCONF1_TXFLOWCTRL |
  524. 1 << S6_GMAC_MACCONF1_RXFLOWCTRL |
  525. 1 << S6_GMAC_MACCONF1_RESTXFUNC |
  526. 1 << S6_GMAC_MACCONF1_RESRXFUNC |
  527. 1 << S6_GMAC_MACCONF1_RESTXMACCTRL |
  528. 1 << S6_GMAC_MACCONF1_RESRXMACCTRL,
  529. pd->reg + S6_GMAC_MACCONF1);
  530. #endif
  531. writel(1 << S6_GMAC_MACCONF1_SOFTRES, pd->reg + S6_GMAC_MACCONF1);
  532. udelay(1000);
  533. writel(1 << S6_GMAC_MACCONF1_TXENA | 1 << S6_GMAC_MACCONF1_RXENA,
  534. pd->reg + S6_GMAC_MACCONF1);
  535. writel(1 << S6_GMAC_HOST_PBLKCTRL_TXSRES |
  536. 1 << S6_GMAC_HOST_PBLKCTRL_RXSRES,
  537. pd->reg + S6_GMAC_HOST_PBLKCTRL);
  538. writel(S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ |
  539. S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ |
  540. 1 << S6_GMAC_HOST_PBLKCTRL_STATENA |
  541. 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR |
  542. is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII,
  543. pd->reg + S6_GMAC_HOST_PBLKCTRL);
  544. writel(1 << S6_GMAC_MACCONF1_TXENA |
  545. 1 << S6_GMAC_MACCONF1_RXENA |
  546. (dev->flags & IFF_LOOPBACK ? 1 : 0)
  547. << S6_GMAC_MACCONF1_LOOPBACK,
  548. pd->reg + S6_GMAC_MACCONF1);
  549. writel(dev->mtu && (dev->mtu < (S6_MAX_FRLEN - ETH_HLEN-ETH_FCS_LEN)) ?
  550. dev->mtu+ETH_HLEN+ETH_FCS_LEN : S6_MAX_FRLEN,
  551. pd->reg + S6_GMAC_MACMAXFRAMELEN);
  552. writel((pd->link.full ? 1 : 0) << S6_GMAC_MACCONF2_FULL |
  553. 1 << S6_GMAC_MACCONF2_PADCRCENA |
  554. 1 << S6_GMAC_MACCONF2_LENGTHFCHK |
  555. (pd->link.giga ?
  556. S6_GMAC_MACCONF2_IFMODE_BYTE :
  557. S6_GMAC_MACCONF2_IFMODE_NIBBLE)
  558. << S6_GMAC_MACCONF2_IFMODE |
  559. 7 << S6_GMAC_MACCONF2_PREAMBLELEN,
  560. pd->reg + S6_GMAC_MACCONF2);
  561. writel(0, pd->reg + S6_GMAC_MACSTATADDR1);
  562. writel(0, pd->reg + S6_GMAC_MACSTATADDR2);
  563. writel(1 << S6_GMAC_FIFOCONF0_WTMENREQ |
  564. 1 << S6_GMAC_FIFOCONF0_SRFENREQ |
  565. 1 << S6_GMAC_FIFOCONF0_FRFENREQ |
  566. 1 << S6_GMAC_FIFOCONF0_STFENREQ |
  567. 1 << S6_GMAC_FIFOCONF0_FTFENREQ,
  568. pd->reg + S6_GMAC_FIFOCONF0);
  569. writel(128 << S6_GMAC_FIFOCONF3_CFGFTTH |
  570. 128 << S6_GMAC_FIFOCONF3_CFGHWMFT,
  571. pd->reg + S6_GMAC_FIFOCONF3);
  572. writel((S6_GMAC_FIFOCONF_RSV_MASK & ~(
  573. 1 << S6_GMAC_FIFOCONF_RSV_RUNT |
  574. 1 << S6_GMAC_FIFOCONF_RSV_CRCERR |
  575. 1 << S6_GMAC_FIFOCONF_RSV_OK |
  576. 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE |
  577. 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME |
  578. 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL |
  579. 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE |
  580. 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED)) |
  581. 1 << S6_GMAC_FIFOCONF5_DROPLT64 |
  582. pd->link.giga << S6_GMAC_FIFOCONF5_CFGBYTM |
  583. 1 << S6_GMAC_FIFOCONF5_RXDROPSIZE,
  584. pd->reg + S6_GMAC_FIFOCONF5);
  585. writel(1 << S6_GMAC_FIFOCONF_RSV_RUNT |
  586. 1 << S6_GMAC_FIFOCONF_RSV_CRCERR |
  587. 1 << S6_GMAC_FIFOCONF_RSV_DRIBBLE |
  588. 1 << S6_GMAC_FIFOCONF_RSV_CTRLFRAME |
  589. 1 << S6_GMAC_FIFOCONF_RSV_PAUSECTRL |
  590. 1 << S6_GMAC_FIFOCONF_RSV_UNOPCODE |
  591. 1 << S6_GMAC_FIFOCONF_RSV_TRUNCATED,
  592. pd->reg + S6_GMAC_FIFOCONF4);
  593. s6gmac_set_dstaddr(pd, 0,
  594. 0xFFFFFFFF, 0x0000FFFF, 0xFFFFFFFF, 0x0000FFFF);
  595. s6gmac_set_dstaddr(pd, 1,
  596. dev->dev_addr[5] |
  597. dev->dev_addr[4] << 8 |
  598. dev->dev_addr[3] << 16 |
  599. dev->dev_addr[2] << 24,
  600. dev->dev_addr[1] |
  601. dev->dev_addr[0] << 8,
  602. 0xFFFFFFFF, 0x0000FFFF);
  603. s6gmac_set_dstaddr(pd, 2,
  604. 0x00000000, 0x00000100, 0x00000000, 0x00000100);
  605. s6gmac_set_dstaddr(pd, 3,
  606. 0x00000000, 0x00000000, 0x00000000, 0x00000000);
  607. writel(1 << S6_GMAC_HOST_PBLKCTRL_TXENA |
  608. 1 << S6_GMAC_HOST_PBLKCTRL_RXENA |
  609. S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_TXBSIZ |
  610. S6_GMAC_HOST_PBLKCTRL_SIZ_128 << S6_GMAC_HOST_PBLKCTRL_RXBSIZ |
  611. 1 << S6_GMAC_HOST_PBLKCTRL_STATENA |
  612. 1 << S6_GMAC_HOST_PBLKCTRL_STATCLEAR |
  613. is_rgmii << S6_GMAC_HOST_PBLKCTRL_RGMII,
  614. pd->reg + S6_GMAC_HOST_PBLKCTRL);
  615. }
  616. static void s6mii_enable(struct s6gmac *pd)
  617. {
  618. writel(readl(pd->reg + S6_GMAC_MACCONF1) &
  619. ~(1 << S6_GMAC_MACCONF1_SOFTRES),
  620. pd->reg + S6_GMAC_MACCONF1);
  621. writel((readl(pd->reg + S6_GMAC_MACMIICONF)
  622. & ~(S6_GMAC_MACMIICONF_CSEL_MASK << S6_GMAC_MACMIICONF_CSEL))
  623. | (S6_GMAC_MACMIICONF_CSEL_DIV168 << S6_GMAC_MACMIICONF_CSEL),
  624. pd->reg + S6_GMAC_MACMIICONF);
  625. }
  626. static int s6mii_busy(struct s6gmac *pd, int tmo)
  627. {
  628. while (readl(pd->reg + S6_GMAC_MACMIIINDI)) {
  629. if (--tmo == 0)
  630. return -ETIME;
  631. udelay(64);
  632. }
  633. return 0;
  634. }
  635. static int s6mii_read(struct mii_bus *bus, int phy_addr, int regnum)
  636. {
  637. struct s6gmac *pd = bus->priv;
  638. s6mii_enable(pd);
  639. if (s6mii_busy(pd, 256))
  640. return -ETIME;
  641. writel(phy_addr << S6_GMAC_MACMIIADDR_PHY |
  642. regnum << S6_GMAC_MACMIIADDR_REG,
  643. pd->reg + S6_GMAC_MACMIIADDR);
  644. writel(1 << S6_GMAC_MACMIICMD_READ, pd->reg + S6_GMAC_MACMIICMD);
  645. writel(0, pd->reg + S6_GMAC_MACMIICMD);
  646. if (s6mii_busy(pd, 256))
  647. return -ETIME;
  648. return (u16)readl(pd->reg + S6_GMAC_MACMIISTAT);
  649. }
  650. static int s6mii_write(struct mii_bus *bus, int phy_addr, int regnum, u16 value)
  651. {
  652. struct s6gmac *pd = bus->priv;
  653. s6mii_enable(pd);
  654. if (s6mii_busy(pd, 256))
  655. return -ETIME;
  656. writel(phy_addr << S6_GMAC_MACMIIADDR_PHY |
  657. regnum << S6_GMAC_MACMIIADDR_REG,
  658. pd->reg + S6_GMAC_MACMIIADDR);
  659. writel(value, pd->reg + S6_GMAC_MACMIICTRL);
  660. if (s6mii_busy(pd, 256))
  661. return -ETIME;
  662. return 0;
  663. }
  664. static int s6mii_reset(struct mii_bus *bus)
  665. {
  666. struct s6gmac *pd = bus->priv;
  667. s6mii_enable(pd);
  668. if (s6mii_busy(pd, PHY_INIT_TIMEOUT))
  669. return -ETIME;
  670. return 0;
  671. }
  672. static void s6gmac_set_rgmii_txclock(struct s6gmac *pd)
  673. {
  674. u32 pllsel = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL);
  675. pllsel &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC);
  676. switch (pd->link.mbit) {
  677. case 10:
  678. pllsel |= S6_GREG1_PLLSEL_GMAC_2500KHZ << S6_GREG1_PLLSEL_GMAC;
  679. break;
  680. case 100:
  681. pllsel |= S6_GREG1_PLLSEL_GMAC_25MHZ << S6_GREG1_PLLSEL_GMAC;
  682. break;
  683. case 1000:
  684. pllsel |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC;
  685. break;
  686. default:
  687. return;
  688. }
  689. writel(pllsel, S6_REG_GREG1 + S6_GREG1_PLLSEL);
  690. }
  691. static inline void s6gmac_linkisup(struct net_device *dev, int isup)
  692. {
  693. struct s6gmac *pd = netdev_priv(dev);
  694. struct phy_device *phydev = pd->phydev;
  695. pd->link.full = phydev->duplex;
  696. pd->link.giga = (phydev->speed == 1000);
  697. if (pd->link.mbit != phydev->speed) {
  698. pd->link.mbit = phydev->speed;
  699. s6gmac_set_rgmii_txclock(pd);
  700. }
  701. pd->link.isup = isup;
  702. if (isup)
  703. netif_carrier_on(dev);
  704. phy_print_status(phydev);
  705. }
  706. static void s6gmac_adjust_link(struct net_device *dev)
  707. {
  708. struct s6gmac *pd = netdev_priv(dev);
  709. struct phy_device *phydev = pd->phydev;
  710. if (pd->link.isup &&
  711. (!phydev->link ||
  712. (pd->link.mbit != phydev->speed) ||
  713. (pd->link.full != phydev->duplex))) {
  714. pd->link.isup = 0;
  715. netif_tx_disable(dev);
  716. if (!phydev->link) {
  717. netif_carrier_off(dev);
  718. phy_print_status(phydev);
  719. }
  720. }
  721. if (!pd->link.isup && phydev->link) {
  722. if (pd->link.full != phydev->duplex) {
  723. u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2);
  724. if (phydev->duplex)
  725. maccfg |= 1 << S6_GMAC_MACCONF2_FULL;
  726. else
  727. maccfg &= ~(1 << S6_GMAC_MACCONF2_FULL);
  728. writel(maccfg, pd->reg + S6_GMAC_MACCONF2);
  729. }
  730. if (pd->link.giga != (phydev->speed == 1000)) {
  731. u32 fifocfg = readl(pd->reg + S6_GMAC_FIFOCONF5);
  732. u32 maccfg = readl(pd->reg + S6_GMAC_MACCONF2);
  733. maccfg &= ~(S6_GMAC_MACCONF2_IFMODE_MASK
  734. << S6_GMAC_MACCONF2_IFMODE);
  735. if (phydev->speed == 1000) {
  736. fifocfg |= 1 << S6_GMAC_FIFOCONF5_CFGBYTM;
  737. maccfg |= S6_GMAC_MACCONF2_IFMODE_BYTE
  738. << S6_GMAC_MACCONF2_IFMODE;
  739. } else {
  740. fifocfg &= ~(1 << S6_GMAC_FIFOCONF5_CFGBYTM);
  741. maccfg |= S6_GMAC_MACCONF2_IFMODE_NIBBLE
  742. << S6_GMAC_MACCONF2_IFMODE;
  743. }
  744. writel(fifocfg, pd->reg + S6_GMAC_FIFOCONF5);
  745. writel(maccfg, pd->reg + S6_GMAC_MACCONF2);
  746. }
  747. if (!s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  748. netif_wake_queue(dev);
  749. s6gmac_linkisup(dev, 1);
  750. }
  751. }
  752. static inline int s6gmac_phy_start(struct net_device *dev)
  753. {
  754. struct s6gmac *pd = netdev_priv(dev);
  755. int i = 0;
  756. struct phy_device *p = NULL;
  757. while ((i < PHY_MAX_ADDR) && (!(p = pd->mii.bus->phy_map[i])))
  758. i++;
  759. p = phy_connect(dev, dev_name(&p->dev), &s6gmac_adjust_link, 0,
  760. PHY_INTERFACE_MODE_RGMII);
  761. if (IS_ERR(p)) {
  762. printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
  763. return PTR_ERR(p);
  764. }
  765. p->supported &= PHY_GBIT_FEATURES;
  766. p->advertising = p->supported;
  767. pd->phydev = p;
  768. return 0;
  769. }
  770. static inline void s6gmac_init_stats(struct net_device *dev)
  771. {
  772. struct s6gmac *pd = netdev_priv(dev);
  773. u32 mask;
  774. mask = 1 << S6_GMAC_STATCARRY1_RDRP |
  775. 1 << S6_GMAC_STATCARRY1_RJBR |
  776. 1 << S6_GMAC_STATCARRY1_RFRG |
  777. 1 << S6_GMAC_STATCARRY1_ROVR |
  778. 1 << S6_GMAC_STATCARRY1_RUND |
  779. 1 << S6_GMAC_STATCARRY1_RCDE |
  780. 1 << S6_GMAC_STATCARRY1_RFLR |
  781. 1 << S6_GMAC_STATCARRY1_RALN |
  782. 1 << S6_GMAC_STATCARRY1_RMCA |
  783. 1 << S6_GMAC_STATCARRY1_RFCS |
  784. 1 << S6_GMAC_STATCARRY1_RPKT |
  785. 1 << S6_GMAC_STATCARRY1_RBYT;
  786. writel(mask, pd->reg + S6_GMAC_STATCARRY(0));
  787. writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(0));
  788. mask = 1 << S6_GMAC_STATCARRY2_TDRP |
  789. 1 << S6_GMAC_STATCARRY2_TNCL |
  790. 1 << S6_GMAC_STATCARRY2_TXCL |
  791. 1 << S6_GMAC_STATCARRY2_TEDF |
  792. 1 << S6_GMAC_STATCARRY2_TPKT |
  793. 1 << S6_GMAC_STATCARRY2_TBYT |
  794. 1 << S6_GMAC_STATCARRY2_TFRG |
  795. 1 << S6_GMAC_STATCARRY2_TUND |
  796. 1 << S6_GMAC_STATCARRY2_TOVR |
  797. 1 << S6_GMAC_STATCARRY2_TFCS |
  798. 1 << S6_GMAC_STATCARRY2_TJBR;
  799. writel(mask, pd->reg + S6_GMAC_STATCARRY(1));
  800. writel(~mask, pd->reg + S6_GMAC_STATCARRYMSK(1));
  801. }
  802. static inline void s6gmac_init_dmac(struct net_device *dev)
  803. {
  804. struct s6gmac *pd = netdev_priv(dev);
  805. s6dmac_disable_chan(pd->tx_dma, pd->tx_chan);
  806. s6dmac_disable_chan(pd->rx_dma, pd->rx_chan);
  807. s6dmac_disable_error_irqs(pd->tx_dma, 1 << S6_HIFDMA_GMACTX);
  808. s6dmac_disable_error_irqs(pd->rx_dma, 1 << S6_HIFDMA_GMACRX);
  809. }
  810. static int s6gmac_tx(struct sk_buff *skb, struct net_device *dev)
  811. {
  812. struct s6gmac *pd = netdev_priv(dev);
  813. unsigned long flags;
  814. spin_lock_irqsave(&pd->lock, flags);
  815. writel(skb->len << S6_GMAC_BURST_PREWR_LEN |
  816. 0 << S6_GMAC_BURST_PREWR_CFE |
  817. 1 << S6_GMAC_BURST_PREWR_PPE |
  818. 1 << S6_GMAC_BURST_PREWR_FCS |
  819. ((skb->len < ETH_ZLEN) ? 1 : 0) << S6_GMAC_BURST_PREWR_PAD,
  820. pd->reg + S6_GMAC_BURST_PREWR);
  821. s6dmac_put_fifo_cache(pd->tx_dma, pd->tx_chan,
  822. (u32)skb->data, pd->io, skb->len);
  823. if (s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  824. netif_stop_queue(dev);
  825. if (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >= S6_NUM_TX_SKB) {
  826. printk(KERN_ERR "GMAC BUG: skb tx ring overflow [%x, %x]\n",
  827. pd->tx_skb_o, pd->tx_skb_i);
  828. BUG();
  829. }
  830. pd->tx_skb[(pd->tx_skb_i++) % S6_NUM_TX_SKB] = skb;
  831. spin_unlock_irqrestore(&pd->lock, flags);
  832. return 0;
  833. }
  834. static void s6gmac_tx_timeout(struct net_device *dev)
  835. {
  836. struct s6gmac *pd = netdev_priv(dev);
  837. unsigned long flags;
  838. spin_lock_irqsave(&pd->lock, flags);
  839. s6gmac_tx_interrupt(dev);
  840. spin_unlock_irqrestore(&pd->lock, flags);
  841. }
  842. static int s6gmac_open(struct net_device *dev)
  843. {
  844. struct s6gmac *pd = netdev_priv(dev);
  845. unsigned long flags;
  846. phy_read_status(pd->phydev);
  847. spin_lock_irqsave(&pd->lock, flags);
  848. pd->link.mbit = 0;
  849. s6gmac_linkisup(dev, pd->phydev->link);
  850. s6gmac_init_device(dev);
  851. s6gmac_init_stats(dev);
  852. s6gmac_init_dmac(dev);
  853. s6gmac_rx_fillfifo(pd);
  854. s6dmac_enable_chan(pd->rx_dma, pd->rx_chan,
  855. 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1);
  856. s6dmac_enable_chan(pd->tx_dma, pd->tx_chan,
  857. 2, 0, 1, 0, 0, 0, 0, 7, -1, 2, 0, 1);
  858. writel(0 << S6_GMAC_HOST_INT_TXBURSTOVER |
  859. 0 << S6_GMAC_HOST_INT_TXPREWOVER |
  860. 0 << S6_GMAC_HOST_INT_RXBURSTUNDER |
  861. 0 << S6_GMAC_HOST_INT_RXPOSTRFULL |
  862. 0 << S6_GMAC_HOST_INT_RXPOSTRUNDER,
  863. pd->reg + S6_GMAC_HOST_INTMASK);
  864. spin_unlock_irqrestore(&pd->lock, flags);
  865. phy_start(pd->phydev);
  866. netif_start_queue(dev);
  867. return 0;
  868. }
  869. static int s6gmac_stop(struct net_device *dev)
  870. {
  871. struct s6gmac *pd = netdev_priv(dev);
  872. unsigned long flags;
  873. netif_stop_queue(dev);
  874. phy_stop(pd->phydev);
  875. spin_lock_irqsave(&pd->lock, flags);
  876. s6gmac_init_dmac(dev);
  877. s6gmac_stop_device(dev);
  878. while (pd->tx_skb_i != pd->tx_skb_o)
  879. dev_kfree_skb(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]);
  880. while (pd->rx_skb_i != pd->rx_skb_o)
  881. dev_kfree_skb(pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]);
  882. spin_unlock_irqrestore(&pd->lock, flags);
  883. return 0;
  884. }
  885. static struct net_device_stats *s6gmac_stats(struct net_device *dev)
  886. {
  887. struct s6gmac *pd = netdev_priv(dev);
  888. struct net_device_stats *st = (struct net_device_stats *)&pd->stats;
  889. int i;
  890. do {
  891. unsigned long flags;
  892. spin_lock_irqsave(&pd->lock, flags);
  893. for (i = 0; i < sizeof(pd->stats) / sizeof(unsigned long); i++)
  894. pd->stats[i] =
  895. pd->carry[i] << (S6_GMAC_STAT_SIZE_MIN - 1);
  896. s6gmac_stats_collect(pd, &statinf[0][0]);
  897. s6gmac_stats_collect(pd, &statinf[1][0]);
  898. i = s6gmac_stats_pending(pd, 0) |
  899. s6gmac_stats_pending(pd, 1);
  900. spin_unlock_irqrestore(&pd->lock, flags);
  901. } while (i);
  902. st->rx_errors = st->rx_crc_errors +
  903. st->rx_frame_errors +
  904. st->rx_length_errors +
  905. st->rx_missed_errors;
  906. st->tx_errors += st->tx_aborted_errors;
  907. return st;
  908. }
  909. static int __devinit s6gmac_probe(struct platform_device *pdev)
  910. {
  911. struct net_device *dev;
  912. struct s6gmac *pd;
  913. int res;
  914. unsigned long i;
  915. struct mii_bus *mb;
  916. dev = alloc_etherdev(sizeof(*pd));
  917. if (!dev) {
  918. printk(KERN_ERR DRV_PRMT "etherdev alloc failed, aborting.\n");
  919. return -ENOMEM;
  920. }
  921. dev->open = s6gmac_open;
  922. dev->stop = s6gmac_stop;
  923. dev->hard_start_xmit = s6gmac_tx;
  924. dev->tx_timeout = s6gmac_tx_timeout;
  925. dev->watchdog_timeo = HZ;
  926. dev->get_stats = s6gmac_stats;
  927. dev->irq = platform_get_irq(pdev, 0);
  928. pd = netdev_priv(dev);
  929. memset(pd, 0, sizeof(*pd));
  930. spin_lock_init(&pd->lock);
  931. pd->reg = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start;
  932. i = platform_get_resource(pdev, IORESOURCE_DMA, 0)->start;
  933. pd->tx_dma = DMA_MASK_DMAC(i);
  934. pd->tx_chan = DMA_INDEX_CHNL(i);
  935. i = platform_get_resource(pdev, IORESOURCE_DMA, 1)->start;
  936. pd->rx_dma = DMA_MASK_DMAC(i);
  937. pd->rx_chan = DMA_INDEX_CHNL(i);
  938. pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
  939. res = request_irq(dev->irq, s6gmac_interrupt, 0, dev->name, dev);
  940. if (res) {
  941. printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq);
  942. goto errirq;
  943. }
  944. res = register_netdev(dev);
  945. if (res) {
  946. printk(KERN_ERR DRV_PRMT "error registering device %s\n",
  947. dev->name);
  948. goto errdev;
  949. }
  950. mb = mdiobus_alloc();
  951. if (!mb) {
  952. printk(KERN_ERR DRV_PRMT "error allocating mii bus\n");
  953. goto errmii;
  954. }
  955. mb->name = "s6gmac_mii";
  956. mb->read = s6mii_read;
  957. mb->write = s6mii_write;
  958. mb->reset = s6mii_reset;
  959. mb->priv = pd;
  960. snprintf(mb->id, MII_BUS_ID_SIZE, "0");
  961. mb->phy_mask = ~(1 << 0);
  962. mb->irq = &pd->mii.irq[0];
  963. for (i = 0; i < PHY_MAX_ADDR; i++) {
  964. int n = platform_get_irq(pdev, i + 1);
  965. if (n < 0)
  966. n = PHY_POLL;
  967. pd->mii.irq[i] = n;
  968. }
  969. mdiobus_register(mb);
  970. pd->mii.bus = mb;
  971. res = s6gmac_phy_start(dev);
  972. if (res)
  973. return res;
  974. platform_set_drvdata(pdev, dev);
  975. return 0;
  976. errmii:
  977. unregister_netdev(dev);
  978. errdev:
  979. free_irq(dev->irq, dev);
  980. errirq:
  981. free_netdev(dev);
  982. return res;
  983. }
  984. static int __devexit s6gmac_remove(struct platform_device *pdev)
  985. {
  986. struct net_device *dev = platform_get_drvdata(pdev);
  987. if (dev) {
  988. struct s6gmac *pd = netdev_priv(dev);
  989. mdiobus_unregister(pd->mii.bus);
  990. unregister_netdev(dev);
  991. free_irq(dev->irq, dev);
  992. free_netdev(dev);
  993. platform_set_drvdata(pdev, NULL);
  994. }
  995. return 0;
  996. }
  997. static struct platform_driver s6gmac_driver = {
  998. .probe = s6gmac_probe,
  999. .remove = __devexit_p(s6gmac_remove),
  1000. .driver = {
  1001. .name = "s6gmac",
  1002. .owner = THIS_MODULE,
  1003. },
  1004. };
  1005. static int __init s6gmac_init(void)
  1006. {
  1007. printk(KERN_INFO DRV_PRMT "S6 GMAC ethernet driver\n");
  1008. return platform_driver_register(&s6gmac_driver);
  1009. }
  1010. static void __exit s6gmac_exit(void)
  1011. {
  1012. platform_driver_unregister(&s6gmac_driver);
  1013. }
  1014. module_init(s6gmac_init);
  1015. module_exit(s6gmac_exit);
  1016. MODULE_LICENSE("GPL");
  1017. MODULE_DESCRIPTION("S6105 on chip Ethernet driver");
  1018. MODULE_AUTHOR("Oskar Schirmer <os@emlix.com>");