Commit f6d7f2c60d3a63d786feeb60628f930cd2d8e912

Authored by Marc Kleine-Budde
1 parent c9218c3a82

ax88796: use generic mdio_bitbang driver

..instead of using hand-crafted and not proper working version.

Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

Showing 2 changed files with 196 additions and 200 deletions Side-by-side Diff

... ... @@ -238,8 +238,8 @@
238 238 config AX88796
239 239 tristate "ASIX AX88796 NE2000 clone support"
240 240 depends on ARM || MIPS || SUPERH
241   - select CRC32
242   - select MII
  241 + select PHYLIB
  242 + select MDIO_BITBANG
243 243 help
244 244 AX88796 driver, using platform bus to provide
245 245 chip detection and resources
drivers/net/ax88796.c
... ... @@ -24,7 +24,8 @@
24 24 #include <linux/netdevice.h>
25 25 #include <linux/etherdevice.h>
26 26 #include <linux/ethtool.h>
27   -#include <linux/mii.h>
  27 +#include <linux/mdio-bitbang.h>
  28 +#include <linux/phy.h>
28 29 #include <linux/eeprom_93cx6.h>
29 30 #include <linux/slab.h>
30 31  
... ... @@ -32,8 +33,6 @@
32 33  
33 34 #include <asm/system.h>
34 35  
35   -static int phy_debug;
36   -
37 36 /* Rename the lib8390.c functions to show that they are in this driver */
38 37 #define __ei_open ax_ei_open
39 38 #define __ei_close ax_ei_close
40 39  
41 40  
... ... @@ -78,14 +77,20 @@
78 77 #define NESM_START_PG 0x40 /* First page of TX buffer */
79 78 #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
80 79  
  80 +#define AX_GPOC_PPDSET BIT(6)
  81 +
