fs_enet-mii.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /*
  2. * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
  3. *
  4. * Copyright (c) 2003 Intracom S.A.
  5. * by Pantelis Antoniou <panto@intracom.gr>
  6. *
  7. * 2005 (c) MontaVista Software, Inc.
  8. * Vitaly Bordug <vbordug@ru.mvista.com>
  9. *
  10. * Heavily based on original FEC driver by Dan Malek <dan@embeddededge.com>
  11. * and modifications by Joakim Tjernlund <joakim.tjernlund@lumentis.se>
  12. *
  13. * This file is licensed under the terms of the GNU General Public License
  14. * version 2. This program is licensed "as is" without any warranty of any
  15. * kind, whether express or implied.
  16. */
  17. #include <linux/module.h>
  18. #include <linux/types.h>
  19. #include <linux/kernel.h>
  20. #include <linux/sched.h>
  21. #include <linux/string.h>
  22. #include <linux/ptrace.h>
  23. #include <linux/errno.h>
  24. #include <linux/ioport.h>
  25. #include <linux/slab.h>
  26. #include <linux/interrupt.h>
  27. #include <linux/pci.h>
  28. #include <linux/init.h>
  29. #include <linux/delay.h>
  30. #include <linux/netdevice.h>
  31. #include <linux/etherdevice.h>
  32. #include <linux/skbuff.h>
  33. #include <linux/spinlock.h>
  34. #include <linux/mii.h>
  35. #include <linux/ethtool.h>
  36. #include <linux/bitops.h>
  37. #include <asm/pgtable.h>
  38. #include <asm/irq.h>
  39. #include <asm/uaccess.h>
  40. #include "fs_enet.h"
  41. /*************************************************/
  42. /*
  43. * Generic PHY support.
  44. * Should work for all PHYs, but link change is detected by polling
  45. */
  46. static void generic_timer_callback(unsigned long data)
  47. {
  48. struct net_device *dev = (struct net_device *)data;
  49. struct fs_enet_private *fep = netdev_priv(dev);
  50. fep->phy_timer_list.expires = jiffies + HZ / 2;
  51. add_timer(&fep->phy_timer_list);
  52. fs_mii_link_status_change_check(dev, 0);
  53. }
  54. static void generic_startup(struct net_device *dev)
  55. {
  56. struct fs_enet_private *fep = netdev_priv(dev);
  57. fep->phy_timer_list.expires = jiffies + HZ / 2; /* every 500ms */
  58. fep->phy_timer_list.data = (unsigned long)dev;
  59. fep->phy_timer_list.function = generic_timer_callback;
  60. add_timer(&fep->phy_timer_list);
  61. }
  62. static void generic_shutdown(struct net_device *dev)
  63. {
  64. struct fs_enet_private *fep = netdev_priv(dev);
  65. del_timer_sync(&fep->phy_timer_list);
  66. }
  67. /* ------------------------------------------------------------------------- */
  68. /* The Davicom DM9161 is used on the NETTA board */
  69. /* register definitions */
  70. #define MII_DM9161_ANAR 4 /* Aux. Config Register */
  71. #define MII_DM9161_ACR 16 /* Aux. Config Register */
  72. #define MII_DM9161_ACSR 17 /* Aux. Config/Status Register */
  73. #define MII_DM9161_10TCSR 18 /* 10BaseT Config/Status Reg. */
  74. #define MII_DM9161_INTR 21 /* Interrupt Register */
  75. #define MII_DM9161_RECR 22 /* Receive Error Counter Reg. */
  76. #define MII_DM9161_DISCR 23 /* Disconnect Counter Register */
  77. static void dm9161_startup(struct net_device *dev)
  78. {
  79. struct fs_enet_private *fep = netdev_priv(dev);
  80. fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0000);
  81. /* Start autonegotiation */
  82. fs_mii_write(dev, fep->mii_if.phy_id, MII_BMCR, 0x1200);
  83. set_current_state(TASK_UNINTERRUPTIBLE);
  84. schedule_timeout(HZ*8);
  85. }
  86. static void dm9161_ack_int(struct net_device *dev)
  87. {
  88. struct fs_enet_private *fep = netdev_priv(dev);
  89. fs_mii_read(dev, fep->mii_if.phy_id, MII_DM9161_INTR);
  90. }
  91. static void dm9161_shutdown(struct net_device *dev)
  92. {
  93. struct fs_enet_private *fep = netdev_priv(dev);
  94. fs_mii_write(dev, fep->mii_if.phy_id, MII_DM9161_INTR, 0x0f00);
  95. }
  96. /**********************************************************************************/
  97. static const struct phy_info phy_info[] = {
  98. {
  99. .id = 0x00181b88,
  100. .name = "DM9161",
  101. .startup = dm9161_startup,
  102. .ack_int = dm9161_ack_int,
  103. .shutdown = dm9161_shutdown,
  104. }, {
  105. .id = 0,
  106. .name = "GENERIC",
  107. .startup = generic_startup,
  108. .shutdown = generic_shutdown,
  109. },
  110. };
  111. /**********************************************************************************/
  112. static int phy_id_detect(struct net_device *dev)
  113. {
  114. struct fs_enet_private *fep = netdev_priv(dev);
  115. const struct fs_platform_info *fpi = fep->fpi;
  116. struct fs_enet_mii_bus *bus = fep->mii_bus;
  117. int i, r, start, end, phytype, physubtype;
  118. const struct phy_info *phy;
  119. int phy_hwid, phy_id;
  120. phy_hwid = -1;
  121. fep->phy = NULL;
  122. /* auto-detect? */
  123. if (fpi->phy_addr == -1) {
  124. start = 1;
  125. end = 32;
  126. } else { /* direct */
  127. start = fpi->phy_addr;
  128. end = start + 1;
  129. }
  130. for (phy_id = start; phy_id < end; phy_id++) {
  131. /* skip already used phy addresses on this bus */
  132. if (bus->usage_map & (1 << phy_id))
  133. continue;
  134. r = fs_mii_read(dev, phy_id, MII_PHYSID1);
  135. if (r == -1 || (phytype = (r & 0xffff)) == 0xffff)
  136. continue;
  137. r = fs_mii_read(dev, phy_id, MII_PHYSID2);
  138. if (r == -1 || (physubtype = (r & 0xffff)) == 0xffff)
  139. continue;
  140. phy_hwid = (phytype << 16) | physubtype;
  141. if (phy_hwid != -1)
  142. break;
  143. }
  144. if (phy_hwid == -1) {
  145. printk(KERN_ERR DRV_MODULE_NAME
  146. ": %s No PHY detected! range=0x%02x-0x%02x\n",
  147. dev->name, start, end);
  148. return -1;
  149. }
  150. for (i = 0, phy = phy_info; i < ARRAY_SIZE(phy_info); i++, phy++)
  151. if (phy->id == (phy_hwid >> 4) || phy->id == 0)
  152. break;
  153. if (i >= ARRAY_SIZE(phy_info)) {
  154. printk(KERN_ERR DRV_MODULE_NAME
  155. ": %s PHY id 0x%08x is not supported!\n",
  156. dev->name, phy_hwid);
  157. return -1;
  158. }
  159. fep->phy = phy;
  160. /* mark this address as used */
  161. bus->usage_map |= (1 << phy_id);
  162. printk(KERN_INFO DRV_MODULE_NAME
  163. ": %s Phy @ 0x%x, type %s (0x%08x)%s\n",
  164. dev->name, phy_id, fep->phy->name, phy_hwid,
  165. fpi->phy_addr == -1 ? " (auto-detected)" : "");
  166. return phy_id;
  167. }
  168. void fs_mii_startup(struct net_device *dev)
  169. {
  170. struct fs_enet_private *fep = netdev_priv(dev);
  171. if (fep->phy->startup)
  172. (*fep->phy->startup) (dev);
  173. }
  174. void fs_mii_shutdown(struct net_device *dev)
  175. {
  176. struct fs_enet_private *fep = netdev_priv(dev);
  177. if (fep->phy->shutdown)
  178. (*fep->phy->shutdown) (dev);
  179. }
  180. void fs_mii_ack_int(struct net_device *dev)
  181. {
  182. struct fs_enet_private *fep = netdev_priv(dev);
  183. if (fep->phy->ack_int)
  184. (*fep->phy->ack_int) (dev);
  185. }
  186. #define MII_LINK 0x0001
  187. #define MII_HALF 0x0002
  188. #define MII_FULL 0x0004
  189. #define MII_BASE4 0x0008
  190. #define MII_10M 0x0010
  191. #define MII_100M 0x0020
  192. #define MII_1G 0x0040
  193. #define MII_10G 0x0080
  194. /* return full mii info at one gulp, with a usable form */
  195. static unsigned int mii_full_status(struct mii_if_info *mii)
  196. {
  197. unsigned int status;
  198. int bmsr, adv, lpa, neg;
  199. struct fs_enet_private* fep = netdev_priv(mii->dev);
  200. /* first, a dummy read, needed to latch some MII phys */
  201. (void)mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
  202. bmsr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
  203. /* no link */
  204. if ((bmsr & BMSR_LSTATUS) == 0)
  205. return 0;
  206. status = MII_LINK;
  207. /* Lets look what ANEG says if it's supported - otherwize we shall
  208. take the right values from the platform info*/
  209. if(!mii->force_media) {
  210. /* autoneg not completed; don't bother */
  211. if ((bmsr & BMSR_ANEGCOMPLETE) == 0)
  212. return 0;
  213. adv = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_ADVERTISE);
  214. lpa = (*mii->mdio_read)(mii->dev, mii->phy_id, MII_LPA);
  215. neg = lpa & adv;
  216. } else {
  217. neg = fep->fpi->bus_info->lpa;
  218. }
  219. if (neg & LPA_100FULL)
  220. status |= MII_FULL | MII_100M;
  221. else if (neg & LPA_100BASE4)
  222. status |= MII_FULL | MII_BASE4 | MII_100M;
  223. else if (neg & LPA_100HALF)
  224. status |= MII_HALF | MII_100M;
  225. else if (neg & LPA_10FULL)
  226. status |= MII_FULL | MII_10M;
  227. else
  228. status |= MII_HALF | MII_10M;
  229. return status;
  230. }
  231. void fs_mii_link_status_change_check(struct net_device *dev, int init_media)
  232. {
  233. struct fs_enet_private *fep = netdev_priv(dev);
  234. struct mii_if_info *mii = &fep->mii_if;
  235. unsigned int mii_status;
  236. int ok_to_print, link, duplex, speed;
  237. unsigned long flags;
  238. ok_to_print = netif_msg_link(fep);
  239. mii_status = mii_full_status(mii);
  240. if (!init_media && mii_status == fep->last_mii_status)
  241. return;
  242. fep->last_mii_status = mii_status;
  243. link = !!(mii_status & MII_LINK);
  244. duplex = !!(mii_status & MII_FULL);
  245. speed = (mii_status & MII_100M) ? 100 : 10;
  246. if (link == 0) {
  247. netif_carrier_off(mii->dev);
  248. netif_stop_queue(dev);
  249. if (!init_media) {
  250. spin_lock_irqsave(&fep->lock, flags);
  251. (*fep->ops->stop)(dev);
  252. spin_unlock_irqrestore(&fep->lock, flags);
  253. }
  254. if (ok_to_print)
  255. printk(KERN_INFO "%s: link down\n", mii->dev->name);
  256. } else {
  257. mii->full_duplex = duplex;
  258. netif_carrier_on(mii->dev);
  259. spin_lock_irqsave(&fep->lock, flags);
  260. fep->duplex = duplex;
  261. fep->speed = speed;
  262. (*fep->ops->restart)(dev);
  263. spin_unlock_irqrestore(&fep->lock, flags);
  264. netif_start_queue(dev);
  265. if (ok_to_print)
  266. printk(KERN_INFO "%s: link up, %dMbps, %s-duplex\n",
  267. dev->name, speed, duplex ? "full" : "half");
  268. }
  269. }
  270. /**********************************************************************************/
  271. int fs_mii_read(struct net_device *dev, int phy_id, int location)
  272. {
  273. struct fs_enet_private *fep = netdev_priv(dev);
  274. struct fs_enet_mii_bus *bus = fep->mii_bus;
  275. unsigned long flags;
  276. int ret;
  277. spin_lock_irqsave(&bus->mii_lock, flags);
  278. ret = (*bus->mii_read)(bus, phy_id, location);
  279. spin_unlock_irqrestore(&bus->mii_lock, flags);
  280. return ret;
  281. }
  282. void fs_mii_write(struct net_device *dev, int phy_id, int location, int value)
  283. {
  284. struct fs_enet_private *fep = netdev_priv(dev);
  285. struct fs_enet_mii_bus *bus = fep->mii_bus;
  286. unsigned long flags;
  287. spin_lock_irqsave(&bus->mii_lock, flags);
  288. (*bus->mii_write)(bus, phy_id, location, value);
  289. spin_unlock_irqrestore(&bus->mii_lock, flags);
  290. }
  291. /*****************************************************************************/
  292. /* list of all registered mii buses */
  293. static LIST_HEAD(fs_mii_bus_list);
  294. static struct fs_enet_mii_bus *lookup_bus(int method, int id)
  295. {
  296. struct list_head *ptr;
  297. struct fs_enet_mii_bus *bus;
  298. list_for_each(ptr, &fs_mii_bus_list) {
  299. bus = list_entry(ptr, struct fs_enet_mii_bus, list);
  300. if (bus->bus_info->method == method &&
  301. bus->bus_info->id == id)
  302. return bus;
  303. }
  304. return NULL;
  305. }
  306. static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi)
  307. {
  308. struct fs_enet_mii_bus *bus;
  309. int ret = 0;
  310. bus = kmalloc(sizeof(*bus), GFP_KERNEL);
  311. if (bus == NULL) {
  312. ret = -ENOMEM;
  313. goto err;
  314. }
  315. memset(bus, 0, sizeof(*bus));
  316. spin_lock_init(&bus->mii_lock);
  317. bus->bus_info = bi;
  318. bus->refs = 0;
  319. bus->usage_map = 0;
  320. /* perform initialization */
  321. switch (bi->method) {
  322. case fsmii_fixed:
  323. ret = fs_mii_fixed_init(bus);
  324. if (ret != 0)
  325. goto err;
  326. break;
  327. case fsmii_bitbang:
  328. ret = fs_mii_bitbang_init(bus);
  329. if (ret != 0)
  330. goto err;
  331. break;
  332. #ifdef CONFIG_FS_ENET_HAS_FEC
  333. case fsmii_fec:
  334. ret = fs_mii_fec_init(bus);
  335. if (ret != 0)
  336. goto err;
  337. break;
  338. #endif
  339. default:
  340. ret = -EINVAL;
  341. goto err;
  342. }
  343. list_add(&bus->list, &fs_mii_bus_list);
  344. return bus;
  345. err:
  346. kfree(bus);
  347. return ERR_PTR(ret);
  348. }
  349. static void destroy_bus(struct fs_enet_mii_bus *bus)
  350. {
  351. /* remove from bus list */
  352. list_del(&bus->list);
  353. /* nothing more needed */
  354. kfree(bus);
  355. }
  356. int fs_mii_connect(struct net_device *dev)
  357. {
  358. struct fs_enet_private *fep = netdev_priv(dev);
  359. const struct fs_platform_info *fpi = fep->fpi;
  360. struct fs_enet_mii_bus *bus = NULL;
  361. /* check method validity */
  362. switch (fpi->bus_info->method) {
  363. case fsmii_fixed:
  364. case fsmii_bitbang:
  365. break;
  366. #ifdef CONFIG_FS_ENET_HAS_FEC
  367. case fsmii_fec:
  368. break;
  369. #endif
  370. default:
  371. printk(KERN_ERR DRV_MODULE_NAME
  372. ": %s Unknown MII bus method (%d)!\n",
  373. dev->name, fpi->bus_info->method);
  374. return -EINVAL;
  375. }
  376. bus = lookup_bus(fpi->bus_info->method, fpi->bus_info->id);
  377. /* if not found create new bus */
  378. if (bus == NULL) {
  379. bus = create_bus(fpi->bus_info);
  380. if (IS_ERR(bus)) {
  381. printk(KERN_ERR DRV_MODULE_NAME
  382. ": %s MII bus creation failure!\n", dev->name);
  383. return PTR_ERR(bus);
  384. }
  385. }
  386. bus->refs++;
  387. fep->mii_bus = bus;
  388. fep->mii_if.dev = dev;
  389. fep->mii_if.phy_id_mask = 0x1f;
  390. fep->mii_if.reg_num_mask = 0x1f;
  391. fep->mii_if.mdio_read = fs_mii_read;
  392. fep->mii_if.mdio_write = fs_mii_write;
  393. fep->mii_if.force_media = fpi->bus_info->disable_aneg;
  394. fep->mii_if.phy_id = phy_id_detect(dev);
  395. return 0;
  396. }
  397. void fs_mii_disconnect(struct net_device *dev)
  398. {
  399. struct fs_enet_private *fep = netdev_priv(dev);
  400. struct fs_enet_mii_bus *bus = NULL;
  401. bus = fep->mii_bus;
  402. fep->mii_bus = NULL;
  403. if (--bus->refs <= 0)
  404. destroy_bus(bus);
  405. }