diff options
Diffstat (limited to 'drivers/net/sis190.c')
-rw-r--r-- | drivers/net/sis190.c | 59 |
1 files changed, 37 insertions, 22 deletions
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index 55ccd51d247e..e2247669a495 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #define PHY_ID_ANY 0x1f | 47 | #define PHY_ID_ANY 0x1f |
48 | #define MII_REG_ANY 0x1f | 48 | #define MII_REG_ANY 0x1f |
49 | 49 | ||
50 | #define DRV_VERSION "1.2" | 50 | #define DRV_VERSION "1.3" |
51 | #define DRV_NAME "sis190" | 51 | #define DRV_NAME "sis190" |
52 | #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION | 52 | #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION |
53 | #define PFX DRV_NAME ": " | 53 | #define PFX DRV_NAME ": " |
@@ -317,6 +317,7 @@ static struct mii_chip_info { | |||
317 | unsigned int type; | 317 | unsigned int type; |
318 | u32 feature; | 318 | u32 feature; |
319 | } mii_chip_table[] = { | 319 | } mii_chip_table[] = { |
320 | { "Atheros PHY", { 0x004d, 0xd010 }, LAN, 0 }, | ||
320 | { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, | 321 | { "Atheros PHY AR8012", { 0x004d, 0xd020 }, LAN, 0 }, |
321 | { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, | 322 | { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 }, |
322 | { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, | 323 | { "Broadcom PHY AC131", { 0x0143, 0xbc70 }, LAN, 0 }, |
@@ -347,7 +348,7 @@ static struct { | |||
347 | u32 msg_enable; | 348 | u32 msg_enable; |
348 | } debug = { -1 }; | 349 | } debug = { -1 }; |
349 | 350 | ||
350 | MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver"); | 351 | MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver"); |
351 | module_param(rx_copybreak, int, 0); | 352 | module_param(rx_copybreak, int, 0); |
352 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); | 353 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); |
353 | module_param_named(debug, debug.msg_enable, int, 0); | 354 | module_param_named(debug, debug.msg_enable, int, 0); |
@@ -539,8 +540,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp, | |||
539 | if (!skb) | 540 | if (!skb) |
540 | goto out; | 541 | goto out; |
541 | 542 | ||
542 | pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size, | 543 | pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz, |
543 | PCI_DMA_FROMDEVICE); | 544 | PCI_DMA_FROMDEVICE); |
544 | skb_reserve(skb, 2); | 545 | skb_reserve(skb, 2); |
545 | skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); | 546 | skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size); |
546 | *sk_buff = skb; | 547 | *sk_buff = skb; |
@@ -942,9 +943,9 @@ static void sis190_phy_task(struct work_struct *work) | |||
942 | u32 ctl; | 943 | u32 ctl; |
943 | const char *msg; | 944 | const char *msg; |
944 | } reg31[] = { | 945 | } reg31[] = { |
945 | { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000, | 946 | { LPA_1000FULL, 0x07000c00 | 0x00001000, |
946 | "1000 Mbps Full Duplex" }, | 947 | "1000 Mbps Full Duplex" }, |
947 | { LPA_1000XHALF | LPA_SLCT, 0x07000c00, | 948 | { LPA_1000HALF, 0x07000c00, |
948 | "1000 Mbps Half Duplex" }, | 949 | "1000 Mbps Half Duplex" }, |
949 | { LPA_100FULL, 0x04000800 | 0x00001000, | 950 | { LPA_100FULL, 0x04000800 | 0x00001000, |
950 | "100 Mbps Full Duplex" }, | 951 | "100 Mbps Full Duplex" }, |
@@ -955,22 +956,35 @@ static void sis190_phy_task(struct work_struct *work) | |||
955 | { LPA_10HALF, 0x04000400, | 956 | { LPA_10HALF, 0x04000400, |
956 | "10 Mbps Half Duplex" }, | 957 | "10 Mbps Half Duplex" }, |
957 | { 0, 0x04000400, "unknown" } | 958 | { 0, 0x04000400, "unknown" } |
958 | }, *p; | 959 | }, *p = NULL; |
959 | u16 adv; | 960 | u16 adv, autoexp, gigadv, gigrec; |
960 | 961 | ||
961 | val = mdio_read(ioaddr, phy_id, 0x1f); | 962 | val = mdio_read(ioaddr, phy_id, 0x1f); |
962 | net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); | 963 | net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); |
963 | 964 | ||
964 | val = mdio_read(ioaddr, phy_id, MII_LPA); | 965 | val = mdio_read(ioaddr, phy_id, MII_LPA); |
965 | adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); | 966 | adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); |
966 | net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n", | 967 | autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION); |
967 | dev->name, val, adv); | 968 | net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n", |
968 | 969 | dev->name, val, adv, autoexp); | |
969 | val &= adv; | 970 | |
971 | if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) { | ||
972 | /* check for gigabit speed */ | ||
973 | gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000); | ||
974 | gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000); | ||
975 | val = (gigadv & (gigrec >> 2)); | ||
976 | if (val & ADVERTISE_1000FULL) | ||
977 | p = reg31; | ||
978 | else if (val & ADVERTISE_1000HALF) | ||
979 | p = reg31 + 1; | ||
980 | } | ||
981 | if (!p) { | ||
982 | val &= adv; | ||
970 | 983 | ||
971 | for (p = reg31; p->val; p++) { | 984 | for (p = reg31; p->val; p++) { |
972 | if ((val & p->val) == p->val) | 985 | if ((val & p->val) == p->val) |
973 | break; | 986 | break; |
987 | } | ||
974 | } | 988 | } |
975 | 989 | ||
976 | p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; | 990 | p->ctl |= SIS_R32(StationControl) & ~0x0f001c00; |
@@ -1204,8 +1218,6 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1204 | 1218 | ||
1205 | SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb); | 1219 | SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb); |
1206 | 1220 | ||
1207 | dev->trans_start = jiffies; | ||
1208 | |||
1209 | dirty_tx = tp->dirty_tx; | 1221 | dirty_tx = tp->dirty_tx; |
1210 | if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) { | 1222 | if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) { |
1211 | netif_stop_queue(dev); | 1223 | netif_stop_queue(dev); |
@@ -1315,12 +1327,15 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp, | |||
1315 | ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? | 1327 | ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? |
1316 | LAN : HOME) : p->type; | 1328 | LAN : HOME) : p->type; |
1317 | tp->features |= p->feature; | 1329 | tp->features |= p->feature; |
1318 | } else | 1330 | net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", |
1331 | pci_name(tp->pci_dev), p->name, phy_id); | ||
1332 | } else { | ||
1319 | phy->type = UNKNOWN; | 1333 | phy->type = UNKNOWN; |
1320 | 1334 | net_probe(tp, KERN_INFO | |
1321 | net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", | 1335 | "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n", |
1322 | pci_name(tp->pci_dev), | 1336 | pci_name(tp->pci_dev), |
1323 | (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); | 1337 | phy->id[0], (phy->id[1] & 0xfff0), phy_id); |
1338 | } | ||
1324 | } | 1339 | } |
1325 | 1340 | ||
1326 | static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp) | 1341 | static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp) |