81 82 /* device private data */
82 83  
83 84 struct ax_device {
84   - struct timer_list mii_timer;
85   - spinlock_t mii_lock;
86   - struct mii_if_info mii;
  85 + struct mii_bus *mii_bus;
  86 + struct mdiobb_ctrl bb_ctrl;
  87 + struct phy_device *phy_dev;
  88 + void __iomem *addr_memr;
  89 + u8 reg_memr;
  90 + int link;
  91 + int speed;
  92 + int duplex;
87 93  
88   - u32 msg_enable;
89 94 void __iomem *map2;
90 95 const struct ax_plat_data *plat;
91 96  
92 97  
93 98  
94 99  
95 100  
96 101  
97 102  
98 103  
99 104  
100 105  
101 106  
102 107  
103 108  
104 109  
105 110  
106 111  
107 112  
108 113  
109 114  
110 115  
111 116  
112 117  
113 118  
... ... @@ -313,159 +318,84 @@
313 318 #define AX_MEMR_EEO BIT(6)
314 319 #define AX_MEMR_EECLK BIT(7)
315 320  
316   -/*
317   - * ax_mii_ei_outbits
318   - *
319   - * write the specified set of bits to the phy
320   - */
321   -static void
322   -ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
  321 +static void ax_handle_link_change(struct net_device *dev)
323 322 {
324   - struct ei_device *ei_local = netdev_priv(dev);
325   - void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
326   - unsigned int memr;
  323 + struct ax_device *ax = to_ax_dev(dev);
  324 + struct phy_device *phy_dev = ax->phy_dev;
  325 + int status_change = 0;
327 326  
328   - /* clock low, data to output mode */
329   - memr = ei_inb(memr_addr);
330   - memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
331   - ei_outb(memr, memr_addr);
  327 + if (phy_dev->link && ((ax->speed != phy_dev->speed) ||
  328 + (ax->duplex != phy_dev->duplex))) {
332 329  
333   - for (len--; len >= 0; len--) {
334   - if (bits & (1 << len))
335   - memr |= AX_MEMR_MDO;
336   - else
337   - memr &= ~AX_MEMR_MDO;
  330 + ax->speed = phy_dev->speed;
  331 + ax->duplex = phy_dev->duplex;
  332 + status_change = 1;
  333 + }
338 334  
339   - ei_outb(memr, memr_addr);
  335 + if (phy_dev->link != ax->link) {
  336 + if (!phy_dev->link) {
  337 + ax->speed = 0;
  338 + ax->duplex = -1;
  339 + }
  340 + ax->link = phy_dev->link;
340 341  
341   - /* clock high */
342   -
343   - ei_outb(memr | AX_MEMR_MDC, memr_addr);
344   - udelay(1);
345   -
346   - /* clock low */
347   - ei_outb(memr, memr_addr);
  342 + status_change = 1;
348 343 }
349 344  
350   - /* leaves the clock line low, mdir input */
351   - memr |= AX_MEMR_MDIR;
352   - ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
  345 + if (status_change)
  346 + phy_print_status(phy_dev);
353 347 }
354 348  
355   -/*
356   - * ax_phy_ei_inbits
357   - *
358   - * read a specified number of bits from the phy
359   - */
360   -static unsigned int
361   -ax_phy_ei_inbits(struct net_device *dev, int no)
  349 +static int ax_mii_probe(struct net_device *dev)
362 350 {
363   - struct ei_device *ei_local = netdev_priv(dev);
364   - void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
365   - unsigned int memr;
366   - unsigned int result = 0;
  351 + struct ax_device *ax = to_ax_dev(dev);
  352 + struct phy_device *phy_dev = NULL;
  353 + int ret;
367 354  
368   - /* clock low, data to input mode */
369   - memr = ei_inb(memr_addr);
370   - memr &= ~AX_MEMR_MDC;
371   - memr |= AX_MEMR_MDIR;
372   - ei_outb(memr, memr_addr);
  355 + /* find the first phy */
  356 + phy_dev = phy_find_first(ax->mii_bus);
  357 + if (!phy_dev) {
  358 + netdev_err(dev, "no PHY found\n");
  359 + return -ENODEV;
  360 + }
373 361  
374   - for (no--; no >= 0; no--) {
375   - ei_outb(memr | AX_MEMR_MDC, memr_addr);
  362 + ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change, 0,
  363 + PHY_INTERFACE_MODE_MII);
  364 + if (ret) {
  365 + netdev_err(dev, "Could not attach to PHY\n");
  366 + return ret;
  367 + }
376 368  
377   - udelay(1);
  369 + /* mask with MAC supported features */
  370 + phy_dev->supported &= PHY_BASIC_FEATURES;
  371 + phy_dev->advertising = phy_dev->supported;
378 372  
379   - if (ei_inb(memr_addr) & AX_MEMR_MDI)
380   - result |= (1 << no);
  373 + ax->phy_dev = phy_dev;
381 374  
382   - ei_outb(memr, memr_addr);
383   - }
  375 + netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
  376 + phy_dev->drv->name, dev_name(&phy_dev->dev), phy_dev->irq);
384 377  
385   - return result;
  378 + return 0;
386 379 }
387 380  
388   -/*
389   - * ax_phy_issueaddr
390   - *
391   - * use the low level bit shifting routines to send the address
392   - * and command to the specified phy
393   - */
394   -static void
395   -ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
  381 +static void ax_phy_switch(struct net_device *dev, int on)
396 382 {
397   - if (phy_debug)
398   - netdev_dbg(dev, "%s: dev %p, %04x, %04x, %d\n",
399   - __func__, dev, phy_addr, reg, opc);
400   -
401   - ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */
402   - ax_mii_ei_outbits(dev, 1, 2); /* frame-start */
403   - ax_mii_ei_outbits(dev, opc, 2); /* op code */
404   - ax_mii_ei_outbits(dev, phy_addr, 5); /* phy address */
405   - ax_mii_ei_outbits(dev, reg, 5); /* reg address */
406   -}
407   -
408   -static int
409   -ax_phy_read(struct net_device *dev, int phy_addr, int reg)
410   -{
411 383 struct ei_device *ei_local = netdev_priv(dev);
412   - unsigned long flags;
413   - unsigned int result;
  384 + struct ax_device *ax = to_ax_dev(dev);
414 385  
415   - spin_lock_irqsave(&ei_local->page_lock, flags);
  386 + u8 reg_gpoc = ax->plat->gpoc_val;
416 387  
417   - ax_phy_issueaddr(dev, phy_addr, reg, 2);
  388 + if (!!on)
  389 + reg_gpoc &= ~AX_GPOC_PPDSET;
  390 + else
  391 + reg_gpoc |= AX_GPOC_PPDSET;
418 392  
419   - result = ax_phy_ei_inbits(dev, 17);
420   - result &= ~(3 << 16);
421   -
422   - spin_unlock_irqrestore(&ei_local->page_lock, flags);
423   -
424   - if (phy_debug)
425   - netdev_dbg(dev, "%s: %04x.%04x => read %04x\n", __func__,
426   - phy_addr, reg, result);
427   -
428   - return result;
  393 + ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17));
