s6gmac.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  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 net_device *dev)
  361. {
  362. struct s6gmac *pd = netdev_priv(dev);
  363. struct sk_buff *skb;
  364. while ((((u8)(pd->rx_skb_i - pd->rx_skb_o)) < S6_NUM_RX_SKB) &&
  365. (!s6dmac_fifo_full(pd->rx_dma, pd->rx_chan)) &&
  366. (skb = netdev_alloc_skb(dev, S6_MAX_FRLEN + 2))) {
  367. pd->rx_skb[(pd->rx_skb_i++) % S6_NUM_RX_SKB] = skb;
  368. s6dmac_put_fifo_cache(pd->rx_dma, pd->rx_chan,
  369. pd->io, (u32)skb->data, S6_MAX_FRLEN);
  370. }
  371. }
  372. static void s6gmac_rx_interrupt(struct net_device *dev)
  373. {
  374. struct s6gmac *pd = netdev_priv(dev);
  375. u32 pfx;
  376. struct sk_buff *skb;
  377. while (((u8)(pd->rx_skb_i - pd->rx_skb_o)) >
  378. s6dmac_pending_count(pd->rx_dma, pd->rx_chan)) {
  379. skb = pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB];
  380. pfx = readl(pd->reg + S6_GMAC_BURST_POSTRD);
  381. if (pfx & (1 << S6_GMAC_BURST_POSTRD_DROP)) {
  382. dev_kfree_skb_irq(skb);
  383. } else {
  384. skb_put(skb, (pfx >> S6_GMAC_BURST_POSTRD_LEN)
  385. & S6_GMAC_BURST_POSTRD_LEN_MASK);
  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(dev);
  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 ((i < PHY_MAX_ADDR) && (!(p = pd->mii.bus->phy_map[i])))
  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. writel(skb->len << S6_GMAC_BURST_PREWR_LEN |
  817. 0 << S6_GMAC_BURST_PREWR_CFE |
  818. 1 << S6_GMAC_BURST_PREWR_PPE |
  819. 1 << S6_GMAC_BURST_PREWR_FCS |
  820. ((skb->len < ETH_ZLEN) ? 1 : 0) << S6_GMAC_BURST_PREWR_PAD,
  821. pd->reg + S6_GMAC_BURST_PREWR);
  822. s6dmac_put_fifo_cache(pd->tx_dma, pd->tx_chan,
  823. (u32)skb->data, pd->io, skb->len);
  824. if (s6dmac_fifo_full(pd->tx_dma, pd->tx_chan))
  825. netif_stop_queue(dev);
  826. if (((u8)(pd->tx_skb_i - pd->tx_skb_o)) >= S6_NUM_TX_SKB) {
  827. printk(KERN_ERR "GMAC BUG: skb tx ring overflow [%x, %x]\n",
  828. pd->tx_skb_o, pd->tx_skb_i);
  829. BUG();
  830. }
  831. pd->tx_skb[(pd->tx_skb_i++) % S6_NUM_TX_SKB] = skb;
  832. spin_unlock_irqrestore(&pd->lock, flags);
  833. return 0;
  834. }
  835. static void s6gmac_tx_timeout(struct net_device *dev)
  836. {
  837. struct s6gmac *pd = netdev_priv(dev);
  838. unsigned long flags;
  839. spin_lock_irqsave(&pd->lock, flags);
  840. s6gmac_tx_interrupt(dev);
  841. spin_unlock_irqrestore(&pd->lock, flags);
  842. }
  843. static int s6gmac_open(struct net_device *dev)
  844. {
  845. struct s6gmac *pd = netdev_priv(dev);
  846. unsigned long flags;
  847. phy_read_status(pd->phydev);
  848. spin_lock_irqsave(&pd->lock, flags);
  849. pd->link.mbit = 0;
  850. s6gmac_linkisup(dev, pd->phydev->link);
  851. s6gmac_init_device(dev);
  852. s6gmac_init_stats(dev);
  853. s6gmac_init_dmac(dev);
  854. s6gmac_rx_fillfifo(dev);
  855. s6dmac_enable_chan(pd->rx_dma, pd->rx_chan,
  856. 2, 1, 0, 1, 0, 0, 0, 7, -1, 2, 0, 1);
  857. s6dmac_enable_chan(pd->tx_dma, pd->tx_chan,
  858. 2, 0, 1, 0, 0, 0, 0, 7, -1, 2, 0, 1);
  859. writel(0 << S6_GMAC_HOST_INT_TXBURSTOVER |
  860. 0 << S6_GMAC_HOST_INT_TXPREWOVER |
  861. 0 << S6_GMAC_HOST_INT_RXBURSTUNDER |
  862. 0 << S6_GMAC_HOST_INT_RXPOSTRFULL |
  863. 0 << S6_GMAC_HOST_INT_RXPOSTRUNDER,
  864. pd->reg + S6_GMAC_HOST_INTMASK);
  865. spin_unlock_irqrestore(&pd->lock, flags);
  866. phy_start(pd->phydev);
  867. netif_start_queue(dev);
  868. return 0;
  869. }
  870. static int s6gmac_stop(struct net_device *dev)
  871. {
  872. struct s6gmac *pd = netdev_priv(dev);
  873. unsigned long flags;
  874. netif_stop_queue(dev);
  875. phy_stop(pd->phydev);
  876. spin_lock_irqsave(&pd->lock, flags);
  877. s6gmac_init_dmac(dev);
  878. s6gmac_stop_device(dev);
  879. while (pd->tx_skb_i != pd->tx_skb_o)
  880. dev_kfree_skb(pd->tx_skb[(pd->tx_skb_o++) % S6_NUM_TX_SKB]);
  881. while (pd->rx_skb_i != pd->rx_skb_o)
  882. dev_kfree_skb(pd->rx_skb[(pd->rx_skb_o++) % S6_NUM_RX_SKB]);
  883. spin_unlock_irqrestore(&pd->lock, flags);
  884. return 0;
  885. }
  886. static struct net_device_stats *s6gmac_stats(struct net_device *dev)
  887. {
  888. struct s6gmac *pd = netdev_priv(dev);
  889. struct net_device_stats *st = (struct net_device_stats *)&pd->stats;
  890. int i;
  891. do {
  892. unsigned long flags;
  893. spin_lock_irqsave(&pd->lock, flags);
  894. for (i = 0; i < sizeof(pd->stats) / sizeof(unsigned long); i++)
  895. pd->stats[i] =
  896. pd->carry[i] << (S6_GMAC_STAT_SIZE_MIN - 1);
  897. s6gmac_stats_collect(pd, &statinf[0][0]);
  898. s6gmac_stats_collect(pd, &statinf[1][0]);
  899. i = s6gmac_stats_pending(pd, 0) |
  900. s6gmac_stats_pending(pd, 1);
  901. spin_unlock_irqrestore(&pd->lock, flags);
  902. } while (i);
  903. st->rx_errors = st->rx_crc_errors +
  904. st->rx_frame_errors +
  905. st->rx_length_errors +
  906. st->rx_missed_errors;
  907. st->tx_errors += st->tx_aborted_errors;
  908. return st;
  909. }
  910. static int __devinit s6gmac_probe(struct platform_device *pdev)
  911. {
  912. struct net_device *dev;
  913. struct s6gmac *pd;
  914. int res;
  915. unsigned long i;
  916. struct mii_bus *mb;
  917. dev = alloc_etherdev(sizeof(*pd));
  918. if (!dev)
  919. return -ENOMEM;
  920. dev->open = s6gmac_open;
  921. dev->stop = s6gmac_stop;
  922. dev->hard_start_xmit = s6gmac_tx;
  923. dev->tx_timeout = s6gmac_tx_timeout;
  924. dev->watchdog_timeo = HZ;
  925. dev->get_stats = s6gmac_stats;
  926. dev->irq = platform_get_irq(pdev, 0);
  927. pd = netdev_priv(dev);
  928. memset(pd, 0, sizeof(*pd));
  929. spin_lock_init(&pd->lock);
  930. pd->reg = platform_get_resource(pdev, IORESOURCE_MEM, 0)->start;
  931. i = platform_get_resource(pdev, IORESOURCE_DMA, 0)->start;
  932. pd->tx_dma = DMA_MASK_DMAC(i);
  933. pd->tx_chan = DMA_INDEX_CHNL(i);
  934. i = platform_get_resource(pdev, IORESOURCE_DMA, 1)->start;
  935. pd->rx_dma = DMA_MASK_DMAC(i);
  936. pd->rx_chan = DMA_INDEX_CHNL(i);
  937. pd->io = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
  938. res = request_irq(dev->irq, s6gmac_interrupt, 0, dev->name, dev);
  939. if (res) {
  940. printk(KERN_ERR DRV_PRMT "irq request failed: %d\n", dev->irq);
  941. goto errirq;
  942. }
  943. res = register_netdev(dev);
  944. if (res) {
  945. printk(KERN_ERR DRV_PRMT "error registering device %s\n",
  946. dev->name);
  947. goto errdev;
  948. }
  949. mb = mdiobus_alloc();
  950. if (!mb) {
  951. printk(KERN_ERR DRV_PRMT "error allocating mii bus\n");
  952. goto errmii;
  953. }
  954. mb->name = "s6gmac_mii";
  955. mb->read = s6mii_read;
  956. mb->write = s6mii_write;
  957. mb->reset = s6mii_reset;
  958. mb->priv = pd;
  959. snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id);
  960. mb->phy_mask = ~(1 << 0);
  961. mb->irq = &pd->mii.irq[0];
  962. for (i = 0; i < PHY_MAX_ADDR; i++) {
  963. int n = platform_get_irq(pdev, i + 1);
  964. if (n < 0)
  965. n = PHY_POLL;
  966. pd->mii.irq[i] = n;
  967. }
  968. mdiobus_register(mb);
  969. pd->mii.bus = mb;
  970. res = s6gmac_phy_start(dev);
  971. if (res)
  972. return res;
  973. platform_set_drvdata(pdev, dev);
  974. return 0;
  975. errmii:
  976. unregister_netdev(dev);
  977. errdev:
  978. free_irq(dev->irq, dev);
  979. errirq:
  980. free_netdev(dev);
  981. return res;
  982. }
  983. static int __devexit s6gmac_remove(struct platform_device *pdev)
  984. {
  985. struct net_device *dev = platform_get_drvdata(pdev);
  986. if (dev) {
  987. struct s6gmac *pd = netdev_priv(dev);
  988. mdiobus_unregister(pd->mii.bus);
  989. unregister_netdev(dev);
  990. free_irq(dev->irq, dev);
  991. free_netdev(dev);
  992. platform_set_drvdata(pdev, NULL);
  993. }
  994. return 0;
  995. }
  996. static struct platform_driver s6gmac_driver = {
  997. .probe = s6gmac_probe,
  998. .remove = __devexit_p(s6gmac_remove),
  999. .driver = {
  1000. .name = "s6gmac",
  1001. .owner = THIS_MODULE,
  1002. },
  1003. };
  1004. static int __init s6gmac_init(void)
  1005. {
  1006. printk(KERN_INFO DRV_PRMT "S6 GMAC ethernet driver\n");
  1007. return platform_driver_register(&s6gmac_driver);
  1008. }
  1009. static void __exit s6gmac_exit(void)
  1010. {
  1011. platform_driver_unregister(&s6gmac_driver);
  1012. }
  1013. module_init(s6gmac_init);
  1014. module_exit(s6gmac_exit);
  1015. MODULE_LICENSE("GPL");
  1016. MODULE_DESCRIPTION("S6105 on chip Ethernet driver");
  1017. MODULE_AUTHOR("Oskar Schirmer <os@emlix.com>");