diff options
-rw-r--r-- | drivers/net/Kconfig | 9 | ||||
-rw-r--r-- | drivers/net/dm9000.c | 41 | ||||
-rw-r--r-- | include/linux/dm9000.h | 1 |
3 files changed, 49 insertions, 2 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 287d0873c60d..4d69474b6125 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -938,6 +938,15 @@ config DM9000 | |||
938 | To compile this driver as a module, choose M here. The module | 938 | To compile this driver as a module, choose M here. The module |
939 | will be called dm9000. | 939 | will be called dm9000. |
940 | 940 | ||
941 | config DM9000_FORCE_SIMPLE_PHY_POLL | ||
942 | bool "Force simple NSR based PHY polling" | ||
943 | depends on DM9000 | ||
944 | ---help--- | ||
945 | This configuration forces the DM9000 to use the NSR's LinkStatus | ||
946 | bit to determine if the link is up or down instead of the more | ||
947 | costly MII PHY reads. Note, this will not work if the chip is | ||
948 | operating with an external PHY. | ||
949 | |||
941 | config ENC28J60 | 950 | config ENC28J60 |
942 | tristate "ENC28J60 support" | 951 | tristate "ENC28J60 support" |
943 | depends on EXPERIMENTAL && SPI && NET_ETHERNET | 952 | depends on EXPERIMENTAL && SPI && NET_ETHERNET |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 7c38f6129b55..5ad2ec537684 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -552,15 +552,48 @@ static const struct ethtool_ops dm9000_ethtool_ops = { | |||
552 | .set_eeprom = dm9000_set_eeprom, | 552 | .set_eeprom = dm9000_set_eeprom, |
553 | }; | 553 | }; |
554 | 554 | ||
555 | static void dm9000_show_carrier(board_info_t *db, | ||
556 | unsigned carrier, unsigned nsr) | ||
557 | { | ||
558 | struct net_device *ndev = db->ndev; | ||
559 | unsigned ncr = dm9000_read_locked(db, DM9000_NCR); | ||
560 | |||
561 | if (carrier) | ||
562 | dev_info(db->dev, "%s: link up, %dMbps, %s-duplex, no LPA\n", | ||
563 | ndev->name, (nsr & NSR_SPEED) ? 10 : 100, | ||
564 | (ncr & NCR_FDX) ? "full" : "half"); | ||
565 | else | ||
566 | dev_info(db->dev, "%s: link down\n", ndev->name); | ||
567 | } | ||
568 | |||
555 | static void | 569 | static void |
556 | dm9000_poll_work(struct work_struct *w) | 570 | dm9000_poll_work(struct work_struct *w) |
557 | { | 571 | { |
558 | struct delayed_work *dw = container_of(w, struct delayed_work, work); | 572 | struct delayed_work *dw = container_of(w, struct delayed_work, work); |
559 | board_info_t *db = container_of(dw, board_info_t, phy_poll); | 573 | board_info_t *db = container_of(dw, board_info_t, phy_poll); |
574 | struct net_device *ndev = db->ndev; | ||
575 | |||
576 | if (db->flags & DM9000_PLATF_SIMPLE_PHY && | ||
577 | !(db->flags & DM9000_PLATF_EXT_PHY)) { | ||
578 | unsigned nsr = dm9000_read_locked(db, DM9000_NSR); | ||
579 | unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0; | ||
580 | unsigned new_carrier; | ||
560 | 581 | ||
561 | mii_check_media(&db->mii, netif_msg_link(db), 0); | 582 | new_carrier = (nsr & NSR_LINKST) ? 1 : 0; |
583 | |||
584 | if (old_carrier != new_carrier) { | ||
585 | if (netif_msg_link(db)) | ||
586 | dm9000_show_carrier(db, new_carrier, nsr); | ||
587 | |||
588 | if (!new_carrier) | ||
589 | netif_carrier_off(ndev); | ||
590 | else | ||
591 | netif_carrier_on(ndev); | ||
592 | } | ||
593 | } else | ||
594 | mii_check_media(&db->mii, netif_msg_link(db), 0); | ||
562 | 595 | ||
563 | if (netif_running(db->ndev)) | 596 | if (netif_running(ndev)) |
564 | dm9000_schedule_poll(db); | 597 | dm9000_schedule_poll(db); |
565 | } | 598 | } |
566 | 599 | ||
@@ -1267,6 +1300,10 @@ dm9000_probe(struct platform_device *pdev) | |||
1267 | db->flags = pdata->flags; | 1300 | db->flags = pdata->flags; |
1268 | } | 1301 | } |
1269 | 1302 | ||
1303 | #ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL | ||
1304 | db->flags |= DM9000_PLATF_SIMPLE_PHY; | ||
1305 | #endif | ||
1306 | |||
1270 | dm9000_reset(db); | 1307 | dm9000_reset(db); |
1271 | 1308 | ||
1272 | /* try multiple times, DM9000 sometimes gets the read wrong */ | 1309 | /* try multiple times, DM9000 sometimes gets the read wrong */ |
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h index a3750462f9e3..fc82446b6425 100644 --- a/include/linux/dm9000.h +++ b/include/linux/dm9000.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define DM9000_PLATF_32BITONLY (0x0004) | 21 | #define DM9000_PLATF_32BITONLY (0x0004) |
22 | #define DM9000_PLATF_EXT_PHY (0x0008) | 22 | #define DM9000_PLATF_EXT_PHY (0x0008) |
23 | #define DM9000_PLATF_NO_EEPROM (0x0010) | 23 | #define DM9000_PLATF_NO_EEPROM (0x0010) |
24 | #define DM9000_PLATF_SIMPLE_PHY (0x0020) /* Use NSR to find LinkStatus */ | ||
24 | 25 | ||
25 | /* platfrom data for platfrom device structure's platfrom_data field */ | 26 | /* platfrom data for platfrom device structure's platfrom_data field */ |
26 | 27 | ||