429 394 }
430 395  
431   -static void
432   -ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
433   -{
434   - struct ei_device *ei = netdev_priv(dev);
435   - unsigned long flags;
436   -
437   - netdev_dbg(dev, "%s: %p, %04x, %04x %04x\n",
438   - __func__, dev, phy_addr, reg, value);
439   -
440   - spin_lock_irqsave(&ei->page_lock, flags);
441   -
442   - ax_phy_issueaddr(dev, phy_addr, reg, 1);
443   - ax_mii_ei_outbits(dev, 2, 2); /* send TA */
444   - ax_mii_ei_outbits(dev, value, 16);
445   -
446   - spin_unlock_irqrestore(&ei->page_lock, flags);
447   -}
448   -
449   -static void ax_mii_expiry(unsigned long data)
450   -{
451   - struct net_device *dev = (struct net_device *)data;
452   - struct ax_device *ax = to_ax_dev(dev);
453   - unsigned long flags;
454   -
455   - spin_lock_irqsave(&ax->mii_lock, flags);
456   - mii_check_media(&ax->mii, netif_msg_link(ax), 0);
457   - spin_unlock_irqrestore(&ax->mii_lock, flags);
458   -
459   - if (ax->running) {
460   - ax->mii_timer.expires = jiffies + HZ*2;
461   - add_timer(&ax->mii_timer);
462   - }
463   -}
464   -
465 396 static int ax_open(struct net_device *dev)
466 397 {
467 398 struct ax_device *ax = to_ax_dev(dev);
468   - struct ei_device *ei_local = netdev_priv(dev);
469 399 int ret;
470 400  
471 401 netdev_dbg(dev, "open\n");
472 402  
473 403  
474 404  
475 405  
476 406  
477 407  
478 408  
479 409  
480 410  
481 411  
482 412  
... ... @@ -473,50 +403,48 @@
473 403 ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags,
474 404 dev->name, dev);
475 405 if (ret)
476   - return ret;
  406 + goto failed_request_irq;
477 407  
478   - ret = ax_ei_open(dev);
479   - if (ret) {
480   - free_irq(dev->irq, dev);
481   - return ret;
482   - }
483   -
484 408 /* turn the phy on (if turned off) */
  409 + ax_phy_switch(dev, 1);
485 410  
486   - ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
487   - ax->running = 1;
  411 + ret = ax_mii_probe(dev);
  412 + if (ret)
  413 + goto failed_mii_probe;
  414 + phy_start(ax->phy_dev);
488 415  
489   - /* start the MII timer */
  416 + ret = ax_ei_open(dev);
  417 + if (ret)
  418 + goto failed_ax_ei_open;
490 419  
491   - init_timer(&ax->mii_timer);
  420 + ax->running = 1;
492 421  
493   - ax->mii_timer.expires = jiffies + 1;
494   - ax->mii_timer.data = (unsigned long) dev;
495   - ax->mii_timer.function = ax_mii_expiry;
496   -
497   - add_timer(&ax->mii_timer);
498   -
499 422 return 0;
  423 +
  424 + failed_ax_ei_open:
  425 + phy_disconnect(ax->phy_dev);
  426 + failed_mii_probe:
  427 + ax_phy_switch(dev, 0);
  428 + free_irq(dev->irq, dev);
  429 + failed_request_irq:
  430 + return ret;
