010-m5445x_fec.patch 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. From c562ab80fe383e6fa49dbe38257421cf37f0e4b3 Mon Sep 17 00:00:00 2001
  2. From: Kurt Mahan <[email protected]>
  3. Date: Wed, 31 Oct 2007 17:07:25 -0600
  4. Subject: [PATCH] MCF5445x FEC support.
  5. LTIBName: m5445x-fec
  6. Signed-off-by: Kurt Mahan <[email protected]>
  7. ---
  8. drivers/net/Kconfig | 8 ++-
  9. drivers/net/fec.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++----
  10. drivers/net/fec.h | 2 +-
  11. 3 files changed, 198 insertions(+), 19 deletions(-)
  12. --- a/drivers/net/Kconfig
  13. +++ b/drivers/net/Kconfig
  14. @@ -1973,7 +1973,7 @@ config 68360_ENET
  15. config FEC
  16. bool "FEC ethernet controller (of ColdFire CPUs)"
  17. - depends on M523x || M527x || M5272 || M528x || M520x
  18. + depends on M523x || M527x || M5272 || M528x || M520x || M54455
  19. help
  20. Say Y here if you want to use the built-in 10/100 Fast ethernet
  21. controller on some Motorola ColdFire processors.
  22. @@ -1985,6 +1985,12 @@ config FEC2
  23. Say Y here if you want to use the second built-in 10/100 Fast
  24. ethernet controller on some Motorola ColdFire processors.
  25. +config FEC_SHARED_PHY
  26. + bool "Shared PHY interface(on some ColdFire designs)"
  27. + depends on FEC2
  28. + help
  29. + Say Y here if both PHYs are controlled via a single channel.
  30. +
  31. config FEC_MPC52xx
  32. tristate "MPC52xx FEC driver"
  33. depends on PPC_MERGE && PPC_MPC52xx && PPC_BESTCOMM_FEC
  34. --- a/drivers/net/fec.c
  35. +++ b/drivers/net/fec.c
  36. @@ -51,7 +51,9 @@
  37. #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
  38. defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
  39. - defined(CONFIG_M520x) || defined(CONFIG_M532x)
  40. + defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
  41. + defined(CONFIG_M54455)
  42. +
  43. #include <asm/coldfire.h>
  44. #include <asm/mcfsim.h>
  45. #include "fec.h"
  46. @@ -82,6 +84,11 @@ static unsigned int fec_hw[] = {
  47. (MCF_MBAR+0x30000),
  48. #elif defined(CONFIG_M532x)
  49. (MCF_MBAR+0xfc030000),
  50. +#elif defined(CONFIG_M54455)
  51. + (MCF_MBAR+0xfc030000),
  52. +#if defined(CONFIG_FEC2)
  53. + (MCF_MBAR+0xfc034000),
  54. +#endif
  55. #else
  56. &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
  57. #endif
  58. @@ -172,7 +179,7 @@ typedef struct {
  59. * account when setting it.
  60. */
  61. #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
  62. - defined(CONFIG_M520x) || defined(CONFIG_M532x)
  63. + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_M54455)
  64. #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
  65. #else
  66. #define OPT_FRAME_SIZE 0
  67. @@ -213,6 +220,7 @@ struct fec_enet_private {
  68. uint phy_speed;
  69. phy_info_t const *phy;
  70. struct work_struct phy_task;
  71. + volatile fec_t *phy_hwp;
  72. uint sequence_done;
  73. uint mii_phy_task_queued;
  74. @@ -349,7 +357,8 @@ fec_enet_start_xmit(struct sk_buff *skb,
  75. if (bdp->cbd_bufaddr & 0x3) {
  76. unsigned int index;
  77. index = bdp - fep->tx_bd_base;
  78. - memcpy(fep->tx_bounce[index], (void *) bdp->cbd_bufaddr, bdp->cbd_datlen);
  79. + memcpy(fep->tx_bounce[index],
  80. + (void *)skb->data, bdp->cbd_datlen);
  81. bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
  82. }
  83. @@ -702,7 +711,7 @@ fec_enet_mii(struct net_device *dev)
  84. uint mii_reg;
  85. fep = netdev_priv(dev);
  86. - ep = fep->hwp;
  87. + ep = fep->phy_hwp;
  88. mii_reg = ep->fec_mii_data;
  89. spin_lock(&fep->lock);
  90. @@ -753,7 +762,7 @@ mii_queue(struct net_device *dev, int re
  91. mii_tail = mip;
  92. } else {
  93. mii_head = mii_tail = mip;
  94. - fep->hwp->fec_mii_data = regval;
  95. + fep->phy_hwp->fec_mii_data = regval;
  96. }
  97. } else {
  98. retval = 1;
  99. @@ -1151,8 +1160,7 @@ static phy_info_t const phy_info_ks8721b
  100. };
  101. /* ------------------------------------------------------------------------- */
  102. -/* register definitions for the DP83848 */
  103. -
  104. +/* register definitions for the DP83848 and DP83849 */
  105. #define MII_DP8384X_PHYSTST 16 /* PHY Status Register */
  106. static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
  107. @@ -1186,27 +1194,50 @@ static void mii_parse_dp8384x_sr2(uint m
  108. *s |= PHY_STAT_FAULT;
  109. }
  110. +static phy_cmd_t const phy_cmd_dp8384x_ack_int[] = {
  111. + { mk_mii_end, }
  112. + };
  113. +
  114. +static phy_cmd_t const phy_cmd_dp8384x_shutdown[] = {
  115. + { mk_mii_end, }
  116. + };
  117. +
  118. static phy_info_t phy_info_dp83848= {
  119. - 0x020005c9,
  120. - "DP83848",
  121. + .id = 0x020005c9,
  122. + .name = "DP83848",
  123. - (const phy_cmd_t []) { /* config */
  124. + .config = (const phy_cmd_t []) { /* config */
  125. { mk_mii_read(MII_REG_CR), mii_parse_cr },
  126. { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
  127. { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
  128. { mk_mii_end, }
  129. },
  130. - (const phy_cmd_t []) { /* startup - enable interrupts */
  131. + .startup = (const phy_cmd_t []) { /* startup - enable interrupts */
  132. { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
  133. { mk_mii_read(MII_REG_SR), mii_parse_sr },
  134. { mk_mii_end, }
  135. },
  136. - (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
  137. + .ack_int = phy_cmd_dp8384x_ack_int,
  138. + .shutdown = phy_cmd_dp8384x_shutdown,
  139. +};
  140. +
  141. +static phy_info_t phy_info_dp83849 = {
  142. + .id = 0x020005ca,
  143. + .name = "DP83849",
  144. +
  145. + .config = (const phy_cmd_t []) { /* config */
  146. + { mk_mii_read(MII_REG_CR), mii_parse_cr },
  147. + { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
  148. + { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
  149. { mk_mii_end, }
  150. },
  151. - (const phy_cmd_t []) { /* shutdown */
  152. + .startup = (const phy_cmd_t []) { /* startup - enable interrupts */
  153. + { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
  154. + { mk_mii_read(MII_REG_SR), mii_parse_sr },
  155. { mk_mii_end, }
  156. },
  157. + .ack_int = phy_cmd_dp8384x_ack_int,
  158. + .shutdown = phy_cmd_dp8384x_shutdown,
  159. };
  160. /* ------------------------------------------------------------------------- */
  161. @@ -1218,6 +1249,7 @@ static phy_info_t const * const phy_info
  162. &phy_info_am79c874,
  163. &phy_info_ks8721bl,
  164. &phy_info_dp83848,
  165. + &phy_info_dp83849,
  166. NULL
  167. };
  168. @@ -1799,6 +1831,138 @@ static void __inline__ fec_uncache(unsig
  169. /* ------------------------------------------------------------------------- */
  170. +#elif defined(CONFIG_M54455)
  171. +/*
  172. + * Code specific for M54455
  173. + */
  174. +
  175. +static void __inline__ fec_request_intrs(struct net_device *dev)
  176. +{
  177. + struct fec_enet_private *fep;
  178. + int b;
  179. + static const struct idesc {
  180. + char *name;
  181. + unsigned short irq;
  182. + } *idp, id[] = {
  183. + { "fec(TXF)", 36 },
  184. + { "fec(TXB)", 37 },
  185. + { "fec(TXFIFO)", 38 },
  186. + { "fec(TXCR)", 39 },
  187. + { "fec(RXF)", 40 },
  188. + { "fec(RXB)", 41 },
  189. + { "fec(MII)", 42 },
  190. + { "fec(LC)", 43 },
  191. + { "fec(HBERR)", 44 },
  192. + { "fec(GRA)", 45 },
  193. + { "fec(EBERR)", 46 },
  194. + { "fec(BABT)", 47 },
  195. + { "fec(BABR)", 48 },
  196. + { NULL },
  197. + };
  198. +
  199. + fep = netdev_priv(dev);
  200. + b = (fep->index) ? 77 : 64;
  201. +
  202. + /* Setup interrupt handlers. */
  203. + for (idp = id; idp->name; idp++) {
  204. + if (request_irq(b+idp->irq, fec_enet_interrupt, 0,
  205. + idp->name, dev) != 0)
  206. + printk(KERN_ERR "FEC: Could not alloc %s IRQ(%d)!\n",
  207. + idp->name, b+idp->irq);
  208. + }
  209. +
  210. + if (fep->index) {
  211. + /* Configure RMII */
  212. + MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
  213. + MCF_GPIO_PAR_FEC_FEC1_MASK) |
  214. + MCF_GPIO_PAR_FEC_FEC1_RMII_GPIO;
  215. + } else {
  216. + /* Configure RMII */
  217. + MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC &
  218. + MCF_GPIO_PAR_FEC_FEC0_MASK) |
  219. + MCF_GPIO_PAR_FEC_FEC0_RMII_GPIO;
  220. + }
  221. +
  222. + /* Set up gpio outputs for MII lines on FEC0 */
  223. + MCF_GPIO_PAR_FECI2C |= (0 |
  224. + MCF_GPIO_PAR_FECI2C_MDIO0_MDIO0 |
  225. + MCF_GPIO_PAR_FECI2C_MDC0_MDC0);
  226. +}
  227. +
  228. +static void __inline__ fec_set_mii(struct net_device *dev,
  229. + struct fec_enet_private *fep)
  230. +{
  231. + volatile fec_t *fecp;
  232. +
  233. + fecp = fep->hwp;
  234. + fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
  235. + fecp->fec_x_cntrl = 0x00;
  236. +
  237. + /*
  238. + * Set MII speed to 2.5 MHz
  239. + */
  240. + fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
  241. + fecp->fec_mii_speed = fep->phy_speed;
  242. +
  243. + fec_restart(dev, 0);
  244. +}
  245. +
  246. +static void __inline__ fec_get_mac(struct net_device *dev)
  247. +{
  248. + struct fec_enet_private *fep = netdev_priv(dev);
  249. + volatile fec_t *fecp;
  250. + unsigned char *iap, tmpaddr[ETH_ALEN];
  251. +
  252. + fecp = fep->hwp;
  253. +
  254. + if (FEC_FLASHMAC) {
  255. + /*
  256. + * Get MAC address from FLASH.
  257. + * If it is all 1's or 0's, use the default.
  258. + */
  259. + iap = FEC_FLASHMAC;
  260. + if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
  261. + (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
  262. + iap = fec_mac_default;
  263. + if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
  264. + (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
  265. + iap = fec_mac_default;
  266. + } else {
  267. + *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
  268. + *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
  269. + iap = &tmpaddr[0];
  270. + }
  271. +
  272. + memcpy(dev->dev_addr, iap, ETH_ALEN);
  273. +
  274. + /* Adjust MAC if using default MAC address */
  275. + if (iap == fec_mac_default)
  276. + dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] +
  277. + fep->index;
  278. +}
  279. +
  280. +static void __inline__ fec_enable_phy_intr(void)
  281. +{
  282. +}
  283. +
  284. +static void __inline__ fec_disable_phy_intr(void)
  285. +{
  286. +}
  287. +
  288. +static void __inline__ fec_phy_ack_intr(void)
  289. +{
  290. +}
  291. +
  292. +static void __inline__ fec_localhw_setup(void)
  293. +{
  294. +}
  295. +
  296. +static void __inline__ fec_uncache(unsigned long addr)
  297. +{
  298. +}
  299. +
  300. +/* ------------------------------------------------------------------------- */
  301. +
  302. #else
  303. @@ -2305,7 +2469,7 @@ fec_set_mac_address(struct net_device *d
  304. }
  305. -/* Initialize the FEC Ethernet on 860T (or ColdFire 5272).
  306. +/* Initialize the FEC Ethernet.
  307. */
  308. /*
  309. * XXX: We need to clean up on failure exits here.
  310. @@ -2326,7 +2490,7 @@ int __init fec_enet_init(struct net_devi
  311. /* Allocate memory for buffer descriptors.
  312. */
  313. - mem_addr = __get_free_page(GFP_KERNEL);
  314. + mem_addr = __get_free_page(GFP_DMA);
  315. if (mem_addr == 0) {
  316. printk("FEC: allocate descriptor memory failed?\n");
  317. return -ENOMEM;
  318. @@ -2339,6 +2503,11 @@ int __init fec_enet_init(struct net_devi
  319. fep->index = index;
  320. fep->hwp = fecp;
  321. fep->netdev = dev;
  322. +#ifdef CONFIG_FEC_SHARED_PHY
  323. + fep->phy_hwp = (volatile fec_t *) fec_hw[index & ~1];
  324. +#else
  325. + fep->phy_hwp = fecp;
  326. +#endif
  327. /* Whack a reset. We should wait for this.
  328. */
  329. @@ -2375,7 +2544,7 @@ int __init fec_enet_init(struct net_devi
  330. /* Allocate a page.
  331. */
  332. - mem_addr = __get_free_page(GFP_KERNEL);
  333. + mem_addr = __get_free_page(GFP_DMA);
  334. /* XXX: missing check for allocation failure */
  335. fec_uncache(mem_addr);
  336. @@ -2400,7 +2569,7 @@ int __init fec_enet_init(struct net_devi
  337. bdp = fep->tx_bd_base;
  338. for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
  339. if (j >= FEC_ENET_TX_FRPPG) {
  340. - mem_addr = __get_free_page(GFP_KERNEL);
  341. + mem_addr = __get_free_page(GFP_DMA);
  342. j = 1;
  343. } else {
  344. mem_addr += FEC_ENET_TX_FRSIZE;
  345. @@ -2462,7 +2631,11 @@ int __init fec_enet_init(struct net_devi
  346. * remainder of the interface.
  347. */
  348. fep->phy_id_done = 0;
  349. +#ifndef CONFIG_FEC_SHARED_PHY
  350. fep->phy_addr = 0;
  351. +#else
  352. + fep->phy_addr = fep->index;
  353. +#endif
  354. mii_queue(dev, mk_mii_read(MII_REG_PHYIR1), mii_discover_phy);
  355. index++;
  356. --- a/drivers/net/fec.h
  357. +++ b/drivers/net/fec.h
  358. @@ -14,7 +14,7 @@
  359. /****************************************************************************/
  360. #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
  361. - defined(CONFIG_M520x) || defined(CONFIG_M532x)
  362. + defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_M54455)
  363. /*
  364. * Just figures, Motorola would have to change the offsets for
  365. * registers in the same peripheral device on different models