500 431 }
501 432  
502 433 static int ax_close(struct net_device *dev)
503 434 {
504 435 struct ax_device *ax = to_ax_dev(dev);
505   - struct ei_device *ei_local = netdev_priv(dev);
506 436  
507 437 netdev_dbg(dev, "close\n");
508 438  
509   - /* turn the phy off */
510   -
511   - ei_outb(ax->plat->gpoc_val | (1 << 6),
512   - ei_local->mem + EI_SHIFT(0x17));
513   -
514 439 ax->running = 0;
515 440 wmb();
516 441  
517   - del_timer_sync(&ax->mii_timer);
518 442 ax_ei_close(dev);
519 443  
  444 + /* turn the phy off */
  445 + ax_phy_switch(dev, 0);
  446 + phy_disconnect(ax->phy_dev);
  447 +
520 448 free_irq(dev->irq, dev);
521 449 return 0;
522 450 }
523 451  
524 452  
... ... @@ -524,17 +452,15 @@
524 452 static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
525 453 {
526 454 struct ax_device *ax = to_ax_dev(dev);
527   - unsigned long flags;
528   - int rc;
  455 + struct phy_device *phy_dev = ax->phy_dev;
529 456  
530 457 if (!netif_running(dev))
531 458 return -EINVAL;
532 459  
533   - spin_lock_irqsave(&ax->mii_lock, flags);
534   - rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
535   - spin_unlock_irqrestore(&ax->mii_lock, flags);
  460 + if (!phy_dev)
  461 + return -ENODEV;
536 462  
537   - return rc;
  463 + return phy_mii_ioctl(phy_dev, req, cmd);
538 464 }
539 465  
540 466 /* ethtool ops */
541 467  
542 468  
543 469  
544 470  
545 471  
546 472  
547 473  
... ... @@ -552,46 +478,30 @@
552 478 static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
553 479 {
554 480 struct ax_device *ax = to_ax_dev(dev);
555   - unsigned long flags;
  481 + struct phy_device *phy_dev = ax->phy_dev;
556 482  
557   - spin_lock_irqsave(&ax->mii_lock, flags);
558   - mii_ethtool_gset(&ax->mii, cmd);
559   - spin_unlock_irqrestore(&ax->mii_lock, flags);
  483 + if (!phy_dev)
  484 + return -ENODEV;
560 485  
561   - return 0;
  486 + return phy_ethtool_gset(phy_dev, cmd);
562 487 }
563 488  
564 489 static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
565 490 {
566 491 struct ax_device *ax = to_ax_dev(dev);
567   - unsigned long flags;
568   - int rc;
  492 + struct phy_device *phy_dev = ax->phy_dev;
569 493  
570   - spin_lock_irqsave(&ax->mii_lock, flags);
571   - rc = mii_ethtool_sset(&ax->mii, cmd);
572   - spin_unlock_irqrestore(&ax->mii_lock, flags);
  494 + if (!phy_dev)
  495 + return -ENODEV;
573 496  
574   - return rc;
  497 + return phy_ethtool_sset(phy_dev, cmd);
575 498 }
576 499  
577   -static int ax_nway_reset(struct net_device *dev)
578   -{
579   - struct ax_device *ax = to_ax_dev(dev);
580   - return mii_nway_restart(&ax->mii);
581   -}
582   -
583   -static u32 ax_get_link(struct net_device *dev)
584   -{
585   - struct ax_device *ax = to_ax_dev(dev);
586   - return mii_link_ok(&ax->mii);
587   -}
588   -
589 500 static const struct ethtool_ops ax_ethtool_ops = {
590 501 .get_drvinfo = ax_get_drvinfo,
591 502 .get_settings = ax_get_settings,
592 503 .set_settings = ax_set_settings,
593   - .nway_reset = ax_nway_reset,
594   - .get_link = ax_get_link,
  504 + .get_link = ethtool_op_get_link,
595 505 };
596 506  
597 507 #ifdef CONFIG_AX88796_93CX6
598 508  
... ... @@ -642,8 +552,102 @@
642 552 #endif
643 553 };
644 554  
  555 +static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level)
  556 +{
  557 + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
  558 +
  559 + if (level)
  560 + ax->reg_memr |= AX_MEMR_MDC;
  561 + else
  562 + ax->reg_memr &= ~AX_MEMR_MDC;
  563 +
  564 + ei_outb(ax->reg_memr, ax->addr_memr);
  565 +}
  566 +
  567 +static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output)
  568 +{
  569 + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
  570 +
  571 + if (output)
  572 + ax->reg_memr &= ~AX_MEMR_MDIR;
  573 + else
  574 + ax->reg_memr |= AX_MEMR_MDIR;
  575 +
  576 + ei_outb(ax->reg_memr, ax->addr_memr);
  577 +}
  578 +
  579 +static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value)
  580 +{
  581 + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
  582 +
  583 + if (value)
  584 + ax->reg_memr |= AX_MEMR_MDO;
  585 + else
  586 + ax->reg_memr &= ~AX_MEMR_MDO;
  587 +
  588 + ei_outb(ax->reg_memr, ax->addr_memr);
  589 +}
  590 +
  591 +static int ax_bb_get_data(struct mdiobb_ctrl *ctrl)
  592 +{
  593 + struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl);
  594 + int reg_memr = ei_inb(ax->addr_memr);
  595 +
  596 + return reg_memr & AX_MEMR_MDI ? 1 : 0;
  597 +}
  598 +
  599 +static struct mdiobb_ops bb_ops = {
  600 + .owner = THIS_MODULE,
  601 + .set_mdc = ax_bb_mdc,
  602 + .set_mdio_dir = ax_bb_dir,
  603 + .set_mdio_data = ax_bb_set_data,
  604 + .get_mdio_data = ax_bb_get_data,
  605 +};
  606 +
645 607 /* setup code */
646 608  
  609 +static int ax_mii_init(struct net_device *dev)
  610 +{
  611 + struct platform_device *pdev = to_platform_device(dev->dev.parent);
  612 + struct ei_device *ei_local = netdev_priv(dev);
  613 + struct ax_device *ax = to_ax_dev(dev);
  614 + int err, i;
  615 +
  616 + ax->bb_ctrl.ops = &bb_ops;
  617 + ax->addr_memr = ei_local->mem + AX_MEMR;
  618 + ax->mii_bus = alloc_mdio_bitbang(&ax->bb_ctrl);
  619 + if (!ax->mii_bus) {
  620 + err = -ENOMEM;
  621 + goto out;
  622 + }
  623 +
  624 + ax->mii_bus->name = "ax88796_mii_bus";
  625 + ax->mii_bus->parent = dev->dev.parent;
  626 + snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);
  627 +
  628 + ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
  629 + if (!ax->mii_bus->irq) {
  630 + err = -ENOMEM;
  631 + goto out_free_mdio_bitbang;
  632 + }
  633 +
  634 + for (i = 0; i < PHY_MAX_ADDR; i++)
  635 + ax->mii_bus->irq[i] = PHY_POLL;
  636 +
  637 + err = mdiobus_register(ax->mii_bus);
  638 + if (err)
  639 + goto out_free_irq;
  640 +
  641 + return 0;
  642 +
  643 + out_free_irq:
  644 + kfree(ax->mii_bus->irq);
  645 + out_free_mdio_bitbang:
  646 + free_mdio_bitbang(ax->mii_bus);
  647 + out:
  648 + return err;
  649 +}
  650 +
647 651 static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
648 652 {
649 653 void __iomem *ioaddr = ei_local->mem;
... ... @@ -763,15 +767,9 @@
763 767 dev->netdev_ops = &ax_netdev_ops;
764 768 dev->ethtool_ops = &ax_ethtool_ops;
765 769  
766   - ax->msg_enable = NETIF_MSG_LINK;
767   - ax->mii.phy_id_mask = 0x1f;
768   - ax->mii.reg_num_mask = 0x1f;
769   - ax->mii.phy_id = 0x10; /* onboard phy */
770   - ax->mii.force_media = 0;
771   - ax->mii.full_duplex = 0;
772   - ax->mii.mdio_read = ax_phy_read;
773   - ax->mii.mdio_write = ax_phy_write;
774   - ax->mii.dev = dev;
  770 + ret = ax_mii_init(dev);
  771 + if (ret)
  772 + goto out_irq;
775 773  
776 774 ax_NS8390_init(dev, 0);
777 775  
... ... @@ -841,8 +839,6 @@
841 839 SET_NETDEV_DEV(dev, &pdev->dev);
842 840 ei_local = netdev_priv(dev);
843 841 ax = to_ax_dev(dev);
844   -
845   - spin_lock_init(&ax->mii_lock);
846 842  
847 843 ax->plat = pdev->dev.platform_data;
848 844 platform_set_drvdata(pdev, dev);