diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-01 18:02:27 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-01 18:02:27 -0400 |
commit | ceeec3dc375e3b0618f16b34efc56fe093918f8b (patch) | |
tree | 2293d02721ee05131aaf1c60e4fba7e281585eec /drivers/net | |
parent | fbff868db3a4cc6a89d51da9a6d49b26c29d04fb (diff) | |
parent | e3ee3b78f83688a0ae4315e8be71b2eac559904a (diff) |
/spare/repo/netdev-2.6 branch 'ieee80211'
Diffstat (limited to 'drivers/net')
100 files changed, 18642 insertions, 4094 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8edb6936fb9b..e0239a10d325 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -131,6 +131,8 @@ config NET_SB1000 | |||
131 | 131 | ||
132 | source "drivers/net/arcnet/Kconfig" | 132 | source "drivers/net/arcnet/Kconfig" |
133 | 133 | ||
134 | source "drivers/net/phy/Kconfig" | ||
135 | |||
134 | # | 136 | # |
135 | # Ethernet | 137 | # Ethernet |
136 | # | 138 | # |
@@ -1921,6 +1923,17 @@ config R8169_VLAN | |||
1921 | 1923 | ||
1922 | If in doubt, say Y. | 1924 | If in doubt, say Y. |
1923 | 1925 | ||
1926 | config SIS190 | ||
1927 | tristate "SiS190 gigabit ethernet support" | ||
1928 | depends on PCI | ||
1929 | select CRC32 | ||
1930 | select MII | ||
1931 | ---help--- | ||
1932 | Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter. | ||
1933 | |||
1934 | To compile this driver as a module, choose M here: the module | ||
1935 | will be called sis190. This is recommended. | ||
1936 | |||
1924 | config SKGE | 1937 | config SKGE |
1925 | tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)" | 1938 | tristate "New SysKonnect GigaEthernet support (EXPERIMENTAL)" |
1926 | depends on PCI && EXPERIMENTAL | 1939 | depends on PCI && EXPERIMENTAL |
@@ -2091,6 +2104,25 @@ endmenu | |||
2091 | menu "Ethernet (10000 Mbit)" | 2104 | menu "Ethernet (10000 Mbit)" |
2092 | depends on !UML | 2105 | depends on !UML |
2093 | 2106 | ||
2107 | config CHELSIO_T1 | ||
2108 | tristate "Chelsio 10Gb Ethernet support" | ||
2109 | depends on PCI | ||
2110 | help | ||
2111 | This driver supports Chelsio N110 and N210 models 10Gb Ethernet | ||
2112 | cards. More information about adapter features and performance | ||
2113 | tuning is in <file:Documentation/networking/cxgb.txt>. | ||
2114 | |||
2115 | For general information about Chelsio and our products, visit | ||
2116 | our website at <http://www.chelsio.com>. | ||
2117 | |||
2118 | For customer support, please visit our customer support page at | ||
2119 | <http://www.chelsio.com/support.htm>. | ||
2120 | |||
2121 | Please send feedback to <linux-bugs@chelsio.com>. | ||
2122 | |||
2123 | To compile this driver as a module, choose M here: the module | ||
2124 | will be called cxgb. | ||
2125 | |||
2094 | config IXGB | 2126 | config IXGB |
2095 | tristate "Intel(R) PRO/10GbE support" | 2127 | tristate "Intel(R) PRO/10GbE support" |
2096 | depends on PCI | 2128 | depends on PCI |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 63c6d1e6d4d9..5baafcd55610 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -9,6 +9,7 @@ endif | |||
9 | obj-$(CONFIG_E1000) += e1000/ | 9 | obj-$(CONFIG_E1000) += e1000/ |
10 | obj-$(CONFIG_IBM_EMAC) += ibm_emac/ | 10 | obj-$(CONFIG_IBM_EMAC) += ibm_emac/ |
11 | obj-$(CONFIG_IXGB) += ixgb/ | 11 | obj-$(CONFIG_IXGB) += ixgb/ |
12 | obj-$(CONFIG_CHELSIO_T1) += chelsio/ | ||
12 | obj-$(CONFIG_BONDING) += bonding/ | 13 | obj-$(CONFIG_BONDING) += bonding/ |
13 | obj-$(CONFIG_GIANFAR) += gianfar_driver.o | 14 | obj-$(CONFIG_GIANFAR) += gianfar_driver.o |
14 | 15 | ||
@@ -42,6 +43,7 @@ obj-$(CONFIG_EEPRO100) += eepro100.o | |||
42 | obj-$(CONFIG_E100) += e100.o | 43 | obj-$(CONFIG_E100) += e100.o |
43 | obj-$(CONFIG_TLAN) += tlan.o | 44 | obj-$(CONFIG_TLAN) += tlan.o |
44 | obj-$(CONFIG_EPIC100) += epic100.o | 45 | obj-$(CONFIG_EPIC100) += epic100.o |
46 | obj-$(CONFIG_SIS190) += sis190.o | ||
45 | obj-$(CONFIG_SIS900) += sis900.o | 47 | obj-$(CONFIG_SIS900) += sis900.o |
46 | obj-$(CONFIG_YELLOWFIN) += yellowfin.o | 48 | obj-$(CONFIG_YELLOWFIN) += yellowfin.o |
47 | obj-$(CONFIG_ACENIC) += acenic.o | 49 | obj-$(CONFIG_ACENIC) += acenic.o |
@@ -65,6 +67,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o | |||
65 | # | 67 | # |
66 | 68 | ||
67 | obj-$(CONFIG_MII) += mii.o | 69 | obj-$(CONFIG_MII) += mii.o |
70 | obj-$(CONFIG_PHYLIB) += phy/ | ||
68 | 71 | ||
69 | obj-$(CONFIG_SUNDANCE) += sundance.o | 72 | obj-$(CONFIG_SUNDANCE) += sundance.o |
70 | obj-$(CONFIG_HAMACHI) += hamachi.o | 73 | obj-$(CONFIG_HAMACHI) += hamachi.o |
diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 3707df6b0cfa..60304f7e7e5b 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c | |||
@@ -87,7 +87,6 @@ extern struct net_device *mvme147lance_probe(int unit); | |||
87 | extern struct net_device *tc515_probe(int unit); | 87 | extern struct net_device *tc515_probe(int unit); |
88 | extern struct net_device *lance_probe(int unit); | 88 | extern struct net_device *lance_probe(int unit); |
89 | extern struct net_device *mace_probe(int unit); | 89 | extern struct net_device *mace_probe(int unit); |
90 | extern struct net_device *macsonic_probe(int unit); | ||
91 | extern struct net_device *mac8390_probe(int unit); | 90 | extern struct net_device *mac8390_probe(int unit); |
92 | extern struct net_device *mac89x0_probe(int unit); | 91 | extern struct net_device *mac89x0_probe(int unit); |
93 | extern struct net_device *mc32_probe(int unit); | 92 | extern struct net_device *mc32_probe(int unit); |
@@ -284,9 +283,6 @@ static struct devprobe2 m68k_probes[] __initdata = { | |||
284 | #ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */ | 283 | #ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */ |
285 | {mace_probe, 0}, | 284 | {mace_probe, 0}, |
286 | #endif | 285 | #endif |
287 | #ifdef CONFIG_MACSONIC /* Mac SONIC-based Ethernet of all sorts */ | ||
288 | {macsonic_probe, 0}, | ||
289 | #endif | ||
290 | #ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ | 286 | #ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ |
291 | {mac8390_probe, 0}, | 287 | {mac8390_probe, 0}, |
292 | #endif | 288 | #endif |
@@ -318,17 +314,9 @@ static void __init ethif_probe2(int unit) | |||
318 | #ifdef CONFIG_TR | 314 | #ifdef CONFIG_TR |
319 | /* Token-ring device probe */ | 315 | /* Token-ring device probe */ |
320 | extern int ibmtr_probe_card(struct net_device *); | 316 | extern int ibmtr_probe_card(struct net_device *); |
321 | extern struct net_device *sk_isa_probe(int unit); | ||
322 | extern struct net_device *proteon_probe(int unit); | ||
323 | extern struct net_device *smctr_probe(int unit); | 317 | extern struct net_device *smctr_probe(int unit); |
324 | 318 | ||
325 | static struct devprobe2 tr_probes2[] __initdata = { | 319 | static struct devprobe2 tr_probes2[] __initdata = { |
326 | #ifdef CONFIG_SKISA | ||
327 | {sk_isa_probe, 0}, | ||
328 | #endif | ||
329 | #ifdef CONFIG_PROTEON | ||
330 | {proteon_probe, 0}, | ||
331 | #endif | ||
332 | #ifdef CONFIG_SMCTR | 320 | #ifdef CONFIG_SMCTR |
333 | {smctr_probe, 0}, | 321 | {smctr_probe, 0}, |
334 | #endif | 322 | #endif |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 8acc655ec1e8..7babf6af4e28 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -14,8 +14,8 @@ | |||
14 | 14 | ||
15 | #define DRV_MODULE_NAME "bnx2" | 15 | #define DRV_MODULE_NAME "bnx2" |
16 | #define PFX DRV_MODULE_NAME ": " | 16 | #define PFX DRV_MODULE_NAME ": " |
17 | #define DRV_MODULE_VERSION "1.2.19" | 17 | #define DRV_MODULE_VERSION "1.2.20" |
18 | #define DRV_MODULE_RELDATE "May 23, 2005" | 18 | #define DRV_MODULE_RELDATE "August 22, 2005" |
19 | 19 | ||
20 | #define RUN_AT(x) (jiffies + (x)) | 20 | #define RUN_AT(x) (jiffies + (x)) |
21 | 21 | ||
@@ -52,7 +52,6 @@ static struct { | |||
52 | { "HP NC370i Multifunction Gigabit Server Adapter" }, | 52 | { "HP NC370i Multifunction Gigabit Server Adapter" }, |
53 | { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, | 53 | { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, |
54 | { "HP NC370F Multifunction Gigabit Server Adapter" }, | 54 | { "HP NC370F Multifunction Gigabit Server Adapter" }, |
55 | { 0 }, | ||
56 | }; | 55 | }; |
57 | 56 | ||
58 | static struct pci_device_id bnx2_pci_tbl[] = { | 57 | static struct pci_device_id bnx2_pci_tbl[] = { |
@@ -108,6 +107,15 @@ static struct flash_spec flash_table[] = | |||
108 | 107 | ||
109 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); | 108 | MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); |
110 | 109 | ||
110 | static inline u32 bnx2_tx_avail(struct bnx2 *bp) | ||
111 | { | ||
112 | u32 diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons); | ||
113 | |||
114 | if (diff > MAX_TX_DESC_CNT) | ||
115 | diff = (diff & MAX_TX_DESC_CNT) - 1; | ||
116 | return (bp->tx_ring_size - diff); | ||
117 | } | ||
118 | |||
111 | static u32 | 119 | static u32 |
112 | bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) | 120 | bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) |
113 | { | 121 | { |
@@ -807,7 +815,19 @@ bnx2_setup_serdes_phy(struct bnx2 *bp) | |||
807 | bnx2_write_phy(bp, MII_ADVERTISE, new_adv); | 815 | bnx2_write_phy(bp, MII_ADVERTISE, new_adv); |
808 | bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | | 816 | bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | |
809 | BMCR_ANENABLE); | 817 | BMCR_ANENABLE); |
810 | bp->serdes_an_pending = SERDES_AN_TIMEOUT / bp->timer_interval; | 818 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { |
819 | /* Speed up link-up time when the link partner | ||
820 | * does not autonegotiate which is very common | ||
821 | * in blade servers. Some blade servers use | ||
822 | * IPMI for kerboard input and it's important | ||
823 | * to minimize link disruptions. Autoneg. involves | ||
824 | * exchanging base pages plus 3 next pages and | ||
825 | * normally completes in about 120 msec. | ||
826 | */ | ||
827 | bp->current_interval = SERDES_AN_TIMEOUT; | ||
828 | bp->serdes_an_pending = 1; | ||
829 | mod_timer(&bp->timer, jiffies + bp->current_interval); | ||
830 | } | ||
811 | } | 831 | } |
812 | 832 | ||
813 | return 0; | 833 | return 0; |
@@ -1327,22 +1347,17 @@ bnx2_tx_int(struct bnx2 *bp) | |||
1327 | } | 1347 | } |
1328 | } | 1348 | } |
1329 | 1349 | ||
1330 | atomic_add(tx_free_bd, &bp->tx_avail_bd); | 1350 | bp->tx_cons = sw_cons; |
1331 | 1351 | ||
1332 | if (unlikely(netif_queue_stopped(bp->dev))) { | 1352 | if (unlikely(netif_queue_stopped(bp->dev))) { |
1333 | unsigned long flags; | 1353 | spin_lock(&bp->tx_lock); |
1334 | |||
1335 | spin_lock_irqsave(&bp->tx_lock, flags); | ||
1336 | if ((netif_queue_stopped(bp->dev)) && | 1354 | if ((netif_queue_stopped(bp->dev)) && |
1337 | (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)) { | 1355 | (bnx2_tx_avail(bp) > MAX_SKB_FRAGS)) { |
1338 | 1356 | ||
1339 | netif_wake_queue(bp->dev); | 1357 | netif_wake_queue(bp->dev); |
1340 | } | 1358 | } |
1341 | spin_unlock_irqrestore(&bp->tx_lock, flags); | 1359 | spin_unlock(&bp->tx_lock); |
1342 | } | 1360 | } |
1343 | |||
1344 | bp->tx_cons = sw_cons; | ||
1345 | |||
1346 | } | 1361 | } |
1347 | 1362 | ||
1348 | static inline void | 1363 | static inline void |
@@ -1523,15 +1538,12 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs) | |||
1523 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); | 1538 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); |
1524 | 1539 | ||
1525 | /* Return here if interrupt is disabled. */ | 1540 | /* Return here if interrupt is disabled. */ |
1526 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) { | 1541 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) |
1527 | return IRQ_RETVAL(1); | 1542 | return IRQ_HANDLED; |
1528 | } | ||
1529 | 1543 | ||
1530 | if (netif_rx_schedule_prep(dev)) { | 1544 | netif_rx_schedule(dev); |
1531 | __netif_rx_schedule(dev); | ||
1532 | } | ||
1533 | 1545 | ||
1534 | return IRQ_RETVAL(1); | 1546 | return IRQ_HANDLED; |
1535 | } | 1547 | } |
1536 | 1548 | ||
1537 | static irqreturn_t | 1549 | static irqreturn_t |
@@ -1549,22 +1561,19 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs) | |||
1549 | if ((bp->status_blk->status_idx == bp->last_status_idx) || | 1561 | if ((bp->status_blk->status_idx == bp->last_status_idx) || |
1550 | (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & | 1562 | (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & |
1551 | BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) | 1563 | BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) |
1552 | return IRQ_RETVAL(0); | 1564 | return IRQ_NONE; |
1553 | 1565 | ||
1554 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 1566 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
1555 | BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | | 1567 | BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | |
1556 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); | 1568 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT); |
1557 | 1569 | ||
1558 | /* Return here if interrupt is shared and is disabled. */ | 1570 | /* Return here if interrupt is shared and is disabled. */ |
1559 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) { | 1571 | if (unlikely(atomic_read(&bp->intr_sem) != 0)) |
1560 | return IRQ_RETVAL(1); | 1572 | return IRQ_HANDLED; |
1561 | } | ||
1562 | 1573 | ||
1563 | if (netif_rx_schedule_prep(dev)) { | 1574 | netif_rx_schedule(dev); |
1564 | __netif_rx_schedule(dev); | ||
1565 | } | ||
1566 | 1575 | ||
1567 | return IRQ_RETVAL(1); | 1576 | return IRQ_HANDLED; |
1568 | } | 1577 | } |
1569 | 1578 | ||
1570 | static int | 1579 | static int |
@@ -1581,11 +1590,9 @@ bnx2_poll(struct net_device *dev, int *budget) | |||
1581 | (bp->status_blk->status_attn_bits_ack & | 1590 | (bp->status_blk->status_attn_bits_ack & |
1582 | STATUS_ATTN_BITS_LINK_STATE)) { | 1591 | STATUS_ATTN_BITS_LINK_STATE)) { |
1583 | 1592 | ||
1584 | unsigned long flags; | 1593 | spin_lock(&bp->phy_lock); |
1585 | |||
1586 | spin_lock_irqsave(&bp->phy_lock, flags); | ||
1587 | bnx2_phy_int(bp); | 1594 | bnx2_phy_int(bp); |
1588 | spin_unlock_irqrestore(&bp->phy_lock, flags); | 1595 | spin_unlock(&bp->phy_lock); |
1589 | } | 1596 | } |
1590 | 1597 | ||
1591 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { | 1598 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { |
@@ -1628,9 +1635,8 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
1628 | struct bnx2 *bp = dev->priv; | 1635 | struct bnx2 *bp = dev->priv; |
1629 | u32 rx_mode, sort_mode; | 1636 | u32 rx_mode, sort_mode; |
1630 | int i; | 1637 | int i; |
1631 | unsigned long flags; | ||
1632 | 1638 | ||
1633 | spin_lock_irqsave(&bp->phy_lock, flags); | 1639 | spin_lock_bh(&bp->phy_lock); |
1634 | 1640 | ||
1635 | rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | | 1641 | rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | |
1636 | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); | 1642 | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); |
@@ -1691,7 +1697,7 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
1691 | REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode); | 1697 | REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode); |
1692 | REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA); | 1698 | REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA); |
1693 | 1699 | ||
1694 | spin_unlock_irqrestore(&bp->phy_lock, flags); | 1700 | spin_unlock_bh(&bp->phy_lock); |
1695 | } | 1701 | } |
1696 | 1702 | ||
1697 | static void | 1703 | static void |
@@ -2960,7 +2966,6 @@ bnx2_init_tx_ring(struct bnx2 *bp) | |||
2960 | bp->tx_prod = 0; | 2966 | bp->tx_prod = 0; |
2961 | bp->tx_cons = 0; | 2967 | bp->tx_cons = 0; |
2962 | bp->tx_prod_bseq = 0; | 2968 | bp->tx_prod_bseq = 0; |
2963 | atomic_set(&bp->tx_avail_bd, bp->tx_ring_size); | ||
2964 | 2969 | ||
2965 | val = BNX2_L2CTX_TYPE_TYPE_L2; | 2970 | val = BNX2_L2CTX_TYPE_TYPE_L2; |
2966 | val |= BNX2_L2CTX_TYPE_SIZE_L2; | 2971 | val |= BNX2_L2CTX_TYPE_SIZE_L2; |
@@ -3507,11 +3512,11 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3507 | rw_mask = reg_tbl[i].rw_mask; | 3512 | rw_mask = reg_tbl[i].rw_mask; |
3508 | ro_mask = reg_tbl[i].ro_mask; | 3513 | ro_mask = reg_tbl[i].ro_mask; |
3509 | 3514 | ||
3510 | save_val = readl((u8 *) bp->regview + offset); | 3515 | save_val = readl(bp->regview + offset); |
3511 | 3516 | ||
3512 | writel(0, (u8 *) bp->regview + offset); | 3517 | writel(0, bp->regview + offset); |
3513 | 3518 | ||
3514 | val = readl((u8 *) bp->regview + offset); | 3519 | val = readl(bp->regview + offset); |
3515 | if ((val & rw_mask) != 0) { | 3520 | if ((val & rw_mask) != 0) { |
3516 | goto reg_test_err; | 3521 | goto reg_test_err; |
3517 | } | 3522 | } |
@@ -3520,9 +3525,9 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3520 | goto reg_test_err; | 3525 | goto reg_test_err; |
3521 | } | 3526 | } |
3522 | 3527 | ||
3523 | writel(0xffffffff, (u8 *) bp->regview + offset); | 3528 | writel(0xffffffff, bp->regview + offset); |
3524 | 3529 | ||
3525 | val = readl((u8 *) bp->regview + offset); | 3530 | val = readl(bp->regview + offset); |
3526 | if ((val & rw_mask) != rw_mask) { | 3531 | if ((val & rw_mask) != rw_mask) { |
3527 | goto reg_test_err; | 3532 | goto reg_test_err; |
3528 | } | 3533 | } |
@@ -3531,11 +3536,11 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3531 | goto reg_test_err; | 3536 | goto reg_test_err; |
3532 | } | 3537 | } |
3533 | 3538 | ||
3534 | writel(save_val, (u8 *) bp->regview + offset); | 3539 | writel(save_val, bp->regview + offset); |
3535 | continue; | 3540 | continue; |
3536 | 3541 | ||
3537 | reg_test_err: | 3542 | reg_test_err: |
3538 | writel(save_val, (u8 *) bp->regview + offset); | 3543 | writel(save_val, bp->regview + offset); |
3539 | ret = -ENODEV; | 3544 | ret = -ENODEV; |
3540 | break; | 3545 | break; |
3541 | } | 3546 | } |
@@ -3752,10 +3757,10 @@ bnx2_test_link(struct bnx2 *bp) | |||
3752 | { | 3757 | { |
3753 | u32 bmsr; | 3758 | u32 bmsr; |
3754 | 3759 | ||
3755 | spin_lock_irq(&bp->phy_lock); | 3760 | spin_lock_bh(&bp->phy_lock); |
3756 | bnx2_read_phy(bp, MII_BMSR, &bmsr); | 3761 | bnx2_read_phy(bp, MII_BMSR, &bmsr); |
3757 | bnx2_read_phy(bp, MII_BMSR, &bmsr); | 3762 | bnx2_read_phy(bp, MII_BMSR, &bmsr); |
3758 | spin_unlock_irq(&bp->phy_lock); | 3763 | spin_unlock_bh(&bp->phy_lock); |
3759 | 3764 | ||
3760 | if (bmsr & BMSR_LSTATUS) { | 3765 | if (bmsr & BMSR_LSTATUS) { |
3761 | return 0; | 3766 | return 0; |
@@ -3801,6 +3806,9 @@ bnx2_timer(unsigned long data) | |||
3801 | struct bnx2 *bp = (struct bnx2 *) data; | 3806 | struct bnx2 *bp = (struct bnx2 *) data; |
3802 | u32 msg; | 3807 | u32 msg; |
3803 | 3808 | ||
3809 | if (!netif_running(bp->dev)) | ||
3810 | return; | ||
3811 | |||
3804 | if (atomic_read(&bp->intr_sem) != 0) | 3812 | if (atomic_read(&bp->intr_sem) != 0) |
3805 | goto bnx2_restart_timer; | 3813 | goto bnx2_restart_timer; |
3806 | 3814 | ||
@@ -3809,15 +3817,16 @@ bnx2_timer(unsigned long data) | |||
3809 | 3817 | ||
3810 | if ((bp->phy_flags & PHY_SERDES_FLAG) && | 3818 | if ((bp->phy_flags & PHY_SERDES_FLAG) && |
3811 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { | 3819 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { |
3812 | unsigned long flags; | ||
3813 | 3820 | ||
3814 | spin_lock_irqsave(&bp->phy_lock, flags); | 3821 | spin_lock(&bp->phy_lock); |
3815 | if (bp->serdes_an_pending) { | 3822 | if (bp->serdes_an_pending) { |
3816 | bp->serdes_an_pending--; | 3823 | bp->serdes_an_pending--; |
3817 | } | 3824 | } |
3818 | else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { | 3825 | else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { |
3819 | u32 bmcr; | 3826 | u32 bmcr; |
3820 | 3827 | ||
3828 | bp->current_interval = bp->timer_interval; | ||
3829 | |||
3821 | bnx2_read_phy(bp, MII_BMCR, &bmcr); | 3830 | bnx2_read_phy(bp, MII_BMCR, &bmcr); |
3822 | 3831 | ||
3823 | if (bmcr & BMCR_ANENABLE) { | 3832 | if (bmcr & BMCR_ANENABLE) { |
@@ -3860,14 +3869,14 @@ bnx2_timer(unsigned long data) | |||
3860 | 3869 | ||
3861 | } | 3870 | } |
3862 | } | 3871 | } |
3872 | else | ||
3873 | bp->current_interval = bp->timer_interval; | ||
3863 | 3874 | ||
3864 | spin_unlock_irqrestore(&bp->phy_lock, flags); | 3875 | spin_unlock(&bp->phy_lock); |
3865 | } | 3876 | } |
3866 | 3877 | ||
3867 | bnx2_restart_timer: | 3878 | bnx2_restart_timer: |
3868 | bp->timer.expires = RUN_AT(bp->timer_interval); | 3879 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
3869 | |||
3870 | add_timer(&bp->timer); | ||
3871 | } | 3880 | } |
3872 | 3881 | ||
3873 | /* Called with rtnl_lock */ | 3882 | /* Called with rtnl_lock */ |
@@ -3920,12 +3929,7 @@ bnx2_open(struct net_device *dev) | |||
3920 | return rc; | 3929 | return rc; |
3921 | } | 3930 | } |
3922 | 3931 | ||
3923 | init_timer(&bp->timer); | 3932 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
3924 | |||
3925 | bp->timer.expires = RUN_AT(bp->timer_interval); | ||
3926 | bp->timer.data = (unsigned long) bp; | ||
3927 | bp->timer.function = bnx2_timer; | ||
3928 | add_timer(&bp->timer); | ||
3929 | 3933 | ||
3930 | atomic_set(&bp->intr_sem, 0); | 3934 | atomic_set(&bp->intr_sem, 0); |
3931 | 3935 | ||
@@ -3976,12 +3980,17 @@ bnx2_reset_task(void *data) | |||
3976 | { | 3980 | { |
3977 | struct bnx2 *bp = data; | 3981 | struct bnx2 *bp = data; |
3978 | 3982 | ||
3983 | if (!netif_running(bp->dev)) | ||
3984 | return; | ||
3985 | |||
3986 | bp->in_reset_task = 1; | ||
3979 | bnx2_netif_stop(bp); | 3987 | bnx2_netif_stop(bp); |
3980 | 3988 | ||
3981 | bnx2_init_nic(bp); | 3989 | bnx2_init_nic(bp); |
3982 | 3990 | ||
3983 | atomic_set(&bp->intr_sem, 1); | 3991 | atomic_set(&bp->intr_sem, 1); |
3984 | bnx2_netif_start(bp); | 3992 | bnx2_netif_start(bp); |
3993 | bp->in_reset_task = 0; | ||
3985 | } | 3994 | } |
3986 | 3995 | ||
3987 | static void | 3996 | static void |
@@ -4041,9 +4050,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4041 | u16 prod, ring_prod; | 4050 | u16 prod, ring_prod; |
4042 | int i; | 4051 | int i; |
4043 | 4052 | ||
4044 | if (unlikely(atomic_read(&bp->tx_avail_bd) < | 4053 | if (unlikely(bnx2_tx_avail(bp) < (skb_shinfo(skb)->nr_frags + 1))) { |
4045 | (skb_shinfo(skb)->nr_frags + 1))) { | ||
4046 | |||
4047 | netif_stop_queue(dev); | 4054 | netif_stop_queue(dev); |
4048 | printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n", | 4055 | printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n", |
4049 | dev->name); | 4056 | dev->name); |
@@ -4140,8 +4147,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4140 | prod = NEXT_TX_BD(prod); | 4147 | prod = NEXT_TX_BD(prod); |
4141 | bp->tx_prod_bseq += skb->len; | 4148 | bp->tx_prod_bseq += skb->len; |
4142 | 4149 | ||
4143 | atomic_sub(last_frag + 1, &bp->tx_avail_bd); | ||
4144 | |||
4145 | REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); | 4150 | REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); |
4146 | REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); | 4151 | REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); |
4147 | 4152 | ||
@@ -4150,17 +4155,13 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4150 | bp->tx_prod = prod; | 4155 | bp->tx_prod = prod; |
4151 | dev->trans_start = jiffies; | 4156 | dev->trans_start = jiffies; |
4152 | 4157 | ||
4153 | if (unlikely(atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS)) { | 4158 | if (unlikely(bnx2_tx_avail(bp) <= MAX_SKB_FRAGS)) { |
4154 | unsigned long flags; | 4159 | spin_lock(&bp->tx_lock); |
4155 | 4160 | netif_stop_queue(dev); | |
4156 | spin_lock_irqsave(&bp->tx_lock, flags); | 4161 | |
4157 | if (atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS) { | 4162 | if (bnx2_tx_avail(bp) > MAX_SKB_FRAGS) |
4158 | netif_stop_queue(dev); | 4163 | netif_wake_queue(dev); |
4159 | 4164 | spin_unlock(&bp->tx_lock); | |
4160 | if (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS) | ||
4161 | netif_wake_queue(dev); | ||
4162 | } | ||
4163 | spin_unlock_irqrestore(&bp->tx_lock, flags); | ||
4164 | } | 4165 | } |
4165 | 4166 | ||
4166 | return NETDEV_TX_OK; | 4167 | return NETDEV_TX_OK; |
@@ -4173,7 +4174,13 @@ bnx2_close(struct net_device *dev) | |||
4173 | struct bnx2 *bp = dev->priv; | 4174 | struct bnx2 *bp = dev->priv; |
4174 | u32 reset_code; | 4175 | u32 reset_code; |
4175 | 4176 | ||
4176 | flush_scheduled_work(); | 4177 | /* Calling flush_scheduled_work() may deadlock because |
4178 | * linkwatch_event() may be on the workqueue and it will try to get | ||
4179 | * the rtnl_lock which we are holding. | ||
4180 | */ | ||
4181 | while (bp->in_reset_task) | ||
4182 | msleep(1); | ||
4183 | |||
4177 | bnx2_netif_stop(bp); | 4184 | bnx2_netif_stop(bp); |
4178 | del_timer_sync(&bp->timer); | 4185 | del_timer_sync(&bp->timer); |
4179 | if (bp->wol) | 4186 | if (bp->wol) |
@@ -4390,11 +4397,11 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
4390 | bp->req_line_speed = req_line_speed; | 4397 | bp->req_line_speed = req_line_speed; |
4391 | bp->req_duplex = req_duplex; | 4398 | bp->req_duplex = req_duplex; |
4392 | 4399 | ||
4393 | spin_lock_irq(&bp->phy_lock); | 4400 | spin_lock_bh(&bp->phy_lock); |
4394 | 4401 | ||
4395 | bnx2_setup_phy(bp); | 4402 | bnx2_setup_phy(bp); |
4396 | 4403 | ||
4397 | spin_unlock_irq(&bp->phy_lock); | 4404 | spin_unlock_bh(&bp->phy_lock); |
4398 | 4405 | ||
4399 | return 0; | 4406 | return 0; |
4400 | } | 4407 | } |
@@ -4464,19 +4471,20 @@ bnx2_nway_reset(struct net_device *dev) | |||
4464 | return -EINVAL; | 4471 | return -EINVAL; |
4465 | } | 4472 | } |
4466 | 4473 | ||
4467 | spin_lock_irq(&bp->phy_lock); | 4474 | spin_lock_bh(&bp->phy_lock); |
4468 | 4475 | ||
4469 | /* Force a link down visible on the other side */ | 4476 | /* Force a link down visible on the other side */ |
4470 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 4477 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
4471 | bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); | 4478 | bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); |
4472 | spin_unlock_irq(&bp->phy_lock); | 4479 | spin_unlock_bh(&bp->phy_lock); |
4473 | 4480 | ||
4474 | msleep(20); | 4481 | msleep(20); |
4475 | 4482 | ||
4476 | spin_lock_irq(&bp->phy_lock); | 4483 | spin_lock_bh(&bp->phy_lock); |
4477 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { | 4484 | if (CHIP_NUM(bp) == CHIP_NUM_5706) { |
4478 | bp->serdes_an_pending = SERDES_AN_TIMEOUT / | 4485 | bp->current_interval = SERDES_AN_TIMEOUT; |
4479 | bp->timer_interval; | 4486 | bp->serdes_an_pending = 1; |
4487 | mod_timer(&bp->timer, jiffies + bp->current_interval); | ||
4480 | } | 4488 | } |
4481 | } | 4489 | } |
4482 | 4490 | ||
@@ -4484,7 +4492,7 @@ bnx2_nway_reset(struct net_device *dev) | |||
4484 | bmcr &= ~BMCR_LOOPBACK; | 4492 | bmcr &= ~BMCR_LOOPBACK; |
4485 | bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); | 4493 | bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); |
4486 | 4494 | ||
4487 | spin_unlock_irq(&bp->phy_lock); | 4495 | spin_unlock_bh(&bp->phy_lock); |
4488 | 4496 | ||
4489 | return 0; | 4497 | return 0; |
4490 | } | 4498 | } |
@@ -4670,11 +4678,11 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | |||
4670 | bp->autoneg &= ~AUTONEG_FLOW_CTRL; | 4678 | bp->autoneg &= ~AUTONEG_FLOW_CTRL; |
4671 | } | 4679 | } |
4672 | 4680 | ||
4673 | spin_lock_irq(&bp->phy_lock); | 4681 | spin_lock_bh(&bp->phy_lock); |
4674 | 4682 | ||
4675 | bnx2_setup_phy(bp); | 4683 | bnx2_setup_phy(bp); |
4676 | 4684 | ||
4677 | spin_unlock_irq(&bp->phy_lock); | 4685 | spin_unlock_bh(&bp->phy_lock); |
4678 | 4686 | ||
4679 | return 0; | 4687 | return 0; |
4680 | } | 4688 | } |
@@ -4698,7 +4706,7 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data) | |||
4698 | 4706 | ||
4699 | #define BNX2_NUM_STATS 45 | 4707 | #define BNX2_NUM_STATS 45 |
4700 | 4708 | ||
4701 | struct { | 4709 | static struct { |
4702 | char string[ETH_GSTRING_LEN]; | 4710 | char string[ETH_GSTRING_LEN]; |
4703 | } bnx2_stats_str_arr[BNX2_NUM_STATS] = { | 4711 | } bnx2_stats_str_arr[BNX2_NUM_STATS] = { |
4704 | { "rx_bytes" }, | 4712 | { "rx_bytes" }, |
@@ -4750,7 +4758,7 @@ struct { | |||
4750 | 4758 | ||
4751 | #define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4) | 4759 | #define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4) |
4752 | 4760 | ||
4753 | unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { | 4761 | static unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { |
4754 | STATS_OFFSET32(stat_IfHCInOctets_hi), | 4762 | STATS_OFFSET32(stat_IfHCInOctets_hi), |
4755 | STATS_OFFSET32(stat_IfHCInBadOctets_hi), | 4763 | STATS_OFFSET32(stat_IfHCInBadOctets_hi), |
4756 | STATS_OFFSET32(stat_IfHCOutOctets_hi), | 4764 | STATS_OFFSET32(stat_IfHCOutOctets_hi), |
@@ -4801,7 +4809,7 @@ unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { | |||
4801 | /* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are | 4809 | /* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are |
4802 | * skipped because of errata. | 4810 | * skipped because of errata. |
4803 | */ | 4811 | */ |
4804 | u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { | 4812 | static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { |
4805 | 8,0,8,8,8,8,8,8,8,8, | 4813 | 8,0,8,8,8,8,8,8,8,8, |
4806 | 4,0,4,4,4,4,4,4,4,4, | 4814 | 4,0,4,4,4,4,4,4,4,4, |
4807 | 4,4,4,4,4,4,4,4,4,4, | 4815 | 4,4,4,4,4,4,4,4,4,4, |
@@ -4811,7 +4819,7 @@ u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { | |||
4811 | 4819 | ||
4812 | #define BNX2_NUM_TESTS 6 | 4820 | #define BNX2_NUM_TESTS 6 |
4813 | 4821 | ||
4814 | struct { | 4822 | static struct { |
4815 | char string[ETH_GSTRING_LEN]; | 4823 | char string[ETH_GSTRING_LEN]; |
4816 | } bnx2_tests_str_arr[BNX2_NUM_TESTS] = { | 4824 | } bnx2_tests_str_arr[BNX2_NUM_TESTS] = { |
4817 | { "register_test (offline)" }, | 4825 | { "register_test (offline)" }, |
@@ -4910,7 +4918,7 @@ bnx2_get_ethtool_stats(struct net_device *dev, | |||
4910 | struct bnx2 *bp = dev->priv; | 4918 | struct bnx2 *bp = dev->priv; |
4911 | int i; | 4919 | int i; |
4912 | u32 *hw_stats = (u32 *) bp->stats_blk; | 4920 | u32 *hw_stats = (u32 *) bp->stats_blk; |
4913 | u8 *stats_len_arr = 0; | 4921 | u8 *stats_len_arr = NULL; |
4914 | 4922 | ||
4915 | if (hw_stats == NULL) { | 4923 | if (hw_stats == NULL) { |
4916 | memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS); | 4924 | memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS); |
@@ -5012,7 +5020,7 @@ static struct ethtool_ops bnx2_ethtool_ops = { | |||
5012 | static int | 5020 | static int |
5013 | bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 5021 | bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
5014 | { | 5022 | { |
5015 | struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; | 5023 | struct mii_ioctl_data *data = if_mii(ifr); |
5016 | struct bnx2 *bp = dev->priv; | 5024 | struct bnx2 *bp = dev->priv; |
5017 | int err; | 5025 | int err; |
5018 | 5026 | ||
@@ -5024,9 +5032,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
5024 | case SIOCGMIIREG: { | 5032 | case SIOCGMIIREG: { |
5025 | u32 mii_regval; | 5033 | u32 mii_regval; |
5026 | 5034 | ||
5027 | spin_lock_irq(&bp->phy_lock); | 5035 | spin_lock_bh(&bp->phy_lock); |
5028 | err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); | 5036 | err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); |
5029 | spin_unlock_irq(&bp->phy_lock); | 5037 | spin_unlock_bh(&bp->phy_lock); |
5030 | 5038 | ||
5031 | data->val_out = mii_regval; | 5039 | data->val_out = mii_regval; |
5032 | 5040 | ||
@@ -5037,9 +5045,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
5037 | if (!capable(CAP_NET_ADMIN)) | 5045 | if (!capable(CAP_NET_ADMIN)) |
5038 | return -EPERM; | 5046 | return -EPERM; |
5039 | 5047 | ||
5040 | spin_lock_irq(&bp->phy_lock); | 5048 | spin_lock_bh(&bp->phy_lock); |
5041 | err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); | 5049 | err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); |
5042 | spin_unlock_irq(&bp->phy_lock); | 5050 | spin_unlock_bh(&bp->phy_lock); |
5043 | 5051 | ||
5044 | return err; | 5052 | return err; |
5045 | 5053 | ||
@@ -5057,6 +5065,9 @@ bnx2_change_mac_addr(struct net_device *dev, void *p) | |||
5057 | struct sockaddr *addr = p; | 5065 | struct sockaddr *addr = p; |
5058 | struct bnx2 *bp = dev->priv; | 5066 | struct bnx2 *bp = dev->priv; |
5059 | 5067 | ||
5068 | if (!is_valid_ether_addr(addr->sa_data)) | ||
5069 | return -EINVAL; | ||
5070 | |||
5060 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 5071 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
5061 | if (netif_running(dev)) | 5072 | if (netif_running(dev)) |
5062 | bnx2_set_mac_addr(bp); | 5073 | bnx2_set_mac_addr(bp); |
@@ -5305,6 +5316,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5305 | bp->stats_ticks = 1000000 & 0xffff00; | 5316 | bp->stats_ticks = 1000000 & 0xffff00; |
5306 | 5317 | ||
5307 | bp->timer_interval = HZ; | 5318 | bp->timer_interval = HZ; |
5319 | bp->current_interval = HZ; | ||
5308 | 5320 | ||
5309 | /* Disable WOL support if we are running on a SERDES chip. */ | 5321 | /* Disable WOL support if we are running on a SERDES chip. */ |
5310 | if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { | 5322 | if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { |
@@ -5328,6 +5340,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5328 | bp->req_line_speed = 0; | 5340 | bp->req_line_speed = 0; |
5329 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 5341 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
5330 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; | 5342 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; |
5343 | |||
5344 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | ||
5345 | BNX2_PORT_HW_CFG_CONFIG); | ||
5346 | reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; | ||
5347 | if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { | ||
5348 | bp->autoneg = 0; | ||
5349 | bp->req_line_speed = bp->line_speed = SPEED_1000; | ||
5350 | bp->req_duplex = DUPLEX_FULL; | ||
5351 | } | ||
5331 | } | 5352 | } |
5332 | else { | 5353 | else { |
5333 | bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; | 5354 | bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; |
@@ -5335,11 +5356,17 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5335 | 5356 | ||
5336 | bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; | 5357 | bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; |
5337 | 5358 | ||
5359 | init_timer(&bp->timer); | ||
5360 | bp->timer.expires = RUN_AT(bp->timer_interval); | ||
5361 | bp->timer.data = (unsigned long) bp; | ||
5362 | bp->timer.function = bnx2_timer; | ||
5363 | |||
5338 | return 0; | 5364 | return 0; |
5339 | 5365 | ||
5340 | err_out_unmap: | 5366 | err_out_unmap: |
5341 | if (bp->regview) { | 5367 | if (bp->regview) { |
5342 | iounmap(bp->regview); | 5368 | iounmap(bp->regview); |
5369 | bp->regview = NULL; | ||
5343 | } | 5370 | } |
5344 | 5371 | ||
5345 | err_out_release: | 5372 | err_out_release: |
@@ -5454,6 +5481,8 @@ bnx2_remove_one(struct pci_dev *pdev) | |||
5454 | struct net_device *dev = pci_get_drvdata(pdev); | 5481 | struct net_device *dev = pci_get_drvdata(pdev); |
5455 | struct bnx2 *bp = dev->priv; | 5482 | struct bnx2 *bp = dev->priv; |
5456 | 5483 | ||
5484 | flush_scheduled_work(); | ||
5485 | |||
5457 | unregister_netdev(dev); | 5486 | unregister_netdev(dev); |
5458 | 5487 | ||
5459 | if (bp->regview) | 5488 | if (bp->regview) |
@@ -5505,12 +5534,12 @@ bnx2_resume(struct pci_dev *pdev) | |||
5505 | } | 5534 | } |
5506 | 5535 | ||
5507 | static struct pci_driver bnx2_pci_driver = { | 5536 | static struct pci_driver bnx2_pci_driver = { |
5508 | name: DRV_MODULE_NAME, | 5537 | .name = DRV_MODULE_NAME, |
5509 | id_table: bnx2_pci_tbl, | 5538 | .id_table = bnx2_pci_tbl, |
5510 | probe: bnx2_init_one, | 5539 | .probe = bnx2_init_one, |
5511 | remove: __devexit_p(bnx2_remove_one), | 5540 | .remove = __devexit_p(bnx2_remove_one), |
5512 | suspend: bnx2_suspend, | 5541 | .suspend = bnx2_suspend, |
5513 | resume: bnx2_resume, | 5542 | .resume = bnx2_resume, |
5514 | }; | 5543 | }; |
5515 | 5544 | ||
5516 | static int __init bnx2_init(void) | 5545 | static int __init bnx2_init(void) |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 8214a2853d0d..9ad3f5740cd8 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -3841,12 +3841,12 @@ struct bnx2 { | |||
3841 | struct status_block *status_blk; | 3841 | struct status_block *status_blk; |
3842 | u32 last_status_idx; | 3842 | u32 last_status_idx; |
3843 | 3843 | ||
3844 | atomic_t tx_avail_bd; | ||
3845 | struct tx_bd *tx_desc_ring; | 3844 | struct tx_bd *tx_desc_ring; |
3846 | struct sw_bd *tx_buf_ring; | 3845 | struct sw_bd *tx_buf_ring; |
3847 | u32 tx_prod_bseq; | 3846 | u32 tx_prod_bseq; |
3848 | u16 tx_prod; | 3847 | u16 tx_prod; |
3849 | u16 tx_cons; | 3848 | u16 tx_cons; |
3849 | int tx_ring_size; | ||
3850 | 3850 | ||
3851 | #ifdef BCM_VLAN | 3851 | #ifdef BCM_VLAN |
3852 | struct vlan_group *vlgrp; | 3852 | struct vlan_group *vlgrp; |
@@ -3872,8 +3872,10 @@ struct bnx2 { | |||
3872 | char *name; | 3872 | char *name; |
3873 | 3873 | ||
3874 | int timer_interval; | 3874 | int timer_interval; |
3875 | int current_interval; | ||
3875 | struct timer_list timer; | 3876 | struct timer_list timer; |
3876 | struct work_struct reset_task; | 3877 | struct work_struct reset_task; |
3878 | int in_reset_task; | ||
3877 | 3879 | ||
3878 | /* Used to synchronize phy accesses. */ | 3880 | /* Used to synchronize phy accesses. */ |
3879 | spinlock_t phy_lock; | 3881 | spinlock_t phy_lock; |
@@ -3927,7 +3929,6 @@ struct bnx2 { | |||
3927 | u16 fw_wr_seq; | 3929 | u16 fw_wr_seq; |
3928 | u16 fw_drv_pulse_wr_seq; | 3930 | u16 fw_drv_pulse_wr_seq; |
3929 | 3931 | ||
3930 | int tx_ring_size; | ||
3931 | dma_addr_t tx_desc_mapping; | 3932 | dma_addr_t tx_desc_mapping; |
3932 | 3933 | ||
3933 | 3934 | ||
@@ -3985,7 +3986,7 @@ struct bnx2 { | |||
3985 | #define PHY_LOOPBACK 2 | 3986 | #define PHY_LOOPBACK 2 |
3986 | 3987 | ||
3987 | u8 serdes_an_pending; | 3988 | u8 serdes_an_pending; |
3988 | #define SERDES_AN_TIMEOUT (2 * HZ) | 3989 | #define SERDES_AN_TIMEOUT (HZ / 3) |
3989 | 3990 | ||
3990 | u8 mac_addr[8]; | 3991 | u8 mac_addr[8]; |
3991 | 3992 | ||
@@ -4171,6 +4172,9 @@ struct fw_info { | |||
4171 | 4172 | ||
4172 | #define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 | 4173 | #define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 |
4173 | #define BNX2_PORT_HW_CFG_CONFIG 0x00000058 | 4174 | #define BNX2_PORT_HW_CFG_CONFIG 0x00000058 |
4175 | #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000 | ||
4176 | #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000 | ||
4177 | #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000 | ||
4174 | 4178 | ||
4175 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 | 4179 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 |
4176 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c | 4180 | #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c |
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index a2e8dda5afac..d2f34d5a8083 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2419,22 +2419,19 @@ out: | |||
2419 | return 0; | 2419 | return 0; |
2420 | } | 2420 | } |
2421 | 2421 | ||
2422 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype) | 2422 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev) |
2423 | { | 2423 | { |
2424 | struct bonding *bond = dev->priv; | 2424 | struct bonding *bond = dev->priv; |
2425 | struct slave *slave = NULL; | 2425 | struct slave *slave = NULL; |
2426 | int ret = NET_RX_DROP; | 2426 | int ret = NET_RX_DROP; |
2427 | 2427 | ||
2428 | if (!(dev->flags & IFF_MASTER)) { | 2428 | if (!(dev->flags & IFF_MASTER)) |
2429 | goto out; | 2429 | goto out; |
2430 | } | ||
2431 | 2430 | ||
2432 | read_lock(&bond->lock); | 2431 | read_lock(&bond->lock); |
2433 | slave = bond_get_slave_by_dev((struct bonding *)dev->priv, | 2432 | slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev); |
2434 | skb->real_dev); | 2433 | if (!slave) |
2435 | if (slave == NULL) { | ||
2436 | goto out_unlock; | 2434 | goto out_unlock; |
2437 | } | ||
2438 | 2435 | ||
2439 | bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); | 2436 | bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); |
2440 | 2437 | ||
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index f46823894187..673a30af5660 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -295,6 +295,6 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave); | |||
295 | void bond_3ad_handle_link_change(struct slave *slave, char link); | 295 | void bond_3ad_handle_link_change(struct slave *slave, char link); |
296 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); | 296 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); |
297 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); | 297 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); |
298 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype); | 298 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); |
299 | #endif //__BOND_3AD_H__ | 299 | #endif //__BOND_3AD_H__ |
300 | 300 | ||
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 5ce606d9dc03..f8fce3961197 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -354,15 +354,14 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
354 | _unlock_rx_hashtbl(bond); | 354 | _unlock_rx_hashtbl(bond); |
355 | } | 355 | } |
356 | 356 | ||
357 | static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype) | 357 | static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev) |
358 | { | 358 | { |
359 | struct bonding *bond = bond_dev->priv; | 359 | struct bonding *bond = bond_dev->priv; |
360 | struct arp_pkt *arp = (struct arp_pkt *)skb->data; | 360 | struct arp_pkt *arp = (struct arp_pkt *)skb->data; |
361 | int res = NET_RX_DROP; | 361 | int res = NET_RX_DROP; |
362 | 362 | ||
363 | if (!(bond_dev->flags & IFF_MASTER)) { | 363 | if (!(bond_dev->flags & IFF_MASTER)) |
364 | goto out; | 364 | goto out; |
365 | } | ||
366 | 365 | ||
367 | if (!arp) { | 366 | if (!arp) { |
368 | dprintk("Packet has no ARP data\n"); | 367 | dprintk("Packet has no ARP data\n"); |
@@ -1106,18 +1105,13 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav | |||
1106 | } | 1105 | } |
1107 | } | 1106 | } |
1108 | 1107 | ||
1109 | if (found) { | 1108 | if (!found) |
1110 | /* a slave was found that is using the mac address | 1109 | return 0; |
1111 | * of the new slave | ||
1112 | */ | ||
1113 | printk(KERN_ERR DRV_NAME | ||
1114 | ": Error: the hw address of slave %s is not " | ||
1115 | "unique - cannot enslave it!", | ||
1116 | slave->dev->name); | ||
1117 | return -EINVAL; | ||
1118 | } | ||
1119 | 1110 | ||
1120 | return 0; | 1111 | /* Try setting slave mac to bond address and fall-through |
1112 | to code handling that situation below... */ | ||
1113 | alb_set_slave_mac_addr(slave, bond->dev->dev_addr, | ||
1114 | bond->alb_info.rlb_enabled); | ||
1121 | } | 1115 | } |
1122 | 1116 | ||
1123 | /* The slave's address is equal to the address of the bond. | 1117 | /* The slave's address is equal to the address of the bond. |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2c930da90a85..94c9f68dd16b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1604,6 +1604,44 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_ | |||
1604 | return 0; | 1604 | return 0; |
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | #define BOND_INTERSECT_FEATURES \ | ||
1608 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) | ||
1609 | |||
1610 | /* | ||
1611 | * Compute the features available to the bonding device by | ||
1612 | * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. | ||
1613 | * Call this after attaching or detaching a slave to update the | ||
1614 | * bond's features. | ||
1615 | */ | ||
1616 | static int bond_compute_features(struct bonding *bond) | ||
1617 | { | ||
1618 | int i; | ||
1619 | struct slave *slave; | ||
1620 | struct net_device *bond_dev = bond->dev; | ||
1621 | int features = bond->bond_features; | ||
1622 | |||
1623 | bond_for_each_slave(bond, slave, i) { | ||
1624 | struct net_device * slave_dev = slave->dev; | ||
1625 | if (i == 0) { | ||
1626 | features |= BOND_INTERSECT_FEATURES; | ||
1627 | } | ||
1628 | features &= | ||
1629 | ~(~slave_dev->features & BOND_INTERSECT_FEATURES); | ||
1630 | } | ||
1631 | |||
1632 | /* turn off NETIF_F_SG if we need a csum and h/w can't do it */ | ||
1633 | if ((features & NETIF_F_SG) && | ||
1634 | !(features & (NETIF_F_IP_CSUM | | ||
1635 | NETIF_F_NO_CSUM | | ||
1636 | NETIF_F_HW_CSUM))) { | ||
1637 | features &= ~NETIF_F_SG; | ||
1638 | } | ||
1639 | |||
1640 | bond_dev->features = features; | ||
1641 | |||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1607 | /* enslave device <slave> to bond device <master> */ | 1645 | /* enslave device <slave> to bond device <master> */ |
1608 | static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1646 | static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
1609 | { | 1647 | { |
@@ -1811,6 +1849,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de | |||
1811 | new_slave->delay = 0; | 1849 | new_slave->delay = 0; |
1812 | new_slave->link_failure_count = 0; | 1850 | new_slave->link_failure_count = 0; |
1813 | 1851 | ||
1852 | bond_compute_features(bond); | ||
1853 | |||
1814 | if (bond->params.miimon && !bond->params.use_carrier) { | 1854 | if (bond->params.miimon && !bond->params.use_carrier) { |
1815 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); | 1855 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); |
1816 | 1856 | ||
@@ -2015,7 +2055,7 @@ err_free: | |||
2015 | 2055 | ||
2016 | err_undo_flags: | 2056 | err_undo_flags: |
2017 | bond_dev->features = old_features; | 2057 | bond_dev->features = old_features; |
2018 | 2058 | ||
2019 | return res; | 2059 | return res; |
2020 | } | 2060 | } |
2021 | 2061 | ||
@@ -2100,6 +2140,8 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de | |||
2100 | /* release the slave from its bond */ | 2140 | /* release the slave from its bond */ |
2101 | bond_detach_slave(bond, slave); | 2141 | bond_detach_slave(bond, slave); |
2102 | 2142 | ||
2143 | bond_compute_features(bond); | ||
2144 | |||
2103 | if (bond->primary_slave == slave) { | 2145 | if (bond->primary_slave == slave) { |
2104 | bond->primary_slave = NULL; | 2146 | bond->primary_slave = NULL; |
2105 | } | 2147 | } |
@@ -2243,6 +2285,8 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2243 | bond_alb_deinit_slave(bond, slave); | 2285 | bond_alb_deinit_slave(bond, slave); |
2244 | } | 2286 | } |
2245 | 2287 | ||
2288 | bond_compute_features(bond); | ||
2289 | |||
2246 | /* now that the slave is detached, unlock and perform | 2290 | /* now that the slave is detached, unlock and perform |
2247 | * all the undo steps that should not be called from | 2291 | * all the undo steps that should not be called from |
2248 | * within a lock. | 2292 | * within a lock. |
@@ -3588,6 +3632,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond | |||
3588 | static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) | 3632 | static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) |
3589 | { | 3633 | { |
3590 | struct net_device *bond_dev = slave_dev->master; | 3634 | struct net_device *bond_dev = slave_dev->master; |
3635 | struct bonding *bond = bond_dev->priv; | ||
3591 | 3636 | ||
3592 | switch (event) { | 3637 | switch (event) { |
3593 | case NETDEV_UNREGISTER: | 3638 | case NETDEV_UNREGISTER: |
@@ -3626,6 +3671,9 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave | |||
3626 | * TODO: handle changing the primary's name | 3671 | * TODO: handle changing the primary's name |
3627 | */ | 3672 | */ |
3628 | break; | 3673 | break; |
3674 | case NETDEV_FEAT_CHANGE: | ||
3675 | bond_compute_features(bond); | ||
3676 | break; | ||
3629 | default: | 3677 | default: |
3630 | break; | 3678 | break; |
3631 | } | 3679 | } |
@@ -4526,6 +4574,11 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4526 | } | 4574 | } |
4527 | } | 4575 | } |
4528 | 4576 | ||
4577 | static struct ethtool_ops bond_ethtool_ops = { | ||
4578 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
4579 | .get_sg = ethtool_op_get_sg, | ||
4580 | }; | ||
4581 | |||
4529 | /* | 4582 | /* |
4530 | * Does not allocate but creates a /proc entry. | 4583 | * Does not allocate but creates a /proc entry. |
4531 | * Allowed to fail. | 4584 | * Allowed to fail. |
@@ -4555,6 +4608,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4555 | bond_dev->stop = bond_close; | 4608 | bond_dev->stop = bond_close; |
4556 | bond_dev->get_stats = bond_get_stats; | 4609 | bond_dev->get_stats = bond_get_stats; |
4557 | bond_dev->do_ioctl = bond_do_ioctl; | 4610 | bond_dev->do_ioctl = bond_do_ioctl; |
4611 | bond_dev->ethtool_ops = &bond_ethtool_ops; | ||
4558 | bond_dev->set_multicast_list = bond_set_multicast_list; | 4612 | bond_dev->set_multicast_list = bond_set_multicast_list; |
4559 | bond_dev->change_mtu = bond_change_mtu; | 4613 | bond_dev->change_mtu = bond_change_mtu; |
4560 | bond_dev->set_mac_address = bond_set_mac_address; | 4614 | bond_dev->set_mac_address = bond_set_mac_address; |
@@ -4591,6 +4645,8 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4591 | NETIF_F_HW_VLAN_RX | | 4645 | NETIF_F_HW_VLAN_RX | |
4592 | NETIF_F_HW_VLAN_FILTER); | 4646 | NETIF_F_HW_VLAN_FILTER); |
4593 | 4647 | ||
4648 | bond->bond_features = bond_dev->features; | ||
4649 | |||
4594 | #ifdef CONFIG_PROC_FS | 4650 | #ifdef CONFIG_PROC_FS |
4595 | bond_create_proc_entry(bond); | 4651 | bond_create_proc_entry(bond); |
4596 | #endif | 4652 | #endif |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index d27f377b3eeb..388196980862 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -211,6 +211,9 @@ struct bonding { | |||
211 | struct bond_params params; | 211 | struct bond_params params; |
212 | struct list_head vlan_list; | 212 | struct list_head vlan_list; |
213 | struct vlan_group *vlgrp; | 213 | struct vlan_group *vlgrp; |
214 | /* the features the bonding device supports, independently | ||
215 | * of any slaves */ | ||
216 | int bond_features; | ||
214 | }; | 217 | }; |
215 | 218 | ||
216 | /** | 219 | /** |
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile new file mode 100644 index 000000000000..91e927827c43 --- /dev/null +++ b/drivers/net/chelsio/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # | ||
2 | # Chelsio 10Gb NIC driver for Linux. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_CHELSIO_T1) += cxgb.o | ||
6 | |||
7 | EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/chelsio $(DEBUG_FLAGS) | ||
8 | |||
9 | |||
10 | cxgb-objs := cxgb2.o espi.o pm3393.o sge.o subr.o mv88x201x.o | ||
11 | |||
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h new file mode 100644 index 000000000000..f09348802b46 --- /dev/null +++ b/drivers/net/chelsio/common.h | |||
@@ -0,0 +1,314 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: common.h * | ||
4 | * $Revision: 1.21 $ * | ||
5 | * $Date: 2005/06/22 00:43:25 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_COMMON_H_ | ||
40 | #define _CXGB_COMMON_H_ | ||
41 | |||
42 | #include <linux/config.h> | ||
43 | #include <linux/module.h> | ||
44 | #include <linux/netdevice.h> | ||
45 | #include <linux/types.h> | ||
46 | #include <linux/delay.h> | ||
47 | #include <linux/pci.h> | ||
48 | #include <linux/ethtool.h> | ||
49 | #include <linux/mii.h> | ||
50 | #include <linux/crc32.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <asm/io.h> | ||
53 | #include <linux/pci_ids.h> | ||
54 | |||
55 | #define DRV_DESCRIPTION "Chelsio 10Gb Ethernet Driver" | ||
56 | #define DRV_NAME "cxgb" | ||
57 | #define DRV_VERSION "2.1.1" | ||
58 | #define PFX DRV_NAME ": " | ||
59 | |||
60 | #define CH_ERR(fmt, ...) printk(KERN_ERR PFX fmt, ## __VA_ARGS__) | ||
61 | #define CH_WARN(fmt, ...) printk(KERN_WARNING PFX fmt, ## __VA_ARGS__) | ||
62 | #define CH_ALERT(fmt, ...) printk(KERN_ALERT PFX fmt, ## __VA_ARGS__) | ||
63 | |||
64 | #define CH_DEVICE(devid, ssid, idx) \ | ||
65 | { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx } | ||
66 | |||
67 | #define SUPPORTED_PAUSE (1 << 13) | ||
68 | #define SUPPORTED_LOOPBACK (1 << 15) | ||
69 | |||
70 | #define ADVERTISED_PAUSE (1 << 13) | ||
71 | #define ADVERTISED_ASYM_PAUSE (1 << 14) | ||
72 | |||
73 | typedef struct adapter adapter_t; | ||
74 | |||
75 | void t1_elmer0_ext_intr(adapter_t *adapter); | ||
76 | void t1_link_changed(adapter_t *adapter, int port_id, int link_status, | ||
77 | int speed, int duplex, int fc); | ||
78 | |||
79 | struct t1_rx_mode { | ||
80 | struct net_device *dev; | ||
81 | u32 idx; | ||
82 | struct dev_mc_list *list; | ||
83 | }; | ||
84 | |||
85 | #define t1_rx_mode_promisc(rm) (rm->dev->flags & IFF_PROMISC) | ||
86 | #define t1_rx_mode_allmulti(rm) (rm->dev->flags & IFF_ALLMULTI) | ||
87 | #define t1_rx_mode_mc_cnt(rm) (rm->dev->mc_count) | ||
88 | |||
89 | static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm) | ||
90 | { | ||
91 | u8 *addr = 0; | ||
92 | |||
93 | if (rm->idx++ < rm->dev->mc_count) { | ||
94 | addr = rm->list->dmi_addr; | ||
95 | rm->list = rm->list->next; | ||
96 | } | ||
97 | return addr; | ||
98 | } | ||
99 | |||
100 | #define MAX_NPORTS 4 | ||
101 | |||
102 | #define SPEED_INVALID 0xffff | ||
103 | #define DUPLEX_INVALID 0xff | ||
104 | |||
105 | enum { | ||
106 | CHBT_BOARD_N110, | ||
107 | CHBT_BOARD_N210 | ||
108 | }; | ||
109 | |||
110 | enum { | ||
111 | CHBT_TERM_T1, | ||
112 | CHBT_TERM_T2 | ||
113 | }; | ||
114 | |||
115 | enum { | ||
116 | CHBT_MAC_PM3393, | ||
117 | }; | ||
118 | |||
119 | enum { | ||
120 | CHBT_PHY_88X2010, | ||
121 | }; | ||
122 | |||
123 | enum { | ||
124 | PAUSE_RX = 1 << 0, | ||
125 | PAUSE_TX = 1 << 1, | ||
126 | PAUSE_AUTONEG = 1 << 2 | ||
127 | }; | ||
128 | |||
129 | /* Revisions of T1 chip */ | ||
130 | enum { | ||
131 | TERM_T1A = 0, | ||
132 | TERM_T1B = 1, | ||
133 | TERM_T2 = 3 | ||
134 | }; | ||
135 | |||
136 | struct sge_params { | ||
137 | unsigned int cmdQ_size[2]; | ||
138 | unsigned int freelQ_size[2]; | ||
139 | unsigned int large_buf_capacity; | ||
140 | unsigned int rx_coalesce_usecs; | ||
141 | unsigned int last_rx_coalesce_raw; | ||
142 | unsigned int default_rx_coalesce_usecs; | ||
143 | unsigned int sample_interval_usecs; | ||
144 | unsigned int coalesce_enable; | ||
145 | unsigned int polling; | ||
146 | }; | ||
147 | |||
148 | struct chelsio_pci_params { | ||
149 | unsigned short speed; | ||
150 | unsigned char width; | ||
151 | unsigned char is_pcix; | ||
152 | }; | ||
153 | |||
154 | struct adapter_params { | ||
155 | struct sge_params sge; | ||
156 | struct chelsio_pci_params pci; | ||
157 | |||
158 | const struct board_info *brd_info; | ||
159 | |||
160 | unsigned int nports; /* # of ethernet ports */ | ||
161 | unsigned int stats_update_period; | ||
162 | unsigned short chip_revision; | ||
163 | unsigned char chip_version; | ||
164 | }; | ||
165 | |||
166 | struct link_config { | ||
167 | unsigned int supported; /* link capabilities */ | ||
168 | unsigned int advertising; /* advertised capabilities */ | ||
169 | unsigned short requested_speed; /* speed user has requested */ | ||
170 | unsigned short speed; /* actual link speed */ | ||
171 | unsigned char requested_duplex; /* duplex user has requested */ | ||
172 | unsigned char duplex; /* actual link duplex */ | ||
173 | unsigned char requested_fc; /* flow control user has requested */ | ||
174 | unsigned char fc; /* actual link flow control */ | ||
175 | unsigned char autoneg; /* autonegotiating? */ | ||
176 | }; | ||
177 | |||
178 | struct cmac; | ||
179 | struct cphy; | ||
180 | |||
181 | struct port_info { | ||
182 | struct net_device *dev; | ||
183 | struct cmac *mac; | ||
184 | struct cphy *phy; | ||
185 | struct link_config link_config; | ||
186 | struct net_device_stats netstats; | ||
187 | }; | ||
188 | |||
189 | struct sge; | ||
190 | struct peespi; | ||
191 | |||
192 | struct adapter { | ||
193 | u8 *regs; | ||
194 | struct pci_dev *pdev; | ||
195 | unsigned long registered_device_map; | ||
196 | unsigned long open_device_map; | ||
197 | unsigned long flags; | ||
198 | |||
199 | const char *name; | ||
200 | int msg_enable; | ||
201 | u32 mmio_len; | ||
202 | |||
203 | struct work_struct ext_intr_handler_task; | ||
204 | struct adapter_params params; | ||
205 | |||
206 | struct vlan_group *vlan_grp; | ||
207 | |||
208 | /* Terminator modules. */ | ||
209 | struct sge *sge; | ||
210 | struct peespi *espi; | ||
211 | |||
212 | struct port_info port[MAX_NPORTS]; | ||
213 | struct work_struct stats_update_task; | ||
214 | struct timer_list stats_update_timer; | ||
215 | |||
216 | struct semaphore mib_mutex; | ||
217 | spinlock_t tpi_lock; | ||
218 | spinlock_t work_lock; | ||
219 | /* guards async operations */ | ||
220 | spinlock_t async_lock ____cacheline_aligned; | ||
221 | u32 slow_intr_mask; | ||
222 | }; | ||
223 | |||
224 | enum { /* adapter flags */ | ||
225 | FULL_INIT_DONE = 1 << 0, | ||
226 | TSO_CAPABLE = 1 << 2, | ||
227 | TCP_CSUM_CAPABLE = 1 << 3, | ||
228 | UDP_CSUM_CAPABLE = 1 << 4, | ||
229 | VLAN_ACCEL_CAPABLE = 1 << 5, | ||
230 | RX_CSUM_ENABLED = 1 << 6, | ||
231 | }; | ||
232 | |||
233 | struct mdio_ops; | ||
234 | struct gmac; | ||
235 | struct gphy; | ||
236 | |||
237 | struct board_info { | ||
238 | unsigned char board; | ||
239 | unsigned char port_number; | ||
240 | unsigned long caps; | ||
241 | unsigned char chip_term; | ||
242 | unsigned char chip_mac; | ||
243 | unsigned char chip_phy; | ||
244 | unsigned int clock_core; | ||
245 | unsigned int clock_mc3; | ||
246 | unsigned int clock_mc4; | ||
247 | unsigned int espi_nports; | ||
248 | unsigned int clock_cspi; | ||
249 | unsigned int clock_elmer0; | ||
250 | unsigned char mdio_mdien; | ||
251 | unsigned char mdio_mdiinv; | ||
252 | unsigned char mdio_mdc; | ||
253 | unsigned char mdio_phybaseaddr; | ||
254 | struct gmac *gmac; | ||
255 | struct gphy *gphy; | ||
256 | struct mdio_ops *mdio_ops; | ||
257 | const char *desc; | ||
258 | }; | ||
259 | |||
260 | extern struct pci_device_id t1_pci_tbl[]; | ||
261 | |||
262 | static inline int adapter_matches_type(const adapter_t *adapter, | ||
263 | int version, int revision) | ||
264 | { | ||
265 | return adapter->params.chip_version == version && | ||
266 | adapter->params.chip_revision == revision; | ||
267 | } | ||
268 | |||
269 | #define t1_is_T1B(adap) adapter_matches_type(adap, CHBT_TERM_T1, TERM_T1B) | ||
270 | #define is_T2(adap) adapter_matches_type(adap, CHBT_TERM_T2, TERM_T2) | ||
271 | |||
272 | /* Returns true if an adapter supports VLAN acceleration and TSO */ | ||
273 | static inline int vlan_tso_capable(const adapter_t *adapter) | ||
274 | { | ||
275 | return !t1_is_T1B(adapter); | ||
276 | } | ||
277 | |||
278 | #define for_each_port(adapter, iter) \ | ||
279 | for (iter = 0; iter < (adapter)->params.nports; ++iter) | ||
280 | |||
281 | #define board_info(adapter) ((adapter)->params.brd_info) | ||
282 | #define is_10G(adapter) (board_info(adapter)->caps & SUPPORTED_10000baseT_Full) | ||
283 | |||
284 | static inline unsigned int core_ticks_per_usec(const adapter_t *adap) | ||
285 | { | ||
286 | return board_info(adap)->clock_core / 1000000; | ||
287 | } | ||
288 | |||
289 | extern int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value); | ||
290 | extern int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *value); | ||
291 | |||
292 | extern void t1_interrupts_enable(adapter_t *adapter); | ||
293 | extern void t1_interrupts_disable(adapter_t *adapter); | ||
294 | extern void t1_interrupts_clear(adapter_t *adapter); | ||
295 | extern int elmer0_ext_intr_handler(adapter_t *adapter); | ||
296 | extern int t1_slow_intr_handler(adapter_t *adapter); | ||
297 | |||
298 | extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); | ||
299 | extern const struct board_info *t1_get_board_info(unsigned int board_id); | ||
300 | extern const struct board_info *t1_get_board_info_from_ids(unsigned int devid, | ||
301 | unsigned short ssid); | ||
302 | extern int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data); | ||
303 | extern int t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, | ||
304 | struct adapter_params *p); | ||
305 | extern int t1_init_hw_modules(adapter_t *adapter); | ||
306 | extern int t1_init_sw_modules(adapter_t *adapter, const struct board_info *bi); | ||
307 | extern void t1_free_sw_modules(adapter_t *adapter); | ||
308 | extern void t1_fatal_err(adapter_t *adapter); | ||
309 | |||
310 | extern void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable); | ||
311 | extern void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable); | ||
312 | extern void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable); | ||
313 | |||
314 | #endif /* _CXGB_COMMON_H_ */ | ||
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h new file mode 100644 index 000000000000..3412342f7345 --- /dev/null +++ b/drivers/net/chelsio/cphy.h | |||
@@ -0,0 +1,148 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: cphy.h * | ||
4 | * $Revision: 1.7 $ * | ||
5 | * $Date: 2005/06/21 18:29:47 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_CPHY_H_ | ||
40 | #define _CXGB_CPHY_H_ | ||
41 | |||
42 | #include "common.h" | ||
43 | |||
44 | struct mdio_ops { | ||
45 | void (*init)(adapter_t *adapter, const struct board_info *bi); | ||
46 | int (*read)(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
47 | int reg_addr, unsigned int *val); | ||
48 | int (*write)(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
49 | int reg_addr, unsigned int val); | ||
50 | }; | ||
51 | |||
52 | /* PHY interrupt types */ | ||
53 | enum { | ||
54 | cphy_cause_link_change = 0x1, | ||
55 | cphy_cause_error = 0x2 | ||
56 | }; | ||
57 | |||
58 | struct cphy; | ||
59 | |||
60 | /* PHY operations */ | ||
61 | struct cphy_ops { | ||
62 | void (*destroy)(struct cphy *); | ||
63 | int (*reset)(struct cphy *, int wait); | ||
64 | |||
65 | int (*interrupt_enable)(struct cphy *); | ||
66 | int (*interrupt_disable)(struct cphy *); | ||
67 | int (*interrupt_clear)(struct cphy *); | ||
68 | int (*interrupt_handler)(struct cphy *); | ||
69 | |||
70 | int (*autoneg_enable)(struct cphy *); | ||
71 | int (*autoneg_disable)(struct cphy *); | ||
72 | int (*autoneg_restart)(struct cphy *); | ||
73 | |||
74 | int (*advertise)(struct cphy *phy, unsigned int advertise_map); | ||
75 | int (*set_loopback)(struct cphy *, int on); | ||
76 | int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex); | ||
77 | int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed, | ||
78 | int *duplex, int *fc); | ||
79 | }; | ||
80 | |||
81 | /* A PHY instance */ | ||
82 | struct cphy { | ||
83 | int addr; /* PHY address */ | ||
84 | adapter_t *adapter; /* associated adapter */ | ||
85 | struct cphy_ops *ops; /* PHY operations */ | ||
86 | int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
87 | int reg_addr, unsigned int *val); | ||
88 | int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
89 | int reg_addr, unsigned int val); | ||
90 | struct cphy_instance *instance; | ||
91 | }; | ||
92 | |||
93 | /* Convenience MDIO read/write wrappers */ | ||
94 | static inline int mdio_read(struct cphy *cphy, int mmd, int reg, | ||
95 | unsigned int *valp) | ||
96 | { | ||
97 | return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp); | ||
98 | } | ||
99 | |||
100 | static inline int mdio_write(struct cphy *cphy, int mmd, int reg, | ||
101 | unsigned int val) | ||
102 | { | ||
103 | return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val); | ||
104 | } | ||
105 | |||
106 | static inline int simple_mdio_read(struct cphy *cphy, int reg, | ||
107 | unsigned int *valp) | ||
108 | { | ||
109 | return mdio_read(cphy, 0, reg, valp); | ||
110 | } | ||
111 | |||
112 | static inline int simple_mdio_write(struct cphy *cphy, int reg, | ||
113 | unsigned int val) | ||
114 | { | ||
115 | return mdio_write(cphy, 0, reg, val); | ||
116 | } | ||
117 | |||
118 | /* Convenience initializer */ | ||
119 | static inline void cphy_init(struct cphy *phy, adapter_t *adapter, | ||
120 | int phy_addr, struct cphy_ops *phy_ops, | ||
121 | struct mdio_ops *mdio_ops) | ||
122 | { | ||
123 | phy->adapter = adapter; | ||
124 | phy->addr = phy_addr; | ||
125 | phy->ops = phy_ops; | ||
126 | if (mdio_ops) { | ||
127 | phy->mdio_read = mdio_ops->read; | ||
128 | phy->mdio_write = mdio_ops->write; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /* Operations of the PHY-instance factory */ | ||
133 | struct gphy { | ||
134 | /* Construct a PHY instance with the given PHY address */ | ||
135 | struct cphy *(*create)(adapter_t *adapter, int phy_addr, | ||
136 | struct mdio_ops *mdio_ops); | ||
137 | |||
138 | /* | ||
139 | * Reset the PHY chip. This resets the whole PHY chip, not individual | ||
140 | * ports. | ||
141 | */ | ||
142 | int (*reset)(adapter_t *adapter); | ||
143 | }; | ||
144 | |||
145 | extern struct gphy t1_mv88x201x_ops; | ||
146 | extern struct gphy t1_dummy_phy_ops; | ||
147 | |||
148 | #endif /* _CXGB_CPHY_H_ */ | ||
diff --git a/drivers/net/chelsio/cpl5_cmd.h b/drivers/net/chelsio/cpl5_cmd.h new file mode 100644 index 000000000000..27925e487bcf --- /dev/null +++ b/drivers/net/chelsio/cpl5_cmd.h | |||
@@ -0,0 +1,145 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: cpl5_cmd.h * | ||
4 | * $Revision: 1.6 $ * | ||
5 | * $Date: 2005/06/21 18:29:47 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_CPL5_CMD_H_ | ||
40 | #define _CXGB_CPL5_CMD_H_ | ||
41 | |||
42 | #include <asm/byteorder.h> | ||
43 | |||
44 | #if !defined(__LITTLE_ENDIAN_BITFIELD) && !defined(__BIG_ENDIAN_BITFIELD) | ||
45 | #error "Adjust your <asm/byteorder.h> defines" | ||
46 | #endif | ||
47 | |||
48 | enum CPL_opcode { | ||
49 | CPL_RX_PKT = 0xAD, | ||
50 | CPL_TX_PKT = 0xB2, | ||
51 | CPL_TX_PKT_LSO = 0xB6, | ||
52 | }; | ||
53 | |||
54 | enum { /* TX_PKT_LSO ethernet types */ | ||
55 | CPL_ETH_II, | ||
56 | CPL_ETH_II_VLAN, | ||
57 | CPL_ETH_802_3, | ||
58 | CPL_ETH_802_3_VLAN | ||
59 | }; | ||
60 | |||
61 | struct cpl_rx_data { | ||
62 | u32 rsvd0; | ||
63 | u32 len; | ||
64 | u32 seq; | ||
65 | u16 urg; | ||
66 | u8 rsvd1; | ||
67 | u8 status; | ||
68 | }; | ||
69 | |||
70 | /* | ||
71 | * We want this header's alignment to be no more stringent than 2-byte aligned. | ||
72 | * All fields are u8 or u16 except for the length. However that field is not | ||
73 | * used so we break it into 2 16-bit parts to easily meet our alignment needs. | ||
74 | */ | ||
75 | struct cpl_tx_pkt { | ||
76 | u8 opcode; | ||
77 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
78 | u8 iff:4; | ||
79 | u8 ip_csum_dis:1; | ||
80 | u8 l4_csum_dis:1; | ||
81 | u8 vlan_valid:1; | ||
82 | u8 rsvd:1; | ||
83 | #else | ||
84 | u8 rsvd:1; | ||
85 | u8 vlan_valid:1; | ||
86 | u8 l4_csum_dis:1; | ||
87 | u8 ip_csum_dis:1; | ||
88 | u8 iff:4; | ||
89 | #endif | ||
90 | u16 vlan; | ||
91 | u16 len_hi; | ||
92 | u16 len_lo; | ||
93 | }; | ||
94 | |||
95 | struct cpl_tx_pkt_lso { | ||
96 | u8 opcode; | ||
97 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
98 | u8 iff:4; | ||
99 | u8 ip_csum_dis:1; | ||
100 | u8 l4_csum_dis:1; | ||
101 | u8 vlan_valid:1; | ||
102 | u8 rsvd:1; | ||
103 | #else | ||
104 | u8 rsvd:1; | ||
105 | u8 vlan_valid:1; | ||
106 | u8 l4_csum_dis:1; | ||
107 | u8 ip_csum_dis:1; | ||
108 | u8 iff:4; | ||
109 | #endif | ||
110 | u16 vlan; | ||
111 | u32 len; | ||
112 | |||
113 | u32 rsvd2; | ||
114 | u8 rsvd3; | ||
115 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
116 | u8 tcp_hdr_words:4; | ||
117 | u8 ip_hdr_words:4; | ||
118 | #else | ||
119 | u8 ip_hdr_words:4; | ||
120 | u8 tcp_hdr_words:4; | ||
121 | #endif | ||
122 | u16 eth_type_mss; | ||
123 | }; | ||
124 | |||
125 | struct cpl_rx_pkt { | ||
126 | u8 opcode; | ||
127 | #if defined(__LITTLE_ENDIAN_BITFIELD) | ||
128 | u8 iff:4; | ||
129 | u8 csum_valid:1; | ||
130 | u8 bad_pkt:1; | ||
131 | u8 vlan_valid:1; | ||
132 | u8 rsvd:1; | ||
133 | #else | ||
134 | u8 rsvd:1; | ||
135 | u8 vlan_valid:1; | ||
136 | u8 bad_pkt:1; | ||
137 | u8 csum_valid:1; | ||
138 | u8 iff:4; | ||
139 | #endif | ||
140 | u16 csum; | ||
141 | u16 vlan; | ||
142 | u16 len; | ||
143 | }; | ||
144 | |||
145 | #endif /* _CXGB_CPL5_CMD_H_ */ | ||
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c new file mode 100644 index 000000000000..28ae478b386d --- /dev/null +++ b/drivers/net/chelsio/cxgb2.c | |||
@@ -0,0 +1,1256 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: cxgb2.c * | ||
4 | * $Revision: 1.25 $ * | ||
5 | * $Date: 2005/06/22 00:43:25 $ * | ||
6 | * Description: * | ||
7 | * Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #include "common.h" | ||
40 | #include <linux/config.h> | ||
41 | #include <linux/module.h> | ||
42 | #include <linux/init.h> | ||
43 | #include <linux/pci.h> | ||
44 | #include <linux/netdevice.h> | ||
45 | #include <linux/etherdevice.h> | ||
46 | #include <linux/if_vlan.h> | ||
47 | #include <linux/mii.h> | ||
48 | #include <linux/sockios.h> | ||
49 | #include <linux/proc_fs.h> | ||
50 | #include <linux/dma-mapping.h> | ||
51 | #include <asm/uaccess.h> | ||
52 | |||
53 | #include "cpl5_cmd.h" | ||
54 | #include "regs.h" | ||
55 | #include "gmac.h" | ||
56 | #include "cphy.h" | ||
57 | #include "sge.h" | ||
58 | #include "espi.h" | ||
59 | |||
60 | #ifdef work_struct | ||
61 | #include <linux/tqueue.h> | ||
62 | #define INIT_WORK INIT_TQUEUE | ||
63 | #define schedule_work schedule_task | ||
64 | #define flush_scheduled_work flush_scheduled_tasks | ||
65 | |||
66 | static inline void schedule_mac_stats_update(struct adapter *ap, int secs) | ||
67 | { | ||
68 | mod_timer(&ap->stats_update_timer, jiffies + secs * HZ); | ||
69 | } | ||
70 | |||
71 | static inline void cancel_mac_stats_update(struct adapter *ap) | ||
72 | { | ||
73 | del_timer_sync(&ap->stats_update_timer); | ||
74 | flush_scheduled_tasks(); | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Stats update timer for 2.4. It schedules a task to do the actual update as | ||
79 | * we need to access MAC statistics in process context. | ||
80 | */ | ||
81 | static void mac_stats_timer(unsigned long data) | ||
82 | { | ||
83 | struct adapter *ap = (struct adapter *)data; | ||
84 | |||
85 | schedule_task(&ap->stats_update_task); | ||
86 | } | ||
87 | #else | ||
88 | #include <linux/workqueue.h> | ||
89 | |||
90 | static inline void schedule_mac_stats_update(struct adapter *ap, int secs) | ||
91 | { | ||
92 | schedule_delayed_work(&ap->stats_update_task, secs * HZ); | ||
93 | } | ||
94 | |||
95 | static inline void cancel_mac_stats_update(struct adapter *ap) | ||
96 | { | ||
97 | cancel_delayed_work(&ap->stats_update_task); | ||
98 | } | ||
99 | #endif | ||
100 | |||
101 | #define MAX_CMDQ_ENTRIES 16384 | ||
102 | #define MAX_CMDQ1_ENTRIES 1024 | ||
103 | #define MAX_RX_BUFFERS 16384 | ||
104 | #define MAX_RX_JUMBO_BUFFERS 16384 | ||
105 | #define MAX_TX_BUFFERS_HIGH 16384U | ||
106 | #define MAX_TX_BUFFERS_LOW 1536U | ||
107 | #define MIN_FL_ENTRIES 32 | ||
108 | |||
109 | #define PORT_MASK ((1 << MAX_NPORTS) - 1) | ||
110 | |||
111 | #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ | ||
112 | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ | ||
113 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | ||
114 | |||
115 | /* | ||
116 | * The EEPROM is actually bigger but only the first few bytes are used so we | ||
117 | * only report those. | ||
118 | */ | ||
119 | #define EEPROM_SIZE 32 | ||
120 | |||
121 | MODULE_DESCRIPTION(DRV_DESCRIPTION); | ||
122 | MODULE_AUTHOR("Chelsio Communications"); | ||
123 | MODULE_LICENSE("GPL"); | ||
124 | |||
125 | static int dflt_msg_enable = DFLT_MSG_ENABLE; | ||
126 | |||
127 | MODULE_PARM(dflt_msg_enable, "i"); | ||
128 | MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 message enable bitmap"); | ||
129 | |||
130 | |||
131 | static const char pci_speed[][4] = { | ||
132 | "33", "66", "100", "133" | ||
133 | }; | ||
134 | |||
135 | /* | ||
136 | * Setup MAC to receive the types of packets we want. | ||
137 | */ | ||
138 | static void t1_set_rxmode(struct net_device *dev) | ||
139 | { | ||
140 | struct adapter *adapter = dev->priv; | ||
141 | struct cmac *mac = adapter->port[dev->if_port].mac; | ||
142 | struct t1_rx_mode rm; | ||
143 | |||
144 | rm.dev = dev; | ||
145 | rm.idx = 0; | ||
146 | rm.list = dev->mc_list; | ||
147 | mac->ops->set_rx_mode(mac, &rm); | ||
148 | } | ||
149 | |||
150 | static void link_report(struct port_info *p) | ||
151 | { | ||
152 | if (!netif_carrier_ok(p->dev)) | ||
153 | printk(KERN_INFO "%s: link down\n", p->dev->name); | ||
154 | else { | ||
155 | const char *s = "10Mbps"; | ||
156 | |||
157 | switch (p->link_config.speed) { | ||
158 | case SPEED_10000: s = "10Gbps"; break; | ||
159 | case SPEED_1000: s = "1000Mbps"; break; | ||
160 | case SPEED_100: s = "100Mbps"; break; | ||
161 | } | ||
162 | |||
163 | printk(KERN_INFO "%s: link up, %s, %s-duplex\n", | ||
164 | p->dev->name, s, | ||
165 | p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); | ||
166 | } | ||
167 | } | ||
168 | |||
169 | void t1_link_changed(struct adapter *adapter, int port_id, int link_stat, | ||
170 | int speed, int duplex, int pause) | ||
171 | { | ||
172 | struct port_info *p = &adapter->port[port_id]; | ||
173 | |||
174 | if (link_stat != netif_carrier_ok(p->dev)) { | ||
175 | if (link_stat) | ||
176 | netif_carrier_on(p->dev); | ||
177 | else | ||
178 | netif_carrier_off(p->dev); | ||
179 | link_report(p); | ||
180 | |||
181 | } | ||
182 | } | ||
183 | |||
184 | static void link_start(struct port_info *p) | ||
185 | { | ||
186 | struct cmac *mac = p->mac; | ||
187 | |||
188 | mac->ops->reset(mac); | ||
189 | if (mac->ops->macaddress_set) | ||
190 | mac->ops->macaddress_set(mac, p->dev->dev_addr); | ||
191 | t1_set_rxmode(p->dev); | ||
192 | t1_link_start(p->phy, mac, &p->link_config); | ||
193 | mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); | ||
194 | } | ||
195 | |||
196 | static void enable_hw_csum(struct adapter *adapter) | ||
197 | { | ||
198 | if (adapter->flags & TSO_CAPABLE) | ||
199 | t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */ | ||
200 | t1_tp_set_tcp_checksum_offload(adapter, 1); | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Things to do upon first use of a card. | ||
205 | * This must run with the rtnl lock held. | ||
206 | */ | ||
207 | static int cxgb_up(struct adapter *adapter) | ||
208 | { | ||
209 | int err = 0; | ||
210 | |||
211 | if (!(adapter->flags & FULL_INIT_DONE)) { | ||
212 | err = t1_init_hw_modules(adapter); | ||
213 | if (err) | ||
214 | goto out_err; | ||
215 | |||
216 | enable_hw_csum(adapter); | ||
217 | adapter->flags |= FULL_INIT_DONE; | ||
218 | } | ||
219 | |||
220 | t1_interrupts_clear(adapter); | ||
221 | if ((err = request_irq(adapter->pdev->irq, | ||
222 | t1_select_intr_handler(adapter), SA_SHIRQ, | ||
223 | adapter->name, adapter))) { | ||
224 | goto out_err; | ||
225 | } | ||
226 | t1_sge_start(adapter->sge); | ||
227 | t1_interrupts_enable(adapter); | ||
228 | out_err: | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Release resources when all the ports have been stopped. | ||
234 | */ | ||
235 | static void cxgb_down(struct adapter *adapter) | ||
236 | { | ||
237 | t1_sge_stop(adapter->sge); | ||
238 | t1_interrupts_disable(adapter); | ||
239 | free_irq(adapter->pdev->irq, adapter); | ||
240 | } | ||
241 | |||
242 | static int cxgb_open(struct net_device *dev) | ||
243 | { | ||
244 | int err; | ||
245 | struct adapter *adapter = dev->priv; | ||
246 | int other_ports = adapter->open_device_map & PORT_MASK; | ||
247 | |||
248 | if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) | ||
249 | return err; | ||
250 | |||
251 | __set_bit(dev->if_port, &adapter->open_device_map); | ||
252 | link_start(&adapter->port[dev->if_port]); | ||
253 | netif_start_queue(dev); | ||
254 | if (!other_ports && adapter->params.stats_update_period) | ||
255 | schedule_mac_stats_update(adapter, | ||
256 | adapter->params.stats_update_period); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static int cxgb_close(struct net_device *dev) | ||
261 | { | ||
262 | struct adapter *adapter = dev->priv; | ||
263 | struct port_info *p = &adapter->port[dev->if_port]; | ||
264 | struct cmac *mac = p->mac; | ||
265 | |||
266 | netif_stop_queue(dev); | ||
267 | mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); | ||
268 | netif_carrier_off(dev); | ||
269 | |||
270 | clear_bit(dev->if_port, &adapter->open_device_map); | ||
271 | if (adapter->params.stats_update_period && | ||
272 | !(adapter->open_device_map & PORT_MASK)) { | ||
273 | /* Stop statistics accumulation. */ | ||
274 | smp_mb__after_clear_bit(); | ||
275 | spin_lock(&adapter->work_lock); /* sync with update task */ | ||
276 | spin_unlock(&adapter->work_lock); | ||
277 | cancel_mac_stats_update(adapter); | ||
278 | } | ||
279 | |||
280 | if (!adapter->open_device_map) | ||
281 | cxgb_down(adapter); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static struct net_device_stats *t1_get_stats(struct net_device *dev) | ||
286 | { | ||
287 | struct adapter *adapter = dev->priv; | ||
288 | struct port_info *p = &adapter->port[dev->if_port]; | ||
289 | struct net_device_stats *ns = &p->netstats; | ||
290 | const struct cmac_statistics *pstats; | ||
291 | |||
292 | /* Do a full update of the MAC stats */ | ||
293 | pstats = p->mac->ops->statistics_update(p->mac, | ||
294 | MAC_STATS_UPDATE_FULL); | ||
295 | |||
296 | ns->tx_packets = pstats->TxUnicastFramesOK + | ||
297 | pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK; | ||
298 | |||
299 | ns->rx_packets = pstats->RxUnicastFramesOK + | ||
300 | pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK; | ||
301 | |||
302 | ns->tx_bytes = pstats->TxOctetsOK; | ||
303 | ns->rx_bytes = pstats->RxOctetsOK; | ||
304 | |||
305 | ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors + | ||
306 | pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions; | ||
307 | ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors + | ||
308 | pstats->RxFCSErrors + pstats->RxAlignErrors + | ||
309 | pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors + | ||
310 | pstats->RxSymbolErrors + pstats->RxRuntErrors; | ||
311 | |||
312 | ns->multicast = pstats->RxMulticastFramesOK; | ||
313 | ns->collisions = pstats->TxTotalCollisions; | ||
314 | |||
315 | /* detailed rx_errors */ | ||
316 | ns->rx_length_errors = pstats->RxFrameTooLongErrors + | ||
317 | pstats->RxJabberErrors; | ||
318 | ns->rx_over_errors = 0; | ||
319 | ns->rx_crc_errors = pstats->RxFCSErrors; | ||
320 | ns->rx_frame_errors = pstats->RxAlignErrors; | ||
321 | ns->rx_fifo_errors = 0; | ||
322 | ns->rx_missed_errors = 0; | ||
323 | |||
324 | /* detailed tx_errors */ | ||
325 | ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions; | ||
326 | ns->tx_carrier_errors = 0; | ||
327 | ns->tx_fifo_errors = pstats->TxUnderrun; | ||
328 | ns->tx_heartbeat_errors = 0; | ||
329 | ns->tx_window_errors = pstats->TxLateCollisions; | ||
330 | return ns; | ||
331 | } | ||
332 | |||
333 | static u32 get_msglevel(struct net_device *dev) | ||
334 | { | ||
335 | struct adapter *adapter = dev->priv; | ||
336 | |||
337 | return adapter->msg_enable; | ||
338 | } | ||
339 | |||
340 | static void set_msglevel(struct net_device *dev, u32 val) | ||
341 | { | ||
342 | struct adapter *adapter = dev->priv; | ||
343 | |||
344 | adapter->msg_enable = val; | ||
345 | } | ||
346 | |||
347 | static char stats_strings[][ETH_GSTRING_LEN] = { | ||
348 | "TxOctetsOK", | ||
349 | "TxOctetsBad", | ||
350 | "TxUnicastFramesOK", | ||
351 | "TxMulticastFramesOK", | ||
352 | "TxBroadcastFramesOK", | ||
353 | "TxPauseFrames", | ||
354 | "TxFramesWithDeferredXmissions", | ||
355 | "TxLateCollisions", | ||
356 | "TxTotalCollisions", | ||
357 | "TxFramesAbortedDueToXSCollisions", | ||
358 | "TxUnderrun", | ||
359 | "TxLengthErrors", | ||
360 | "TxInternalMACXmitError", | ||
361 | "TxFramesWithExcessiveDeferral", | ||
362 | "TxFCSErrors", | ||
363 | |||
364 | "RxOctetsOK", | ||
365 | "RxOctetsBad", | ||
366 | "RxUnicastFramesOK", | ||
367 | "RxMulticastFramesOK", | ||
368 | "RxBroadcastFramesOK", | ||
369 | "RxPauseFrames", | ||
370 | "RxFCSErrors", | ||
371 | "RxAlignErrors", | ||
372 | "RxSymbolErrors", | ||
373 | "RxDataErrors", | ||
374 | "RxSequenceErrors", | ||
375 | "RxRuntErrors", | ||
376 | "RxJabberErrors", | ||
377 | "RxInternalMACRcvError", | ||
378 | "RxInRangeLengthErrors", | ||
379 | "RxOutOfRangeLengthField", | ||
380 | "RxFrameTooLongErrors", | ||
381 | |||
382 | "TSO", | ||
383 | "VLANextractions", | ||
384 | "VLANinsertions", | ||
385 | "RxCsumGood", | ||
386 | "TxCsumOffload", | ||
387 | "RxDrops" | ||
388 | |||
389 | "respQ_empty", | ||
390 | "respQ_overflow", | ||
391 | "freelistQ_empty", | ||
392 | "pkt_too_big", | ||
393 | "pkt_mismatch", | ||
394 | "cmdQ_full0", | ||
395 | "cmdQ_full1", | ||
396 | "tx_ipfrags", | ||
397 | "tx_reg_pkts", | ||
398 | "tx_lso_pkts", | ||
399 | "tx_do_cksum", | ||
400 | |||
401 | "espi_DIP2ParityErr", | ||
402 | "espi_DIP4Err", | ||
403 | "espi_RxDrops", | ||
404 | "espi_TxDrops", | ||
405 | "espi_RxOvfl", | ||
406 | "espi_ParityErr" | ||
407 | }; | ||
408 | |||
409 | #define T2_REGMAP_SIZE (3 * 1024) | ||
410 | |||
411 | static int get_regs_len(struct net_device *dev) | ||
412 | { | ||
413 | return T2_REGMAP_SIZE; | ||
414 | } | ||
415 | |||
416 | static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
417 | { | ||
418 | struct adapter *adapter = dev->priv; | ||
419 | |||
420 | strcpy(info->driver, DRV_NAME); | ||
421 | strcpy(info->version, DRV_VERSION); | ||
422 | strcpy(info->fw_version, "N/A"); | ||
423 | strcpy(info->bus_info, pci_name(adapter->pdev)); | ||
424 | } | ||
425 | |||
426 | static int get_stats_count(struct net_device *dev) | ||
427 | { | ||
428 | return ARRAY_SIZE(stats_strings); | ||
429 | } | ||
430 | |||
431 | static void get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
432 | { | ||
433 | if (stringset == ETH_SS_STATS) | ||
434 | memcpy(data, stats_strings, sizeof(stats_strings)); | ||
435 | } | ||
436 | |||
437 | static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | ||
438 | u64 *data) | ||
439 | { | ||
440 | struct adapter *adapter = dev->priv; | ||
441 | struct cmac *mac = adapter->port[dev->if_port].mac; | ||
442 | const struct cmac_statistics *s; | ||
443 | const struct sge_port_stats *ss; | ||
444 | const struct sge_intr_counts *t; | ||
445 | |||
446 | s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); | ||
447 | ss = t1_sge_get_port_stats(adapter->sge, dev->if_port); | ||
448 | t = t1_sge_get_intr_counts(adapter->sge); | ||
449 | |||
450 | *data++ = s->TxOctetsOK; | ||
451 | *data++ = s->TxOctetsBad; | ||
452 | *data++ = s->TxUnicastFramesOK; | ||
453 | *data++ = s->TxMulticastFramesOK; | ||
454 | *data++ = s->TxBroadcastFramesOK; | ||
455 | *data++ = s->TxPauseFrames; | ||
456 | *data++ = s->TxFramesWithDeferredXmissions; | ||
457 | *data++ = s->TxLateCollisions; | ||
458 | *data++ = s->TxTotalCollisions; | ||
459 | *data++ = s->TxFramesAbortedDueToXSCollisions; | ||
460 | *data++ = s->TxUnderrun; | ||
461 | *data++ = s->TxLengthErrors; | ||
462 | *data++ = s->TxInternalMACXmitError; | ||
463 | *data++ = s->TxFramesWithExcessiveDeferral; | ||
464 | *data++ = s->TxFCSErrors; | ||
465 | |||
466 | *data++ = s->RxOctetsOK; | ||
467 | *data++ = s->RxOctetsBad; | ||
468 | *data++ = s->RxUnicastFramesOK; | ||
469 | *data++ = s->RxMulticastFramesOK; | ||
470 | *data++ = s->RxBroadcastFramesOK; | ||
471 | *data++ = s->RxPauseFrames; | ||
472 | *data++ = s->RxFCSErrors; | ||
473 | *data++ = s->RxAlignErrors; | ||
474 | *data++ = s->RxSymbolErrors; | ||
475 | *data++ = s->RxDataErrors; | ||
476 | *data++ = s->RxSequenceErrors; | ||
477 | *data++ = s->RxRuntErrors; | ||
478 | *data++ = s->RxJabberErrors; | ||
479 | *data++ = s->RxInternalMACRcvError; | ||
480 | *data++ = s->RxInRangeLengthErrors; | ||
481 | *data++ = s->RxOutOfRangeLengthField; | ||
482 | *data++ = s->RxFrameTooLongErrors; | ||
483 | |||
484 | *data++ = ss->tso; | ||
485 | *data++ = ss->vlan_xtract; | ||
486 | *data++ = ss->vlan_insert; | ||
487 | *data++ = ss->rx_cso_good; | ||
488 | *data++ = ss->tx_cso; | ||
489 | *data++ = ss->rx_drops; | ||
490 | |||
491 | *data++ = (u64)t->respQ_empty; | ||
492 | *data++ = (u64)t->respQ_overflow; | ||
493 | *data++ = (u64)t->freelistQ_empty; | ||
494 | *data++ = (u64)t->pkt_too_big; | ||
495 | *data++ = (u64)t->pkt_mismatch; | ||
496 | *data++ = (u64)t->cmdQ_full[0]; | ||
497 | *data++ = (u64)t->cmdQ_full[1]; | ||
498 | *data++ = (u64)t->tx_ipfrags; | ||
499 | *data++ = (u64)t->tx_reg_pkts; | ||
500 | *data++ = (u64)t->tx_lso_pkts; | ||
501 | *data++ = (u64)t->tx_do_cksum; | ||
502 | } | ||
503 | |||
504 | static inline void reg_block_dump(struct adapter *ap, void *buf, | ||
505 | unsigned int start, unsigned int end) | ||
506 | { | ||
507 | u32 *p = buf + start; | ||
508 | |||
509 | for ( ; start <= end; start += sizeof(u32)) | ||
510 | *p++ = readl(ap->regs + start); | ||
511 | } | ||
512 | |||
513 | static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
514 | void *buf) | ||
515 | { | ||
516 | struct adapter *ap = dev->priv; | ||
517 | |||
518 | /* | ||
519 | * Version scheme: bits 0..9: chip version, bits 10..15: chip revision | ||
520 | */ | ||
521 | regs->version = 2; | ||
522 | |||
523 | memset(buf, 0, T2_REGMAP_SIZE); | ||
524 | reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER); | ||
525 | } | ||
526 | |||
527 | static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
528 | { | ||
529 | struct adapter *adapter = dev->priv; | ||
530 | struct port_info *p = &adapter->port[dev->if_port]; | ||
531 | |||
532 | cmd->supported = p->link_config.supported; | ||
533 | cmd->advertising = p->link_config.advertising; | ||
534 | |||
535 | if (netif_carrier_ok(dev)) { | ||
536 | cmd->speed = p->link_config.speed; | ||
537 | cmd->duplex = p->link_config.duplex; | ||
538 | } else { | ||
539 | cmd->speed = -1; | ||
540 | cmd->duplex = -1; | ||
541 | } | ||
542 | |||
543 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; | ||
544 | cmd->phy_address = p->phy->addr; | ||
545 | cmd->transceiver = XCVR_EXTERNAL; | ||
546 | cmd->autoneg = p->link_config.autoneg; | ||
547 | cmd->maxtxpkt = 0; | ||
548 | cmd->maxrxpkt = 0; | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | static int speed_duplex_to_caps(int speed, int duplex) | ||
553 | { | ||
554 | int cap = 0; | ||
555 | |||
556 | switch (speed) { | ||
557 | case SPEED_10: | ||
558 | if (duplex == DUPLEX_FULL) | ||
559 | cap = SUPPORTED_10baseT_Full; | ||
560 | else | ||
561 | cap = SUPPORTED_10baseT_Half; | ||
562 | break; | ||
563 | case SPEED_100: | ||
564 | if (duplex == DUPLEX_FULL) | ||
565 | cap = SUPPORTED_100baseT_Full; | ||
566 | else | ||
567 | cap = SUPPORTED_100baseT_Half; | ||
568 | break; | ||
569 | case SPEED_1000: | ||
570 | if (duplex == DUPLEX_FULL) | ||
571 | cap = SUPPORTED_1000baseT_Full; | ||
572 | else | ||
573 | cap = SUPPORTED_1000baseT_Half; | ||
574 | break; | ||
575 | case SPEED_10000: | ||
576 | if (duplex == DUPLEX_FULL) | ||
577 | cap = SUPPORTED_10000baseT_Full; | ||
578 | } | ||
579 | return cap; | ||
580 | } | ||
581 | |||
582 | #define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ | ||
583 | ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ | ||
584 | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \ | ||
585 | ADVERTISED_10000baseT_Full) | ||
586 | |||
587 | static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
588 | { | ||
589 | struct adapter *adapter = dev->priv; | ||
590 | struct port_info *p = &adapter->port[dev->if_port]; | ||
591 | struct link_config *lc = &p->link_config; | ||
592 | |||
593 | if (!(lc->supported & SUPPORTED_Autoneg)) | ||
594 | return -EOPNOTSUPP; /* can't change speed/duplex */ | ||
595 | |||
596 | if (cmd->autoneg == AUTONEG_DISABLE) { | ||
597 | int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex); | ||
598 | |||
599 | if (!(lc->supported & cap) || cmd->speed == SPEED_1000) | ||
600 | return -EINVAL; | ||
601 | lc->requested_speed = cmd->speed; | ||
602 | lc->requested_duplex = cmd->duplex; | ||
603 | lc->advertising = 0; | ||
604 | } else { | ||
605 | cmd->advertising &= ADVERTISED_MASK; | ||
606 | if (cmd->advertising & (cmd->advertising - 1)) | ||
607 | cmd->advertising = lc->supported; | ||
608 | cmd->advertising &= lc->supported; | ||
609 | if (!cmd->advertising) | ||
610 | return -EINVAL; | ||
611 | lc->requested_speed = SPEED_INVALID; | ||
612 | lc->requested_duplex = DUPLEX_INVALID; | ||
613 | lc->advertising = cmd->advertising | ADVERTISED_Autoneg; | ||
614 | } | ||
615 | lc->autoneg = cmd->autoneg; | ||
616 | if (netif_running(dev)) | ||
617 | t1_link_start(p->phy, p->mac, lc); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static void get_pauseparam(struct net_device *dev, | ||
622 | struct ethtool_pauseparam *epause) | ||
623 | { | ||
624 | struct adapter *adapter = dev->priv; | ||
625 | struct port_info *p = &adapter->port[dev->if_port]; | ||
626 | |||
627 | epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0; | ||
628 | epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0; | ||
629 | epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0; | ||
630 | } | ||
631 | |||
632 | static int set_pauseparam(struct net_device *dev, | ||
633 | struct ethtool_pauseparam *epause) | ||
634 | { | ||
635 | struct adapter *adapter = dev->priv; | ||
636 | struct port_info *p = &adapter->port[dev->if_port]; | ||
637 | struct link_config *lc = &p->link_config; | ||
638 | |||
639 | if (epause->autoneg == AUTONEG_DISABLE) | ||
640 | lc->requested_fc = 0; | ||
641 | else if (lc->supported & SUPPORTED_Autoneg) | ||
642 | lc->requested_fc = PAUSE_AUTONEG; | ||
643 | else | ||
644 | return -EINVAL; | ||
645 | |||
646 | if (epause->rx_pause) | ||
647 | lc->requested_fc |= PAUSE_RX; | ||
648 | if (epause->tx_pause) | ||
649 | lc->requested_fc |= PAUSE_TX; | ||
650 | if (lc->autoneg == AUTONEG_ENABLE) { | ||
651 | if (netif_running(dev)) | ||
652 | t1_link_start(p->phy, p->mac, lc); | ||
653 | } else { | ||
654 | lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
655 | if (netif_running(dev)) | ||
656 | p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1, | ||
657 | lc->fc); | ||
658 | } | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static u32 get_rx_csum(struct net_device *dev) | ||
663 | { | ||
664 | struct adapter *adapter = dev->priv; | ||
665 | |||
666 | return (adapter->flags & RX_CSUM_ENABLED) != 0; | ||
667 | } | ||
668 | |||
669 | static int set_rx_csum(struct net_device *dev, u32 data) | ||
670 | { | ||
671 | struct adapter *adapter = dev->priv; | ||
672 | |||
673 | if (data) | ||
674 | adapter->flags |= RX_CSUM_ENABLED; | ||
675 | else | ||
676 | adapter->flags &= ~RX_CSUM_ENABLED; | ||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | static int set_tso(struct net_device *dev, u32 value) | ||
681 | { | ||
682 | struct adapter *adapter = dev->priv; | ||
683 | |||
684 | if (!(adapter->flags & TSO_CAPABLE)) | ||
685 | return value ? -EOPNOTSUPP : 0; | ||
686 | return ethtool_op_set_tso(dev, value); | ||
687 | } | ||
688 | |||
689 | static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
690 | { | ||
691 | struct adapter *adapter = dev->priv; | ||
692 | int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; | ||
693 | |||
694 | e->rx_max_pending = MAX_RX_BUFFERS; | ||
695 | e->rx_mini_max_pending = 0; | ||
696 | e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS; | ||
697 | e->tx_max_pending = MAX_CMDQ_ENTRIES; | ||
698 | |||
699 | e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl]; | ||
700 | e->rx_mini_pending = 0; | ||
701 | e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl]; | ||
702 | e->tx_pending = adapter->params.sge.cmdQ_size[0]; | ||
703 | } | ||
704 | |||
705 | static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | ||
706 | { | ||
707 | struct adapter *adapter = dev->priv; | ||
708 | int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; | ||
709 | |||
710 | if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending || | ||
711 | e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS || | ||
712 | e->tx_pending > MAX_CMDQ_ENTRIES || | ||
713 | e->rx_pending < MIN_FL_ENTRIES || | ||
714 | e->rx_jumbo_pending < MIN_FL_ENTRIES || | ||
715 | e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1)) | ||
716 | return -EINVAL; | ||
717 | |||
718 | if (adapter->flags & FULL_INIT_DONE) | ||
719 | return -EBUSY; | ||
720 | |||
721 | adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; | ||
722 | adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; | ||
723 | adapter->params.sge.cmdQ_size[0] = e->tx_pending; | ||
724 | adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ? | ||
725 | MAX_CMDQ1_ENTRIES : e->tx_pending; | ||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
730 | { | ||
731 | struct adapter *adapter = dev->priv; | ||
732 | |||
733 | /* | ||
734 | * If RX coalescing is requested we use NAPI, otherwise interrupts. | ||
735 | * This choice can be made only when all ports and the TOE are off. | ||
736 | */ | ||
737 | if (adapter->open_device_map == 0) | ||
738 | adapter->params.sge.polling = c->use_adaptive_rx_coalesce; | ||
739 | |||
740 | if (adapter->params.sge.polling) { | ||
741 | adapter->params.sge.rx_coalesce_usecs = 0; | ||
742 | } else { | ||
743 | adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; | ||
744 | } | ||
745 | adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce; | ||
746 | adapter->params.sge.sample_interval_usecs = c->rate_sample_interval; | ||
747 | t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge); | ||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | ||
752 | { | ||
753 | struct adapter *adapter = dev->priv; | ||
754 | |||
755 | c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs; | ||
756 | c->rate_sample_interval = adapter->params.sge.sample_interval_usecs; | ||
757 | c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable; | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | static int get_eeprom_len(struct net_device *dev) | ||
762 | { | ||
763 | return EEPROM_SIZE; | ||
764 | } | ||
765 | |||
766 | #define EEPROM_MAGIC(ap) \ | ||
767 | (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16)) | ||
768 | |||
769 | static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, | ||
770 | u8 *data) | ||
771 | { | ||
772 | int i; | ||
773 | u8 buf[EEPROM_SIZE] __attribute__((aligned(4))); | ||
774 | struct adapter *adapter = dev->priv; | ||
775 | |||
776 | e->magic = EEPROM_MAGIC(adapter); | ||
777 | for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32)) | ||
778 | t1_seeprom_read(adapter, i, (u32 *)&buf[i]); | ||
779 | memcpy(data, buf + e->offset, e->len); | ||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | static struct ethtool_ops t1_ethtool_ops = { | ||
784 | .get_settings = get_settings, | ||
785 | .set_settings = set_settings, | ||
786 | .get_drvinfo = get_drvinfo, | ||
787 | .get_msglevel = get_msglevel, | ||
788 | .set_msglevel = set_msglevel, | ||
789 | .get_ringparam = get_sge_param, | ||
790 | .set_ringparam = set_sge_param, | ||
791 | .get_coalesce = get_coalesce, | ||
792 | .set_coalesce = set_coalesce, | ||
793 | .get_eeprom_len = get_eeprom_len, | ||
794 | .get_eeprom = get_eeprom, | ||
795 | .get_pauseparam = get_pauseparam, | ||
796 | .set_pauseparam = set_pauseparam, | ||
797 | .get_rx_csum = get_rx_csum, | ||
798 | .set_rx_csum = set_rx_csum, | ||
799 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
800 | .set_tx_csum = ethtool_op_set_tx_csum, | ||
801 | .get_sg = ethtool_op_get_sg, | ||
802 | .set_sg = ethtool_op_set_sg, | ||
803 | .get_link = ethtool_op_get_link, | ||
804 | .get_strings = get_strings, | ||
805 | .get_stats_count = get_stats_count, | ||
806 | .get_ethtool_stats = get_stats, | ||
807 | .get_regs_len = get_regs_len, | ||
808 | .get_regs = get_regs, | ||
809 | .get_tso = ethtool_op_get_tso, | ||
810 | .set_tso = set_tso, | ||
811 | }; | ||
812 | |||
813 | static void cxgb_proc_cleanup(struct adapter *adapter, | ||
814 | struct proc_dir_entry *dir) | ||
815 | { | ||
816 | const char *name; | ||
817 | name = adapter->name; | ||
818 | remove_proc_entry(name, dir); | ||
819 | } | ||
820 | //#define chtoe_setup_toedev(adapter) NULL | ||
821 | #define update_mtu_tab(adapter) | ||
822 | #define write_smt_entry(adapter, idx) | ||
823 | |||
824 | static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
825 | { | ||
826 | struct adapter *adapter = dev->priv; | ||
827 | struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data; | ||
828 | |||
829 | switch (cmd) { | ||
830 | case SIOCGMIIPHY: | ||
831 | data->phy_id = adapter->port[dev->if_port].phy->addr; | ||
832 | /* FALLTHRU */ | ||
833 | case SIOCGMIIREG: { | ||
834 | struct cphy *phy = adapter->port[dev->if_port].phy; | ||
835 | u32 val; | ||
836 | |||
837 | if (!phy->mdio_read) | ||
838 | return -EOPNOTSUPP; | ||
839 | phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, | ||
840 | &val); | ||
841 | data->val_out = val; | ||
842 | break; | ||
843 | } | ||
844 | case SIOCSMIIREG: { | ||
845 | struct cphy *phy = adapter->port[dev->if_port].phy; | ||
846 | |||
847 | if (!capable(CAP_NET_ADMIN)) | ||
848 | return -EPERM; | ||
849 | if (!phy->mdio_write) | ||
850 | return -EOPNOTSUPP; | ||
851 | phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, | ||
852 | data->val_in); | ||
853 | break; | ||
854 | } | ||
855 | |||
856 | default: | ||
857 | return -EOPNOTSUPP; | ||
858 | } | ||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static int t1_change_mtu(struct net_device *dev, int new_mtu) | ||
863 | { | ||
864 | int ret; | ||
865 | struct adapter *adapter = dev->priv; | ||
866 | struct cmac *mac = adapter->port[dev->if_port].mac; | ||
867 | |||
868 | if (!mac->ops->set_mtu) | ||
869 | return -EOPNOTSUPP; | ||
870 | if (new_mtu < 68) | ||
871 | return -EINVAL; | ||
872 | if ((ret = mac->ops->set_mtu(mac, new_mtu))) | ||
873 | return ret; | ||
874 | dev->mtu = new_mtu; | ||
875 | return 0; | ||
876 | } | ||
877 | |||
878 | static int t1_set_mac_addr(struct net_device *dev, void *p) | ||
879 | { | ||
880 | struct adapter *adapter = dev->priv; | ||
881 | struct cmac *mac = adapter->port[dev->if_port].mac; | ||
882 | struct sockaddr *addr = p; | ||
883 | |||
884 | if (!mac->ops->macaddress_set) | ||
885 | return -EOPNOTSUPP; | ||
886 | |||
887 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | ||
888 | mac->ops->macaddress_set(mac, dev->dev_addr); | ||
889 | return 0; | ||
890 | } | ||
891 | |||
892 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
893 | static void vlan_rx_register(struct net_device *dev, | ||
894 | struct vlan_group *grp) | ||
895 | { | ||
896 | struct adapter *adapter = dev->priv; | ||
897 | |||
898 | spin_lock_irq(&adapter->async_lock); | ||
899 | adapter->vlan_grp = grp; | ||
900 | t1_set_vlan_accel(adapter, grp != NULL); | ||
901 | spin_unlock_irq(&adapter->async_lock); | ||
902 | } | ||
903 | |||
904 | static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | ||
905 | { | ||
906 | struct adapter *adapter = dev->priv; | ||
907 | |||
908 | spin_lock_irq(&adapter->async_lock); | ||
909 | if (adapter->vlan_grp) | ||
910 | adapter->vlan_grp->vlan_devices[vid] = NULL; | ||
911 | spin_unlock_irq(&adapter->async_lock); | ||
912 | } | ||
913 | #endif | ||
914 | |||
915 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
916 | static void t1_netpoll(struct net_device *dev) | ||
917 | { | ||
918 | unsigned long flags; | ||
919 | struct adapter *adapter = dev->priv; | ||
920 | |||
921 | local_irq_save(flags); | ||
922 | t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter, NULL); | ||
923 | local_irq_restore(flags); | ||
924 | } | ||
925 | #endif | ||
926 | |||
927 | /* | ||
928 | * Periodic accumulation of MAC statistics. This is used only if the MAC | ||
929 | * does not have any other way to prevent stats counter overflow. | ||
930 | */ | ||
931 | static void mac_stats_task(void *data) | ||
932 | { | ||
933 | int i; | ||
934 | struct adapter *adapter = data; | ||
935 | |||
936 | for_each_port(adapter, i) { | ||
937 | struct port_info *p = &adapter->port[i]; | ||
938 | |||
939 | if (netif_running(p->dev)) | ||
940 | p->mac->ops->statistics_update(p->mac, | ||
941 | MAC_STATS_UPDATE_FAST); | ||
942 | } | ||
943 | |||
944 | /* Schedule the next statistics update if any port is active. */ | ||
945 | spin_lock(&adapter->work_lock); | ||
946 | if (adapter->open_device_map & PORT_MASK) | ||
947 | schedule_mac_stats_update(adapter, | ||
948 | adapter->params.stats_update_period); | ||
949 | spin_unlock(&adapter->work_lock); | ||
950 | } | ||
951 | |||
952 | /* | ||
953 | * Processes elmer0 external interrupts in process context. | ||
954 | */ | ||
955 | static void ext_intr_task(void *data) | ||
956 | { | ||
957 | struct adapter *adapter = data; | ||
958 | |||
959 | elmer0_ext_intr_handler(adapter); | ||
960 | |||
961 | /* Now reenable external interrupts */ | ||
962 | spin_lock_irq(&adapter->async_lock); | ||
963 | adapter->slow_intr_mask |= F_PL_INTR_EXT; | ||
964 | writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE); | ||
965 | writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, | ||
966 | adapter->regs + A_PL_ENABLE); | ||
967 | spin_unlock_irq(&adapter->async_lock); | ||
968 | } | ||
969 | |||
970 | /* | ||
971 | * Interrupt-context handler for elmer0 external interrupts. | ||
972 | */ | ||
973 | void t1_elmer0_ext_intr(struct adapter *adapter) | ||
974 | { | ||
975 | /* | ||
976 | * Schedule a task to handle external interrupts as we require | ||
977 | * a process context. We disable EXT interrupts in the interim | ||
978 | * and let the task reenable them when it's done. | ||
979 | */ | ||
980 | adapter->slow_intr_mask &= ~F_PL_INTR_EXT; | ||
981 | writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, | ||
982 | adapter->regs + A_PL_ENABLE); | ||
983 | schedule_work(&adapter->ext_intr_handler_task); | ||
984 | } | ||
985 | |||
986 | void t1_fatal_err(struct adapter *adapter) | ||
987 | { | ||
988 | if (adapter->flags & FULL_INIT_DONE) { | ||
989 | t1_sge_stop(adapter->sge); | ||
990 | t1_interrupts_disable(adapter); | ||
991 | } | ||
992 | CH_ALERT("%s: encountered fatal error, operation suspended\n", | ||
993 | adapter->name); | ||
994 | } | ||
995 | |||
996 | static int __devinit init_one(struct pci_dev *pdev, | ||
997 | const struct pci_device_id *ent) | ||
998 | { | ||
999 | static int version_printed; | ||
1000 | |||
1001 | int i, err, pci_using_dac = 0; | ||
1002 | unsigned long mmio_start, mmio_len; | ||
1003 | const struct board_info *bi; | ||
1004 | struct adapter *adapter = NULL; | ||
1005 | struct port_info *pi; | ||
1006 | |||
1007 | if (!version_printed) { | ||
1008 | printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION, | ||
1009 | DRV_VERSION); | ||
1010 | ++version_printed; | ||
1011 | } | ||
1012 | |||
1013 | err = pci_enable_device(pdev); | ||
1014 | if (err) | ||
1015 | return err; | ||
1016 | |||
1017 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | ||
1018 | CH_ERR("%s: cannot find PCI device memory base address\n", | ||
1019 | pci_name(pdev)); | ||
1020 | err = -ENODEV; | ||
1021 | goto out_disable_pdev; | ||
1022 | } | ||
1023 | |||
1024 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | ||
1025 | pci_using_dac = 1; | ||
1026 | |||
1027 | if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { | ||
1028 | CH_ERR("%s: unable to obtain 64-bit DMA for" | ||
1029 | "consistent allocations\n", pci_name(pdev)); | ||
1030 | err = -ENODEV; | ||
1031 | goto out_disable_pdev; | ||
1032 | } | ||
1033 | |||
1034 | } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) { | ||
1035 | CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev)); | ||
1036 | goto out_disable_pdev; | ||
1037 | } | ||
1038 | |||
1039 | err = pci_request_regions(pdev, DRV_NAME); | ||
1040 | if (err) { | ||
1041 | CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev)); | ||
1042 | goto out_disable_pdev; | ||
1043 | } | ||
1044 | |||
1045 | pci_set_master(pdev); | ||
1046 | |||
1047 | mmio_start = pci_resource_start(pdev, 0); | ||
1048 | mmio_len = pci_resource_len(pdev, 0); | ||
1049 | bi = t1_get_board_info(ent->driver_data); | ||
1050 | |||
1051 | for (i = 0; i < bi->port_number; ++i) { | ||
1052 | struct net_device *netdev; | ||
1053 | |||
1054 | netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter)); | ||
1055 | if (!netdev) { | ||
1056 | err = -ENOMEM; | ||
1057 | goto out_free_dev; | ||
1058 | } | ||
1059 | |||
1060 | SET_MODULE_OWNER(netdev); | ||
1061 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
1062 | |||
1063 | if (!adapter) { | ||
1064 | adapter = netdev->priv; | ||
1065 | adapter->pdev = pdev; | ||
1066 | adapter->port[0].dev = netdev; /* so we don't leak it */ | ||
1067 | |||
1068 | adapter->regs = ioremap(mmio_start, mmio_len); | ||
1069 | if (!adapter->regs) { | ||
1070 | CH_ERR("%s: cannot map device registers\n", | ||
1071 | pci_name(pdev)); | ||
1072 | err = -ENOMEM; | ||
1073 | goto out_free_dev; | ||
1074 | } | ||
1075 | |||
1076 | if (t1_get_board_rev(adapter, bi, &adapter->params)) { | ||
1077 | err = -ENODEV; /* Can't handle this chip rev */ | ||
1078 | goto out_free_dev; | ||
1079 | } | ||
1080 | |||
1081 | adapter->name = pci_name(pdev); | ||
1082 | adapter->msg_enable = dflt_msg_enable; | ||
1083 | adapter->mmio_len = mmio_len; | ||
1084 | |||
1085 | init_MUTEX(&adapter->mib_mutex); | ||
1086 | spin_lock_init(&adapter->tpi_lock); | ||
1087 | spin_lock_init(&adapter->work_lock); | ||
1088 | spin_lock_init(&adapter->async_lock); | ||
1089 | |||
1090 | INIT_WORK(&adapter->ext_intr_handler_task, | ||
1091 | ext_intr_task, adapter); | ||
1092 | INIT_WORK(&adapter->stats_update_task, mac_stats_task, | ||
1093 | adapter); | ||
1094 | #ifdef work_struct | ||
1095 | init_timer(&adapter->stats_update_timer); | ||
1096 | adapter->stats_update_timer.function = mac_stats_timer; | ||
1097 | adapter->stats_update_timer.data = | ||
1098 | (unsigned long)adapter; | ||
1099 | #endif | ||
1100 | |||
1101 | pci_set_drvdata(pdev, netdev); | ||
1102 | } | ||
1103 | |||
1104 | pi = &adapter->port[i]; | ||
1105 | pi->dev = netdev; | ||
1106 | netif_carrier_off(netdev); | ||
1107 | netdev->irq = pdev->irq; | ||
1108 | netdev->if_port = i; | ||
1109 | netdev->mem_start = mmio_start; | ||
1110 | netdev->mem_end = mmio_start + mmio_len - 1; | ||
1111 | netdev->priv = adapter; | ||
1112 | netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | ||
1113 | netdev->features |= NETIF_F_LLTX; | ||
1114 | |||
1115 | adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE; | ||
1116 | if (pci_using_dac) | ||
1117 | netdev->features |= NETIF_F_HIGHDMA; | ||
1118 | if (vlan_tso_capable(adapter)) { | ||
1119 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
1120 | adapter->flags |= VLAN_ACCEL_CAPABLE; | ||
1121 | netdev->features |= | ||
1122 | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
1123 | netdev->vlan_rx_register = vlan_rx_register; | ||
1124 | netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; | ||
1125 | #endif | ||
1126 | adapter->flags |= TSO_CAPABLE; | ||
1127 | netdev->features |= NETIF_F_TSO; | ||
1128 | } | ||
1129 | |||
1130 | netdev->open = cxgb_open; | ||
1131 | netdev->stop = cxgb_close; | ||
1132 | netdev->hard_start_xmit = t1_start_xmit; | ||
1133 | netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? | ||
1134 | sizeof(struct cpl_tx_pkt_lso) : | ||
1135 | sizeof(struct cpl_tx_pkt); | ||
1136 | netdev->get_stats = t1_get_stats; | ||
1137 | netdev->set_multicast_list = t1_set_rxmode; | ||
1138 | netdev->do_ioctl = t1_ioctl; | ||
1139 | netdev->change_mtu = t1_change_mtu; | ||
1140 | netdev->set_mac_address = t1_set_mac_addr; | ||
1141 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1142 | netdev->poll_controller = t1_netpoll; | ||
1143 | #endif | ||
1144 | netdev->weight = 64; | ||
1145 | |||
1146 | SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); | ||
1147 | } | ||
1148 | |||
1149 | if (t1_init_sw_modules(adapter, bi) < 0) { | ||
1150 | err = -ENODEV; | ||
1151 | goto out_free_dev; | ||
1152 | } | ||
1153 | |||
1154 | /* | ||
1155 | * The card is now ready to go. If any errors occur during device | ||
1156 | * registration we do not fail the whole card but rather proceed only | ||
1157 | * with the ports we manage to register successfully. However we must | ||
1158 | * register at least one net device. | ||
1159 | */ | ||
1160 | for (i = 0; i < bi->port_number; ++i) { | ||
1161 | err = register_netdev(adapter->port[i].dev); | ||
1162 | if (err) | ||
1163 | CH_WARN("%s: cannot register net device %s, skipping\n", | ||
1164 | pci_name(pdev), adapter->port[i].dev->name); | ||
1165 | else { | ||
1166 | /* | ||
1167 | * Change the name we use for messages to the name of | ||
1168 | * the first successfully registered interface. | ||
1169 | */ | ||
1170 | if (!adapter->registered_device_map) | ||
1171 | adapter->name = adapter->port[i].dev->name; | ||
1172 | |||
1173 | __set_bit(i, &adapter->registered_device_map); | ||
1174 | } | ||
1175 | } | ||
1176 | if (!adapter->registered_device_map) { | ||
1177 | CH_ERR("%s: could not register any net devices\n", | ||
1178 | pci_name(pdev)); | ||
1179 | goto out_release_adapter_res; | ||
1180 | } | ||
1181 | |||
1182 | printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name, | ||
1183 | bi->desc, adapter->params.chip_revision, | ||
1184 | adapter->params.pci.is_pcix ? "PCIX" : "PCI", | ||
1185 | adapter->params.pci.speed, adapter->params.pci.width); | ||
1186 | return 0; | ||
1187 | |||
1188 | out_release_adapter_res: | ||
1189 | t1_free_sw_modules(adapter); | ||
1190 | out_free_dev: | ||
1191 | if (adapter) { | ||
1192 | if (adapter->regs) iounmap(adapter->regs); | ||
1193 | for (i = bi->port_number - 1; i >= 0; --i) | ||
1194 | if (adapter->port[i].dev) { | ||
1195 | cxgb_proc_cleanup(adapter, proc_root_driver); | ||
1196 | kfree(adapter->port[i].dev); | ||
1197 | } | ||
1198 | } | ||
1199 | pci_release_regions(pdev); | ||
1200 | out_disable_pdev: | ||
1201 | pci_disable_device(pdev); | ||
1202 | pci_set_drvdata(pdev, NULL); | ||
1203 | return err; | ||
1204 | } | ||
1205 | |||
1206 | static inline void t1_sw_reset(struct pci_dev *pdev) | ||
1207 | { | ||
1208 | pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3); | ||
1209 | pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0); | ||
1210 | } | ||
1211 | |||
1212 | static void __devexit remove_one(struct pci_dev *pdev) | ||
1213 | { | ||
1214 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1215 | |||
1216 | if (dev) { | ||
1217 | int i; | ||
1218 | struct adapter *adapter = dev->priv; | ||
1219 | |||
1220 | for_each_port(adapter, i) | ||
1221 | if (test_bit(i, &adapter->registered_device_map)) | ||
1222 | unregister_netdev(adapter->port[i].dev); | ||
1223 | |||
1224 | t1_free_sw_modules(adapter); | ||
1225 | iounmap(adapter->regs); | ||
1226 | while (--i >= 0) | ||
1227 | if (adapter->port[i].dev) { | ||
1228 | cxgb_proc_cleanup(adapter, proc_root_driver); | ||
1229 | kfree(adapter->port[i].dev); | ||
1230 | } | ||
1231 | pci_release_regions(pdev); | ||
1232 | pci_disable_device(pdev); | ||
1233 | pci_set_drvdata(pdev, NULL); | ||
1234 | t1_sw_reset(pdev); | ||
1235 | } | ||
1236 | } | ||
1237 | |||
1238 | static struct pci_driver driver = { | ||
1239 | .name = DRV_NAME, | ||
1240 | .id_table = t1_pci_tbl, | ||
1241 | .probe = init_one, | ||
1242 | .remove = __devexit_p(remove_one), | ||
1243 | }; | ||
1244 | |||
1245 | static int __init t1_init_module(void) | ||
1246 | { | ||
1247 | return pci_module_init(&driver); | ||
1248 | } | ||
1249 | |||
1250 | static void __exit t1_cleanup_module(void) | ||
1251 | { | ||
1252 | pci_unregister_driver(&driver); | ||
1253 | } | ||
1254 | |||
1255 | module_init(t1_init_module); | ||
1256 | module_exit(t1_cleanup_module); | ||
diff --git a/drivers/net/chelsio/elmer0.h b/drivers/net/chelsio/elmer0.h new file mode 100644 index 000000000000..5590cb2dac19 --- /dev/null +++ b/drivers/net/chelsio/elmer0.h | |||
@@ -0,0 +1,151 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: elmer0.h * | ||
4 | * $Revision: 1.6 $ * | ||
5 | * $Date: 2005/06/21 22:49:43 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_ELMER0_H_ | ||
40 | #define _CXGB_ELMER0_H_ | ||
41 | |||
42 | /* ELMER0 registers */ | ||
43 | #define A_ELMER0_VERSION 0x100000 | ||
44 | #define A_ELMER0_PHY_CFG 0x100004 | ||
45 | #define A_ELMER0_INT_ENABLE 0x100008 | ||
46 | #define A_ELMER0_INT_CAUSE 0x10000c | ||
47 | #define A_ELMER0_GPI_CFG 0x100010 | ||
48 | #define A_ELMER0_GPI_STAT 0x100014 | ||
49 | #define A_ELMER0_GPO 0x100018 | ||
50 | #define A_ELMER0_PORT0_MI1_CFG 0x400000 | ||
51 | |||
52 | #define S_MI1_MDI_ENABLE 0 | ||
53 | #define V_MI1_MDI_ENABLE(x) ((x) << S_MI1_MDI_ENABLE) | ||
54 | #define F_MI1_MDI_ENABLE V_MI1_MDI_ENABLE(1U) | ||
55 | |||
56 | #define S_MI1_MDI_INVERT 1 | ||
57 | #define V_MI1_MDI_INVERT(x) ((x) << S_MI1_MDI_INVERT) | ||
58 | #define F_MI1_MDI_INVERT V_MI1_MDI_INVERT(1U) | ||
59 | |||
60 | #define S_MI1_PREAMBLE_ENABLE 2 | ||
61 | #define V_MI1_PREAMBLE_ENABLE(x) ((x) << S_MI1_PREAMBLE_ENABLE) | ||
62 | #define F_MI1_PREAMBLE_ENABLE V_MI1_PREAMBLE_ENABLE(1U) | ||
63 | |||
64 | #define S_MI1_SOF 3 | ||
65 | #define M_MI1_SOF 0x3 | ||
66 | #define V_MI1_SOF(x) ((x) << S_MI1_SOF) | ||
67 | #define G_MI1_SOF(x) (((x) >> S_MI1_SOF) & M_MI1_SOF) | ||
68 | |||
69 | #define S_MI1_CLK_DIV 5 | ||
70 | #define M_MI1_CLK_DIV 0xff | ||
71 | #define V_MI1_CLK_DIV(x) ((x) << S_MI1_CLK_DIV) | ||
72 | #define G_MI1_CLK_DIV(x) (((x) >> S_MI1_CLK_DIV) & M_MI1_CLK_DIV) | ||
73 | |||
74 | #define A_ELMER0_PORT0_MI1_ADDR 0x400004 | ||
75 | |||
76 | #define S_MI1_REG_ADDR 0 | ||
77 | #define M_MI1_REG_ADDR 0x1f | ||
78 | #define V_MI1_REG_ADDR(x) ((x) << S_MI1_REG_ADDR) | ||
79 | #define G_MI1_REG_ADDR(x) (((x) >> S_MI1_REG_ADDR) & M_MI1_REG_ADDR) | ||
80 | |||
81 | #define S_MI1_PHY_ADDR 5 | ||
82 | #define M_MI1_PHY_ADDR 0x1f | ||
83 | #define V_MI1_PHY_ADDR(x) ((x) << S_MI1_PHY_ADDR) | ||
84 | #define G_MI1_PHY_ADDR(x) (((x) >> S_MI1_PHY_ADDR) & M_MI1_PHY_ADDR) | ||
85 | |||
86 | #define A_ELMER0_PORT0_MI1_DATA 0x400008 | ||
87 | |||
88 | #define S_MI1_DATA 0 | ||
89 | #define M_MI1_DATA 0xffff | ||
90 | #define V_MI1_DATA(x) ((x) << S_MI1_DATA) | ||
91 | #define G_MI1_DATA(x) (((x) >> S_MI1_DATA) & M_MI1_DATA) | ||
92 | |||
93 | #define A_ELMER0_PORT0_MI1_OP 0x40000c | ||
94 | |||
95 | #define S_MI1_OP 0 | ||
96 | #define M_MI1_OP 0x3 | ||
97 | #define V_MI1_OP(x) ((x) << S_MI1_OP) | ||
98 | #define G_MI1_OP(x) (((x) >> S_MI1_OP) & M_MI1_OP) | ||
99 | |||
100 | #define S_MI1_ADDR_AUTOINC 2 | ||
101 | #define V_MI1_ADDR_AUTOINC(x) ((x) << S_MI1_ADDR_AUTOINC) | ||
102 | #define F_MI1_ADDR_AUTOINC V_MI1_ADDR_AUTOINC(1U) | ||
103 | |||
104 | #define S_MI1_OP_BUSY 31 | ||
105 | #define V_MI1_OP_BUSY(x) ((x) << S_MI1_OP_BUSY) | ||
106 | #define F_MI1_OP_BUSY V_MI1_OP_BUSY(1U) | ||
107 | |||
108 | #define A_ELMER0_PORT1_MI1_CFG 0x500000 | ||
109 | #define A_ELMER0_PORT1_MI1_ADDR 0x500004 | ||
110 | #define A_ELMER0_PORT1_MI1_DATA 0x500008 | ||
111 | #define A_ELMER0_PORT1_MI1_OP 0x50000c | ||
112 | #define A_ELMER0_PORT2_MI1_CFG 0x600000 | ||
113 | #define A_ELMER0_PORT2_MI1_ADDR 0x600004 | ||
114 | #define A_ELMER0_PORT2_MI1_DATA 0x600008 | ||
115 | #define A_ELMER0_PORT2_MI1_OP 0x60000c | ||
116 | #define A_ELMER0_PORT3_MI1_CFG 0x700000 | ||
117 | #define A_ELMER0_PORT3_MI1_ADDR 0x700004 | ||
118 | #define A_ELMER0_PORT3_MI1_DATA 0x700008 | ||
119 | #define A_ELMER0_PORT3_MI1_OP 0x70000c | ||
120 | |||
121 | /* Simple bit definition for GPI and GP0 registers. */ | ||
122 | #define ELMER0_GP_BIT0 0x0001 | ||
123 | #define ELMER0_GP_BIT1 0x0002 | ||
124 | #define ELMER0_GP_BIT2 0x0004 | ||
125 | #define ELMER0_GP_BIT3 0x0008 | ||
126 | #define ELMER0_GP_BIT4 0x0010 | ||
127 | #define ELMER0_GP_BIT5 0x0020 | ||
128 | #define ELMER0_GP_BIT6 0x0040 | ||
129 | #define ELMER0_GP_BIT7 0x0080 | ||
130 | #define ELMER0_GP_BIT8 0x0100 | ||
131 | #define ELMER0_GP_BIT9 0x0200 | ||
132 | #define ELMER0_GP_BIT10 0x0400 | ||
133 | #define ELMER0_GP_BIT11 0x0800 | ||
134 | #define ELMER0_GP_BIT12 0x1000 | ||
135 | #define ELMER0_GP_BIT13 0x2000 | ||
136 | #define ELMER0_GP_BIT14 0x4000 | ||
137 | #define ELMER0_GP_BIT15 0x8000 | ||
138 | #define ELMER0_GP_BIT16 0x10000 | ||
139 | #define ELMER0_GP_BIT17 0x20000 | ||
140 | #define ELMER0_GP_BIT18 0x40000 | ||
141 | #define ELMER0_GP_BIT19 0x80000 | ||
142 | |||
143 | #define MI1_OP_DIRECT_WRITE 1 | ||
144 | #define MI1_OP_DIRECT_READ 2 | ||
145 | |||
146 | #define MI1_OP_INDIRECT_ADDRESS 0 | ||
147 | #define MI1_OP_INDIRECT_WRITE 1 | ||
148 | #define MI1_OP_INDIRECT_READ_INC 2 | ||
149 | #define MI1_OP_INDIRECT_READ 3 | ||
150 | |||
151 | #endif /* _CXGB_ELMER0_H_ */ | ||
diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c new file mode 100644 index 000000000000..230642571c92 --- /dev/null +++ b/drivers/net/chelsio/espi.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: espi.c * | ||
4 | * $Revision: 1.14 $ * | ||
5 | * $Date: 2005/05/14 00:59:32 $ * | ||
6 | * Description: * | ||
7 | * Ethernet SPI functionality. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
25 | * All rights reserved. * | ||
26 | * * | ||
27 | * Maintainers: maintainers@chelsio.com * | ||
28 | * * | ||
29 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
30 | * Tina Yang <tainay@chelsio.com> * | ||
31 | * Felix Marti <felix@chelsio.com> * | ||
32 | * Scott Bardone <sbardone@chelsio.com> * | ||
33 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
34 | * Frank DiMambro <frank@chelsio.com> * | ||
35 | * * | ||
36 | * History: * | ||
37 | * * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include "common.h" | ||
41 | #include "regs.h" | ||
42 | #include "espi.h" | ||
43 | |||
44 | struct peespi { | ||
45 | adapter_t *adapter; | ||
46 | struct espi_intr_counts intr_cnt; | ||
47 | u32 misc_ctrl; | ||
48 | spinlock_t lock; | ||
49 | }; | ||
50 | |||
51 | #define ESPI_INTR_MASK (F_DIP4ERR | F_RXDROP | F_TXDROP | F_RXOVERFLOW | \ | ||
52 | F_RAMPARITYERR | F_DIP2PARITYERR) | ||
53 | #define MON_MASK (V_MONITORED_PORT_NUM(3) | F_MONITORED_DIRECTION \ | ||
54 | | F_MONITORED_INTERFACE) | ||
55 | |||
56 | #define TRICN_CNFG 14 | ||
57 | #define TRICN_CMD_READ 0x11 | ||
58 | #define TRICN_CMD_WRITE 0x21 | ||
59 | #define TRICN_CMD_ATTEMPTS 10 | ||
60 | |||
61 | static int tricn_write(adapter_t *adapter, int bundle_addr, int module_addr, | ||
62 | int ch_addr, int reg_offset, u32 wr_data) | ||
63 | { | ||
64 | int busy, attempts = TRICN_CMD_ATTEMPTS; | ||
65 | |||
66 | writel(V_WRITE_DATA(wr_data) | | ||
67 | V_REGISTER_OFFSET(reg_offset) | | ||
68 | V_CHANNEL_ADDR(ch_addr) | V_MODULE_ADDR(module_addr) | | ||
69 | V_BUNDLE_ADDR(bundle_addr) | | ||
70 | V_SPI4_COMMAND(TRICN_CMD_WRITE), | ||
71 | adapter->regs + A_ESPI_CMD_ADDR); | ||
72 | writel(0, adapter->regs + A_ESPI_GOSTAT); | ||
73 | |||
74 | do { | ||
75 | busy = readl(adapter->regs + A_ESPI_GOSTAT) & F_ESPI_CMD_BUSY; | ||
76 | } while (busy && --attempts); | ||
77 | |||
78 | if (busy) | ||
79 | CH_ERR("%s: TRICN write timed out\n", adapter->name); | ||
80 | |||
81 | return busy; | ||
82 | } | ||
83 | |||
84 | /* 1. Deassert rx_reset_core. */ | ||
85 | /* 2. Program TRICN_CNFG registers. */ | ||
86 | /* 3. Deassert rx_reset_link */ | ||
87 | static int tricn_init(adapter_t *adapter) | ||
88 | { | ||
89 | int i = 0; | ||
90 | int sme = 1; | ||
91 | int stat = 0; | ||
92 | int timeout = 0; | ||
93 | int is_ready = 0; | ||
94 | int dynamic_deskew = 0; | ||
95 | |||
96 | if (dynamic_deskew) | ||
97 | sme = 0; | ||
98 | |||
99 | |||
100 | /* 1 */ | ||
101 | timeout=1000; | ||
102 | do { | ||
103 | stat = readl(adapter->regs + A_ESPI_RX_RESET); | ||
104 | is_ready = (stat & 0x4); | ||
105 | timeout--; | ||
106 | udelay(5); | ||
107 | } while (!is_ready || (timeout==0)); | ||
108 | writel(0x2, adapter->regs + A_ESPI_RX_RESET); | ||
109 | if (timeout==0) | ||
110 | { | ||
111 | CH_ERR("ESPI : ERROR : Timeout tricn_init() \n"); | ||
112 | t1_fatal_err(adapter); | ||
113 | } | ||
114 | |||
115 | /* 2 */ | ||
116 | if (sme) { | ||
117 | tricn_write(adapter, 0, 0, 0, TRICN_CNFG, 0x81); | ||
118 | tricn_write(adapter, 0, 1, 0, TRICN_CNFG, 0x81); | ||
119 | tricn_write(adapter, 0, 2, 0, TRICN_CNFG, 0x81); | ||
120 | } | ||
121 | for (i=1; i<= 8; i++) tricn_write(adapter, 0, 0, i, TRICN_CNFG, 0xf1); | ||
122 | for (i=1; i<= 2; i++) tricn_write(adapter, 0, 1, i, TRICN_CNFG, 0xf1); | ||
123 | for (i=1; i<= 3; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1); | ||
124 | for (i=4; i<= 4; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); | ||
125 | for (i=5; i<= 5; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xe1); | ||
126 | for (i=6; i<= 6; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); | ||
127 | for (i=7; i<= 7; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0x80); | ||
128 | for (i=8; i<= 8; i++) tricn_write(adapter, 0, 2, i, TRICN_CNFG, 0xf1); | ||
129 | |||
130 | /* 3 */ | ||
131 | writel(0x3, adapter->regs + A_ESPI_RX_RESET); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | void t1_espi_intr_enable(struct peespi *espi) | ||
137 | { | ||
138 | u32 enable, pl_intr = readl(espi->adapter->regs + A_PL_ENABLE); | ||
139 | |||
140 | /* | ||
141 | * Cannot enable ESPI interrupts on T1B because HW asserts the | ||
142 | * interrupt incorrectly, namely the driver gets ESPI interrupts | ||
143 | * but no data is actually dropped (can verify this reading the ESPI | ||
144 | * drop registers). Also, once the ESPI interrupt is asserted it | ||
145 | * cannot be cleared (HW bug). | ||
146 | */ | ||
147 | enable = t1_is_T1B(espi->adapter) ? 0 : ESPI_INTR_MASK; | ||
148 | writel(enable, espi->adapter->regs + A_ESPI_INTR_ENABLE); | ||
149 | writel(pl_intr | F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE); | ||
150 | } | ||
151 | |||
152 | void t1_espi_intr_clear(struct peespi *espi) | ||
153 | { | ||
154 | writel(0xffffffff, espi->adapter->regs + A_ESPI_INTR_STATUS); | ||
155 | writel(F_PL_INTR_ESPI, espi->adapter->regs + A_PL_CAUSE); | ||
156 | } | ||
157 | |||
158 | void t1_espi_intr_disable(struct peespi *espi) | ||
159 | { | ||
160 | u32 pl_intr = readl(espi->adapter->regs + A_PL_ENABLE); | ||
161 | |||
162 | writel(0, espi->adapter->regs + A_ESPI_INTR_ENABLE); | ||
163 | writel(pl_intr & ~F_PL_INTR_ESPI, espi->adapter->regs + A_PL_ENABLE); | ||
164 | } | ||
165 | |||
166 | int t1_espi_intr_handler(struct peespi *espi) | ||
167 | { | ||
168 | u32 cnt; | ||
169 | u32 status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS); | ||
170 | |||
171 | if (status & F_DIP4ERR) | ||
172 | espi->intr_cnt.DIP4_err++; | ||
173 | if (status & F_RXDROP) | ||
174 | espi->intr_cnt.rx_drops++; | ||
175 | if (status & F_TXDROP) | ||
176 | espi->intr_cnt.tx_drops++; | ||
177 | if (status & F_RXOVERFLOW) | ||
178 | espi->intr_cnt.rx_ovflw++; | ||
179 | if (status & F_RAMPARITYERR) | ||
180 | espi->intr_cnt.parity_err++; | ||
181 | if (status & F_DIP2PARITYERR) { | ||
182 | espi->intr_cnt.DIP2_parity_err++; | ||
183 | |||
184 | /* | ||
185 | * Must read the error count to clear the interrupt | ||
186 | * that it causes. | ||
187 | */ | ||
188 | cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT); | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * For T1B we need to write 1 to clear ESPI interrupts. For T2+ we | ||
193 | * write the status as is. | ||
194 | */ | ||
195 | if (status && t1_is_T1B(espi->adapter)) | ||
196 | status = 1; | ||
197 | writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi) | ||
202 | { | ||
203 | return &espi->intr_cnt; | ||
204 | } | ||
205 | |||
206 | static void espi_setup_for_pm3393(adapter_t *adapter) | ||
207 | { | ||
208 | u32 wmark = t1_is_T1B(adapter) ? 0x4000 : 0x3200; | ||
209 | |||
210 | writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN0); | ||
211 | writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN1); | ||
212 | writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN2); | ||
213 | writel(0x1f4, adapter->regs + A_ESPI_SCH_TOKEN3); | ||
214 | writel(0x100, adapter->regs + A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK); | ||
215 | writel(wmark, adapter->regs + A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK); | ||
216 | writel(3, adapter->regs + A_ESPI_CALENDAR_LENGTH); | ||
217 | writel(0x08000008, adapter->regs + A_ESPI_TRAIN); | ||
218 | writel(V_RX_NPORTS(1) | V_TX_NPORTS(1), adapter->regs + A_PORT_CONFIG); | ||
219 | } | ||
220 | |||
221 | /* T2 Init part -- */ | ||
222 | /* 1. Set T_ESPI_MISCCTRL_ADDR */ | ||
223 | /* 2. Init ESPI registers. */ | ||
224 | /* 3. Init TriCN Hard Macro */ | ||
225 | int t1_espi_init(struct peespi *espi, int mac_type, int nports) | ||
226 | { | ||
227 | u32 cnt; | ||
228 | |||
229 | u32 status_enable_extra = 0; | ||
230 | adapter_t *adapter = espi->adapter; | ||
231 | u32 status, burstval = 0x800100; | ||
232 | |||
233 | /* Disable ESPI training. MACs that can handle it enable it below. */ | ||
234 | writel(0, adapter->regs + A_ESPI_TRAIN); | ||
235 | |||
236 | if (is_T2(adapter)) { | ||
237 | writel(V_OUT_OF_SYNC_COUNT(4) | | ||
238 | V_DIP2_PARITY_ERR_THRES(3) | | ||
239 | V_DIP4_THRES(1), adapter->regs + A_ESPI_MISC_CONTROL); | ||
240 | if (nports == 4) { | ||
241 | /* T204: maxburst1 = 0x40, maxburst2 = 0x20 */ | ||
242 | burstval = 0x200040; | ||
243 | } | ||
244 | } | ||
245 | writel(burstval, adapter->regs + A_ESPI_MAXBURST1_MAXBURST2); | ||
246 | |||
247 | switch (mac_type) { | ||
248 | case CHBT_MAC_PM3393: | ||
249 | espi_setup_for_pm3393(adapter); | ||
250 | break; | ||
251 | default: | ||
252 | return -1; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * Make sure any pending interrupts from the SPI are | ||
257 | * Cleared before enabling the interrupt. | ||
258 | */ | ||
259 | writel(ESPI_INTR_MASK, espi->adapter->regs + A_ESPI_INTR_ENABLE); | ||
260 | status = readl(espi->adapter->regs + A_ESPI_INTR_STATUS); | ||
261 | if (status & F_DIP2PARITYERR) { | ||
262 | cnt = readl(espi->adapter->regs + A_ESPI_DIP2_ERR_COUNT); | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * For T1B we need to write 1 to clear ESPI interrupts. For T2+ we | ||
267 | * write the status as is. | ||
268 | */ | ||
269 | if (status && t1_is_T1B(espi->adapter)) | ||
270 | status = 1; | ||
271 | writel(status, espi->adapter->regs + A_ESPI_INTR_STATUS); | ||
272 | |||
273 | writel(status_enable_extra | F_RXSTATUSENABLE, | ||
274 | adapter->regs + A_ESPI_FIFO_STATUS_ENABLE); | ||
275 | |||
276 | if (is_T2(adapter)) { | ||
277 | tricn_init(adapter); | ||
278 | /* | ||
279 | * Always position the control at the 1st port egress IN | ||
280 | * (sop,eop) counter to reduce PIOs for T/N210 workaround. | ||
281 | */ | ||
282 | espi->misc_ctrl = (readl(adapter->regs + A_ESPI_MISC_CONTROL) | ||
283 | & ~MON_MASK) | (F_MONITORED_DIRECTION | ||
284 | | F_MONITORED_INTERFACE); | ||
285 | writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); | ||
286 | spin_lock_init(&espi->lock); | ||
287 | } | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | void t1_espi_destroy(struct peespi *espi) | ||
293 | { | ||
294 | kfree(espi); | ||
295 | } | ||
296 | |||
297 | struct peespi *t1_espi_create(adapter_t *adapter) | ||
298 | { | ||
299 | struct peespi *espi = kmalloc(sizeof(*espi), GFP_KERNEL); | ||
300 | |||
301 | memset(espi, 0, sizeof(*espi)); | ||
302 | |||
303 | if (espi) | ||
304 | espi->adapter = adapter; | ||
305 | return espi; | ||
306 | } | ||
307 | |||
308 | void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) | ||
309 | { | ||
310 | struct peespi *espi = adapter->espi; | ||
311 | |||
312 | if (!is_T2(adapter)) | ||
313 | return; | ||
314 | spin_lock(&espi->lock); | ||
315 | espi->misc_ctrl = (val & ~MON_MASK) | | ||
316 | (espi->misc_ctrl & MON_MASK); | ||
317 | writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); | ||
318 | spin_unlock(&espi->lock); | ||
319 | } | ||
320 | |||
321 | u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) | ||
322 | { | ||
323 | u32 sel; | ||
324 | |||
325 | struct peespi *espi = adapter->espi; | ||
326 | |||
327 | if (!is_T2(adapter)) | ||
328 | return 0; | ||
329 | sel = V_MONITORED_PORT_NUM((addr & 0x3c) >> 2); | ||
330 | if (!wait) { | ||
331 | if (!spin_trylock(&espi->lock)) | ||
332 | return 0; | ||
333 | } | ||
334 | else | ||
335 | spin_lock(&espi->lock); | ||
336 | if ((sel != (espi->misc_ctrl & MON_MASK))) { | ||
337 | writel(((espi->misc_ctrl & ~MON_MASK) | sel), | ||
338 | adapter->regs + A_ESPI_MISC_CONTROL); | ||
339 | sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3); | ||
340 | writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); | ||
341 | } | ||
342 | else | ||
343 | sel = readl(adapter->regs + A_ESPI_SCH_TOKEN3); | ||
344 | spin_unlock(&espi->lock); | ||
345 | return sel; | ||
346 | } | ||
diff --git a/drivers/net/chelsio/espi.h b/drivers/net/chelsio/espi.h new file mode 100644 index 000000000000..c90e37f8457c --- /dev/null +++ b/drivers/net/chelsio/espi.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: espi.h * | ||
4 | * $Revision: 1.7 $ * | ||
5 | * $Date: 2005/06/21 18:29:47 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_ESPI_H_ | ||
40 | #define _CXGB_ESPI_H_ | ||
41 | |||
42 | #include "common.h" | ||
43 | |||
44 | struct espi_intr_counts { | ||
45 | unsigned int DIP4_err; | ||
46 | unsigned int rx_drops; | ||
47 | unsigned int tx_drops; | ||
48 | unsigned int rx_ovflw; | ||
49 | unsigned int parity_err; | ||
50 | unsigned int DIP2_parity_err; | ||
51 | }; | ||
52 | |||
53 | struct peespi; | ||
54 | |||
55 | struct peespi *t1_espi_create(adapter_t *adapter); | ||
56 | void t1_espi_destroy(struct peespi *espi); | ||
57 | int t1_espi_init(struct peespi *espi, int mac_type, int nports); | ||
58 | |||
59 | void t1_espi_intr_enable(struct peespi *); | ||
60 | void t1_espi_intr_clear(struct peespi *); | ||
61 | void t1_espi_intr_disable(struct peespi *); | ||
62 | int t1_espi_intr_handler(struct peespi *); | ||
63 | const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi); | ||
64 | |||
65 | void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val); | ||
66 | u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait); | ||
67 | |||
68 | #endif /* _CXGB_ESPI_H_ */ | ||
diff --git a/drivers/net/chelsio/gmac.h b/drivers/net/chelsio/gmac.h new file mode 100644 index 000000000000..746b0eeea964 --- /dev/null +++ b/drivers/net/chelsio/gmac.h | |||
@@ -0,0 +1,134 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: gmac.h * | ||
4 | * $Revision: 1.6 $ * | ||
5 | * $Date: 2005/06/21 18:29:47 $ * | ||
6 | * Description: * | ||
7 | * Generic MAC functionality. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
25 | * All rights reserved. * | ||
26 | * * | ||
27 | * Maintainers: maintainers@chelsio.com * | ||
28 | * * | ||
29 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
30 | * Tina Yang <tainay@chelsio.com> * | ||
31 | * Felix Marti <felix@chelsio.com> * | ||
32 | * Scott Bardone <sbardone@chelsio.com> * | ||
33 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
34 | * Frank DiMambro <frank@chelsio.com> * | ||
35 | * * | ||
36 | * History: * | ||
37 | * * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #ifndef _CXGB_GMAC_H_ | ||
41 | #define _CXGB_GMAC_H_ | ||
42 | |||
43 | #include "common.h" | ||
44 | |||
45 | enum { MAC_STATS_UPDATE_FAST, MAC_STATS_UPDATE_FULL }; | ||
46 | enum { MAC_DIRECTION_RX = 1, MAC_DIRECTION_TX = 2 }; | ||
47 | |||
48 | struct cmac_statistics { | ||
49 | /* Transmit */ | ||
50 | u64 TxOctetsOK; | ||
51 | u64 TxOctetsBad; | ||
52 | u64 TxUnicastFramesOK; | ||
53 | u64 TxMulticastFramesOK; | ||
54 | u64 TxBroadcastFramesOK; | ||
55 | u64 TxPauseFrames; | ||
56 | u64 TxFramesWithDeferredXmissions; | ||
57 | u64 TxLateCollisions; | ||
58 | u64 TxTotalCollisions; | ||
59 | u64 TxFramesAbortedDueToXSCollisions; | ||
60 | u64 TxUnderrun; | ||
61 | u64 TxLengthErrors; | ||
62 | u64 TxInternalMACXmitError; | ||
63 | u64 TxFramesWithExcessiveDeferral; | ||
64 | u64 TxFCSErrors; | ||
65 | |||
66 | /* Receive */ | ||
67 | u64 RxOctetsOK; | ||
68 | u64 RxOctetsBad; | ||
69 | u64 RxUnicastFramesOK; | ||
70 | u64 RxMulticastFramesOK; | ||
71 | u64 RxBroadcastFramesOK; | ||
72 | u64 RxPauseFrames; | ||
73 | u64 RxFCSErrors; | ||
74 | u64 RxAlignErrors; | ||
75 | u64 RxSymbolErrors; | ||
76 | u64 RxDataErrors; | ||
77 | u64 RxSequenceErrors; | ||
78 | u64 RxRuntErrors; | ||
79 | u64 RxJabberErrors; | ||
80 | u64 RxInternalMACRcvError; | ||
81 | u64 RxInRangeLengthErrors; | ||
82 | u64 RxOutOfRangeLengthField; | ||
83 | u64 RxFrameTooLongErrors; | ||
84 | }; | ||
85 | |||
86 | struct cmac_ops { | ||
87 | void (*destroy)(struct cmac *); | ||
88 | int (*reset)(struct cmac *); | ||
89 | int (*interrupt_enable)(struct cmac *); | ||
90 | int (*interrupt_disable)(struct cmac *); | ||
91 | int (*interrupt_clear)(struct cmac *); | ||
92 | int (*interrupt_handler)(struct cmac *); | ||
93 | |||
94 | int (*enable)(struct cmac *, int); | ||
95 | int (*disable)(struct cmac *, int); | ||
96 | |||
97 | int (*loopback_enable)(struct cmac *); | ||
98 | int (*loopback_disable)(struct cmac *); | ||
99 | |||
100 | int (*set_mtu)(struct cmac *, int mtu); | ||
101 | int (*set_rx_mode)(struct cmac *, struct t1_rx_mode *rm); | ||
102 | |||
103 | int (*set_speed_duplex_fc)(struct cmac *, int speed, int duplex, int fc); | ||
104 | int (*get_speed_duplex_fc)(struct cmac *, int *speed, int *duplex, | ||
105 | int *fc); | ||
106 | |||
107 | const struct cmac_statistics *(*statistics_update)(struct cmac *, int); | ||
108 | |||
109 | int (*macaddress_get)(struct cmac *, u8 mac_addr[6]); | ||
110 | int (*macaddress_set)(struct cmac *, u8 mac_addr[6]); | ||
111 | }; | ||
112 | |||
113 | typedef struct _cmac_instance cmac_instance; | ||
114 | |||
115 | struct cmac { | ||
116 | struct cmac_statistics stats; | ||
117 | adapter_t *adapter; | ||
118 | struct cmac_ops *ops; | ||
119 | cmac_instance *instance; | ||
120 | }; | ||
121 | |||
122 | struct gmac { | ||
123 | unsigned int stats_update_period; | ||
124 | struct cmac *(*create)(adapter_t *adapter, int index); | ||
125 | int (*reset)(adapter_t *); | ||
126 | }; | ||
127 | |||
128 | extern struct gmac t1_pm3393_ops; | ||
129 | extern struct gmac t1_chelsio_mac_ops; | ||
130 | extern struct gmac t1_vsc7321_ops; | ||
131 | extern struct gmac t1_ixf1010_ops; | ||
132 | extern struct gmac t1_dummy_mac_ops; | ||
133 | |||
134 | #endif /* _CXGB_GMAC_H_ */ | ||
diff --git a/drivers/net/chelsio/mv88x201x.c b/drivers/net/chelsio/mv88x201x.c new file mode 100644 index 000000000000..db5034282782 --- /dev/null +++ b/drivers/net/chelsio/mv88x201x.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: mv88x201x.c * | ||
4 | * $Revision: 1.12 $ * | ||
5 | * $Date: 2005/04/15 19:27:14 $ * | ||
6 | * Description: * | ||
7 | * Marvell PHY (mv88x201x) functionality. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
25 | * All rights reserved. * | ||
26 | * * | ||
27 | * Maintainers: maintainers@chelsio.com * | ||
28 | * * | ||
29 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
30 | * Tina Yang <tainay@chelsio.com> * | ||
31 | * Felix Marti <felix@chelsio.com> * | ||
32 | * Scott Bardone <sbardone@chelsio.com> * | ||
33 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
34 | * Frank DiMambro <frank@chelsio.com> * | ||
35 | * * | ||
36 | * History: * | ||
37 | * * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include "cphy.h" | ||
41 | #include "elmer0.h" | ||
42 | |||
43 | /* | ||
44 | * The 88x2010 Rev C. requires some link status registers * to be read | ||
45 | * twice in order to get the right values. Future * revisions will fix | ||
46 | * this problem and then this macro * can disappear. | ||
47 | */ | ||
48 | #define MV88x2010_LINK_STATUS_BUGS 1 | ||
49 | |||
50 | static int led_init(struct cphy *cphy) | ||
51 | { | ||
52 | /* Setup the LED registers so we can turn on/off. | ||
53 | * Writing these bits maps control to another | ||
54 | * register. mmd(0x1) addr(0x7) | ||
55 | */ | ||
56 | mdio_write(cphy, 0x3, 0x8304, 0xdddd); | ||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static int led_link(struct cphy *cphy, u32 do_enable) | ||
61 | { | ||
62 | u32 led = 0; | ||
63 | #define LINK_ENABLE_BIT 0x1 | ||
64 | |||
65 | mdio_read(cphy, 0x1, 0x7, &led); | ||
66 | |||
67 | if (do_enable & LINK_ENABLE_BIT) { | ||
68 | led |= LINK_ENABLE_BIT; | ||
69 | mdio_write(cphy, 0x1, 0x7, led); | ||
70 | } else { | ||
71 | led &= ~LINK_ENABLE_BIT; | ||
72 | mdio_write(cphy, 0x1, 0x7, led); | ||
73 | } | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | /* Port Reset */ | ||
78 | static int mv88x201x_reset(struct cphy *cphy, int wait) | ||
79 | { | ||
80 | /* This can be done through registers. It is not required since | ||
81 | * a full chip reset is used. | ||
82 | */ | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static int mv88x201x_interrupt_enable(struct cphy *cphy) | ||
87 | { | ||
88 | u32 elmer; | ||
89 | |||
90 | /* Enable PHY LASI interrupts. */ | ||
91 | mdio_write(cphy, 0x1, 0x9002, 0x1); | ||
92 | |||
93 | /* Enable Marvell interrupts through Elmer0. */ | ||
94 | t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); | ||
95 | elmer |= ELMER0_GP_BIT6; | ||
96 | t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int mv88x201x_interrupt_disable(struct cphy *cphy) | ||
101 | { | ||
102 | u32 elmer; | ||
103 | |||
104 | /* Disable PHY LASI interrupts. */ | ||
105 | mdio_write(cphy, 0x1, 0x9002, 0x0); | ||
106 | |||
107 | /* Disable Marvell interrupts through Elmer0. */ | ||
108 | t1_tpi_read(cphy->adapter, A_ELMER0_INT_ENABLE, &elmer); | ||
109 | elmer &= ~ELMER0_GP_BIT6; | ||
110 | t1_tpi_write(cphy->adapter, A_ELMER0_INT_ENABLE, elmer); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int mv88x201x_interrupt_clear(struct cphy *cphy) | ||
115 | { | ||
116 | u32 elmer; | ||
117 | u32 val; | ||
118 | |||
119 | #ifdef MV88x2010_LINK_STATUS_BUGS | ||
120 | /* Required to read twice before clear takes affect. */ | ||
121 | mdio_read(cphy, 0x1, 0x9003, &val); | ||
122 | mdio_read(cphy, 0x1, 0x9004, &val); | ||
123 | mdio_read(cphy, 0x1, 0x9005, &val); | ||
124 | |||
125 | /* Read this register after the others above it else | ||
126 | * the register doesn't clear correctly. | ||
127 | */ | ||
128 | mdio_read(cphy, 0x1, 0x1, &val); | ||
129 | #endif | ||
130 | |||
131 | /* Clear link status. */ | ||
132 | mdio_read(cphy, 0x1, 0x1, &val); | ||
133 | /* Clear PHY LASI interrupts. */ | ||
134 | mdio_read(cphy, 0x1, 0x9005, &val); | ||
135 | |||
136 | #ifdef MV88x2010_LINK_STATUS_BUGS | ||
137 | /* Do it again. */ | ||
138 | mdio_read(cphy, 0x1, 0x9003, &val); | ||
139 | mdio_read(cphy, 0x1, 0x9004, &val); | ||
140 | #endif | ||
141 | |||
142 | /* Clear Marvell interrupts through Elmer0. */ | ||
143 | t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer); | ||
144 | elmer |= ELMER0_GP_BIT6; | ||
145 | t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int mv88x201x_interrupt_handler(struct cphy *cphy) | ||
150 | { | ||
151 | /* Clear interrupts */ | ||
152 | mv88x201x_interrupt_clear(cphy); | ||
153 | |||
154 | /* We have only enabled link change interrupts and so | ||
155 | * cphy_cause must be a link change interrupt. | ||
156 | */ | ||
157 | return cphy_cause_link_change; | ||
158 | } | ||
159 | |||
160 | static int mv88x201x_set_loopback(struct cphy *cphy, int on) | ||
161 | { | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok, | ||
166 | int *speed, int *duplex, int *fc) | ||
167 | { | ||
168 | u32 val = 0; | ||
169 | #define LINK_STATUS_BIT 0x4 | ||
170 | |||
171 | if (link_ok) { | ||
172 | /* Read link status. */ | ||
173 | mdio_read(cphy, 0x1, 0x1, &val); | ||
174 | val &= LINK_STATUS_BIT; | ||
175 | *link_ok = (val == LINK_STATUS_BIT); | ||
176 | /* Turn on/off Link LED */ | ||
177 | led_link(cphy, *link_ok); | ||
178 | } | ||
179 | if (speed) | ||
180 | *speed = SPEED_10000; | ||
181 | if (duplex) | ||
182 | *duplex = DUPLEX_FULL; | ||
183 | if (fc) | ||
184 | *fc = PAUSE_RX | PAUSE_TX; | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static void mv88x201x_destroy(struct cphy *cphy) | ||
189 | { | ||
190 | kfree(cphy); | ||
191 | } | ||
192 | |||
193 | static struct cphy_ops mv88x201x_ops = { | ||
194 | .destroy = mv88x201x_destroy, | ||
195 | .reset = mv88x201x_reset, | ||
196 | .interrupt_enable = mv88x201x_interrupt_enable, | ||
197 | .interrupt_disable = mv88x201x_interrupt_disable, | ||
198 | .interrupt_clear = mv88x201x_interrupt_clear, | ||
199 | .interrupt_handler = mv88x201x_interrupt_handler, | ||
200 | .get_link_status = mv88x201x_get_link_status, | ||
201 | .set_loopback = mv88x201x_set_loopback, | ||
202 | }; | ||
203 | |||
204 | static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr, | ||
205 | struct mdio_ops *mdio_ops) | ||
206 | { | ||
207 | u32 val; | ||
208 | struct cphy *cphy = kmalloc(sizeof(*cphy), GFP_KERNEL); | ||
209 | |||
210 | if (!cphy) | ||
211 | return NULL; | ||
212 | memset(cphy, 0, sizeof(*cphy)); | ||
213 | cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops); | ||
214 | |||
215 | /* Commands the PHY to enable XFP's clock. */ | ||
216 | mdio_read(cphy, 0x3, 0x8300, &val); | ||
217 | mdio_write(cphy, 0x3, 0x8300, val | 1); | ||
218 | |||
219 | /* Clear link status. Required because of a bug in the PHY. */ | ||
220 | mdio_read(cphy, 0x1, 0x8, &val); | ||
221 | mdio_read(cphy, 0x3, 0x8, &val); | ||
222 | |||
223 | /* Allows for Link,Ack LED turn on/off */ | ||
224 | led_init(cphy); | ||
225 | return cphy; | ||
226 | } | ||
227 | |||
228 | /* Chip Reset */ | ||
229 | static int mv88x201x_phy_reset(adapter_t *adapter) | ||
230 | { | ||
231 | u32 val; | ||
232 | |||
233 | t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
234 | val &= ~4; | ||
235 | t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
236 | msleep(100); | ||
237 | |||
238 | t1_tpi_write(adapter, A_ELMER0_GPO, val | 4); | ||
239 | msleep(1000); | ||
240 | |||
241 | /* Now lets enable the Laser. Delay 100us */ | ||
242 | t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
243 | val |= 0x8000; | ||
244 | t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
245 | udelay(100); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | struct gphy t1_mv88x201x_ops = { | ||
250 | mv88x201x_phy_create, | ||
251 | mv88x201x_phy_reset | ||
252 | }; | ||
diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c new file mode 100644 index 000000000000..04a1404fc65e --- /dev/null +++ b/drivers/net/chelsio/pm3393.c | |||
@@ -0,0 +1,826 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: pm3393.c * | ||
4 | * $Revision: 1.16 $ * | ||
5 | * $Date: 2005/05/14 00:59:32 $ * | ||
6 | * Description: * | ||
7 | * PMC/SIERRA (pm3393) MAC-PHY functionality. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
25 | * All rights reserved. * | ||
26 | * * | ||
27 | * Maintainers: maintainers@chelsio.com * | ||
28 | * * | ||
29 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
30 | * Tina Yang <tainay@chelsio.com> * | ||
31 | * Felix Marti <felix@chelsio.com> * | ||
32 | * Scott Bardone <sbardone@chelsio.com> * | ||
33 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
34 | * Frank DiMambro <frank@chelsio.com> * | ||
35 | * * | ||
36 | * History: * | ||
37 | * * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include "common.h" | ||
41 | #include "regs.h" | ||
42 | #include "gmac.h" | ||
43 | #include "elmer0.h" | ||
44 | #include "suni1x10gexp_regs.h" | ||
45 | |||
46 | /* 802.3ae 10Gb/s MDIO Manageable Device(MMD) | ||
47 | */ | ||
48 | enum { | ||
49 | MMD_RESERVED, | ||
50 | MMD_PMAPMD, | ||
51 | MMD_WIS, | ||
52 | MMD_PCS, | ||
53 | MMD_PHY_XGXS, /* XGMII Extender Sublayer */ | ||
54 | MMD_DTE_XGXS, | ||
55 | }; | ||
56 | |||
57 | enum { | ||
58 | PHY_XGXS_CTRL_1, | ||
59 | PHY_XGXS_STATUS_1 | ||
60 | }; | ||
61 | |||
62 | #define OFFSET(REG_ADDR) (REG_ADDR << 2) | ||
63 | |||
64 | /* Max frame size PM3393 can handle. Includes Ethernet header and CRC. */ | ||
65 | #define MAX_FRAME_SIZE 9600 | ||
66 | |||
67 | #define IPG 12 | ||
68 | #define TXXG_CONF1_VAL ((IPG << SUNI1x10GEXP_BITOFF_TXXG_IPGT) | \ | ||
69 | SUNI1x10GEXP_BITMSK_TXXG_32BIT_ALIGN | SUNI1x10GEXP_BITMSK_TXXG_CRCEN | \ | ||
70 | SUNI1x10GEXP_BITMSK_TXXG_PADEN) | ||
71 | #define RXXG_CONF1_VAL (SUNI1x10GEXP_BITMSK_RXXG_PUREP | 0x14 | \ | ||
72 | SUNI1x10GEXP_BITMSK_RXXG_FLCHK | SUNI1x10GEXP_BITMSK_RXXG_CRC_STRIP) | ||
73 | |||
74 | /* Update statistics every 15 minutes */ | ||
75 | #define STATS_TICK_SECS (15 * 60) | ||
76 | |||
77 | enum { /* RMON registers */ | ||
78 | RxOctetsReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW, | ||
79 | RxUnicastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_4_LOW, | ||
80 | RxMulticastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_5_LOW, | ||
81 | RxBroadcastFramesReceivedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_6_LOW, | ||
82 | RxPAUSEMACCtrlFramesReceived = SUNI1x10GEXP_REG_MSTAT_COUNTER_8_LOW, | ||
83 | RxFrameCheckSequenceErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_10_LOW, | ||
84 | RxFramesLostDueToInternalMACErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_11_LOW, | ||
85 | RxSymbolErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_12_LOW, | ||
86 | RxInRangeLengthErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_13_LOW, | ||
87 | RxFramesTooLongErrors = SUNI1x10GEXP_REG_MSTAT_COUNTER_15_LOW, | ||
88 | RxJabbers = SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW, | ||
89 | RxFragments = SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW, | ||
90 | RxUndersizedFrames = SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW, | ||
91 | |||
92 | TxOctetsTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW, | ||
93 | TxFramesLostDueToInternalMACTransmissionError = SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW, | ||
94 | TxTransmitSystemError = SUNI1x10GEXP_REG_MSTAT_COUNTER_36_LOW, | ||
95 | TxUnicastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW, | ||
96 | TxMulticastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW, | ||
97 | TxBroadcastFramesTransmittedOK = SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW, | ||
98 | TxPAUSEMACCtrlFramesTransmitted = SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW | ||
99 | }; | ||
100 | |||
101 | struct _cmac_instance { | ||
102 | u8 enabled; | ||
103 | u8 fc; | ||
104 | u8 mac_addr[6]; | ||
105 | }; | ||
106 | |||
107 | static int pmread(struct cmac *cmac, u32 reg, u32 * data32) | ||
108 | { | ||
109 | t1_tpi_read(cmac->adapter, OFFSET(reg), data32); | ||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int pmwrite(struct cmac *cmac, u32 reg, u32 data32) | ||
114 | { | ||
115 | t1_tpi_write(cmac->adapter, OFFSET(reg), data32); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | /* Port reset. */ | ||
120 | static int pm3393_reset(struct cmac *cmac) | ||
121 | { | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Enable interrupts for the PM3393 | ||
127 | |||
128 | 1. Enable PM3393 BLOCK interrupts. | ||
129 | 2. Enable PM3393 Master Interrupt bit(INTE) | ||
130 | 3. Enable ELMER's PM3393 bit. | ||
131 | 4. Enable Terminator external interrupt. | ||
132 | */ | ||
133 | static int pm3393_interrupt_enable(struct cmac *cmac) | ||
134 | { | ||
135 | u32 pl_intr; | ||
136 | |||
137 | /* PM3393 - Enabling all hardware block interrupts. | ||
138 | */ | ||
139 | pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0xffff); | ||
140 | pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0xffff); | ||
141 | pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0xffff); | ||
142 | pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0xffff); | ||
143 | |||
144 | /* Don't interrupt on statistics overflow, we are polling */ | ||
145 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0); | ||
146 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0); | ||
147 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0); | ||
148 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0); | ||
149 | |||
150 | pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0xffff); | ||
151 | pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0xffff); | ||
152 | pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0xffff); | ||
153 | pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0xffff); | ||
154 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0xffff); | ||
155 | pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0xffff); | ||
156 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0xffff); | ||
157 | pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0xffff); | ||
158 | pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0xffff); | ||
159 | |||
160 | /* PM3393 - Global interrupt enable | ||
161 | */ | ||
162 | /* TBD XXX Disable for now until we figure out why error interrupts keep asserting. */ | ||
163 | pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE, | ||
164 | 0 /*SUNI1x10GEXP_BITMSK_TOP_INTE */ ); | ||
165 | |||
166 | /* TERMINATOR - PL_INTERUPTS_EXT */ | ||
167 | pl_intr = readl(cmac->adapter->regs + A_PL_ENABLE); | ||
168 | pl_intr |= F_PL_INTR_EXT; | ||
169 | writel(pl_intr, cmac->adapter->regs + A_PL_ENABLE); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int pm3393_interrupt_disable(struct cmac *cmac) | ||
174 | { | ||
175 | u32 elmer; | ||
176 | |||
177 | /* PM3393 - Enabling HW interrupt blocks. */ | ||
178 | pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0); | ||
179 | pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0); | ||
180 | pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0); | ||
181 | pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0); | ||
182 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0); | ||
183 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0); | ||
184 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0); | ||
185 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0); | ||
186 | pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0); | ||
187 | pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0); | ||
188 | pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0); | ||
189 | pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0); | ||
190 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0); | ||
191 | pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0); | ||
192 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0); | ||
193 | pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0); | ||
194 | pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0); | ||
195 | |||
196 | /* PM3393 - Global interrupt enable */ | ||
197 | pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE, 0); | ||
198 | |||
199 | /* ELMER - External chip interrupts. */ | ||
200 | t1_tpi_read(cmac->adapter, A_ELMER0_INT_ENABLE, &elmer); | ||
201 | elmer &= ~ELMER0_GP_BIT1; | ||
202 | t1_tpi_write(cmac->adapter, A_ELMER0_INT_ENABLE, elmer); | ||
203 | |||
204 | /* TERMINATOR - PL_INTERUPTS_EXT */ | ||
205 | /* DO NOT DISABLE TERMINATOR's EXTERNAL INTERRUPTS. ANOTHER CHIP | ||
206 | * COULD WANT THEM ENABLED. We disable PM3393 at the ELMER level. | ||
207 | */ | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | static int pm3393_interrupt_clear(struct cmac *cmac) | ||
213 | { | ||
214 | u32 elmer; | ||
215 | u32 pl_intr; | ||
216 | u32 val32; | ||
217 | |||
218 | /* PM3393 - Clearing HW interrupt blocks. Note, this assumes | ||
219 | * bit WCIMODE=0 for a clear-on-read. | ||
220 | */ | ||
221 | pmread(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS, &val32); | ||
222 | pmread(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS, &val32); | ||
223 | pmread(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS, &val32); | ||
224 | pmread(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS, &val32); | ||
225 | pmread(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT, &val32); | ||
226 | pmread(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS, &val32); | ||
227 | pmread(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT, &val32); | ||
228 | pmread(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS, &val32); | ||
229 | pmread(cmac, SUNI1x10GEXP_REG_RXXG_INTERRUPT, &val32); | ||
230 | pmread(cmac, SUNI1x10GEXP_REG_TXXG_INTERRUPT, &val32); | ||
231 | pmread(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT, &val32); | ||
232 | pmread(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION, | ||
233 | &val32); | ||
234 | pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS, &val32); | ||
235 | pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE, &val32); | ||
236 | |||
237 | /* PM3393 - Global interrupt status | ||
238 | */ | ||
239 | pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, &val32); | ||
240 | |||
241 | /* ELMER - External chip interrupts. | ||
242 | */ | ||
243 | t1_tpi_read(cmac->adapter, A_ELMER0_INT_CAUSE, &elmer); | ||
244 | elmer |= ELMER0_GP_BIT1; | ||
245 | t1_tpi_write(cmac->adapter, A_ELMER0_INT_CAUSE, elmer); | ||
246 | |||
247 | /* TERMINATOR - PL_INTERUPTS_EXT | ||
248 | */ | ||
249 | pl_intr = readl(cmac->adapter->regs + A_PL_CAUSE); | ||
250 | pl_intr |= F_PL_INTR_EXT; | ||
251 | writel(pl_intr, cmac->adapter->regs + A_PL_CAUSE); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | /* Interrupt handler */ | ||
257 | static int pm3393_interrupt_handler(struct cmac *cmac) | ||
258 | { | ||
259 | u32 master_intr_status; | ||
260 | /* | ||
261 | 1. Read master interrupt register. | ||
262 | 2. Read BLOCK's interrupt status registers. | ||
263 | 3. Handle BLOCK interrupts. | ||
264 | */ | ||
265 | /* Read the master interrupt status register. */ | ||
266 | pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, | ||
267 | &master_intr_status); | ||
268 | |||
269 | /* TBD XXX Lets just clear everything for now */ | ||
270 | pm3393_interrupt_clear(cmac); | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int pm3393_enable(struct cmac *cmac, int which) | ||
276 | { | ||
277 | if (which & MAC_DIRECTION_RX) | ||
278 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1, | ||
279 | (RXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_RXXG_RXEN)); | ||
280 | |||
281 | if (which & MAC_DIRECTION_TX) { | ||
282 | u32 val = TXXG_CONF1_VAL | SUNI1x10GEXP_BITMSK_TXXG_TXEN0; | ||
283 | |||
284 | if (cmac->instance->fc & PAUSE_RX) | ||
285 | val |= SUNI1x10GEXP_BITMSK_TXXG_FCRX; | ||
286 | if (cmac->instance->fc & PAUSE_TX) | ||
287 | val |= SUNI1x10GEXP_BITMSK_TXXG_FCTX; | ||
288 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, val); | ||
289 | } | ||
290 | |||
291 | cmac->instance->enabled |= which; | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int pm3393_enable_port(struct cmac *cmac, int which) | ||
296 | { | ||
297 | /* Clear port statistics */ | ||
298 | pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_CONTROL, | ||
299 | SUNI1x10GEXP_BITMSK_MSTAT_CLEAR); | ||
300 | udelay(2); | ||
301 | memset(&cmac->stats, 0, sizeof(struct cmac_statistics)); | ||
302 | |||
303 | pm3393_enable(cmac, which); | ||
304 | |||
305 | /* | ||
306 | * XXX This should be done by the PHY and preferrably not at all. | ||
307 | * The PHY doesn't give us link status indication on its own so have | ||
308 | * the link management code query it instead. | ||
309 | */ | ||
310 | { | ||
311 | extern void link_changed(adapter_t *adapter, int port_id); | ||
312 | |||
313 | link_changed(cmac->adapter, 0); | ||
314 | } | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int pm3393_disable(struct cmac *cmac, int which) | ||
319 | { | ||
320 | if (which & MAC_DIRECTION_RX) | ||
321 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_1, RXXG_CONF1_VAL); | ||
322 | if (which & MAC_DIRECTION_TX) | ||
323 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_1, TXXG_CONF1_VAL); | ||
324 | |||
325 | /* | ||
326 | * The disable is graceful. Give the PM3393 time. Can't wait very | ||
327 | * long here, we may be holding locks. | ||
328 | */ | ||
329 | udelay(20); | ||
330 | |||
331 | cmac->instance->enabled &= ~which; | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int pm3393_loopback_enable(struct cmac *cmac) | ||
336 | { | ||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static int pm3393_loopback_disable(struct cmac *cmac) | ||
341 | { | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int pm3393_set_mtu(struct cmac *cmac, int mtu) | ||
346 | { | ||
347 | int enabled = cmac->instance->enabled; | ||
348 | |||
349 | /* MAX_FRAME_SIZE includes header + FCS, mtu doesn't */ | ||
350 | mtu += 14 + 4; | ||
351 | if (mtu > MAX_FRAME_SIZE) | ||
352 | return -EINVAL; | ||
353 | |||
354 | /* Disable Rx/Tx MAC before configuring it. */ | ||
355 | if (enabled) | ||
356 | pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); | ||
357 | |||
358 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MAX_FRAME_LENGTH, mtu); | ||
359 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_MAX_FRAME_SIZE, mtu); | ||
360 | |||
361 | if (enabled) | ||
362 | pm3393_enable(cmac, enabled); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static u32 calc_crc(u8 *b, int len) | ||
367 | { | ||
368 | int i; | ||
369 | u32 crc = (u32)~0; | ||
370 | |||
371 | /* calculate crc one bit at a time */ | ||
372 | while (len--) { | ||
373 | crc ^= *b++; | ||
374 | for (i = 0; i < 8; i++) { | ||
375 | if (crc & 0x1) | ||
376 | crc = (crc >> 1) ^ 0xedb88320; | ||
377 | else | ||
378 | crc = (crc >> 1); | ||
379 | } | ||
380 | } | ||
381 | |||
382 | /* reverse bits */ | ||
383 | crc = ((crc >> 4) & 0x0f0f0f0f) | ((crc << 4) & 0xf0f0f0f0); | ||
384 | crc = ((crc >> 2) & 0x33333333) | ((crc << 2) & 0xcccccccc); | ||
385 | crc = ((crc >> 1) & 0x55555555) | ((crc << 1) & 0xaaaaaaaa); | ||
386 | /* swap bytes */ | ||
387 | crc = (crc >> 16) | (crc << 16); | ||
388 | crc = (crc >> 8 & 0x00ff00ff) | (crc << 8 & 0xff00ff00); | ||
389 | |||
390 | return crc; | ||
391 | } | ||
392 | |||
393 | static int pm3393_set_rx_mode(struct cmac *cmac, struct t1_rx_mode *rm) | ||
394 | { | ||
395 | int enabled = cmac->instance->enabled & MAC_DIRECTION_RX; | ||
396 | u32 rx_mode; | ||
397 | |||
398 | /* Disable MAC RX before reconfiguring it */ | ||
399 | if (enabled) | ||
400 | pm3393_disable(cmac, MAC_DIRECTION_RX); | ||
401 | |||
402 | pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, &rx_mode); | ||
403 | rx_mode &= ~(SUNI1x10GEXP_BITMSK_RXXG_PMODE | | ||
404 | SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN); | ||
405 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, | ||
406 | (u16)rx_mode); | ||
407 | |||
408 | if (t1_rx_mode_promisc(rm)) { | ||
409 | /* Promiscuous mode. */ | ||
410 | rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_PMODE; | ||
411 | } | ||
412 | if (t1_rx_mode_allmulti(rm)) { | ||
413 | /* Accept all multicast. */ | ||
414 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, 0xffff); | ||
415 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, 0xffff); | ||
416 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, 0xffff); | ||
417 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, 0xffff); | ||
418 | rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN; | ||
419 | } else if (t1_rx_mode_mc_cnt(rm)) { | ||
420 | /* Accept one or more multicast(s). */ | ||
421 | u8 *addr; | ||
422 | int bit; | ||
423 | u16 mc_filter[4] = { 0, }; | ||
424 | |||
425 | while ((addr = t1_get_next_mcaddr(rm))) { | ||
426 | bit = (calc_crc(addr, ETH_ALEN) >> 23) & 0x3f; /* bit[23:28] */ | ||
427 | mc_filter[bit >> 4] |= 1 << (bit & 0xf); | ||
428 | } | ||
429 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, mc_filter[0]); | ||
430 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, mc_filter[1]); | ||
431 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, mc_filter[2]); | ||
432 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, mc_filter[3]); | ||
433 | rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN; | ||
434 | } | ||
435 | |||
436 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, (u16)rx_mode); | ||
437 | |||
438 | if (enabled) | ||
439 | pm3393_enable(cmac, MAC_DIRECTION_RX); | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static int pm3393_get_speed_duplex_fc(struct cmac *cmac, int *speed, | ||
445 | int *duplex, int *fc) | ||
446 | { | ||
447 | if (speed) | ||
448 | *speed = SPEED_10000; | ||
449 | if (duplex) | ||
450 | *duplex = DUPLEX_FULL; | ||
451 | if (fc) | ||
452 | *fc = cmac->instance->fc; | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static int pm3393_set_speed_duplex_fc(struct cmac *cmac, int speed, int duplex, | ||
457 | int fc) | ||
458 | { | ||
459 | if (speed >= 0 && speed != SPEED_10000) | ||
460 | return -1; | ||
461 | if (duplex >= 0 && duplex != DUPLEX_FULL) | ||
462 | return -1; | ||
463 | if (fc & ~(PAUSE_TX | PAUSE_RX)) | ||
464 | return -1; | ||
465 | |||
466 | if (fc != cmac->instance->fc) { | ||
467 | cmac->instance->fc = (u8) fc; | ||
468 | if (cmac->instance->enabled & MAC_DIRECTION_TX) | ||
469 | pm3393_enable(cmac, MAC_DIRECTION_TX); | ||
470 | } | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | #define RMON_UPDATE(mac, name, stat_name) \ | ||
475 | { \ | ||
476 | t1_tpi_read((mac)->adapter, OFFSET(name), &val0); \ | ||
477 | t1_tpi_read((mac)->adapter, OFFSET(((name)+1)), &val1); \ | ||
478 | t1_tpi_read((mac)->adapter, OFFSET(((name)+2)), &val2); \ | ||
479 | (mac)->stats.stat_name = ((u64)val0 & 0xffff) | \ | ||
480 | (((u64)val1 & 0xffff) << 16) | \ | ||
481 | (((u64)val2 & 0xff) << 32) | \ | ||
482 | ((mac)->stats.stat_name & \ | ||
483 | (~(u64)0 << 40)); \ | ||
484 | if (ro & \ | ||
485 | ((name - SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW) >> 2)) \ | ||
486 | (mac)->stats.stat_name += ((u64)1 << 40); \ | ||
487 | } | ||
488 | |||
489 | static const struct cmac_statistics *pm3393_update_statistics(struct cmac *mac, | ||
490 | int flag) | ||
491 | { | ||
492 | u64 ro; | ||
493 | u32 val0, val1, val2, val3; | ||
494 | |||
495 | /* Snap the counters */ | ||
496 | pmwrite(mac, SUNI1x10GEXP_REG_MSTAT_CONTROL, | ||
497 | SUNI1x10GEXP_BITMSK_MSTAT_SNAP); | ||
498 | |||
499 | /* Counter rollover, clear on read */ | ||
500 | pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_0, &val0); | ||
501 | pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_1, &val1); | ||
502 | pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_2, &val2); | ||
503 | pmread(mac, SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_3, &val3); | ||
504 | ro = ((u64)val0 & 0xffff) | (((u64)val1 & 0xffff) << 16) | | ||
505 | (((u64)val2 & 0xffff) << 32) | (((u64)val3 & 0xffff) << 48); | ||
506 | |||
507 | /* Rx stats */ | ||
508 | RMON_UPDATE(mac, RxOctetsReceivedOK, RxOctetsOK); | ||
509 | RMON_UPDATE(mac, RxUnicastFramesReceivedOK, RxUnicastFramesOK); | ||
510 | RMON_UPDATE(mac, RxMulticastFramesReceivedOK, RxMulticastFramesOK); | ||
511 | RMON_UPDATE(mac, RxBroadcastFramesReceivedOK, RxBroadcastFramesOK); | ||
512 | RMON_UPDATE(mac, RxPAUSEMACCtrlFramesReceived, RxPauseFrames); | ||
513 | RMON_UPDATE(mac, RxFrameCheckSequenceErrors, RxFCSErrors); | ||
514 | RMON_UPDATE(mac, RxFramesLostDueToInternalMACErrors, | ||
515 | RxInternalMACRcvError); | ||
516 | RMON_UPDATE(mac, RxSymbolErrors, RxSymbolErrors); | ||
517 | RMON_UPDATE(mac, RxInRangeLengthErrors, RxInRangeLengthErrors); | ||
518 | RMON_UPDATE(mac, RxFramesTooLongErrors , RxFrameTooLongErrors); | ||
519 | RMON_UPDATE(mac, RxJabbers, RxJabberErrors); | ||
520 | RMON_UPDATE(mac, RxFragments, RxRuntErrors); | ||
521 | RMON_UPDATE(mac, RxUndersizedFrames, RxRuntErrors); | ||
522 | |||
523 | /* Tx stats */ | ||
524 | RMON_UPDATE(mac, TxOctetsTransmittedOK, TxOctetsOK); | ||
525 | RMON_UPDATE(mac, TxFramesLostDueToInternalMACTransmissionError, | ||
526 | TxInternalMACXmitError); | ||
527 | RMON_UPDATE(mac, TxTransmitSystemError, TxFCSErrors); | ||
528 | RMON_UPDATE(mac, TxUnicastFramesTransmittedOK, TxUnicastFramesOK); | ||
529 | RMON_UPDATE(mac, TxMulticastFramesTransmittedOK, TxMulticastFramesOK); | ||
530 | RMON_UPDATE(mac, TxBroadcastFramesTransmittedOK, TxBroadcastFramesOK); | ||
531 | RMON_UPDATE(mac, TxPAUSEMACCtrlFramesTransmitted, TxPauseFrames); | ||
532 | |||
533 | return &mac->stats; | ||
534 | } | ||
535 | |||
536 | static int pm3393_macaddress_get(struct cmac *cmac, u8 mac_addr[6]) | ||
537 | { | ||
538 | memcpy(mac_addr, cmac->instance->mac_addr, 6); | ||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | static int pm3393_macaddress_set(struct cmac *cmac, u8 ma[6]) | ||
543 | { | ||
544 | u32 val, lo, mid, hi, enabled = cmac->instance->enabled; | ||
545 | |||
546 | /* | ||
547 | * MAC addr: 00:07:43:00:13:09 | ||
548 | * | ||
549 | * ma[5] = 0x09 | ||
550 | * ma[4] = 0x13 | ||
551 | * ma[3] = 0x00 | ||
552 | * ma[2] = 0x43 | ||
553 | * ma[1] = 0x07 | ||
554 | * ma[0] = 0x00 | ||
555 | * | ||
556 | * The PM3393 requires byte swapping and reverse order entry | ||
557 | * when programming MAC addresses: | ||
558 | * | ||
559 | * low_bits[15:0] = ma[1]:ma[0] | ||
560 | * mid_bits[31:16] = ma[3]:ma[2] | ||
561 | * high_bits[47:32] = ma[5]:ma[4] | ||
562 | */ | ||
563 | |||
564 | /* Store local copy */ | ||
565 | memcpy(cmac->instance->mac_addr, ma, 6); | ||
566 | |||
567 | lo = ((u32) ma[1] << 8) | (u32) ma[0]; | ||
568 | mid = ((u32) ma[3] << 8) | (u32) ma[2]; | ||
569 | hi = ((u32) ma[5] << 8) | (u32) ma[4]; | ||
570 | |||
571 | /* Disable Rx/Tx MAC before configuring it. */ | ||
572 | if (enabled) | ||
573 | pm3393_disable(cmac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); | ||
574 | |||
575 | /* Set RXXG Station Address */ | ||
576 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_15_0, lo); | ||
577 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_31_16, mid); | ||
578 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_SA_47_32, hi); | ||
579 | |||
580 | /* Set TXXG Station Address */ | ||
581 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_15_0, lo); | ||
582 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_31_16, mid); | ||
583 | pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_SA_47_32, hi); | ||
584 | |||
585 | /* Setup Exact Match Filter 1 with our MAC address | ||
586 | * | ||
587 | * Must disable exact match filter before configuring it. | ||
588 | */ | ||
589 | pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, &val); | ||
590 | val &= 0xff0f; | ||
591 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val); | ||
592 | |||
593 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_LOW, lo); | ||
594 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_MID, mid); | ||
595 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_HIGH, hi); | ||
596 | |||
597 | val |= 0x0090; | ||
598 | pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0, val); | ||
599 | |||
600 | if (enabled) | ||
601 | pm3393_enable(cmac, enabled); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static void pm3393_destroy(struct cmac *cmac) | ||
606 | { | ||
607 | kfree(cmac); | ||
608 | } | ||
609 | |||
610 | static struct cmac_ops pm3393_ops = { | ||
611 | .destroy = pm3393_destroy, | ||
612 | .reset = pm3393_reset, | ||
613 | .interrupt_enable = pm3393_interrupt_enable, | ||
614 | .interrupt_disable = pm3393_interrupt_disable, | ||
615 | .interrupt_clear = pm3393_interrupt_clear, | ||
616 | .interrupt_handler = pm3393_interrupt_handler, | ||
617 | .enable = pm3393_enable_port, | ||
618 | .disable = pm3393_disable, | ||
619 | .loopback_enable = pm3393_loopback_enable, | ||
620 | .loopback_disable = pm3393_loopback_disable, | ||
621 | .set_mtu = pm3393_set_mtu, | ||
622 | .set_rx_mode = pm3393_set_rx_mode, | ||
623 | .get_speed_duplex_fc = pm3393_get_speed_duplex_fc, | ||
624 | .set_speed_duplex_fc = pm3393_set_speed_duplex_fc, | ||
625 | .statistics_update = pm3393_update_statistics, | ||
626 | .macaddress_get = pm3393_macaddress_get, | ||
627 | .macaddress_set = pm3393_macaddress_set | ||
628 | }; | ||
629 | |||
630 | static struct cmac *pm3393_mac_create(adapter_t *adapter, int index) | ||
631 | { | ||
632 | struct cmac *cmac; | ||
633 | |||
634 | cmac = kmalloc(sizeof(*cmac) + sizeof(cmac_instance), GFP_KERNEL); | ||
635 | if (!cmac) | ||
636 | return NULL; | ||
637 | memset(cmac, 0, sizeof(*cmac)); | ||
638 | |||
639 | cmac->ops = &pm3393_ops; | ||
640 | cmac->instance = (cmac_instance *) (cmac + 1); | ||
641 | cmac->adapter = adapter; | ||
642 | cmac->instance->fc = PAUSE_TX | PAUSE_RX; | ||
643 | |||
644 | t1_tpi_write(adapter, OFFSET(0x0001), 0x00008000); | ||
645 | t1_tpi_write(adapter, OFFSET(0x0001), 0x00000000); | ||
646 | t1_tpi_write(adapter, OFFSET(0x2308), 0x00009800); | ||
647 | t1_tpi_write(adapter, OFFSET(0x2305), 0x00001001); /* PL4IO Enable */ | ||
648 | t1_tpi_write(adapter, OFFSET(0x2320), 0x00008800); | ||
649 | t1_tpi_write(adapter, OFFSET(0x2321), 0x00008800); | ||
650 | t1_tpi_write(adapter, OFFSET(0x2322), 0x00008800); | ||
651 | t1_tpi_write(adapter, OFFSET(0x2323), 0x00008800); | ||
652 | t1_tpi_write(adapter, OFFSET(0x2324), 0x00008800); | ||
653 | t1_tpi_write(adapter, OFFSET(0x2325), 0x00008800); | ||
654 | t1_tpi_write(adapter, OFFSET(0x2326), 0x00008800); | ||
655 | t1_tpi_write(adapter, OFFSET(0x2327), 0x00008800); | ||
656 | t1_tpi_write(adapter, OFFSET(0x2328), 0x00008800); | ||
657 | t1_tpi_write(adapter, OFFSET(0x2329), 0x00008800); | ||
658 | t1_tpi_write(adapter, OFFSET(0x232a), 0x00008800); | ||
659 | t1_tpi_write(adapter, OFFSET(0x232b), 0x00008800); | ||
660 | t1_tpi_write(adapter, OFFSET(0x232c), 0x00008800); | ||
661 | t1_tpi_write(adapter, OFFSET(0x232d), 0x00008800); | ||
662 | t1_tpi_write(adapter, OFFSET(0x232e), 0x00008800); | ||
663 | t1_tpi_write(adapter, OFFSET(0x232f), 0x00008800); | ||
664 | t1_tpi_write(adapter, OFFSET(0x230d), 0x00009c00); | ||
665 | t1_tpi_write(adapter, OFFSET(0x2304), 0x00000202); /* PL4IO Calendar Repetitions */ | ||
666 | |||
667 | t1_tpi_write(adapter, OFFSET(0x3200), 0x00008080); /* EFLX Enable */ | ||
668 | t1_tpi_write(adapter, OFFSET(0x3210), 0x00000000); /* EFLX Channel Deprovision */ | ||
669 | t1_tpi_write(adapter, OFFSET(0x3203), 0x00000000); /* EFLX Low Limit */ | ||
670 | t1_tpi_write(adapter, OFFSET(0x3204), 0x00000040); /* EFLX High Limit */ | ||
671 | t1_tpi_write(adapter, OFFSET(0x3205), 0x000002cc); /* EFLX Almost Full */ | ||
672 | t1_tpi_write(adapter, OFFSET(0x3206), 0x00000199); /* EFLX Almost Empty */ | ||
673 | t1_tpi_write(adapter, OFFSET(0x3207), 0x00000240); /* EFLX Cut Through Threshold */ | ||
674 | t1_tpi_write(adapter, OFFSET(0x3202), 0x00000000); /* EFLX Indirect Register Update */ | ||
675 | t1_tpi_write(adapter, OFFSET(0x3210), 0x00000001); /* EFLX Channel Provision */ | ||
676 | t1_tpi_write(adapter, OFFSET(0x3208), 0x0000ffff); /* EFLX Undocumented */ | ||
677 | t1_tpi_write(adapter, OFFSET(0x320a), 0x0000ffff); /* EFLX Undocumented */ | ||
678 | t1_tpi_write(adapter, OFFSET(0x320c), 0x0000ffff); /* EFLX enable overflow interrupt The other bit are undocumented */ | ||
679 | t1_tpi_write(adapter, OFFSET(0x320e), 0x0000ffff); /* EFLX Undocumented */ | ||
680 | |||
681 | t1_tpi_write(adapter, OFFSET(0x2200), 0x0000c000); /* IFLX Configuration - enable */ | ||
682 | t1_tpi_write(adapter, OFFSET(0x2201), 0x00000000); /* IFLX Channel Deprovision */ | ||
683 | t1_tpi_write(adapter, OFFSET(0x220e), 0x00000000); /* IFLX Low Limit */ | ||
684 | t1_tpi_write(adapter, OFFSET(0x220f), 0x00000100); /* IFLX High Limit */ | ||
685 | t1_tpi_write(adapter, OFFSET(0x2210), 0x00000c00); /* IFLX Almost Full Limit */ | ||
686 | t1_tpi_write(adapter, OFFSET(0x2211), 0x00000599); /* IFLX Almost Empty Limit */ | ||
687 | t1_tpi_write(adapter, OFFSET(0x220d), 0x00000000); /* IFLX Indirect Register Update */ | ||
688 | t1_tpi_write(adapter, OFFSET(0x2201), 0x00000001); /* IFLX Channel Provision */ | ||
689 | t1_tpi_write(adapter, OFFSET(0x2203), 0x0000ffff); /* IFLX Undocumented */ | ||
690 | t1_tpi_write(adapter, OFFSET(0x2205), 0x0000ffff); /* IFLX Undocumented */ | ||
691 | t1_tpi_write(adapter, OFFSET(0x2209), 0x0000ffff); /* IFLX Enable overflow interrupt. The other bit are undocumented */ | ||
692 | |||
693 | t1_tpi_write(adapter, OFFSET(0x2241), 0xfffffffe); /* PL4MOS Undocumented */ | ||
694 | t1_tpi_write(adapter, OFFSET(0x2242), 0x0000ffff); /* PL4MOS Undocumented */ | ||
695 | t1_tpi_write(adapter, OFFSET(0x2243), 0x00000008); /* PL4MOS Starving Burst Size */ | ||
696 | t1_tpi_write(adapter, OFFSET(0x2244), 0x00000008); /* PL4MOS Hungry Burst Size */ | ||
697 | t1_tpi_write(adapter, OFFSET(0x2245), 0x00000008); /* PL4MOS Transfer Size */ | ||
698 | t1_tpi_write(adapter, OFFSET(0x2240), 0x00000005); /* PL4MOS Disable */ | ||
699 | |||
700 | t1_tpi_write(adapter, OFFSET(0x2280), 0x00002103); /* PL4ODP Training Repeat and SOP rule */ | ||
701 | t1_tpi_write(adapter, OFFSET(0x2284), 0x00000000); /* PL4ODP MAX_T setting */ | ||
702 | |||
703 | t1_tpi_write(adapter, OFFSET(0x3280), 0x00000087); /* PL4IDU Enable data forward, port state machine. Set ALLOW_NON_ZERO_OLB */ | ||
704 | t1_tpi_write(adapter, OFFSET(0x3282), 0x0000001f); /* PL4IDU Enable Dip4 check error interrupts */ | ||
705 | |||
706 | t1_tpi_write(adapter, OFFSET(0x3040), 0x0c32); /* # TXXG Config */ | ||
707 | /* For T1 use timer based Mac flow control. */ | ||
708 | t1_tpi_write(adapter, OFFSET(0x304d), 0x8000); | ||
709 | t1_tpi_write(adapter, OFFSET(0x2040), 0x059c); /* # RXXG Config */ | ||
710 | t1_tpi_write(adapter, OFFSET(0x2049), 0x0001); /* # RXXG Cut Through */ | ||
711 | t1_tpi_write(adapter, OFFSET(0x2070), 0x0000); /* # Disable promiscuous mode */ | ||
712 | |||
713 | /* Setup Exact Match Filter 0 to allow broadcast packets. | ||
714 | */ | ||
715 | t1_tpi_write(adapter, OFFSET(0x206e), 0x0000); /* # Disable Match Enable bit */ | ||
716 | t1_tpi_write(adapter, OFFSET(0x204a), 0xffff); /* # low addr */ | ||
717 | t1_tpi_write(adapter, OFFSET(0x204b), 0xffff); /* # mid addr */ | ||
718 | t1_tpi_write(adapter, OFFSET(0x204c), 0xffff); /* # high addr */ | ||
719 | t1_tpi_write(adapter, OFFSET(0x206e), 0x0009); /* # Enable Match Enable bit */ | ||
720 | |||
721 | t1_tpi_write(adapter, OFFSET(0x0003), 0x0000); /* # NO SOP/ PAD_EN setup */ | ||
722 | t1_tpi_write(adapter, OFFSET(0x0100), 0x0ff0); /* # RXEQB disabled */ | ||
723 | t1_tpi_write(adapter, OFFSET(0x0101), 0x0f0f); /* # No Preemphasis */ | ||
724 | |||
725 | return cmac; | ||
726 | } | ||
727 | |||
728 | static int pm3393_mac_reset(adapter_t * adapter) | ||
729 | { | ||
730 | u32 val; | ||
731 | u32 x; | ||
732 | u32 is_pl4_reset_finished; | ||
733 | u32 is_pl4_outof_lock; | ||
734 | u32 is_xaui_mabc_pll_locked; | ||
735 | u32 successful_reset; | ||
736 | int i; | ||
737 | |||
738 | /* The following steps are required to properly reset | ||
739 | * the PM3393. This information is provided in the | ||
740 | * PM3393 datasheet (Issue 2: November 2002) | ||
741 | * section 13.1 -- Device Reset. | ||
742 | * | ||
743 | * The PM3393 has three types of components that are | ||
744 | * individually reset: | ||
745 | * | ||
746 | * DRESETB - Digital circuitry | ||
747 | * PL4_ARESETB - PL4 analog circuitry | ||
748 | * XAUI_ARESETB - XAUI bus analog circuitry | ||
749 | * | ||
750 | * Steps to reset PM3393 using RSTB pin: | ||
751 | * | ||
752 | * 1. Assert RSTB pin low ( write 0 ) | ||
753 | * 2. Wait at least 1ms to initiate a complete initialization of device. | ||
754 | * 3. Wait until all external clocks and REFSEL are stable. | ||
755 | * 4. Wait minimum of 1ms. (after external clocks and REFEL are stable) | ||
756 | * 5. De-assert RSTB ( write 1 ) | ||
757 | * 6. Wait until internal timers to expires after ~14ms. | ||
758 | * - Allows analog clock synthesizer(PL4CSU) to stabilize to | ||
759 | * selected reference frequency before allowing the digital | ||
760 | * portion of the device to operate. | ||
761 | * 7. Wait at least 200us for XAUI interface to stabilize. | ||
762 | * 8. Verify the PM3393 came out of reset successfully. | ||
763 | * Set successful reset flag if everything worked else try again | ||
764 | * a few more times. | ||
765 | */ | ||
766 | |||
767 | successful_reset = 0; | ||
768 | for (i = 0; i < 3 && !successful_reset; i++) { | ||
769 | /* 1 */ | ||
770 | t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
771 | val &= ~1; | ||
772 | t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
773 | |||
774 | /* 2 */ | ||
775 | msleep(1); | ||
776 | |||
777 | /* 3 */ | ||
778 | msleep(1); | ||
779 | |||
780 | /* 4 */ | ||
781 | msleep(2 /*1 extra ms for safety */ ); | ||
782 | |||
783 | /* 5 */ | ||
784 | val |= 1; | ||
785 | t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
786 | |||
787 | /* 6 */ | ||
788 | msleep(15 /*1 extra ms for safety */ ); | ||
789 | |||
790 | /* 7 */ | ||
791 | msleep(1); | ||
792 | |||
793 | /* 8 */ | ||
794 | |||
795 | /* Has PL4 analog block come out of reset correctly? */ | ||
796 | t1_tpi_read(adapter, OFFSET(SUNI1x10GEXP_REG_DEVICE_STATUS), &val); | ||
797 | is_pl4_reset_finished = (val & SUNI1x10GEXP_BITMSK_TOP_EXPIRED); | ||
798 | |||
799 | /* TBD XXX SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL gets locked later in the init sequence | ||
800 | * figure out why? */ | ||
801 | |||
802 | /* Have all PL4 block clocks locked? */ | ||
803 | x = (SUNI1x10GEXP_BITMSK_TOP_PL4_ID_DOOL | ||
804 | /*| SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL */ | | ||
805 | SUNI1x10GEXP_BITMSK_TOP_PL4_ID_ROOL | | ||
806 | SUNI1x10GEXP_BITMSK_TOP_PL4_IS_ROOL | | ||
807 | SUNI1x10GEXP_BITMSK_TOP_PL4_OUT_ROOL); | ||
808 | is_pl4_outof_lock = (val & x); | ||
809 | |||
810 | /* ??? If this fails, might be able to software reset the XAUI part | ||
811 | * and try to recover... thus saving us from doing another HW reset */ | ||
812 | /* Has the XAUI MABC PLL circuitry stablized? */ | ||
813 | is_xaui_mabc_pll_locked = | ||
814 | (val & SUNI1x10GEXP_BITMSK_TOP_SXRA_EXPIRED); | ||
815 | |||
816 | successful_reset = (is_pl4_reset_finished && !is_pl4_outof_lock | ||
817 | && is_xaui_mabc_pll_locked); | ||
818 | } | ||
819 | return successful_reset ? 0 : 1; | ||
820 | } | ||
821 | |||
822 | struct gmac t1_pm3393_ops = { | ||
823 | STATS_TICK_SECS, | ||
824 | pm3393_mac_create, | ||
825 | pm3393_mac_reset | ||
826 | }; | ||
diff --git a/drivers/net/chelsio/regs.h b/drivers/net/chelsio/regs.h new file mode 100644 index 000000000000..b90e11f40d1f --- /dev/null +++ b/drivers/net/chelsio/regs.h | |||
@@ -0,0 +1,468 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: regs.h * | ||
4 | * $Revision: 1.8 $ * | ||
5 | * $Date: 2005/06/21 18:29:48 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_REGS_H_ | ||
40 | #define _CXGB_REGS_H_ | ||
41 | |||
42 | /* SGE registers */ | ||
43 | #define A_SG_CONTROL 0x0 | ||
44 | |||
45 | #define S_CMDQ0_ENABLE 0 | ||
46 | #define V_CMDQ0_ENABLE(x) ((x) << S_CMDQ0_ENABLE) | ||
47 | #define F_CMDQ0_ENABLE V_CMDQ0_ENABLE(1U) | ||
48 | |||
49 | #define S_CMDQ1_ENABLE 1 | ||
50 | #define V_CMDQ1_ENABLE(x) ((x) << S_CMDQ1_ENABLE) | ||
51 | #define F_CMDQ1_ENABLE V_CMDQ1_ENABLE(1U) | ||
52 | |||
53 | #define S_FL0_ENABLE 2 | ||
54 | #define V_FL0_ENABLE(x) ((x) << S_FL0_ENABLE) | ||
55 | #define F_FL0_ENABLE V_FL0_ENABLE(1U) | ||
56 | |||
57 | #define S_FL1_ENABLE 3 | ||
58 | #define V_FL1_ENABLE(x) ((x) << S_FL1_ENABLE) | ||
59 | #define F_FL1_ENABLE V_FL1_ENABLE(1U) | ||
60 | |||
61 | #define S_CPL_ENABLE 4 | ||
62 | #define V_CPL_ENABLE(x) ((x) << S_CPL_ENABLE) | ||
63 | #define F_CPL_ENABLE V_CPL_ENABLE(1U) | ||
64 | |||
65 | #define S_RESPONSE_QUEUE_ENABLE 5 | ||
66 | #define V_RESPONSE_QUEUE_ENABLE(x) ((x) << S_RESPONSE_QUEUE_ENABLE) | ||
67 | #define F_RESPONSE_QUEUE_ENABLE V_RESPONSE_QUEUE_ENABLE(1U) | ||
68 | |||
69 | #define S_CMDQ_PRIORITY 6 | ||
70 | #define M_CMDQ_PRIORITY 0x3 | ||
71 | #define V_CMDQ_PRIORITY(x) ((x) << S_CMDQ_PRIORITY) | ||
72 | #define G_CMDQ_PRIORITY(x) (((x) >> S_CMDQ_PRIORITY) & M_CMDQ_PRIORITY) | ||
73 | |||
74 | #define S_DISABLE_CMDQ1_GTS 9 | ||
75 | #define V_DISABLE_CMDQ1_GTS(x) ((x) << S_DISABLE_CMDQ1_GTS) | ||
76 | #define F_DISABLE_CMDQ1_GTS V_DISABLE_CMDQ1_GTS(1U) | ||
77 | |||
78 | #define S_DISABLE_FL0_GTS 10 | ||
79 | #define V_DISABLE_FL0_GTS(x) ((x) << S_DISABLE_FL0_GTS) | ||
80 | #define F_DISABLE_FL0_GTS V_DISABLE_FL0_GTS(1U) | ||
81 | |||
82 | #define S_DISABLE_FL1_GTS 11 | ||
83 | #define V_DISABLE_FL1_GTS(x) ((x) << S_DISABLE_FL1_GTS) | ||
84 | #define F_DISABLE_FL1_GTS V_DISABLE_FL1_GTS(1U) | ||
85 | |||
86 | #define S_ENABLE_BIG_ENDIAN 12 | ||
87 | #define V_ENABLE_BIG_ENDIAN(x) ((x) << S_ENABLE_BIG_ENDIAN) | ||
88 | #define F_ENABLE_BIG_ENDIAN V_ENABLE_BIG_ENDIAN(1U) | ||
89 | |||
90 | #define S_ISCSI_COALESCE 14 | ||
91 | #define V_ISCSI_COALESCE(x) ((x) << S_ISCSI_COALESCE) | ||
92 | #define F_ISCSI_COALESCE V_ISCSI_COALESCE(1U) | ||
93 | |||
94 | #define S_RX_PKT_OFFSET 15 | ||
95 | #define V_RX_PKT_OFFSET(x) ((x) << S_RX_PKT_OFFSET) | ||
96 | |||
97 | #define S_VLAN_XTRACT 18 | ||
98 | #define V_VLAN_XTRACT(x) ((x) << S_VLAN_XTRACT) | ||
99 | #define F_VLAN_XTRACT V_VLAN_XTRACT(1U) | ||
100 | |||
101 | #define A_SG_DOORBELL 0x4 | ||
102 | #define A_SG_CMD0BASELWR 0x8 | ||
103 | #define A_SG_CMD0BASEUPR 0xc | ||
104 | #define A_SG_CMD1BASELWR 0x10 | ||
105 | #define A_SG_CMD1BASEUPR 0x14 | ||
106 | #define A_SG_FL0BASELWR 0x18 | ||
107 | #define A_SG_FL0BASEUPR 0x1c | ||
108 | #define A_SG_FL1BASELWR 0x20 | ||
109 | #define A_SG_FL1BASEUPR 0x24 | ||
110 | #define A_SG_CMD0SIZE 0x28 | ||
111 | #define A_SG_FL0SIZE 0x2c | ||
112 | #define A_SG_RSPSIZE 0x30 | ||
113 | #define A_SG_RSPBASELWR 0x34 | ||
114 | #define A_SG_RSPBASEUPR 0x38 | ||
115 | #define A_SG_FLTHRESHOLD 0x3c | ||
116 | #define A_SG_RSPQUEUECREDIT 0x40 | ||
117 | #define A_SG_SLEEPING 0x48 | ||
118 | #define A_SG_INTRTIMER 0x4c | ||
119 | #define A_SG_CMD1SIZE 0xb0 | ||
120 | #define A_SG_FL1SIZE 0xb4 | ||
121 | #define A_SG_INT_ENABLE 0xb8 | ||
122 | |||
123 | #define S_RESPQ_EXHAUSTED 0 | ||
124 | #define V_RESPQ_EXHAUSTED(x) ((x) << S_RESPQ_EXHAUSTED) | ||
125 | #define F_RESPQ_EXHAUSTED V_RESPQ_EXHAUSTED(1U) | ||
126 | |||
127 | #define S_RESPQ_OVERFLOW 1 | ||
128 | #define V_RESPQ_OVERFLOW(x) ((x) << S_RESPQ_OVERFLOW) | ||
129 | #define F_RESPQ_OVERFLOW V_RESPQ_OVERFLOW(1U) | ||
130 | |||
131 | #define S_FL_EXHAUSTED 2 | ||
132 | #define V_FL_EXHAUSTED(x) ((x) << S_FL_EXHAUSTED) | ||
133 | #define F_FL_EXHAUSTED V_FL_EXHAUSTED(1U) | ||
134 | |||
135 | #define S_PACKET_TOO_BIG 3 | ||
136 | #define V_PACKET_TOO_BIG(x) ((x) << S_PACKET_TOO_BIG) | ||
137 | #define F_PACKET_TOO_BIG V_PACKET_TOO_BIG(1U) | ||
138 | |||
139 | #define S_PACKET_MISMATCH 4 | ||
140 | #define V_PACKET_MISMATCH(x) ((x) << S_PACKET_MISMATCH) | ||
141 | #define F_PACKET_MISMATCH V_PACKET_MISMATCH(1U) | ||
142 | |||
143 | #define A_SG_INT_CAUSE 0xbc | ||
144 | #define A_SG_RESPACCUTIMER 0xc0 | ||
145 | |||
146 | /* MC3 registers */ | ||
147 | |||
148 | #define S_READY 1 | ||
149 | #define V_READY(x) ((x) << S_READY) | ||
150 | #define F_READY V_READY(1U) | ||
151 | |||
152 | /* MC4 registers */ | ||
153 | |||
154 | #define A_MC4_CFG 0x180 | ||
155 | #define S_MC4_SLOW 25 | ||
156 | #define V_MC4_SLOW(x) ((x) << S_MC4_SLOW) | ||
157 | #define F_MC4_SLOW V_MC4_SLOW(1U) | ||
158 | |||
159 | /* TPI registers */ | ||
160 | |||
161 | #define A_TPI_ADDR 0x280 | ||
162 | #define A_TPI_WR_DATA 0x284 | ||
163 | #define A_TPI_RD_DATA 0x288 | ||
164 | #define A_TPI_CSR 0x28c | ||
165 | |||
166 | #define S_TPIWR 0 | ||
167 | #define V_TPIWR(x) ((x) << S_TPIWR) | ||
168 | #define F_TPIWR V_TPIWR(1U) | ||
169 | |||
170 | #define S_TPIRDY 1 | ||
171 | #define V_TPIRDY(x) ((x) << S_TPIRDY) | ||
172 | #define F_TPIRDY V_TPIRDY(1U) | ||
173 | |||
174 | #define A_TPI_PAR 0x29c | ||
175 | |||
176 | #define S_TPIPAR 0 | ||
177 | #define M_TPIPAR 0x7f | ||
178 | #define V_TPIPAR(x) ((x) << S_TPIPAR) | ||
179 | #define G_TPIPAR(x) (((x) >> S_TPIPAR) & M_TPIPAR) | ||
180 | |||
181 | /* TP registers */ | ||
182 | |||
183 | #define A_TP_IN_CONFIG 0x300 | ||
184 | |||
185 | #define S_TP_IN_CSPI_CPL 3 | ||
186 | #define V_TP_IN_CSPI_CPL(x) ((x) << S_TP_IN_CSPI_CPL) | ||
187 | #define F_TP_IN_CSPI_CPL V_TP_IN_CSPI_CPL(1U) | ||
188 | |||
189 | #define S_TP_IN_CSPI_CHECK_IP_CSUM 5 | ||
190 | #define V_TP_IN_CSPI_CHECK_IP_CSUM(x) ((x) << S_TP_IN_CSPI_CHECK_IP_CSUM) | ||
191 | #define F_TP_IN_CSPI_CHECK_IP_CSUM V_TP_IN_CSPI_CHECK_IP_CSUM(1U) | ||
192 | |||
193 | #define S_TP_IN_CSPI_CHECK_TCP_CSUM 6 | ||
194 | #define V_TP_IN_CSPI_CHECK_TCP_CSUM(x) ((x) << S_TP_IN_CSPI_CHECK_TCP_CSUM) | ||
195 | #define F_TP_IN_CSPI_CHECK_TCP_CSUM V_TP_IN_CSPI_CHECK_TCP_CSUM(1U) | ||
196 | |||
197 | #define S_TP_IN_ESPI_ETHERNET 8 | ||
198 | #define V_TP_IN_ESPI_ETHERNET(x) ((x) << S_TP_IN_ESPI_ETHERNET) | ||
199 | #define F_TP_IN_ESPI_ETHERNET V_TP_IN_ESPI_ETHERNET(1U) | ||
200 | |||
201 | #define S_TP_IN_ESPI_CHECK_IP_CSUM 12 | ||
202 | #define V_TP_IN_ESPI_CHECK_IP_CSUM(x) ((x) << S_TP_IN_ESPI_CHECK_IP_CSUM) | ||
203 | #define F_TP_IN_ESPI_CHECK_IP_CSUM V_TP_IN_ESPI_CHECK_IP_CSUM(1U) | ||
204 | |||
205 | #define S_TP_IN_ESPI_CHECK_TCP_CSUM 13 | ||
206 | #define V_TP_IN_ESPI_CHECK_TCP_CSUM(x) ((x) << S_TP_IN_ESPI_CHECK_TCP_CSUM) | ||
207 | #define F_TP_IN_ESPI_CHECK_TCP_CSUM V_TP_IN_ESPI_CHECK_TCP_CSUM(1U) | ||
208 | |||
209 | #define S_OFFLOAD_DISABLE 14 | ||
210 | #define V_OFFLOAD_DISABLE(x) ((x) << S_OFFLOAD_DISABLE) | ||
211 | #define F_OFFLOAD_DISABLE V_OFFLOAD_DISABLE(1U) | ||
212 | |||
213 | #define A_TP_OUT_CONFIG 0x304 | ||
214 | |||
215 | #define S_TP_OUT_CSPI_CPL 2 | ||
216 | #define V_TP_OUT_CSPI_CPL(x) ((x) << S_TP_OUT_CSPI_CPL) | ||
217 | #define F_TP_OUT_CSPI_CPL V_TP_OUT_CSPI_CPL(1U) | ||
218 | |||
219 | #define S_TP_OUT_ESPI_ETHERNET 6 | ||
220 | #define V_TP_OUT_ESPI_ETHERNET(x) ((x) << S_TP_OUT_ESPI_ETHERNET) | ||
221 | #define F_TP_OUT_ESPI_ETHERNET V_TP_OUT_ESPI_ETHERNET(1U) | ||
222 | |||
223 | #define S_TP_OUT_ESPI_GENERATE_IP_CSUM 10 | ||
224 | #define V_TP_OUT_ESPI_GENERATE_IP_CSUM(x) ((x) << S_TP_OUT_ESPI_GENERATE_IP_CSUM) | ||
225 | #define F_TP_OUT_ESPI_GENERATE_IP_CSUM V_TP_OUT_ESPI_GENERATE_IP_CSUM(1U) | ||
226 | |||
227 | #define S_TP_OUT_ESPI_GENERATE_TCP_CSUM 11 | ||
228 | #define V_TP_OUT_ESPI_GENERATE_TCP_CSUM(x) ((x) << S_TP_OUT_ESPI_GENERATE_TCP_CSUM) | ||
229 | #define F_TP_OUT_ESPI_GENERATE_TCP_CSUM V_TP_OUT_ESPI_GENERATE_TCP_CSUM(1U) | ||
230 | |||
231 | #define A_TP_GLOBAL_CONFIG 0x308 | ||
232 | |||
233 | #define S_IP_TTL 0 | ||
234 | #define M_IP_TTL 0xff | ||
235 | #define V_IP_TTL(x) ((x) << S_IP_TTL) | ||
236 | |||
237 | #define S_TCP_CSUM 11 | ||
238 | #define V_TCP_CSUM(x) ((x) << S_TCP_CSUM) | ||
239 | #define F_TCP_CSUM V_TCP_CSUM(1U) | ||
240 | |||
241 | #define S_UDP_CSUM 12 | ||
242 | #define V_UDP_CSUM(x) ((x) << S_UDP_CSUM) | ||
243 | #define F_UDP_CSUM V_UDP_CSUM(1U) | ||
244 | |||
245 | #define S_IP_CSUM 13 | ||
246 | #define V_IP_CSUM(x) ((x) << S_IP_CSUM) | ||
247 | #define F_IP_CSUM V_IP_CSUM(1U) | ||
248 | |||
249 | #define S_PATH_MTU 15 | ||
250 | #define V_PATH_MTU(x) ((x) << S_PATH_MTU) | ||
251 | #define F_PATH_MTU V_PATH_MTU(1U) | ||
252 | |||
253 | #define S_5TUPLE_LOOKUP 17 | ||
254 | #define V_5TUPLE_LOOKUP(x) ((x) << S_5TUPLE_LOOKUP) | ||
255 | |||
256 | #define S_SYN_COOKIE_PARAMETER 26 | ||
257 | #define V_SYN_COOKIE_PARAMETER(x) ((x) << S_SYN_COOKIE_PARAMETER) | ||
258 | |||
259 | #define A_TP_PC_CONFIG 0x348 | ||
260 | #define S_DIS_TX_FILL_WIN_PUSH 12 | ||
261 | #define V_DIS_TX_FILL_WIN_PUSH(x) ((x) << S_DIS_TX_FILL_WIN_PUSH) | ||
262 | #define F_DIS_TX_FILL_WIN_PUSH V_DIS_TX_FILL_WIN_PUSH(1U) | ||
263 | |||
264 | #define S_TP_PC_REV 30 | ||
265 | #define M_TP_PC_REV 0x3 | ||
266 | #define G_TP_PC_REV(x) (((x) >> S_TP_PC_REV) & M_TP_PC_REV) | ||
267 | #define A_TP_RESET 0x44c | ||
268 | #define S_TP_RESET 0 | ||
269 | #define V_TP_RESET(x) ((x) << S_TP_RESET) | ||
270 | #define F_TP_RESET V_TP_RESET(1U) | ||
271 | |||
272 | #define A_TP_INT_ENABLE 0x470 | ||
273 | #define A_TP_INT_CAUSE 0x474 | ||
274 | #define A_TP_TX_DROP_CONFIG 0x4b8 | ||
275 | |||
276 | #define S_ENABLE_TX_DROP 31 | ||
277 | #define V_ENABLE_TX_DROP(x) ((x) << S_ENABLE_TX_DROP) | ||
278 | #define F_ENABLE_TX_DROP V_ENABLE_TX_DROP(1U) | ||
279 | |||
280 | #define S_ENABLE_TX_ERROR 30 | ||
281 | #define V_ENABLE_TX_ERROR(x) ((x) << S_ENABLE_TX_ERROR) | ||
282 | #define F_ENABLE_TX_ERROR V_ENABLE_TX_ERROR(1U) | ||
283 | |||
284 | #define S_DROP_TICKS_CNT 4 | ||
285 | #define V_DROP_TICKS_CNT(x) ((x) << S_DROP_TICKS_CNT) | ||
286 | |||
287 | #define S_NUM_PKTS_DROPPED 0 | ||
288 | #define V_NUM_PKTS_DROPPED(x) ((x) << S_NUM_PKTS_DROPPED) | ||
289 | |||
290 | /* CSPI registers */ | ||
291 | |||
292 | #define S_DIP4ERR 0 | ||
293 | #define V_DIP4ERR(x) ((x) << S_DIP4ERR) | ||
294 | #define F_DIP4ERR V_DIP4ERR(1U) | ||
295 | |||
296 | #define S_RXDROP 1 | ||
297 | #define V_RXDROP(x) ((x) << S_RXDROP) | ||
298 | #define F_RXDROP V_RXDROP(1U) | ||
299 | |||
300 | #define S_TXDROP 2 | ||
301 | #define V_TXDROP(x) ((x) << S_TXDROP) | ||
302 | #define F_TXDROP V_TXDROP(1U) | ||
303 | |||
304 | #define S_RXOVERFLOW 3 | ||
305 | #define V_RXOVERFLOW(x) ((x) << S_RXOVERFLOW) | ||
306 | #define F_RXOVERFLOW V_RXOVERFLOW(1U) | ||
307 | |||
308 | #define S_RAMPARITYERR 4 | ||
309 | #define V_RAMPARITYERR(x) ((x) << S_RAMPARITYERR) | ||
310 | #define F_RAMPARITYERR V_RAMPARITYERR(1U) | ||
311 | |||
312 | /* ESPI registers */ | ||
313 | |||
314 | #define A_ESPI_SCH_TOKEN0 0x880 | ||
315 | #define A_ESPI_SCH_TOKEN1 0x884 | ||
316 | #define A_ESPI_SCH_TOKEN2 0x888 | ||
317 | #define A_ESPI_SCH_TOKEN3 0x88c | ||
318 | #define A_ESPI_RX_FIFO_ALMOST_EMPTY_WATERMARK 0x890 | ||
319 | #define A_ESPI_RX_FIFO_ALMOST_FULL_WATERMARK 0x894 | ||
320 | #define A_ESPI_CALENDAR_LENGTH 0x898 | ||
321 | #define A_PORT_CONFIG 0x89c | ||
322 | |||
323 | #define S_RX_NPORTS 0 | ||
324 | #define V_RX_NPORTS(x) ((x) << S_RX_NPORTS) | ||
325 | |||
326 | #define S_TX_NPORTS 8 | ||
327 | #define V_TX_NPORTS(x) ((x) << S_TX_NPORTS) | ||
328 | |||
329 | #define A_ESPI_FIFO_STATUS_ENABLE 0x8a0 | ||
330 | |||
331 | #define S_RXSTATUSENABLE 0 | ||
332 | #define V_RXSTATUSENABLE(x) ((x) << S_RXSTATUSENABLE) | ||
333 | #define F_RXSTATUSENABLE V_RXSTATUSENABLE(1U) | ||
334 | |||
335 | #define S_INTEL1010MODE 4 | ||
336 | #define V_INTEL1010MODE(x) ((x) << S_INTEL1010MODE) | ||
337 | #define F_INTEL1010MODE V_INTEL1010MODE(1U) | ||
338 | |||
339 | #define A_ESPI_MAXBURST1_MAXBURST2 0x8a8 | ||
340 | #define A_ESPI_TRAIN 0x8ac | ||
341 | #define A_ESPI_INTR_STATUS 0x8c8 | ||
342 | |||
343 | #define S_DIP2PARITYERR 5 | ||
344 | #define V_DIP2PARITYERR(x) ((x) << S_DIP2PARITYERR) | ||
345 | #define F_DIP2PARITYERR V_DIP2PARITYERR(1U) | ||
346 | |||
347 | #define A_ESPI_INTR_ENABLE 0x8cc | ||
348 | #define A_RX_DROP_THRESHOLD 0x8d0 | ||
349 | #define A_ESPI_RX_RESET 0x8ec | ||
350 | #define A_ESPI_MISC_CONTROL 0x8f0 | ||
351 | |||
352 | #define S_OUT_OF_SYNC_COUNT 0 | ||
353 | #define V_OUT_OF_SYNC_COUNT(x) ((x) << S_OUT_OF_SYNC_COUNT) | ||
354 | |||
355 | #define S_DIP2_PARITY_ERR_THRES 5 | ||
356 | #define V_DIP2_PARITY_ERR_THRES(x) ((x) << S_DIP2_PARITY_ERR_THRES) | ||
357 | |||
358 | #define S_DIP4_THRES 9 | ||
359 | #define V_DIP4_THRES(x) ((x) << S_DIP4_THRES) | ||
360 | |||
361 | #define S_MONITORED_PORT_NUM 25 | ||
362 | #define V_MONITORED_PORT_NUM(x) ((x) << S_MONITORED_PORT_NUM) | ||
363 | |||
364 | #define S_MONITORED_DIRECTION 27 | ||
365 | #define V_MONITORED_DIRECTION(x) ((x) << S_MONITORED_DIRECTION) | ||
366 | #define F_MONITORED_DIRECTION V_MONITORED_DIRECTION(1U) | ||
367 | |||
368 | #define S_MONITORED_INTERFACE 28 | ||
369 | #define V_MONITORED_INTERFACE(x) ((x) << S_MONITORED_INTERFACE) | ||
370 | #define F_MONITORED_INTERFACE V_MONITORED_INTERFACE(1U) | ||
371 | |||
372 | #define A_ESPI_DIP2_ERR_COUNT 0x8f4 | ||
373 | #define A_ESPI_CMD_ADDR 0x8f8 | ||
374 | |||
375 | #define S_WRITE_DATA 0 | ||
376 | #define V_WRITE_DATA(x) ((x) << S_WRITE_DATA) | ||
377 | |||
378 | #define S_REGISTER_OFFSET 8 | ||
379 | #define V_REGISTER_OFFSET(x) ((x) << S_REGISTER_OFFSET) | ||
380 | |||
381 | #define S_CHANNEL_ADDR 12 | ||
382 | #define V_CHANNEL_ADDR(x) ((x) << S_CHANNEL_ADDR) | ||
383 | |||
384 | #define S_MODULE_ADDR 16 | ||
385 | #define V_MODULE_ADDR(x) ((x) << S_MODULE_ADDR) | ||
386 | |||
387 | #define S_BUNDLE_ADDR 20 | ||
388 | #define V_BUNDLE_ADDR(x) ((x) << S_BUNDLE_ADDR) | ||
389 | |||
390 | #define S_SPI4_COMMAND 24 | ||
391 | #define V_SPI4_COMMAND(x) ((x) << S_SPI4_COMMAND) | ||
392 | |||
393 | #define A_ESPI_GOSTAT 0x8fc | ||
394 | #define S_ESPI_CMD_BUSY 8 | ||
395 | #define V_ESPI_CMD_BUSY(x) ((x) << S_ESPI_CMD_BUSY) | ||
396 | #define F_ESPI_CMD_BUSY V_ESPI_CMD_BUSY(1U) | ||
397 | |||
398 | /* PL registers */ | ||
399 | |||
400 | #define A_PL_ENABLE 0xa00 | ||
401 | |||
402 | #define S_PL_INTR_SGE_ERR 0 | ||
403 | #define V_PL_INTR_SGE_ERR(x) ((x) << S_PL_INTR_SGE_ERR) | ||
404 | #define F_PL_INTR_SGE_ERR V_PL_INTR_SGE_ERR(1U) | ||
405 | |||
406 | #define S_PL_INTR_SGE_DATA 1 | ||
407 | #define V_PL_INTR_SGE_DATA(x) ((x) << S_PL_INTR_SGE_DATA) | ||
408 | #define F_PL_INTR_SGE_DATA V_PL_INTR_SGE_DATA(1U) | ||
409 | |||
410 | #define S_PL_INTR_TP 6 | ||
411 | #define V_PL_INTR_TP(x) ((x) << S_PL_INTR_TP) | ||
412 | #define F_PL_INTR_TP V_PL_INTR_TP(1U) | ||
413 | |||
414 | #define S_PL_INTR_ESPI 8 | ||
415 | #define V_PL_INTR_ESPI(x) ((x) << S_PL_INTR_ESPI) | ||
416 | #define F_PL_INTR_ESPI V_PL_INTR_ESPI(1U) | ||
417 | |||
418 | #define S_PL_INTR_PCIX 10 | ||
419 | #define V_PL_INTR_PCIX(x) ((x) << S_PL_INTR_PCIX) | ||
420 | #define F_PL_INTR_PCIX V_PL_INTR_PCIX(1U) | ||
421 | |||
422 | #define S_PL_INTR_EXT 11 | ||
423 | #define V_PL_INTR_EXT(x) ((x) << S_PL_INTR_EXT) | ||
424 | #define F_PL_INTR_EXT V_PL_INTR_EXT(1U) | ||
425 | |||
426 | #define A_PL_CAUSE 0xa04 | ||
427 | |||
428 | /* MC5 registers */ | ||
429 | |||
430 | #define A_MC5_CONFIG 0xc04 | ||
431 | |||
432 | #define S_TCAM_RESET 1 | ||
433 | #define V_TCAM_RESET(x) ((x) << S_TCAM_RESET) | ||
434 | #define F_TCAM_RESET V_TCAM_RESET(1U) | ||
435 | |||
436 | #define S_M_BUS_ENABLE 5 | ||
437 | #define V_M_BUS_ENABLE(x) ((x) << S_M_BUS_ENABLE) | ||
438 | #define F_M_BUS_ENABLE V_M_BUS_ENABLE(1U) | ||
439 | |||
440 | /* PCICFG registers */ | ||
441 | |||
442 | #define A_PCICFG_PM_CSR 0x44 | ||
443 | #define A_PCICFG_VPD_ADDR 0x4a | ||
444 | |||
445 | #define S_VPD_OP_FLAG 15 | ||
446 | #define V_VPD_OP_FLAG(x) ((x) << S_VPD_OP_FLAG) | ||
447 | #define F_VPD_OP_FLAG V_VPD_OP_FLAG(1U) | ||
448 | |||
449 | #define A_PCICFG_VPD_DATA 0x4c | ||
450 | |||
451 | #define A_PCICFG_INTR_ENABLE 0xf4 | ||
452 | #define A_PCICFG_INTR_CAUSE 0xf8 | ||
453 | |||
454 | #define A_PCICFG_MODE 0xfc | ||
455 | |||
456 | #define S_PCI_MODE_64BIT 0 | ||
457 | #define V_PCI_MODE_64BIT(x) ((x) << S_PCI_MODE_64BIT) | ||
458 | #define F_PCI_MODE_64BIT V_PCI_MODE_64BIT(1U) | ||
459 | |||
460 | #define S_PCI_MODE_PCIX 5 | ||
461 | #define V_PCI_MODE_PCIX(x) ((x) << S_PCI_MODE_PCIX) | ||
462 | #define F_PCI_MODE_PCIX V_PCI_MODE_PCIX(1U) | ||
463 | |||
464 | #define S_PCI_MODE_CLK 6 | ||
465 | #define M_PCI_MODE_CLK 0x3 | ||
466 | #define G_PCI_MODE_CLK(x) (((x) >> S_PCI_MODE_CLK) & M_PCI_MODE_CLK) | ||
467 | |||
468 | #endif /* _CXGB_REGS_H_ */ | ||
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c new file mode 100644 index 000000000000..53b41d99b00b --- /dev/null +++ b/drivers/net/chelsio/sge.c | |||
@@ -0,0 +1,1684 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: sge.c * | ||
4 | * $Revision: 1.26 $ * | ||
5 | * $Date: 2005/06/21 18:29:48 $ * | ||
6 | * Description: * | ||
7 | * DMA engine. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
25 | * All rights reserved. * | ||
26 | * * | ||
27 | * Maintainers: maintainers@chelsio.com * | ||
28 | * * | ||
29 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
30 | * Tina Yang <tainay@chelsio.com> * | ||
31 | * Felix Marti <felix@chelsio.com> * | ||
32 | * Scott Bardone <sbardone@chelsio.com> * | ||
33 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
34 | * Frank DiMambro <frank@chelsio.com> * | ||
35 | * * | ||
36 | * History: * | ||
37 | * * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include "common.h" | ||
41 | |||
42 | #include <linux/config.h> | ||
43 | #include <linux/types.h> | ||
44 | #include <linux/errno.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/netdevice.h> | ||
47 | #include <linux/etherdevice.h> | ||
48 | #include <linux/if_vlan.h> | ||
49 | #include <linux/skbuff.h> | ||
50 | #include <linux/init.h> | ||
51 | #include <linux/mm.h> | ||
52 | #include <linux/ip.h> | ||
53 | #include <linux/in.h> | ||
54 | #include <linux/if_arp.h> | ||
55 | |||
56 | #include "cpl5_cmd.h" | ||
57 | #include "sge.h" | ||
58 | #include "regs.h" | ||
59 | #include "espi.h" | ||
60 | |||
61 | |||
62 | #ifdef NETIF_F_TSO | ||
63 | #include <linux/tcp.h> | ||
64 | #endif | ||
65 | |||
66 | #define SGE_CMDQ_N 2 | ||
67 | #define SGE_FREELQ_N 2 | ||
68 | #define SGE_CMDQ0_E_N 1024 | ||
69 | #define SGE_CMDQ1_E_N 128 | ||
70 | #define SGE_FREEL_SIZE 4096 | ||
71 | #define SGE_JUMBO_FREEL_SIZE 512 | ||
72 | #define SGE_FREEL_REFILL_THRESH 16 | ||
73 | #define SGE_RESPQ_E_N 1024 | ||
74 | #define SGE_INTRTIMER_NRES 1000 | ||
75 | #define SGE_RX_COPY_THRES 256 | ||
76 | #define SGE_RX_SM_BUF_SIZE 1536 | ||
77 | |||
78 | # define SGE_RX_DROP_THRES 2 | ||
79 | |||
80 | #define SGE_RESPQ_REPLENISH_THRES (SGE_RESPQ_E_N / 4) | ||
81 | |||
82 | /* | ||
83 | * Period of the TX buffer reclaim timer. This timer does not need to run | ||
84 | * frequently as TX buffers are usually reclaimed by new TX packets. | ||
85 | */ | ||
86 | #define TX_RECLAIM_PERIOD (HZ / 4) | ||
87 | |||
88 | #ifndef NET_IP_ALIGN | ||
89 | # define NET_IP_ALIGN 2 | ||
90 | #endif | ||
91 | |||
92 | #define M_CMD_LEN 0x7fffffff | ||
93 | #define V_CMD_LEN(v) (v) | ||
94 | #define G_CMD_LEN(v) ((v) & M_CMD_LEN) | ||
95 | #define V_CMD_GEN1(v) ((v) << 31) | ||
96 | #define V_CMD_GEN2(v) (v) | ||
97 | #define F_CMD_DATAVALID (1 << 1) | ||
98 | #define F_CMD_SOP (1 << 2) | ||
99 | #define V_CMD_EOP(v) ((v) << 3) | ||
100 | |||
101 | /* | ||
102 | * Command queue, receive buffer list, and response queue descriptors. | ||
103 | */ | ||
104 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
105 | struct cmdQ_e { | ||
106 | u32 addr_lo; | ||
107 | u32 len_gen; | ||
108 | u32 flags; | ||
109 | u32 addr_hi; | ||
110 | }; | ||
111 | |||
112 | struct freelQ_e { | ||
113 | u32 addr_lo; | ||
114 | u32 len_gen; | ||
115 | u32 gen2; | ||
116 | u32 addr_hi; | ||
117 | }; | ||
118 | |||
119 | struct respQ_e { | ||
120 | u32 Qsleeping : 4; | ||
121 | u32 Cmdq1CreditReturn : 5; | ||
122 | u32 Cmdq1DmaComplete : 5; | ||
123 | u32 Cmdq0CreditReturn : 5; | ||
124 | u32 Cmdq0DmaComplete : 5; | ||
125 | u32 FreelistQid : 2; | ||
126 | u32 CreditValid : 1; | ||
127 | u32 DataValid : 1; | ||
128 | u32 Offload : 1; | ||
129 | u32 Eop : 1; | ||
130 | u32 Sop : 1; | ||
131 | u32 GenerationBit : 1; | ||
132 | u32 BufferLength; | ||
133 | }; | ||
134 | #elif defined(__LITTLE_ENDIAN_BITFIELD) | ||
135 | struct cmdQ_e { | ||
136 | u32 len_gen; | ||
137 | u32 addr_lo; | ||
138 | u32 addr_hi; | ||
139 | u32 flags; | ||
140 | }; | ||
141 | |||
142 | struct freelQ_e { | ||
143 | u32 len_gen; | ||
144 | u32 addr_lo; | ||
145 | u32 addr_hi; | ||
146 | u32 gen2; | ||
147 | }; | ||
148 | |||
149 | struct respQ_e { | ||
150 | u32 BufferLength; | ||
151 | u32 GenerationBit : 1; | ||
152 | u32 Sop : 1; | ||
153 | u32 Eop : 1; | ||
154 | u32 Offload : 1; | ||
155 | u32 DataValid : 1; | ||
156 | u32 CreditValid : 1; | ||
157 | u32 FreelistQid : 2; | ||
158 | u32 Cmdq0DmaComplete : 5; | ||
159 | u32 Cmdq0CreditReturn : 5; | ||
160 | u32 Cmdq1DmaComplete : 5; | ||
161 | u32 Cmdq1CreditReturn : 5; | ||
162 | u32 Qsleeping : 4; | ||
163 | } ; | ||
164 | #endif | ||
165 | |||
166 | /* | ||
167 | * SW Context Command and Freelist Queue Descriptors | ||
168 | */ | ||
169 | struct cmdQ_ce { | ||
170 | struct sk_buff *skb; | ||
171 | DECLARE_PCI_UNMAP_ADDR(dma_addr); | ||
172 | DECLARE_PCI_UNMAP_LEN(dma_len); | ||
173 | }; | ||
174 | |||
175 | struct freelQ_ce { | ||
176 | struct sk_buff *skb; | ||
177 | DECLARE_PCI_UNMAP_ADDR(dma_addr); | ||
178 | DECLARE_PCI_UNMAP_LEN(dma_len); | ||
179 | }; | ||
180 | |||
181 | /* | ||
182 | * SW command, freelist and response rings | ||
183 | */ | ||
184 | struct cmdQ { | ||
185 | unsigned long status; /* HW DMA fetch status */ | ||
186 | unsigned int in_use; /* # of in-use command descriptors */ | ||
187 | unsigned int size; /* # of descriptors */ | ||
188 | unsigned int processed; /* total # of descs HW has processed */ | ||
189 | unsigned int cleaned; /* total # of descs SW has reclaimed */ | ||
190 | unsigned int stop_thres; /* SW TX queue suspend threshold */ | ||
191 | u16 pidx; /* producer index (SW) */ | ||
192 | u16 cidx; /* consumer index (HW) */ | ||
193 | u8 genbit; /* current generation (=valid) bit */ | ||
194 | u8 sop; /* is next entry start of packet? */ | ||
195 | struct cmdQ_e *entries; /* HW command descriptor Q */ | ||
196 | struct cmdQ_ce *centries; /* SW command context descriptor Q */ | ||
197 | spinlock_t lock; /* Lock to protect cmdQ enqueuing */ | ||
198 | dma_addr_t dma_addr; /* DMA addr HW command descriptor Q */ | ||
199 | }; | ||
200 | |||
201 | struct freelQ { | ||
202 | unsigned int credits; /* # of available RX buffers */ | ||
203 | unsigned int size; /* free list capacity */ | ||
204 | u16 pidx; /* producer index (SW) */ | ||
205 | u16 cidx; /* consumer index (HW) */ | ||
206 | u16 rx_buffer_size; /* Buffer size on this free list */ | ||
207 | u16 dma_offset; /* DMA offset to align IP headers */ | ||
208 | u16 recycleq_idx; /* skb recycle q to use */ | ||
209 | u8 genbit; /* current generation (=valid) bit */ | ||
210 | struct freelQ_e *entries; /* HW freelist descriptor Q */ | ||
211 | struct freelQ_ce *centries; /* SW freelist context descriptor Q */ | ||
212 | dma_addr_t dma_addr; /* DMA addr HW freelist descriptor Q */ | ||
213 | }; | ||
214 | |||
215 | struct respQ { | ||
216 | unsigned int credits; /* credits to be returned to SGE */ | ||
217 | unsigned int size; /* # of response Q descriptors */ | ||
218 | u16 cidx; /* consumer index (SW) */ | ||
219 | u8 genbit; /* current generation(=valid) bit */ | ||
220 | struct respQ_e *entries; /* HW response descriptor Q */ | ||
221 | dma_addr_t dma_addr; /* DMA addr HW response descriptor Q */ | ||
222 | }; | ||
223 | |||
224 | /* Bit flags for cmdQ.status */ | ||
225 | enum { | ||
226 | CMDQ_STAT_RUNNING = 1, /* fetch engine is running */ | ||
227 | CMDQ_STAT_LAST_PKT_DB = 2 /* last packet rung the doorbell */ | ||
228 | }; | ||
229 | |||
230 | /* | ||
231 | * Main SGE data structure | ||
232 | * | ||
233 | * Interrupts are handled by a single CPU and it is likely that on a MP system | ||
234 | * the application is migrated to another CPU. In that scenario, we try to | ||
235 | * seperate the RX(in irq context) and TX state in order to decrease memory | ||
236 | * contention. | ||
237 | */ | ||
238 | struct sge { | ||
239 | struct adapter *adapter; /* adapter backpointer */ | ||
240 | struct net_device *netdev; /* netdevice backpointer */ | ||
241 | struct freelQ freelQ[SGE_FREELQ_N]; /* buffer free lists */ | ||
242 | struct respQ respQ; /* response Q */ | ||
243 | unsigned long stopped_tx_queues; /* bitmap of suspended Tx queues */ | ||
244 | unsigned int rx_pkt_pad; /* RX padding for L2 packets */ | ||
245 | unsigned int jumbo_fl; /* jumbo freelist Q index */ | ||
246 | unsigned int intrtimer_nres; /* no-resource interrupt timer */ | ||
247 | unsigned int fixed_intrtimer;/* non-adaptive interrupt timer */ | ||
248 | struct timer_list tx_reclaim_timer; /* reclaims TX buffers */ | ||
249 | struct timer_list espibug_timer; | ||
250 | unsigned int espibug_timeout; | ||
251 | struct sk_buff *espibug_skb; | ||
252 | u32 sge_control; /* shadow value of sge control reg */ | ||
253 | struct sge_intr_counts stats; | ||
254 | struct sge_port_stats port_stats[MAX_NPORTS]; | ||
255 | struct cmdQ cmdQ[SGE_CMDQ_N] ____cacheline_aligned_in_smp; | ||
256 | }; | ||
257 | |||
258 | /* | ||
259 | * PIO to indicate that memory mapped Q contains valid descriptor(s). | ||
260 | */ | ||
261 | static inline void doorbell_pio(struct adapter *adapter, u32 val) | ||
262 | { | ||
263 | wmb(); | ||
264 | writel(val, adapter->regs + A_SG_DOORBELL); | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Frees all RX buffers on the freelist Q. The caller must make sure that | ||
269 | * the SGE is turned off before calling this function. | ||
270 | */ | ||
271 | static void free_freelQ_buffers(struct pci_dev *pdev, struct freelQ *q) | ||
272 | { | ||
273 | unsigned int cidx = q->cidx; | ||
274 | |||
275 | while (q->credits--) { | ||
276 | struct freelQ_ce *ce = &q->centries[cidx]; | ||
277 | |||
278 | pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr), | ||
279 | pci_unmap_len(ce, dma_len), | ||
280 | PCI_DMA_FROMDEVICE); | ||
281 | dev_kfree_skb(ce->skb); | ||
282 | ce->skb = NULL; | ||
283 | if (++cidx == q->size) | ||
284 | cidx = 0; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | /* | ||
289 | * Free RX free list and response queue resources. | ||
290 | */ | ||
291 | static void free_rx_resources(struct sge *sge) | ||
292 | { | ||
293 | struct pci_dev *pdev = sge->adapter->pdev; | ||
294 | unsigned int size, i; | ||
295 | |||
296 | if (sge->respQ.entries) { | ||
297 | size = sizeof(struct respQ_e) * sge->respQ.size; | ||
298 | pci_free_consistent(pdev, size, sge->respQ.entries, | ||
299 | sge->respQ.dma_addr); | ||
300 | } | ||
301 | |||
302 | for (i = 0; i < SGE_FREELQ_N; i++) { | ||
303 | struct freelQ *q = &sge->freelQ[i]; | ||
304 | |||
305 | if (q->centries) { | ||
306 | free_freelQ_buffers(pdev, q); | ||
307 | kfree(q->centries); | ||
308 | } | ||
309 | if (q->entries) { | ||
310 | size = sizeof(struct freelQ_e) * q->size; | ||
311 | pci_free_consistent(pdev, size, q->entries, | ||
312 | q->dma_addr); | ||
313 | } | ||
314 | } | ||
315 | } | ||
316 | |||
317 | /* | ||
318 | * Allocates basic RX resources, consisting of memory mapped freelist Qs and a | ||
319 | * response queue. | ||
320 | */ | ||
321 | static int alloc_rx_resources(struct sge *sge, struct sge_params *p) | ||
322 | { | ||
323 | struct pci_dev *pdev = sge->adapter->pdev; | ||
324 | unsigned int size, i; | ||
325 | |||
326 | for (i = 0; i < SGE_FREELQ_N; i++) { | ||
327 | struct freelQ *q = &sge->freelQ[i]; | ||
328 | |||
329 | q->genbit = 1; | ||
330 | q->size = p->freelQ_size[i]; | ||
331 | q->dma_offset = sge->rx_pkt_pad ? 0 : NET_IP_ALIGN; | ||
332 | size = sizeof(struct freelQ_e) * q->size; | ||
333 | q->entries = (struct freelQ_e *) | ||
334 | pci_alloc_consistent(pdev, size, &q->dma_addr); | ||
335 | if (!q->entries) | ||
336 | goto err_no_mem; | ||
337 | memset(q->entries, 0, size); | ||
338 | size = sizeof(struct freelQ_ce) * q->size; | ||
339 | q->centries = kmalloc(size, GFP_KERNEL); | ||
340 | if (!q->centries) | ||
341 | goto err_no_mem; | ||
342 | memset(q->centries, 0, size); | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * Calculate the buffer sizes for the two free lists. FL0 accommodates | ||
347 | * regular sized Ethernet frames, FL1 is sized not to exceed 16K, | ||
348 | * including all the sk_buff overhead. | ||
349 | * | ||
350 | * Note: For T2 FL0 and FL1 are reversed. | ||
351 | */ | ||
352 | sge->freelQ[!sge->jumbo_fl].rx_buffer_size = SGE_RX_SM_BUF_SIZE + | ||
353 | sizeof(struct cpl_rx_data) + | ||
354 | sge->freelQ[!sge->jumbo_fl].dma_offset; | ||
355 | sge->freelQ[sge->jumbo_fl].rx_buffer_size = (16 * 1024) - | ||
356 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); | ||
357 | |||
358 | /* | ||
359 | * Setup which skb recycle Q should be used when recycling buffers from | ||
360 | * each free list. | ||
361 | */ | ||
362 | sge->freelQ[!sge->jumbo_fl].recycleq_idx = 0; | ||
363 | sge->freelQ[sge->jumbo_fl].recycleq_idx = 1; | ||
364 | |||
365 | sge->respQ.genbit = 1; | ||
366 | sge->respQ.size = SGE_RESPQ_E_N; | ||
367 | sge->respQ.credits = 0; | ||
368 | size = sizeof(struct respQ_e) * sge->respQ.size; | ||
369 | sge->respQ.entries = (struct respQ_e *) | ||
370 | pci_alloc_consistent(pdev, size, &sge->respQ.dma_addr); | ||
371 | if (!sge->respQ.entries) | ||
372 | goto err_no_mem; | ||
373 | memset(sge->respQ.entries, 0, size); | ||
374 | return 0; | ||
375 | |||
376 | err_no_mem: | ||
377 | free_rx_resources(sge); | ||
378 | return -ENOMEM; | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Reclaims n TX descriptors and frees the buffers associated with them. | ||
383 | */ | ||
384 | static void free_cmdQ_buffers(struct sge *sge, struct cmdQ *q, unsigned int n) | ||
385 | { | ||
386 | struct cmdQ_ce *ce; | ||
387 | struct pci_dev *pdev = sge->adapter->pdev; | ||
388 | unsigned int cidx = q->cidx; | ||
389 | |||
390 | q->in_use -= n; | ||
391 | ce = &q->centries[cidx]; | ||
392 | while (n--) { | ||
393 | if (q->sop) | ||
394 | pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr), | ||
395 | pci_unmap_len(ce, dma_len), | ||
396 | PCI_DMA_TODEVICE); | ||
397 | else | ||
398 | pci_unmap_page(pdev, pci_unmap_addr(ce, dma_addr), | ||
399 | pci_unmap_len(ce, dma_len), | ||
400 | PCI_DMA_TODEVICE); | ||
401 | q->sop = 0; | ||
402 | if (ce->skb) { | ||
403 | dev_kfree_skb(ce->skb); | ||
404 | q->sop = 1; | ||
405 | } | ||
406 | ce++; | ||
407 | if (++cidx == q->size) { | ||
408 | cidx = 0; | ||
409 | ce = q->centries; | ||
410 | } | ||
411 | } | ||
412 | q->cidx = cidx; | ||
413 | } | ||
414 | |||
415 | /* | ||
416 | * Free TX resources. | ||
417 | * | ||
418 | * Assumes that SGE is stopped and all interrupts are disabled. | ||
419 | */ | ||
420 | static void free_tx_resources(struct sge *sge) | ||
421 | { | ||
422 | struct pci_dev *pdev = sge->adapter->pdev; | ||
423 | unsigned int size, i; | ||
424 | |||
425 | for (i = 0; i < SGE_CMDQ_N; i++) { | ||
426 | struct cmdQ *q = &sge->cmdQ[i]; | ||
427 | |||
428 | if (q->centries) { | ||
429 | if (q->in_use) | ||
430 | free_cmdQ_buffers(sge, q, q->in_use); | ||
431 | kfree(q->centries); | ||
432 | } | ||
433 | if (q->entries) { | ||
434 | size = sizeof(struct cmdQ_e) * q->size; | ||
435 | pci_free_consistent(pdev, size, q->entries, | ||
436 | q->dma_addr); | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Allocates basic TX resources, consisting of memory mapped command Qs. | ||
443 | */ | ||
444 | static int alloc_tx_resources(struct sge *sge, struct sge_params *p) | ||
445 | { | ||
446 | struct pci_dev *pdev = sge->adapter->pdev; | ||
447 | unsigned int size, i; | ||
448 | |||
449 | for (i = 0; i < SGE_CMDQ_N; i++) { | ||
450 | struct cmdQ *q = &sge->cmdQ[i]; | ||
451 | |||
452 | q->genbit = 1; | ||
453 | q->sop = 1; | ||
454 | q->size = p->cmdQ_size[i]; | ||
455 | q->in_use = 0; | ||
456 | q->status = 0; | ||
457 | q->processed = q->cleaned = 0; | ||
458 | q->stop_thres = 0; | ||
459 | spin_lock_init(&q->lock); | ||
460 | size = sizeof(struct cmdQ_e) * q->size; | ||
461 | q->entries = (struct cmdQ_e *) | ||
462 | pci_alloc_consistent(pdev, size, &q->dma_addr); | ||
463 | if (!q->entries) | ||
464 | goto err_no_mem; | ||
465 | memset(q->entries, 0, size); | ||
466 | size = sizeof(struct cmdQ_ce) * q->size; | ||
467 | q->centries = kmalloc(size, GFP_KERNEL); | ||
468 | if (!q->centries) | ||
469 | goto err_no_mem; | ||
470 | memset(q->centries, 0, size); | ||
471 | } | ||
472 | |||
473 | /* | ||
474 | * CommandQ 0 handles Ethernet and TOE packets, while queue 1 is TOE | ||
475 | * only. For queue 0 set the stop threshold so we can handle one more | ||
476 | * packet from each port, plus reserve an additional 24 entries for | ||
477 | * Ethernet packets only. Queue 1 never suspends nor do we reserve | ||
478 | * space for Ethernet packets. | ||
479 | */ | ||
480 | sge->cmdQ[0].stop_thres = sge->adapter->params.nports * | ||
481 | (MAX_SKB_FRAGS + 1); | ||
482 | return 0; | ||
483 | |||
484 | err_no_mem: | ||
485 | free_tx_resources(sge); | ||
486 | return -ENOMEM; | ||
487 | } | ||
488 | |||
489 | static inline void setup_ring_params(struct adapter *adapter, u64 addr, | ||
490 | u32 size, int base_reg_lo, | ||
491 | int base_reg_hi, int size_reg) | ||
492 | { | ||
493 | writel((u32)addr, adapter->regs + base_reg_lo); | ||
494 | writel(addr >> 32, adapter->regs + base_reg_hi); | ||
495 | writel(size, adapter->regs + size_reg); | ||
496 | } | ||
497 | |||
498 | /* | ||
499 | * Enable/disable VLAN acceleration. | ||
500 | */ | ||
501 | void t1_set_vlan_accel(struct adapter *adapter, int on_off) | ||
502 | { | ||
503 | struct sge *sge = adapter->sge; | ||
504 | |||
505 | sge->sge_control &= ~F_VLAN_XTRACT; | ||
506 | if (on_off) | ||
507 | sge->sge_control |= F_VLAN_XTRACT; | ||
508 | if (adapter->open_device_map) { | ||
509 | writel(sge->sge_control, adapter->regs + A_SG_CONTROL); | ||
510 | readl(adapter->regs + A_SG_CONTROL); /* flush */ | ||
511 | } | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Programs the various SGE registers. However, the engine is not yet enabled, | ||
516 | * but sge->sge_control is setup and ready to go. | ||
517 | */ | ||
518 | static void configure_sge(struct sge *sge, struct sge_params *p) | ||
519 | { | ||
520 | struct adapter *ap = sge->adapter; | ||
521 | |||
522 | writel(0, ap->regs + A_SG_CONTROL); | ||
523 | setup_ring_params(ap, sge->cmdQ[0].dma_addr, sge->cmdQ[0].size, | ||
524 | A_SG_CMD0BASELWR, A_SG_CMD0BASEUPR, A_SG_CMD0SIZE); | ||
525 | setup_ring_params(ap, sge->cmdQ[1].dma_addr, sge->cmdQ[1].size, | ||
526 | A_SG_CMD1BASELWR, A_SG_CMD1BASEUPR, A_SG_CMD1SIZE); | ||
527 | setup_ring_params(ap, sge->freelQ[0].dma_addr, | ||
528 | sge->freelQ[0].size, A_SG_FL0BASELWR, | ||
529 | A_SG_FL0BASEUPR, A_SG_FL0SIZE); | ||
530 | setup_ring_params(ap, sge->freelQ[1].dma_addr, | ||
531 | sge->freelQ[1].size, A_SG_FL1BASELWR, | ||
532 | A_SG_FL1BASEUPR, A_SG_FL1SIZE); | ||
533 | |||
534 | /* The threshold comparison uses <. */ | ||
535 | writel(SGE_RX_SM_BUF_SIZE + 1, ap->regs + A_SG_FLTHRESHOLD); | ||
536 | |||
537 | setup_ring_params(ap, sge->respQ.dma_addr, sge->respQ.size, | ||
538 | A_SG_RSPBASELWR, A_SG_RSPBASEUPR, A_SG_RSPSIZE); | ||
539 | writel((u32)sge->respQ.size - 1, ap->regs + A_SG_RSPQUEUECREDIT); | ||
540 | |||
541 | sge->sge_control = F_CMDQ0_ENABLE | F_CMDQ1_ENABLE | F_FL0_ENABLE | | ||
542 | F_FL1_ENABLE | F_CPL_ENABLE | F_RESPONSE_QUEUE_ENABLE | | ||
543 | V_CMDQ_PRIORITY(2) | F_DISABLE_CMDQ1_GTS | F_ISCSI_COALESCE | | ||
544 | F_DISABLE_FL0_GTS | F_DISABLE_FL1_GTS | | ||
545 | V_RX_PKT_OFFSET(sge->rx_pkt_pad); | ||
546 | |||
547 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
548 | sge->sge_control |= F_ENABLE_BIG_ENDIAN; | ||
549 | #endif | ||
550 | |||
551 | /* Initialize no-resource timer */ | ||
552 | sge->intrtimer_nres = SGE_INTRTIMER_NRES * core_ticks_per_usec(ap); | ||
553 | |||
554 | t1_sge_set_coalesce_params(sge, p); | ||
555 | } | ||
556 | |||
557 | /* | ||
558 | * Return the payload capacity of the jumbo free-list buffers. | ||
559 | */ | ||
560 | static inline unsigned int jumbo_payload_capacity(const struct sge *sge) | ||
561 | { | ||
562 | return sge->freelQ[sge->jumbo_fl].rx_buffer_size - | ||
563 | sge->freelQ[sge->jumbo_fl].dma_offset - | ||
564 | sizeof(struct cpl_rx_data); | ||
565 | } | ||
566 | |||
567 | /* | ||
568 | * Frees all SGE related resources and the sge structure itself | ||
569 | */ | ||
570 | void t1_sge_destroy(struct sge *sge) | ||
571 | { | ||
572 | if (sge->espibug_skb) | ||
573 | kfree_skb(sge->espibug_skb); | ||
574 | |||
575 | free_tx_resources(sge); | ||
576 | free_rx_resources(sge); | ||
577 | kfree(sge); | ||
578 | } | ||
579 | |||
580 | /* | ||
581 | * Allocates new RX buffers on the freelist Q (and tracks them on the freelist | ||
582 | * context Q) until the Q is full or alloc_skb fails. | ||
583 | * | ||
584 | * It is possible that the generation bits already match, indicating that the | ||
585 | * buffer is already valid and nothing needs to be done. This happens when we | ||
586 | * copied a received buffer into a new sk_buff during the interrupt processing. | ||
587 | * | ||
588 | * If the SGE doesn't automatically align packets properly (!sge->rx_pkt_pad), | ||
589 | * we specify a RX_OFFSET in order to make sure that the IP header is 4B | ||
590 | * aligned. | ||
591 | */ | ||
592 | static void refill_free_list(struct sge *sge, struct freelQ *q) | ||
593 | { | ||
594 | struct pci_dev *pdev = sge->adapter->pdev; | ||
595 | struct freelQ_ce *ce = &q->centries[q->pidx]; | ||
596 | struct freelQ_e *e = &q->entries[q->pidx]; | ||
597 | unsigned int dma_len = q->rx_buffer_size - q->dma_offset; | ||
598 | |||
599 | |||
600 | while (q->credits < q->size) { | ||
601 | struct sk_buff *skb; | ||
602 | dma_addr_t mapping; | ||
603 | |||
604 | skb = alloc_skb(q->rx_buffer_size, GFP_ATOMIC); | ||
605 | if (!skb) | ||
606 | break; | ||
607 | |||
608 | skb_reserve(skb, q->dma_offset); | ||
609 | mapping = pci_map_single(pdev, skb->data, dma_len, | ||
610 | PCI_DMA_FROMDEVICE); | ||
611 | ce->skb = skb; | ||
612 | pci_unmap_addr_set(ce, dma_addr, mapping); | ||
613 | pci_unmap_len_set(ce, dma_len, dma_len); | ||
614 | e->addr_lo = (u32)mapping; | ||
615 | e->addr_hi = (u64)mapping >> 32; | ||
616 | e->len_gen = V_CMD_LEN(dma_len) | V_CMD_GEN1(q->genbit); | ||
617 | wmb(); | ||
618 | e->gen2 = V_CMD_GEN2(q->genbit); | ||
619 | |||
620 | e++; | ||
621 | ce++; | ||
622 | if (++q->pidx == q->size) { | ||
623 | q->pidx = 0; | ||
624 | q->genbit ^= 1; | ||
625 | ce = q->centries; | ||
626 | e = q->entries; | ||
627 | } | ||
628 | q->credits++; | ||
629 | } | ||
630 | |||
631 | } | ||
632 | |||
633 | /* | ||
634 | * Calls refill_free_list for both free lists. If we cannot fill at least 1/4 | ||
635 | * of both rings, we go into 'few interrupt mode' in order to give the system | ||
636 | * time to free up resources. | ||
637 | */ | ||
638 | static void freelQs_empty(struct sge *sge) | ||
639 | { | ||
640 | struct adapter *adapter = sge->adapter; | ||
641 | u32 irq_reg = readl(adapter->regs + A_SG_INT_ENABLE); | ||
642 | u32 irqholdoff_reg; | ||
643 | |||
644 | refill_free_list(sge, &sge->freelQ[0]); | ||
645 | refill_free_list(sge, &sge->freelQ[1]); | ||
646 | |||
647 | if (sge->freelQ[0].credits > (sge->freelQ[0].size >> 2) && | ||
648 | sge->freelQ[1].credits > (sge->freelQ[1].size >> 2)) { | ||
649 | irq_reg |= F_FL_EXHAUSTED; | ||
650 | irqholdoff_reg = sge->fixed_intrtimer; | ||
651 | } else { | ||
652 | /* Clear the F_FL_EXHAUSTED interrupts for now */ | ||
653 | irq_reg &= ~F_FL_EXHAUSTED; | ||
654 | irqholdoff_reg = sge->intrtimer_nres; | ||
655 | } | ||
656 | writel(irqholdoff_reg, adapter->regs + A_SG_INTRTIMER); | ||
657 | writel(irq_reg, adapter->regs + A_SG_INT_ENABLE); | ||
658 | |||
659 | /* We reenable the Qs to force a freelist GTS interrupt later */ | ||
660 | doorbell_pio(adapter, F_FL0_ENABLE | F_FL1_ENABLE); | ||
661 | } | ||
662 | |||
663 | #define SGE_PL_INTR_MASK (F_PL_INTR_SGE_ERR | F_PL_INTR_SGE_DATA) | ||
664 | #define SGE_INT_FATAL (F_RESPQ_OVERFLOW | F_PACKET_TOO_BIG | F_PACKET_MISMATCH) | ||
665 | #define SGE_INT_ENABLE (F_RESPQ_EXHAUSTED | F_RESPQ_OVERFLOW | \ | ||
666 | F_FL_EXHAUSTED | F_PACKET_TOO_BIG | F_PACKET_MISMATCH) | ||
667 | |||
668 | /* | ||
669 | * Disable SGE Interrupts | ||
670 | */ | ||
671 | void t1_sge_intr_disable(struct sge *sge) | ||
672 | { | ||
673 | u32 val = readl(sge->adapter->regs + A_PL_ENABLE); | ||
674 | |||
675 | writel(val & ~SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE); | ||
676 | writel(0, sge->adapter->regs + A_SG_INT_ENABLE); | ||
677 | } | ||
678 | |||
679 | /* | ||
680 | * Enable SGE interrupts. | ||
681 | */ | ||
682 | void t1_sge_intr_enable(struct sge *sge) | ||
683 | { | ||
684 | u32 en = SGE_INT_ENABLE; | ||
685 | u32 val = readl(sge->adapter->regs + A_PL_ENABLE); | ||
686 | |||
687 | if (sge->adapter->flags & TSO_CAPABLE) | ||
688 | en &= ~F_PACKET_TOO_BIG; | ||
689 | writel(en, sge->adapter->regs + A_SG_INT_ENABLE); | ||
690 | writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE); | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | * Clear SGE interrupts. | ||
695 | */ | ||
696 | void t1_sge_intr_clear(struct sge *sge) | ||
697 | { | ||
698 | writel(SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_CAUSE); | ||
699 | writel(0xffffffff, sge->adapter->regs + A_SG_INT_CAUSE); | ||
700 | } | ||
701 | |||
702 | /* | ||
703 | * SGE 'Error' interrupt handler | ||
704 | */ | ||
705 | int t1_sge_intr_error_handler(struct sge *sge) | ||
706 | { | ||
707 | struct adapter *adapter = sge->adapter; | ||
708 | u32 cause = readl(adapter->regs + A_SG_INT_CAUSE); | ||
709 | |||
710 | if (adapter->flags & TSO_CAPABLE) | ||
711 | cause &= ~F_PACKET_TOO_BIG; | ||
712 | if (cause & F_RESPQ_EXHAUSTED) | ||
713 | sge->stats.respQ_empty++; | ||
714 | if (cause & F_RESPQ_OVERFLOW) { | ||
715 | sge->stats.respQ_overflow++; | ||
716 | CH_ALERT("%s: SGE response queue overflow\n", | ||
717 | adapter->name); | ||
718 | } | ||
719 | if (cause & F_FL_EXHAUSTED) { | ||
720 | sge->stats.freelistQ_empty++; | ||
721 | freelQs_empty(sge); | ||
722 | } | ||
723 | if (cause & F_PACKET_TOO_BIG) { | ||
724 | sge->stats.pkt_too_big++; | ||
725 | CH_ALERT("%s: SGE max packet size exceeded\n", | ||
726 | adapter->name); | ||
727 | } | ||
728 | if (cause & F_PACKET_MISMATCH) { | ||
729 | sge->stats.pkt_mismatch++; | ||
730 | CH_ALERT("%s: SGE packet mismatch\n", adapter->name); | ||
731 | } | ||
732 | if (cause & SGE_INT_FATAL) | ||
733 | t1_fatal_err(adapter); | ||
734 | |||
735 | writel(cause, adapter->regs + A_SG_INT_CAUSE); | ||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge) | ||
740 | { | ||
741 | return &sge->stats; | ||
742 | } | ||
743 | |||
744 | const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port) | ||
745 | { | ||
746 | return &sge->port_stats[port]; | ||
747 | } | ||
748 | |||
749 | /** | ||
750 | * recycle_fl_buf - recycle a free list buffer | ||
751 | * @fl: the free list | ||
752 | * @idx: index of buffer to recycle | ||
753 | * | ||
754 | * Recycles the specified buffer on the given free list by adding it at | ||
755 | * the next available slot on the list. | ||
756 | */ | ||
757 | static void recycle_fl_buf(struct freelQ *fl, int idx) | ||
758 | { | ||
759 | struct freelQ_e *from = &fl->entries[idx]; | ||
760 | struct freelQ_e *to = &fl->entries[fl->pidx]; | ||
761 | |||
762 | fl->centries[fl->pidx] = fl->centries[idx]; | ||
763 | to->addr_lo = from->addr_lo; | ||
764 | to->addr_hi = from->addr_hi; | ||
765 | to->len_gen = G_CMD_LEN(from->len_gen) | V_CMD_GEN1(fl->genbit); | ||
766 | wmb(); | ||
767 | to->gen2 = V_CMD_GEN2(fl->genbit); | ||
768 | fl->credits++; | ||
769 | |||
770 | if (++fl->pidx == fl->size) { | ||
771 | fl->pidx = 0; | ||
772 | fl->genbit ^= 1; | ||
773 | } | ||
774 | } | ||
775 | |||
776 | /** | ||
777 | * get_packet - return the next ingress packet buffer | ||
778 | * @pdev: the PCI device that received the packet | ||
779 | * @fl: the SGE free list holding the packet | ||
780 | * @len: the actual packet length, excluding any SGE padding | ||
781 | * @dma_pad: padding at beginning of buffer left by SGE DMA | ||
782 | * @skb_pad: padding to be used if the packet is copied | ||
783 | * @copy_thres: length threshold under which a packet should be copied | ||
784 | * @drop_thres: # of remaining buffers before we start dropping packets | ||
785 | * | ||
786 | * Get the next packet from a free list and complete setup of the | ||
787 | * sk_buff. If the packet is small we make a copy and recycle the | ||
788 | * original buffer, otherwise we use the original buffer itself. If a | ||
789 | * positive drop threshold is supplied packets are dropped and their | ||
790 | * buffers recycled if (a) the number of remaining buffers is under the | ||
791 | * threshold and the packet is too big to copy, or (b) the packet should | ||
792 | * be copied but there is no memory for the copy. | ||
793 | */ | ||
794 | static inline struct sk_buff *get_packet(struct pci_dev *pdev, | ||
795 | struct freelQ *fl, unsigned int len, | ||
796 | int dma_pad, int skb_pad, | ||
797 | unsigned int copy_thres, | ||
798 | unsigned int drop_thres) | ||
799 | { | ||
800 | struct sk_buff *skb; | ||
801 | struct freelQ_ce *ce = &fl->centries[fl->cidx]; | ||
802 | |||
803 | if (len < copy_thres) { | ||
804 | skb = alloc_skb(len + skb_pad, GFP_ATOMIC); | ||
805 | if (likely(skb != NULL)) { | ||
806 | skb_reserve(skb, skb_pad); | ||
807 | skb_put(skb, len); | ||
808 | pci_dma_sync_single_for_cpu(pdev, | ||
809 | pci_unmap_addr(ce, dma_addr), | ||
810 | pci_unmap_len(ce, dma_len), | ||
811 | PCI_DMA_FROMDEVICE); | ||
812 | memcpy(skb->data, ce->skb->data + dma_pad, len); | ||
813 | pci_dma_sync_single_for_device(pdev, | ||
814 | pci_unmap_addr(ce, dma_addr), | ||
815 | pci_unmap_len(ce, dma_len), | ||
816 | PCI_DMA_FROMDEVICE); | ||
817 | } else if (!drop_thres) | ||
818 | goto use_orig_buf; | ||
819 | |||
820 | recycle_fl_buf(fl, fl->cidx); | ||
821 | return skb; | ||
822 | } | ||
823 | |||
824 | if (fl->credits < drop_thres) { | ||
825 | recycle_fl_buf(fl, fl->cidx); | ||
826 | return NULL; | ||
827 | } | ||
828 | |||
829 | use_orig_buf: | ||
830 | pci_unmap_single(pdev, pci_unmap_addr(ce, dma_addr), | ||
831 | pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE); | ||
832 | skb = ce->skb; | ||
833 | skb_reserve(skb, dma_pad); | ||
834 | skb_put(skb, len); | ||
835 | return skb; | ||
836 | } | ||
837 | |||
838 | /** | ||
839 | * unexpected_offload - handle an unexpected offload packet | ||
840 | * @adapter: the adapter | ||
841 | * @fl: the free list that received the packet | ||
842 | * | ||
843 | * Called when we receive an unexpected offload packet (e.g., the TOE | ||
844 | * function is disabled or the card is a NIC). Prints a message and | ||
845 | * recycles the buffer. | ||
846 | */ | ||
847 | static void unexpected_offload(struct adapter *adapter, struct freelQ *fl) | ||
848 | { | ||
849 | struct freelQ_ce *ce = &fl->centries[fl->cidx]; | ||
850 | struct sk_buff *skb = ce->skb; | ||
851 | |||
852 | pci_dma_sync_single_for_cpu(adapter->pdev, pci_unmap_addr(ce, dma_addr), | ||
853 | pci_unmap_len(ce, dma_len), PCI_DMA_FROMDEVICE); | ||
854 | CH_ERR("%s: unexpected offload packet, cmd %u\n", | ||
855 | adapter->name, *skb->data); | ||
856 | recycle_fl_buf(fl, fl->cidx); | ||
857 | } | ||
858 | |||
859 | /* | ||
860 | * Write the command descriptors to transmit the given skb starting at | ||
861 | * descriptor pidx with the given generation. | ||
862 | */ | ||
863 | static inline void write_tx_descs(struct adapter *adapter, struct sk_buff *skb, | ||
864 | unsigned int pidx, unsigned int gen, | ||
865 | struct cmdQ *q) | ||
866 | { | ||
867 | dma_addr_t mapping; | ||
868 | struct cmdQ_e *e, *e1; | ||
869 | struct cmdQ_ce *ce; | ||
870 | unsigned int i, flags, nfrags = skb_shinfo(skb)->nr_frags; | ||
871 | |||
872 | mapping = pci_map_single(adapter->pdev, skb->data, | ||
873 | skb->len - skb->data_len, PCI_DMA_TODEVICE); | ||
874 | ce = &q->centries[pidx]; | ||
875 | ce->skb = NULL; | ||
876 | pci_unmap_addr_set(ce, dma_addr, mapping); | ||
877 | pci_unmap_len_set(ce, dma_len, skb->len - skb->data_len); | ||
878 | |||
879 | flags = F_CMD_DATAVALID | F_CMD_SOP | V_CMD_EOP(nfrags == 0) | | ||
880 | V_CMD_GEN2(gen); | ||
881 | e = &q->entries[pidx]; | ||
882 | e->addr_lo = (u32)mapping; | ||
883 | e->addr_hi = (u64)mapping >> 32; | ||
884 | e->len_gen = V_CMD_LEN(skb->len - skb->data_len) | V_CMD_GEN1(gen); | ||
885 | for (e1 = e, i = 0; nfrags--; i++) { | ||
886 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | ||
887 | |||
888 | ce++; | ||
889 | e1++; | ||
890 | if (++pidx == q->size) { | ||
891 | pidx = 0; | ||
892 | gen ^= 1; | ||
893 | ce = q->centries; | ||
894 | e1 = q->entries; | ||
895 | } | ||
896 | |||
897 | mapping = pci_map_page(adapter->pdev, frag->page, | ||
898 | frag->page_offset, frag->size, | ||
899 | PCI_DMA_TODEVICE); | ||
900 | ce->skb = NULL; | ||
901 | pci_unmap_addr_set(ce, dma_addr, mapping); | ||
902 | pci_unmap_len_set(ce, dma_len, frag->size); | ||
903 | |||
904 | e1->addr_lo = (u32)mapping; | ||
905 | e1->addr_hi = (u64)mapping >> 32; | ||
906 | e1->len_gen = V_CMD_LEN(frag->size) | V_CMD_GEN1(gen); | ||
907 | e1->flags = F_CMD_DATAVALID | V_CMD_EOP(nfrags == 0) | | ||
908 | V_CMD_GEN2(gen); | ||
909 | } | ||
910 | |||
911 | ce->skb = skb; | ||
912 | wmb(); | ||
913 | e->flags = flags; | ||
914 | } | ||
915 | |||
916 | /* | ||
917 | * Clean up completed Tx buffers. | ||
918 | */ | ||
919 | static inline void reclaim_completed_tx(struct sge *sge, struct cmdQ *q) | ||
920 | { | ||
921 | unsigned int reclaim = q->processed - q->cleaned; | ||
922 | |||
923 | if (reclaim) { | ||
924 | free_cmdQ_buffers(sge, q, reclaim); | ||
925 | q->cleaned += reclaim; | ||
926 | } | ||
927 | } | ||
928 | |||
929 | #ifndef SET_ETHTOOL_OPS | ||
930 | # define __netif_rx_complete(dev) netif_rx_complete(dev) | ||
931 | #endif | ||
932 | |||
933 | /* | ||
934 | * We cannot use the standard netif_rx_schedule_prep() because we have multiple | ||
935 | * ports plus the TOE all multiplexing onto a single response queue, therefore | ||
936 | * accepting new responses cannot depend on the state of any particular port. | ||
937 | * So define our own equivalent that omits the netif_running() test. | ||
938 | */ | ||
939 | static inline int napi_schedule_prep(struct net_device *dev) | ||
940 | { | ||
941 | return !test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state); | ||
942 | } | ||
943 | |||
944 | |||
945 | /** | ||
946 | * sge_rx - process an ingress ethernet packet | ||
947 | * @sge: the sge structure | ||
948 | * @fl: the free list that contains the packet buffer | ||
949 | * @len: the packet length | ||
950 | * | ||
951 | * Process an ingress ethernet pakcet and deliver it to the stack. | ||
952 | */ | ||
953 | static int sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) | ||
954 | { | ||
955 | struct sk_buff *skb; | ||
956 | struct cpl_rx_pkt *p; | ||
957 | struct adapter *adapter = sge->adapter; | ||
958 | |||
959 | sge->stats.ethernet_pkts++; | ||
960 | skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad, | ||
961 | sge->rx_pkt_pad, 2, SGE_RX_COPY_THRES, | ||
962 | SGE_RX_DROP_THRES); | ||
963 | if (!skb) { | ||
964 | sge->port_stats[0].rx_drops++; /* charge only port 0 for now */ | ||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | p = (struct cpl_rx_pkt *)skb->data; | ||
969 | skb_pull(skb, sizeof(*p)); | ||
970 | skb->dev = adapter->port[p->iff].dev; | ||
971 | skb->dev->last_rx = jiffies; | ||
972 | skb->protocol = eth_type_trans(skb, skb->dev); | ||
973 | if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff && | ||
974 | skb->protocol == htons(ETH_P_IP) && | ||
975 | (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) { | ||
976 | sge->port_stats[p->iff].rx_cso_good++; | ||
977 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
978 | } else | ||
979 | skb->ip_summed = CHECKSUM_NONE; | ||
980 | |||
981 | if (unlikely(adapter->vlan_grp && p->vlan_valid)) { | ||
982 | sge->port_stats[p->iff].vlan_xtract++; | ||
983 | if (adapter->params.sge.polling) | ||
984 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, | ||
985 | ntohs(p->vlan)); | ||
986 | else | ||
987 | vlan_hwaccel_rx(skb, adapter->vlan_grp, | ||
988 | ntohs(p->vlan)); | ||
989 | } else if (adapter->params.sge.polling) | ||
990 | netif_receive_skb(skb); | ||
991 | else | ||
992 | netif_rx(skb); | ||
993 | return 0; | ||
994 | } | ||
995 | |||
996 | /* | ||
997 | * Returns true if a command queue has enough available descriptors that | ||
998 | * we can resume Tx operation after temporarily disabling its packet queue. | ||
999 | */ | ||
1000 | static inline int enough_free_Tx_descs(const struct cmdQ *q) | ||
1001 | { | ||
1002 | unsigned int r = q->processed - q->cleaned; | ||
1003 | |||
1004 | return q->in_use - r < (q->size >> 1); | ||
1005 | } | ||
1006 | |||
1007 | /* | ||
1008 | * Called when sufficient space has become available in the SGE command queues | ||
1009 | * after the Tx packet schedulers have been suspended to restart the Tx path. | ||
1010 | */ | ||
1011 | static void restart_tx_queues(struct sge *sge) | ||
1012 | { | ||
1013 | struct adapter *adap = sge->adapter; | ||
1014 | |||
1015 | if (enough_free_Tx_descs(&sge->cmdQ[0])) { | ||
1016 | int i; | ||
1017 | |||
1018 | for_each_port(adap, i) { | ||
1019 | struct net_device *nd = adap->port[i].dev; | ||
1020 | |||
1021 | if (test_and_clear_bit(nd->if_port, | ||
1022 | &sge->stopped_tx_queues) && | ||
1023 | netif_running(nd)) { | ||
1024 | sge->stats.cmdQ_restarted[3]++; | ||
1025 | netif_wake_queue(nd); | ||
1026 | } | ||
1027 | } | ||
1028 | } | ||
1029 | } | ||
1030 | |||
1031 | /* | ||
1032 | * update_tx_info is called from the interrupt handler/NAPI to return cmdQ0 | ||
1033 | * information. | ||
1034 | */ | ||
1035 | static unsigned int update_tx_info(struct adapter *adapter, | ||
1036 | unsigned int flags, | ||
1037 | unsigned int pr0) | ||
1038 | { | ||
1039 | struct sge *sge = adapter->sge; | ||
1040 | struct cmdQ *cmdq = &sge->cmdQ[0]; | ||
1041 | |||
1042 | cmdq->processed += pr0; | ||
1043 | |||
1044 | if (flags & F_CMDQ0_ENABLE) { | ||
1045 | clear_bit(CMDQ_STAT_RUNNING, &cmdq->status); | ||
1046 | |||
1047 | if (cmdq->cleaned + cmdq->in_use != cmdq->processed && | ||
1048 | !test_and_set_bit(CMDQ_STAT_LAST_PKT_DB, &cmdq->status)) { | ||
1049 | set_bit(CMDQ_STAT_RUNNING, &cmdq->status); | ||
1050 | writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL); | ||
1051 | } | ||
1052 | flags &= ~F_CMDQ0_ENABLE; | ||
1053 | } | ||
1054 | |||
1055 | if (unlikely(sge->stopped_tx_queues != 0)) | ||
1056 | restart_tx_queues(sge); | ||
1057 | |||
1058 | return flags; | ||
1059 | } | ||
1060 | |||
1061 | /* | ||
1062 | * Process SGE responses, up to the supplied budget. Returns the number of | ||
1063 | * responses processed. A negative budget is effectively unlimited. | ||
1064 | */ | ||
1065 | static int process_responses(struct adapter *adapter, int budget) | ||
1066 | { | ||
1067 | struct sge *sge = adapter->sge; | ||
1068 | struct respQ *q = &sge->respQ; | ||
1069 | struct respQ_e *e = &q->entries[q->cidx]; | ||
1070 | int budget_left = budget; | ||
1071 | unsigned int flags = 0; | ||
1072 | unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0}; | ||
1073 | |||
1074 | |||
1075 | while (likely(budget_left && e->GenerationBit == q->genbit)) { | ||
1076 | flags |= e->Qsleeping; | ||
1077 | |||
1078 | cmdq_processed[0] += e->Cmdq0CreditReturn; | ||
1079 | cmdq_processed[1] += e->Cmdq1CreditReturn; | ||
1080 | |||
1081 | /* We batch updates to the TX side to avoid cacheline | ||
1082 | * ping-pong of TX state information on MP where the sender | ||
1083 | * might run on a different CPU than this function... | ||
1084 | */ | ||
1085 | if (unlikely(flags & F_CMDQ0_ENABLE || cmdq_processed[0] > 64)) { | ||
1086 | flags = update_tx_info(adapter, flags, cmdq_processed[0]); | ||
1087 | cmdq_processed[0] = 0; | ||
1088 | } | ||
1089 | if (unlikely(cmdq_processed[1] > 16)) { | ||
1090 | sge->cmdQ[1].processed += cmdq_processed[1]; | ||
1091 | cmdq_processed[1] = 0; | ||
1092 | } | ||
1093 | if (likely(e->DataValid)) { | ||
1094 | struct freelQ *fl = &sge->freelQ[e->FreelistQid]; | ||
1095 | |||
1096 | if (unlikely(!e->Sop || !e->Eop)) | ||
1097 | BUG(); | ||
1098 | if (unlikely(e->Offload)) | ||
1099 | unexpected_offload(adapter, fl); | ||
1100 | else | ||
1101 | sge_rx(sge, fl, e->BufferLength); | ||
1102 | |||
1103 | /* | ||
1104 | * Note: this depends on each packet consuming a | ||
1105 | * single free-list buffer; cf. the BUG above. | ||
1106 | */ | ||
1107 | if (++fl->cidx == fl->size) | ||
1108 | fl->cidx = 0; | ||
1109 | if (unlikely(--fl->credits < | ||
1110 | fl->size - SGE_FREEL_REFILL_THRESH)) | ||
1111 | refill_free_list(sge, fl); | ||
1112 | } else | ||
1113 | sge->stats.pure_rsps++; | ||
1114 | |||
1115 | e++; | ||
1116 | if (unlikely(++q->cidx == q->size)) { | ||
1117 | q->cidx = 0; | ||
1118 | q->genbit ^= 1; | ||
1119 | e = q->entries; | ||
1120 | } | ||
1121 | prefetch(e); | ||
1122 | |||
1123 | if (++q->credits > SGE_RESPQ_REPLENISH_THRES) { | ||
1124 | writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT); | ||
1125 | q->credits = 0; | ||
1126 | } | ||
1127 | --budget_left; | ||
1128 | } | ||
1129 | |||
1130 | flags = update_tx_info(adapter, flags, cmdq_processed[0]); | ||
1131 | sge->cmdQ[1].processed += cmdq_processed[1]; | ||
1132 | |||
1133 | budget -= budget_left; | ||
1134 | return budget; | ||
1135 | } | ||
1136 | |||
1137 | /* | ||
1138 | * A simpler version of process_responses() that handles only pure (i.e., | ||
1139 | * non data-carrying) responses. Such respones are too light-weight to justify | ||
1140 | * calling a softirq when using NAPI, so we handle them specially in hard | ||
1141 | * interrupt context. The function is called with a pointer to a response, | ||
1142 | * which the caller must ensure is a valid pure response. Returns 1 if it | ||
1143 | * encounters a valid data-carrying response, 0 otherwise. | ||
1144 | */ | ||
1145 | static int process_pure_responses(struct adapter *adapter, struct respQ_e *e) | ||
1146 | { | ||
1147 | struct sge *sge = adapter->sge; | ||
1148 | struct respQ *q = &sge->respQ; | ||
1149 | unsigned int flags = 0; | ||
1150 | unsigned int cmdq_processed[SGE_CMDQ_N] = {0, 0}; | ||
1151 | |||
1152 | do { | ||
1153 | flags |= e->Qsleeping; | ||
1154 | |||
1155 | cmdq_processed[0] += e->Cmdq0CreditReturn; | ||
1156 | cmdq_processed[1] += e->Cmdq1CreditReturn; | ||
1157 | |||
1158 | e++; | ||
1159 | if (unlikely(++q->cidx == q->size)) { | ||
1160 | q->cidx = 0; | ||
1161 | q->genbit ^= 1; | ||
1162 | e = q->entries; | ||
1163 | } | ||
1164 | prefetch(e); | ||
1165 | |||
1166 | if (++q->credits > SGE_RESPQ_REPLENISH_THRES) { | ||
1167 | writel(q->credits, adapter->regs + A_SG_RSPQUEUECREDIT); | ||
1168 | q->credits = 0; | ||
1169 | } | ||
1170 | sge->stats.pure_rsps++; | ||
1171 | } while (e->GenerationBit == q->genbit && !e->DataValid); | ||
1172 | |||
1173 | flags = update_tx_info(adapter, flags, cmdq_processed[0]); | ||
1174 | sge->cmdQ[1].processed += cmdq_processed[1]; | ||
1175 | |||
1176 | return e->GenerationBit == q->genbit; | ||
1177 | } | ||
1178 | |||
1179 | /* | ||
1180 | * Handler for new data events when using NAPI. This does not need any locking | ||
1181 | * or protection from interrupts as data interrupts are off at this point and | ||
1182 | * other adapter interrupts do not interfere. | ||
1183 | */ | ||
1184 | static int t1_poll(struct net_device *dev, int *budget) | ||
1185 | { | ||
1186 | struct adapter *adapter = dev->priv; | ||
1187 | int effective_budget = min(*budget, dev->quota); | ||
1188 | |||
1189 | int work_done = process_responses(adapter, effective_budget); | ||
1190 | *budget -= work_done; | ||
1191 | dev->quota -= work_done; | ||
1192 | |||
1193 | if (work_done >= effective_budget) | ||
1194 | return 1; | ||
1195 | |||
1196 | __netif_rx_complete(dev); | ||
1197 | |||
1198 | /* | ||
1199 | * Because we don't atomically flush the following write it is | ||
1200 | * possible that in very rare cases it can reach the device in a way | ||
1201 | * that races with a new response being written plus an error interrupt | ||
1202 | * causing the NAPI interrupt handler below to return unhandled status | ||
1203 | * to the OS. To protect against this would require flushing the write | ||
1204 | * and doing both the write and the flush with interrupts off. Way too | ||
1205 | * expensive and unjustifiable given the rarity of the race. | ||
1206 | */ | ||
1207 | writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING); | ||
1208 | return 0; | ||
1209 | } | ||
1210 | |||
1211 | /* | ||
1212 | * Returns true if the device is already scheduled for polling. | ||
1213 | */ | ||
1214 | static inline int napi_is_scheduled(struct net_device *dev) | ||
1215 | { | ||
1216 | return test_bit(__LINK_STATE_RX_SCHED, &dev->state); | ||
1217 | } | ||
1218 | |||
1219 | /* | ||
1220 | * NAPI version of the main interrupt handler. | ||
1221 | */ | ||
1222 | static irqreturn_t t1_interrupt_napi(int irq, void *data, struct pt_regs *regs) | ||
1223 | { | ||
1224 | int handled; | ||
1225 | struct adapter *adapter = data; | ||
1226 | struct sge *sge = adapter->sge; | ||
1227 | struct respQ *q = &adapter->sge->respQ; | ||
1228 | |||
1229 | /* | ||
1230 | * Clear the SGE_DATA interrupt first thing. Normally the NAPI | ||
1231 | * handler has control of the response queue and the interrupt handler | ||
1232 | * can look at the queue reliably only once it knows NAPI is off. | ||
1233 | * We can't wait that long to clear the SGE_DATA interrupt because we | ||
1234 | * could race with t1_poll rearming the SGE interrupt, so we need to | ||
1235 | * clear the interrupt speculatively and really early on. | ||
1236 | */ | ||
1237 | writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); | ||
1238 | |||
1239 | spin_lock(&adapter->async_lock); | ||
1240 | if (!napi_is_scheduled(sge->netdev)) { | ||
1241 | struct respQ_e *e = &q->entries[q->cidx]; | ||
1242 | |||
1243 | if (e->GenerationBit == q->genbit) { | ||
1244 | if (e->DataValid || | ||
1245 | process_pure_responses(adapter, e)) { | ||
1246 | if (likely(napi_schedule_prep(sge->netdev))) | ||
1247 | __netif_rx_schedule(sge->netdev); | ||
1248 | else | ||
1249 | printk(KERN_CRIT | ||
1250 | "NAPI schedule failure!\n"); | ||
1251 | } else | ||
1252 | writel(q->cidx, adapter->regs + A_SG_SLEEPING); | ||
1253 | handled = 1; | ||
1254 | goto unlock; | ||
1255 | } else | ||
1256 | writel(q->cidx, adapter->regs + A_SG_SLEEPING); | ||
1257 | } else | ||
1258 | if (readl(adapter->regs + A_PL_CAUSE) & F_PL_INTR_SGE_DATA) | ||
1259 | printk(KERN_ERR "data interrupt while NAPI running\n"); | ||
1260 | |||
1261 | handled = t1_slow_intr_handler(adapter); | ||
1262 | if (!handled) | ||
1263 | sge->stats.unhandled_irqs++; | ||
1264 | unlock: | ||
1265 | spin_unlock(&adapter->async_lock); | ||
1266 | return IRQ_RETVAL(handled != 0); | ||
1267 | } | ||
1268 | |||
1269 | /* | ||
1270 | * Main interrupt handler, optimized assuming that we took a 'DATA' | ||
1271 | * interrupt. | ||
1272 | * | ||
1273 | * 1. Clear the interrupt | ||
1274 | * 2. Loop while we find valid descriptors and process them; accumulate | ||
1275 | * information that can be processed after the loop | ||
1276 | * 3. Tell the SGE at which index we stopped processing descriptors | ||
1277 | * 4. Bookkeeping; free TX buffers, ring doorbell if there are any | ||
1278 | * outstanding TX buffers waiting, replenish RX buffers, potentially | ||
1279 | * reenable upper layers if they were turned off due to lack of TX | ||
1280 | * resources which are available again. | ||
1281 | * 5. If we took an interrupt, but no valid respQ descriptors was found we | ||
1282 | * let the slow_intr_handler run and do error handling. | ||
1283 | */ | ||
1284 | static irqreturn_t t1_interrupt(int irq, void *cookie, struct pt_regs *regs) | ||
1285 | { | ||
1286 | int work_done; | ||
1287 | struct respQ_e *e; | ||
1288 | struct adapter *adapter = cookie; | ||
1289 | struct respQ *Q = &adapter->sge->respQ; | ||
1290 | |||
1291 | spin_lock(&adapter->async_lock); | ||
1292 | e = &Q->entries[Q->cidx]; | ||
1293 | prefetch(e); | ||
1294 | |||
1295 | writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE); | ||
1296 | |||
1297 | if (likely(e->GenerationBit == Q->genbit)) | ||
1298 | work_done = process_responses(adapter, -1); | ||
1299 | else | ||
1300 | work_done = t1_slow_intr_handler(adapter); | ||
1301 | |||
1302 | /* | ||
1303 | * The unconditional clearing of the PL_CAUSE above may have raced | ||
1304 | * with DMA completion and the corresponding generation of a response | ||
1305 | * to cause us to miss the resulting data interrupt. The next write | ||
1306 | * is also unconditional to recover the missed interrupt and render | ||
1307 | * this race harmless. | ||
1308 | */ | ||
1309 | writel(Q->cidx, adapter->regs + A_SG_SLEEPING); | ||
1310 | |||
1311 | if (!work_done) | ||
1312 | adapter->sge->stats.unhandled_irqs++; | ||
1313 | spin_unlock(&adapter->async_lock); | ||
1314 | return IRQ_RETVAL(work_done != 0); | ||
1315 | } | ||
1316 | |||
1317 | intr_handler_t t1_select_intr_handler(adapter_t *adapter) | ||
1318 | { | ||
1319 | return adapter->params.sge.polling ? t1_interrupt_napi : t1_interrupt; | ||
1320 | } | ||
1321 | |||
1322 | /* | ||
1323 | * Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it. | ||
1324 | * | ||
1325 | * The code figures out how many entries the sk_buff will require in the | ||
1326 | * cmdQ and updates the cmdQ data structure with the state once the enqueue | ||
1327 | * has complete. Then, it doesn't access the global structure anymore, but | ||
1328 | * uses the corresponding fields on the stack. In conjuction with a spinlock | ||
1329 | * around that code, we can make the function reentrant without holding the | ||
1330 | * lock when we actually enqueue (which might be expensive, especially on | ||
1331 | * architectures with IO MMUs). | ||
1332 | * | ||
1333 | * This runs with softirqs disabled. | ||
1334 | */ | ||
1335 | unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, | ||
1336 | unsigned int qid, struct net_device *dev) | ||
1337 | { | ||
1338 | struct sge *sge = adapter->sge; | ||
1339 | struct cmdQ *q = &sge->cmdQ[qid]; | ||
1340 | unsigned int credits, pidx, genbit, count; | ||
1341 | |||
1342 | spin_lock(&q->lock); | ||
1343 | reclaim_completed_tx(sge, q); | ||
1344 | |||
1345 | pidx = q->pidx; | ||
1346 | credits = q->size - q->in_use; | ||
1347 | count = 1 + skb_shinfo(skb)->nr_frags; | ||
1348 | |||
1349 | { /* Ethernet packet */ | ||
1350 | if (unlikely(credits < count)) { | ||
1351 | netif_stop_queue(dev); | ||
1352 | set_bit(dev->if_port, &sge->stopped_tx_queues); | ||
1353 | sge->stats.cmdQ_full[3]++; | ||
1354 | spin_unlock(&q->lock); | ||
1355 | CH_ERR("%s: Tx ring full while queue awake!\n", | ||
1356 | adapter->name); | ||
1357 | return 1; | ||
1358 | } | ||
1359 | if (unlikely(credits - count < q->stop_thres)) { | ||
1360 | sge->stats.cmdQ_full[3]++; | ||
1361 | netif_stop_queue(dev); | ||
1362 | set_bit(dev->if_port, &sge->stopped_tx_queues); | ||
1363 | } | ||
1364 | } | ||
1365 | q->in_use += count; | ||
1366 | genbit = q->genbit; | ||
1367 | q->pidx += count; | ||
1368 | if (q->pidx >= q->size) { | ||
1369 | q->pidx -= q->size; | ||
1370 | q->genbit ^= 1; | ||
1371 | } | ||
1372 | spin_unlock(&q->lock); | ||
1373 | |||
1374 | write_tx_descs(adapter, skb, pidx, genbit, q); | ||
1375 | |||
1376 | /* | ||
1377 | * We always ring the doorbell for cmdQ1. For cmdQ0, we only ring | ||
1378 | * the doorbell if the Q is asleep. There is a natural race, where | ||
1379 | * the hardware is going to sleep just after we checked, however, | ||
1380 | * then the interrupt handler will detect the outstanding TX packet | ||
1381 | * and ring the doorbell for us. | ||
1382 | */ | ||
1383 | if (qid) | ||
1384 | doorbell_pio(adapter, F_CMDQ1_ENABLE); | ||
1385 | else { | ||
1386 | clear_bit(CMDQ_STAT_LAST_PKT_DB, &q->status); | ||
1387 | if (test_and_set_bit(CMDQ_STAT_RUNNING, &q->status) == 0) { | ||
1388 | set_bit(CMDQ_STAT_LAST_PKT_DB, &q->status); | ||
1389 | writel(F_CMDQ0_ENABLE, adapter->regs + A_SG_DOORBELL); | ||
1390 | } | ||
1391 | } | ||
1392 | return 0; | ||
1393 | } | ||
1394 | |||
1395 | #define MK_ETH_TYPE_MSS(type, mss) (((mss) & 0x3FFF) | ((type) << 14)) | ||
1396 | |||
1397 | /* | ||
1398 | * eth_hdr_len - return the length of an Ethernet header | ||
1399 | * @data: pointer to the start of the Ethernet header | ||
1400 | * | ||
1401 | * Returns the length of an Ethernet header, including optional VLAN tag. | ||
1402 | */ | ||
1403 | static inline int eth_hdr_len(const void *data) | ||
1404 | { | ||
1405 | const struct ethhdr *e = data; | ||
1406 | |||
1407 | return e->h_proto == htons(ETH_P_8021Q) ? VLAN_ETH_HLEN : ETH_HLEN; | ||
1408 | } | ||
1409 | |||
1410 | /* | ||
1411 | * Adds the CPL header to the sk_buff and passes it to t1_sge_tx. | ||
1412 | */ | ||
1413 | int t1_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1414 | { | ||
1415 | struct adapter *adapter = dev->priv; | ||
1416 | struct sge_port_stats *st = &adapter->sge->port_stats[dev->if_port]; | ||
1417 | struct sge *sge = adapter->sge; | ||
1418 | struct cpl_tx_pkt *cpl; | ||
1419 | |||
1420 | #ifdef NETIF_F_TSO | ||
1421 | if (skb_shinfo(skb)->tso_size) { | ||
1422 | int eth_type; | ||
1423 | struct cpl_tx_pkt_lso *hdr; | ||
1424 | |||
1425 | st->tso++; | ||
1426 | |||
1427 | eth_type = skb->nh.raw - skb->data == ETH_HLEN ? | ||
1428 | CPL_ETH_II : CPL_ETH_II_VLAN; | ||
1429 | |||
1430 | hdr = (struct cpl_tx_pkt_lso *)skb_push(skb, sizeof(*hdr)); | ||
1431 | hdr->opcode = CPL_TX_PKT_LSO; | ||
1432 | hdr->ip_csum_dis = hdr->l4_csum_dis = 0; | ||
1433 | hdr->ip_hdr_words = skb->nh.iph->ihl; | ||
1434 | hdr->tcp_hdr_words = skb->h.th->doff; | ||
1435 | hdr->eth_type_mss = htons(MK_ETH_TYPE_MSS(eth_type, | ||
1436 | skb_shinfo(skb)->tso_size)); | ||
1437 | hdr->len = htonl(skb->len - sizeof(*hdr)); | ||
1438 | cpl = (struct cpl_tx_pkt *)hdr; | ||
1439 | sge->stats.tx_lso_pkts++; | ||
1440 | } else | ||
1441 | #endif | ||
1442 | { | ||
1443 | /* | ||
1444 | * Packets shorter than ETH_HLEN can break the MAC, drop them | ||
1445 | * early. Also, we may get oversized packets because some | ||
1446 | * parts of the kernel don't handle our unusual hard_header_len | ||
1447 | * right, drop those too. | ||
1448 | */ | ||
1449 | if (unlikely(skb->len < ETH_HLEN || | ||
1450 | skb->len > dev->mtu + eth_hdr_len(skb->data))) { | ||
1451 | dev_kfree_skb_any(skb); | ||
1452 | return NET_XMIT_SUCCESS; | ||
1453 | } | ||
1454 | |||
1455 | /* | ||
1456 | * We are using a non-standard hard_header_len and some kernel | ||
1457 | * components, such as pktgen, do not handle it right. | ||
1458 | * Complain when this happens but try to fix things up. | ||
1459 | */ | ||
1460 | if (unlikely(skb_headroom(skb) < | ||
1461 | dev->hard_header_len - ETH_HLEN)) { | ||
1462 | struct sk_buff *orig_skb = skb; | ||
1463 | |||
1464 | if (net_ratelimit()) | ||
1465 | printk(KERN_ERR "%s: inadequate headroom in " | ||
1466 | "Tx packet\n", dev->name); | ||
1467 | skb = skb_realloc_headroom(skb, sizeof(*cpl)); | ||
1468 | dev_kfree_skb_any(orig_skb); | ||
1469 | if (!skb) | ||
1470 | return -ENOMEM; | ||
1471 | } | ||
1472 | |||
1473 | if (!(adapter->flags & UDP_CSUM_CAPABLE) && | ||
1474 | skb->ip_summed == CHECKSUM_HW && | ||
1475 | skb->nh.iph->protocol == IPPROTO_UDP) | ||
1476 | if (unlikely(skb_checksum_help(skb, 0))) { | ||
1477 | dev_kfree_skb_any(skb); | ||
1478 | return -ENOMEM; | ||
1479 | } | ||
1480 | |||
1481 | /* Hmmm, assuming to catch the gratious arp... and we'll use | ||
1482 | * it to flush out stuck espi packets... | ||
1483 | */ | ||
1484 | if (unlikely(!adapter->sge->espibug_skb)) { | ||
1485 | if (skb->protocol == htons(ETH_P_ARP) && | ||
1486 | skb->nh.arph->ar_op == htons(ARPOP_REQUEST)) { | ||
1487 | adapter->sge->espibug_skb = skb; | ||
1488 | /* We want to re-use this skb later. We | ||
1489 | * simply bump the reference count and it | ||
1490 | * will not be freed... | ||
1491 | */ | ||
1492 | skb = skb_get(skb); | ||
1493 | } | ||
1494 | } | ||
1495 | |||
1496 | cpl = (struct cpl_tx_pkt *)__skb_push(skb, sizeof(*cpl)); | ||
1497 | cpl->opcode = CPL_TX_PKT; | ||
1498 | cpl->ip_csum_dis = 1; /* SW calculates IP csum */ | ||
1499 | cpl->l4_csum_dis = skb->ip_summed == CHECKSUM_HW ? 0 : 1; | ||
1500 | /* the length field isn't used so don't bother setting it */ | ||
1501 | |||
1502 | st->tx_cso += (skb->ip_summed == CHECKSUM_HW); | ||
1503 | sge->stats.tx_do_cksum += (skb->ip_summed == CHECKSUM_HW); | ||
1504 | sge->stats.tx_reg_pkts++; | ||
1505 | } | ||
1506 | cpl->iff = dev->if_port; | ||
1507 | |||
1508 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | ||
1509 | if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { | ||
1510 | cpl->vlan_valid = 1; | ||
1511 | cpl->vlan = htons(vlan_tx_tag_get(skb)); | ||
1512 | st->vlan_insert++; | ||
1513 | } else | ||
1514 | #endif | ||
1515 | cpl->vlan_valid = 0; | ||
1516 | |||
1517 | dev->trans_start = jiffies; | ||
1518 | return t1_sge_tx(skb, adapter, 0, dev); | ||
1519 | } | ||
1520 | |||
1521 | /* | ||
1522 | * Callback for the Tx buffer reclaim timer. Runs with softirqs disabled. | ||
1523 | */ | ||
1524 | static void sge_tx_reclaim_cb(unsigned long data) | ||
1525 | { | ||
1526 | int i; | ||
1527 | struct sge *sge = (struct sge *)data; | ||
1528 | |||
1529 | for (i = 0; i < SGE_CMDQ_N; ++i) { | ||
1530 | struct cmdQ *q = &sge->cmdQ[i]; | ||
1531 | |||
1532 | if (!spin_trylock(&q->lock)) | ||
1533 | continue; | ||
1534 | |||
1535 | reclaim_completed_tx(sge, q); | ||
1536 | if (i == 0 && q->in_use) /* flush pending credits */ | ||
1537 | writel(F_CMDQ0_ENABLE, | ||
1538 | sge->adapter->regs + A_SG_DOORBELL); | ||
1539 | |||
1540 | spin_unlock(&q->lock); | ||
1541 | } | ||
1542 | mod_timer(&sge->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD); | ||
1543 | } | ||
1544 | |||
1545 | /* | ||
1546 | * Propagate changes of the SGE coalescing parameters to the HW. | ||
1547 | */ | ||
1548 | int t1_sge_set_coalesce_params(struct sge *sge, struct sge_params *p) | ||
1549 | { | ||
1550 | sge->netdev->poll = t1_poll; | ||
1551 | sge->fixed_intrtimer = p->rx_coalesce_usecs * | ||
1552 | core_ticks_per_usec(sge->adapter); | ||
1553 | writel(sge->fixed_intrtimer, sge->adapter->regs + A_SG_INTRTIMER); | ||
1554 | return 0; | ||
1555 | } | ||
1556 | |||
1557 | /* | ||
1558 | * Allocates both RX and TX resources and configures the SGE. However, | ||
1559 | * the hardware is not enabled yet. | ||
1560 | */ | ||
1561 | int t1_sge_configure(struct sge *sge, struct sge_params *p) | ||
1562 | { | ||
1563 | if (alloc_rx_resources(sge, p)) | ||
1564 | return -ENOMEM; | ||
1565 | if (alloc_tx_resources(sge, p)) { | ||
1566 | free_rx_resources(sge); | ||
1567 | return -ENOMEM; | ||
1568 | } | ||
1569 | configure_sge(sge, p); | ||
1570 | |||
1571 | /* | ||
1572 | * Now that we have sized the free lists calculate the payload | ||
1573 | * capacity of the large buffers. Other parts of the driver use | ||
1574 | * this to set the max offload coalescing size so that RX packets | ||
1575 | * do not overflow our large buffers. | ||
1576 | */ | ||
1577 | p->large_buf_capacity = jumbo_payload_capacity(sge); | ||
1578 | return 0; | ||
1579 | } | ||
1580 | |||
1581 | /* | ||
1582 | * Disables the DMA engine. | ||
1583 | */ | ||
1584 | void t1_sge_stop(struct sge *sge) | ||
1585 | { | ||
1586 | writel(0, sge->adapter->regs + A_SG_CONTROL); | ||
1587 | (void) readl(sge->adapter->regs + A_SG_CONTROL); /* flush */ | ||
1588 | if (is_T2(sge->adapter)) | ||
1589 | del_timer_sync(&sge->espibug_timer); | ||
1590 | del_timer_sync(&sge->tx_reclaim_timer); | ||
1591 | } | ||
1592 | |||
1593 | /* | ||
1594 | * Enables the DMA engine. | ||
1595 | */ | ||
1596 | void t1_sge_start(struct sge *sge) | ||
1597 | { | ||
1598 | refill_free_list(sge, &sge->freelQ[0]); | ||
1599 | refill_free_list(sge, &sge->freelQ[1]); | ||
1600 | |||
1601 | writel(sge->sge_control, sge->adapter->regs + A_SG_CONTROL); | ||
1602 | doorbell_pio(sge->adapter, F_FL0_ENABLE | F_FL1_ENABLE); | ||
1603 | (void) readl(sge->adapter->regs + A_SG_CONTROL); /* flush */ | ||
1604 | |||
1605 | mod_timer(&sge->tx_reclaim_timer, jiffies + TX_RECLAIM_PERIOD); | ||
1606 | |||
1607 | if (is_T2(sge->adapter)) | ||
1608 | mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout); | ||
1609 | } | ||
1610 | |||
1611 | /* | ||
1612 | * Callback for the T2 ESPI 'stuck packet feature' workaorund | ||
1613 | */ | ||
1614 | static void espibug_workaround(void *data) | ||
1615 | { | ||
1616 | struct adapter *adapter = (struct adapter *)data; | ||
1617 | struct sge *sge = adapter->sge; | ||
1618 | |||
1619 | if (netif_running(adapter->port[0].dev)) { | ||
1620 | struct sk_buff *skb = sge->espibug_skb; | ||
1621 | |||
1622 | u32 seop = t1_espi_get_mon(adapter, 0x930, 0); | ||
1623 | |||
1624 | if ((seop & 0xfff0fff) == 0xfff && skb) { | ||
1625 | if (!skb->cb[0]) { | ||
1626 | u8 ch_mac_addr[ETH_ALEN] = | ||
1627 | {0x0, 0x7, 0x43, 0x0, 0x0, 0x0}; | ||
1628 | memcpy(skb->data + sizeof(struct cpl_tx_pkt), | ||
1629 | ch_mac_addr, ETH_ALEN); | ||
1630 | memcpy(skb->data + skb->len - 10, ch_mac_addr, | ||
1631 | ETH_ALEN); | ||
1632 | skb->cb[0] = 0xff; | ||
1633 | } | ||
1634 | |||
1635 | /* bump the reference count to avoid freeing of the | ||
1636 | * skb once the DMA has completed. | ||
1637 | */ | ||
1638 | skb = skb_get(skb); | ||
1639 | t1_sge_tx(skb, adapter, 0, adapter->port[0].dev); | ||
1640 | } | ||
1641 | } | ||
1642 | mod_timer(&sge->espibug_timer, jiffies + sge->espibug_timeout); | ||
1643 | } | ||
1644 | |||
1645 | /* | ||
1646 | * Creates a t1_sge structure and returns suggested resource parameters. | ||
1647 | */ | ||
1648 | struct sge * __devinit t1_sge_create(struct adapter *adapter, | ||
1649 | struct sge_params *p) | ||
1650 | { | ||
1651 | struct sge *sge = kmalloc(sizeof(*sge), GFP_KERNEL); | ||
1652 | |||
1653 | if (!sge) | ||
1654 | return NULL; | ||
1655 | memset(sge, 0, sizeof(*sge)); | ||
1656 | |||
1657 | sge->adapter = adapter; | ||
1658 | sge->netdev = adapter->port[0].dev; | ||
1659 | sge->rx_pkt_pad = t1_is_T1B(adapter) ? 0 : 2; | ||
1660 | sge->jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; | ||
1661 | |||
1662 | init_timer(&sge->tx_reclaim_timer); | ||
1663 | sge->tx_reclaim_timer.data = (unsigned long)sge; | ||
1664 | sge->tx_reclaim_timer.function = sge_tx_reclaim_cb; | ||
1665 | |||
1666 | if (is_T2(sge->adapter)) { | ||
1667 | init_timer(&sge->espibug_timer); | ||
1668 | sge->espibug_timer.function = (void *)&espibug_workaround; | ||
1669 | sge->espibug_timer.data = (unsigned long)sge->adapter; | ||
1670 | sge->espibug_timeout = 1; | ||
1671 | } | ||
1672 | |||
1673 | |||
1674 | p->cmdQ_size[0] = SGE_CMDQ0_E_N; | ||
1675 | p->cmdQ_size[1] = SGE_CMDQ1_E_N; | ||
1676 | p->freelQ_size[!sge->jumbo_fl] = SGE_FREEL_SIZE; | ||
1677 | p->freelQ_size[sge->jumbo_fl] = SGE_JUMBO_FREEL_SIZE; | ||
1678 | p->rx_coalesce_usecs = 50; | ||
1679 | p->coalesce_enable = 0; | ||
1680 | p->sample_interval_usecs = 0; | ||
1681 | p->polling = 0; | ||
1682 | |||
1683 | return sge; | ||
1684 | } | ||
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h new file mode 100644 index 000000000000..434b25586851 --- /dev/null +++ b/drivers/net/chelsio/sge.h | |||
@@ -0,0 +1,105 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: sge.h * | ||
4 | * $Revision: 1.11 $ * | ||
5 | * $Date: 2005/06/21 22:10:55 $ * | ||
6 | * Description: * | ||
7 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
8 | * * | ||
9 | * This program is free software; you can redistribute it and/or modify * | ||
10 | * it under the terms of the GNU General Public License, version 2, as * | ||
11 | * published by the Free Software Foundation. * | ||
12 | * * | ||
13 | * You should have received a copy of the GNU General Public License along * | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
15 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
16 | * * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
20 | * * | ||
21 | * http://www.chelsio.com * | ||
22 | * * | ||
23 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
24 | * All rights reserved. * | ||
25 | * * | ||
26 | * Maintainers: maintainers@chelsio.com * | ||
27 | * * | ||
28 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
29 | * Tina Yang <tainay@chelsio.com> * | ||
30 | * Felix Marti <felix@chelsio.com> * | ||
31 | * Scott Bardone <sbardone@chelsio.com> * | ||
32 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
33 | * Frank DiMambro <frank@chelsio.com> * | ||
34 | * * | ||
35 | * History: * | ||
36 | * * | ||
37 | ****************************************************************************/ | ||
38 | |||
39 | #ifndef _CXGB_SGE_H_ | ||
40 | #define _CXGB_SGE_H_ | ||
41 | |||
42 | #include <linux/types.h> | ||
43 | #include <linux/interrupt.h> | ||
44 | #include <asm/byteorder.h> | ||
45 | |||
46 | #ifndef IRQ_RETVAL | ||
47 | #define IRQ_RETVAL(x) | ||
48 | typedef void irqreturn_t; | ||
49 | #endif | ||
50 | |||
51 | typedef irqreturn_t (*intr_handler_t)(int, void *, struct pt_regs *); | ||
52 | |||
53 | struct sge_intr_counts { | ||
54 | unsigned int respQ_empty; /* # times respQ empty */ | ||
55 | unsigned int respQ_overflow; /* # respQ overflow (fatal) */ | ||
56 | unsigned int freelistQ_empty; /* # times freelist empty */ | ||
57 | unsigned int pkt_too_big; /* packet too large (fatal) */ | ||
58 | unsigned int pkt_mismatch; | ||
59 | unsigned int cmdQ_full[3]; /* not HW IRQ, host cmdQ[] full */ | ||
60 | unsigned int cmdQ_restarted[3];/* # of times cmdQ X was restarted */ | ||
61 | unsigned int ethernet_pkts; /* # of Ethernet packets received */ | ||
62 | unsigned int offload_pkts; /* # of offload packets received */ | ||
63 | unsigned int offload_bundles; /* # of offload pkt bundles delivered */ | ||
64 | unsigned int pure_rsps; /* # of non-payload responses */ | ||
65 | unsigned int unhandled_irqs; /* # of unhandled interrupts */ | ||
66 | unsigned int tx_ipfrags; | ||
67 | unsigned int tx_reg_pkts; | ||
68 | unsigned int tx_lso_pkts; | ||
69 | unsigned int tx_do_cksum; | ||
70 | }; | ||
71 | |||
72 | struct sge_port_stats { | ||
73 | unsigned long rx_cso_good; /* # of successful RX csum offloads */ | ||
74 | unsigned long tx_cso; /* # of TX checksum offloads */ | ||
75 | unsigned long vlan_xtract; /* # of VLAN tag extractions */ | ||
76 | unsigned long vlan_insert; /* # of VLAN tag extractions */ | ||
77 | unsigned long tso; /* # of TSO requests */ | ||
78 | unsigned long rx_drops; /* # of packets dropped due to no mem */ | ||
79 | }; | ||
80 | |||
81 | struct sk_buff; | ||
82 | struct net_device; | ||
83 | struct adapter; | ||
84 | struct sge_params; | ||
85 | struct sge; | ||
86 | |||
87 | struct sge *t1_sge_create(struct adapter *, struct sge_params *); | ||
88 | int t1_sge_configure(struct sge *, struct sge_params *); | ||
89 | int t1_sge_set_coalesce_params(struct sge *, struct sge_params *); | ||
90 | void t1_sge_destroy(struct sge *); | ||
91 | intr_handler_t t1_select_intr_handler(adapter_t *adapter); | ||
92 | unsigned int t1_sge_tx(struct sk_buff *skb, struct adapter *adapter, | ||
93 | unsigned int qid, struct net_device *netdev); | ||
94 | int t1_start_xmit(struct sk_buff *skb, struct net_device *dev); | ||
95 | void t1_set_vlan_accel(struct adapter *adapter, int on_off); | ||
96 | void t1_sge_start(struct sge *); | ||
97 | void t1_sge_stop(struct sge *); | ||
98 | int t1_sge_intr_error_handler(struct sge *); | ||
99 | void t1_sge_intr_enable(struct sge *); | ||
100 | void t1_sge_intr_disable(struct sge *); | ||
101 | void t1_sge_intr_clear(struct sge *); | ||
102 | const struct sge_intr_counts *t1_sge_get_intr_counts(struct sge *sge); | ||
103 | const struct sge_port_stats *t1_sge_get_port_stats(struct sge *sge, int port); | ||
104 | |||
105 | #endif /* _CXGB_SGE_H_ */ | ||
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c new file mode 100644 index 000000000000..1ebb5d149aef --- /dev/null +++ b/drivers/net/chelsio/subr.c | |||
@@ -0,0 +1,812 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: subr.c * | ||
4 | * $Revision: 1.27 $ * | ||
5 | * $Date: 2005/06/22 01:08:36 $ * | ||
6 | * Description: * | ||
7 | * Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * | ||
25 | * All rights reserved. * | ||
26 | * * | ||
27 | * Maintainers: maintainers@chelsio.com * | ||
28 | * * | ||
29 | * Authors: Dimitrios Michailidis <dm@chelsio.com> * | ||
30 | * Tina Yang <tainay@chelsio.com> * | ||
31 | * Felix Marti <felix@chelsio.com> * | ||
32 | * Scott Bardone <sbardone@chelsio.com> * | ||
33 | * Kurt Ottaway <kottaway@chelsio.com> * | ||
34 | * Frank DiMambro <frank@chelsio.com> * | ||
35 | * * | ||
36 | * History: * | ||
37 | * * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include "common.h" | ||
41 | #include "elmer0.h" | ||
42 | #include "regs.h" | ||
43 | #include "gmac.h" | ||
44 | #include "cphy.h" | ||
45 | #include "sge.h" | ||
46 | #include "espi.h" | ||
47 | |||
48 | /** | ||
49 | * t1_wait_op_done - wait until an operation is completed | ||
50 | * @adapter: the adapter performing the operation | ||
51 | * @reg: the register to check for completion | ||
52 | * @mask: a single-bit field within @reg that indicates completion | ||
53 | * @polarity: the value of the field when the operation is completed | ||
54 | * @attempts: number of check iterations | ||
55 | * @delay: delay in usecs between iterations | ||
56 | * | ||
57 | * Wait until an operation is completed by checking a bit in a register | ||
58 | * up to @attempts times. Returns %0 if the operation completes and %1 | ||
59 | * otherwise. | ||
60 | */ | ||
61 | static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, | ||
62 | int attempts, int delay) | ||
63 | { | ||
64 | while (1) { | ||
65 | u32 val = readl(adapter->regs + reg) & mask; | ||
66 | |||
67 | if (!!val == polarity) | ||
68 | return 0; | ||
69 | if (--attempts == 0) | ||
70 | return 1; | ||
71 | if (delay) | ||
72 | udelay(delay); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | #define TPI_ATTEMPTS 50 | ||
77 | |||
78 | /* | ||
79 | * Write a register over the TPI interface (unlocked and locked versions). | ||
80 | */ | ||
81 | static int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) | ||
82 | { | ||
83 | int tpi_busy; | ||
84 | |||
85 | writel(addr, adapter->regs + A_TPI_ADDR); | ||
86 | writel(value, adapter->regs + A_TPI_WR_DATA); | ||
87 | writel(F_TPIWR, adapter->regs + A_TPI_CSR); | ||
88 | |||
89 | tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1, | ||
90 | TPI_ATTEMPTS, 3); | ||
91 | if (tpi_busy) | ||
92 | CH_ALERT("%s: TPI write to 0x%x failed\n", | ||
93 | adapter->name, addr); | ||
94 | return tpi_busy; | ||
95 | } | ||
96 | |||
97 | int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) | ||
98 | { | ||
99 | int ret; | ||
100 | |||
101 | spin_lock(&(adapter)->tpi_lock); | ||
102 | ret = __t1_tpi_write(adapter, addr, value); | ||
103 | spin_unlock(&(adapter)->tpi_lock); | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Read a register over the TPI interface (unlocked and locked versions). | ||
109 | */ | ||
110 | static int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) | ||
111 | { | ||
112 | int tpi_busy; | ||
113 | |||
114 | writel(addr, adapter->regs + A_TPI_ADDR); | ||
115 | writel(0, adapter->regs + A_TPI_CSR); | ||
116 | |||
117 | tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1, | ||
118 | TPI_ATTEMPTS, 3); | ||
119 | if (tpi_busy) | ||
120 | CH_ALERT("%s: TPI read from 0x%x failed\n", | ||
121 | adapter->name, addr); | ||
122 | else | ||
123 | *valp = readl(adapter->regs + A_TPI_RD_DATA); | ||
124 | return tpi_busy; | ||
125 | } | ||
126 | |||
127 | int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) | ||
128 | { | ||
129 | int ret; | ||
130 | |||
131 | spin_lock(&(adapter)->tpi_lock); | ||
132 | ret = __t1_tpi_read(adapter, addr, valp); | ||
133 | spin_unlock(&(adapter)->tpi_lock); | ||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Called when a port's link settings change to propagate the new values to the | ||
139 | * associated PHY and MAC. After performing the common tasks it invokes an | ||
140 | * OS-specific handler. | ||
141 | */ | ||
142 | /* static */ void link_changed(adapter_t *adapter, int port_id) | ||
143 | { | ||
144 | int link_ok, speed, duplex, fc; | ||
145 | struct cphy *phy = adapter->port[port_id].phy; | ||
146 | struct link_config *lc = &adapter->port[port_id].link_config; | ||
147 | |||
148 | phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); | ||
149 | |||
150 | lc->speed = speed < 0 ? SPEED_INVALID : speed; | ||
151 | lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; | ||
152 | if (!(lc->requested_fc & PAUSE_AUTONEG)) | ||
153 | fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
154 | |||
155 | if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { | ||
156 | /* Set MAC speed, duplex, and flow control to match PHY. */ | ||
157 | struct cmac *mac = adapter->port[port_id].mac; | ||
158 | |||
159 | mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc); | ||
160 | lc->fc = (unsigned char)fc; | ||
161 | } | ||
162 | t1_link_changed(adapter, port_id, link_ok, speed, duplex, fc); | ||
163 | } | ||
164 | |||
165 | static int t1_pci_intr_handler(adapter_t *adapter) | ||
166 | { | ||
167 | u32 pcix_cause; | ||
168 | |||
169 | pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause); | ||
170 | |||
171 | if (pcix_cause) { | ||
172 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, | ||
173 | pcix_cause); | ||
174 | t1_fatal_err(adapter); /* PCI errors are fatal */ | ||
175 | } | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | |||
180 | /* | ||
181 | * Wait until Elmer's MI1 interface is ready for new operations. | ||
182 | */ | ||
183 | static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg) | ||
184 | { | ||
185 | int attempts = 100, busy; | ||
186 | |||
187 | do { | ||
188 | u32 val; | ||
189 | |||
190 | __t1_tpi_read(adapter, mi1_reg, &val); | ||
191 | busy = val & F_MI1_OP_BUSY; | ||
192 | if (busy) | ||
193 | udelay(10); | ||
194 | } while (busy && --attempts); | ||
195 | if (busy) | ||
196 | CH_ALERT("%s: MDIO operation timed out\n", | ||
197 | adapter->name); | ||
198 | return busy; | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * MI1 MDIO initialization. | ||
203 | */ | ||
204 | static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi) | ||
205 | { | ||
206 | u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1; | ||
207 | u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) | | ||
208 | V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv); | ||
209 | |||
210 | if (!(bi->caps & SUPPORTED_10000baseT_Full)) | ||
211 | val |= V_MI1_SOF(1); | ||
212 | t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val); | ||
213 | } | ||
214 | |||
215 | static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
216 | int reg_addr, unsigned int *valp) | ||
217 | { | ||
218 | u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); | ||
219 | |||
220 | spin_lock(&(adapter)->tpi_lock); | ||
221 | |||
222 | /* Write the address we want. */ | ||
223 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); | ||
224 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); | ||
225 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, | ||
226 | MI1_OP_INDIRECT_ADDRESS); | ||
227 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | ||
228 | |||
229 | /* Write the operation we want. */ | ||
230 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ); | ||
231 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | ||
232 | |||
233 | /* Read the data. */ | ||
234 | __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); | ||
235 | spin_unlock(&(adapter)->tpi_lock); | ||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
240 | int reg_addr, unsigned int val) | ||
241 | { | ||
242 | u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); | ||
243 | |||
244 | spin_lock(&(adapter)->tpi_lock); | ||
245 | |||
246 | /* Write the address we want. */ | ||
247 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); | ||
248 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); | ||
249 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, | ||
250 | MI1_OP_INDIRECT_ADDRESS); | ||
251 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | ||
252 | |||
253 | /* Write the data. */ | ||
254 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); | ||
255 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE); | ||
256 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | ||
257 | spin_unlock(&(adapter)->tpi_lock); | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static struct mdio_ops mi1_mdio_ext_ops = { | ||
262 | mi1_mdio_init, | ||
263 | mi1_mdio_ext_read, | ||
264 | mi1_mdio_ext_write | ||
265 | }; | ||
266 | |||
267 | enum { | ||
268 | CH_BRD_N110_1F, | ||
269 | CH_BRD_N210_1F, | ||
270 | }; | ||
271 | |||
272 | static struct board_info t1_board[] = { | ||
273 | |||
274 | { CHBT_BOARD_N110, 1/*ports#*/, | ||
275 | SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, | ||
276 | CHBT_MAC_PM3393, CHBT_PHY_88X2010, | ||
277 | 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, | ||
278 | 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, | ||
279 | 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, | ||
280 | &t1_mv88x201x_ops, &mi1_mdio_ext_ops, | ||
281 | "Chelsio N110 1x10GBaseX NIC" }, | ||
282 | |||
283 | { CHBT_BOARD_N210, 1/*ports#*/, | ||
284 | SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2, | ||
285 | CHBT_MAC_PM3393, CHBT_PHY_88X2010, | ||
286 | 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, | ||
287 | 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, | ||
288 | 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, | ||
289 | &t1_mv88x201x_ops, &mi1_mdio_ext_ops, | ||
290 | "Chelsio N210 1x10GBaseX NIC" }, | ||
291 | |||
292 | }; | ||
293 | |||
294 | struct pci_device_id t1_pci_tbl[] = { | ||
295 | CH_DEVICE(7, 0, CH_BRD_N110_1F), | ||
296 | CH_DEVICE(10, 1, CH_BRD_N210_1F), | ||
297 | { 0, } | ||
298 | }; | ||
299 | |||
300 | MODULE_DEVICE_TABLE(pci, t1_pci_tbl); | ||
301 | |||
302 | /* | ||
303 | * Return the board_info structure with a given index. Out-of-range indices | ||
304 | * return NULL. | ||
305 | */ | ||
306 | const struct board_info *t1_get_board_info(unsigned int board_id) | ||
307 | { | ||
308 | return board_id < ARRAY_SIZE(t1_board) ? &t1_board[board_id] : NULL; | ||
309 | } | ||
310 | |||
311 | struct chelsio_vpd_t { | ||
312 | u32 format_version; | ||
313 | u8 serial_number[16]; | ||
314 | u8 mac_base_address[6]; | ||
315 | u8 pad[2]; /* make multiple-of-4 size requirement explicit */ | ||
316 | }; | ||
317 | |||
318 | #define EEPROMSIZE (8 * 1024) | ||
319 | #define EEPROM_MAX_POLL 4 | ||
320 | |||
321 | /* | ||
322 | * Read SEEPROM. A zero is written to the flag register when the addres is | ||
323 | * written to the Control register. The hardware device will set the flag to a | ||
324 | * one when 4B have been transferred to the Data register. | ||
325 | */ | ||
326 | int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data) | ||
327 | { | ||
328 | int i = EEPROM_MAX_POLL; | ||
329 | u16 val; | ||
330 | |||
331 | if (addr >= EEPROMSIZE || (addr & 3)) | ||
332 | return -EINVAL; | ||
333 | |||
334 | pci_write_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, (u16)addr); | ||
335 | do { | ||
336 | udelay(50); | ||
337 | pci_read_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, &val); | ||
338 | } while (!(val & F_VPD_OP_FLAG) && --i); | ||
339 | |||
340 | if (!(val & F_VPD_OP_FLAG)) { | ||
341 | CH_ERR("%s: reading EEPROM address 0x%x failed\n", | ||
342 | adapter->name, addr); | ||
343 | return -EIO; | ||
344 | } | ||
345 | pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data); | ||
346 | *data = le32_to_cpu(*data); | ||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd) | ||
351 | { | ||
352 | int addr, ret = 0; | ||
353 | |||
354 | for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32)) | ||
355 | ret = t1_seeprom_read(adapter, addr, | ||
356 | (u32 *)((u8 *)vpd + addr)); | ||
357 | |||
358 | return ret; | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * Read a port's MAC address from the VPD ROM. | ||
363 | */ | ||
364 | static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[]) | ||
365 | { | ||
366 | struct chelsio_vpd_t vpd; | ||
367 | |||
368 | if (t1_eeprom_vpd_get(adapter, &vpd)) | ||
369 | return 1; | ||
370 | memcpy(mac_addr, vpd.mac_base_address, 5); | ||
371 | mac_addr[5] = vpd.mac_base_address[5] + index; | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Set up the MAC/PHY according to the requested link settings. | ||
377 | * | ||
378 | * If the PHY can auto-negotiate first decide what to advertise, then | ||
379 | * enable/disable auto-negotiation as desired and reset. | ||
380 | * | ||
381 | * If the PHY does not auto-negotiate we just reset it. | ||
382 | * | ||
383 | * If auto-negotiation is off set the MAC to the proper speed/duplex/FC, | ||
384 | * otherwise do it later based on the outcome of auto-negotiation. | ||
385 | */ | ||
386 | int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) | ||
387 | { | ||
388 | unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); | ||
389 | |||
390 | if (lc->supported & SUPPORTED_Autoneg) { | ||
391 | lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE); | ||
392 | if (fc) { | ||
393 | lc->advertising |= ADVERTISED_ASYM_PAUSE; | ||
394 | if (fc == (PAUSE_RX | PAUSE_TX)) | ||
395 | lc->advertising |= ADVERTISED_PAUSE; | ||
396 | } | ||
397 | phy->ops->advertise(phy, lc->advertising); | ||
398 | |||
399 | if (lc->autoneg == AUTONEG_DISABLE) { | ||
400 | lc->speed = lc->requested_speed; | ||
401 | lc->duplex = lc->requested_duplex; | ||
402 | lc->fc = (unsigned char)fc; | ||
403 | mac->ops->set_speed_duplex_fc(mac, lc->speed, | ||
404 | lc->duplex, fc); | ||
405 | /* Also disables autoneg */ | ||
406 | phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); | ||
407 | phy->ops->reset(phy, 0); | ||
408 | } else | ||
409 | phy->ops->autoneg_enable(phy); /* also resets PHY */ | ||
410 | } else { | ||
411 | mac->ops->set_speed_duplex_fc(mac, -1, -1, fc); | ||
412 | lc->fc = (unsigned char)fc; | ||
413 | phy->ops->reset(phy, 0); | ||
414 | } | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * External interrupt handler for boards using elmer0. | ||
420 | */ | ||
421 | int elmer0_ext_intr_handler(adapter_t *adapter) | ||
422 | { | ||
423 | struct cphy *phy; | ||
424 | int phy_cause; | ||
425 | u32 cause; | ||
426 | |||
427 | t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause); | ||
428 | |||
429 | switch (board_info(adapter)->board) { | ||
430 | case CHBT_BOARD_N210: | ||
431 | case CHBT_BOARD_N110: | ||
432 | if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */ | ||
433 | phy = adapter->port[0].phy; | ||
434 | phy_cause = phy->ops->interrupt_handler(phy); | ||
435 | if (phy_cause & cphy_cause_link_change) | ||
436 | link_changed(adapter, 0); | ||
437 | } | ||
438 | break; | ||
439 | } | ||
440 | t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause); | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | /* Enables all interrupts. */ | ||
445 | void t1_interrupts_enable(adapter_t *adapter) | ||
446 | { | ||
447 | unsigned int i; | ||
448 | u32 pl_intr; | ||
449 | |||
450 | adapter->slow_intr_mask = F_PL_INTR_SGE_ERR; | ||
451 | |||
452 | t1_sge_intr_enable(adapter->sge); | ||
453 | if (adapter->espi) { | ||
454 | adapter->slow_intr_mask |= F_PL_INTR_ESPI; | ||
455 | t1_espi_intr_enable(adapter->espi); | ||
456 | } | ||
457 | |||
458 | /* Enable MAC/PHY interrupts for each port. */ | ||
459 | for_each_port(adapter, i) { | ||
460 | adapter->port[i].mac->ops->interrupt_enable(adapter->port[i].mac); | ||
461 | adapter->port[i].phy->ops->interrupt_enable(adapter->port[i].phy); | ||
462 | } | ||
463 | |||
464 | /* Enable PCIX & external chip interrupts on ASIC boards. */ | ||
465 | pl_intr = readl(adapter->regs + A_PL_ENABLE); | ||
466 | |||
467 | /* PCI-X interrupts */ | ||
468 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, | ||
469 | 0xffffffff); | ||
470 | |||
471 | adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX; | ||
472 | pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX; | ||
473 | writel(pl_intr, adapter->regs + A_PL_ENABLE); | ||
474 | } | ||
475 | |||
476 | /* Disables all interrupts. */ | ||
477 | void t1_interrupts_disable(adapter_t* adapter) | ||
478 | { | ||
479 | unsigned int i; | ||
480 | |||
481 | t1_sge_intr_disable(adapter->sge); | ||
482 | if (adapter->espi) | ||
483 | t1_espi_intr_disable(adapter->espi); | ||
484 | |||
485 | /* Disable MAC/PHY interrupts for each port. */ | ||
486 | for_each_port(adapter, i) { | ||
487 | adapter->port[i].mac->ops->interrupt_disable(adapter->port[i].mac); | ||
488 | adapter->port[i].phy->ops->interrupt_disable(adapter->port[i].phy); | ||
489 | } | ||
490 | |||
491 | /* Disable PCIX & external chip interrupts. */ | ||
492 | writel(0, adapter->regs + A_PL_ENABLE); | ||
493 | |||
494 | /* PCI-X interrupts */ | ||
495 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0); | ||
496 | |||
497 | adapter->slow_intr_mask = 0; | ||
498 | } | ||
499 | |||
500 | /* Clears all interrupts */ | ||
501 | void t1_interrupts_clear(adapter_t* adapter) | ||
502 | { | ||
503 | unsigned int i; | ||
504 | u32 pl_intr; | ||
505 | |||
506 | |||
507 | t1_sge_intr_clear(adapter->sge); | ||
508 | if (adapter->espi) | ||
509 | t1_espi_intr_clear(adapter->espi); | ||
510 | |||
511 | /* Clear MAC/PHY interrupts for each port. */ | ||
512 | for_each_port(adapter, i) { | ||
513 | adapter->port[i].mac->ops->interrupt_clear(adapter->port[i].mac); | ||
514 | adapter->port[i].phy->ops->interrupt_clear(adapter->port[i].phy); | ||
515 | } | ||
516 | |||
517 | /* Enable interrupts for external devices. */ | ||
518 | pl_intr = readl(adapter->regs + A_PL_CAUSE); | ||
519 | |||
520 | writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX, | ||
521 | adapter->regs + A_PL_CAUSE); | ||
522 | |||
523 | /* PCI-X interrupts */ | ||
524 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff); | ||
525 | } | ||
526 | |||
527 | /* | ||
528 | * Slow path interrupt handler for ASICs. | ||
529 | */ | ||
530 | int t1_slow_intr_handler(adapter_t *adapter) | ||
531 | { | ||
532 | u32 cause = readl(adapter->regs + A_PL_CAUSE); | ||
533 | |||
534 | cause &= adapter->slow_intr_mask; | ||
535 | if (!cause) | ||
536 | return 0; | ||
537 | if (cause & F_PL_INTR_SGE_ERR) | ||
538 | t1_sge_intr_error_handler(adapter->sge); | ||
539 | if (cause & F_PL_INTR_ESPI) | ||
540 | t1_espi_intr_handler(adapter->espi); | ||
541 | if (cause & F_PL_INTR_PCIX) | ||
542 | t1_pci_intr_handler(adapter); | ||
543 | if (cause & F_PL_INTR_EXT) | ||
544 | t1_elmer0_ext_intr(adapter); | ||
545 | |||
546 | /* Clear the interrupts just processed. */ | ||
547 | writel(cause, adapter->regs + A_PL_CAUSE); | ||
548 | (void)readl(adapter->regs + A_PL_CAUSE); /* flush writes */ | ||
549 | return 1; | ||
550 | } | ||
551 | |||
552 | /* Pause deadlock avoidance parameters */ | ||
553 | #define DROP_MSEC 16 | ||
554 | #define DROP_PKTS_CNT 1 | ||
555 | |||
556 | static void set_csum_offload(adapter_t *adapter, u32 csum_bit, int enable) | ||
557 | { | ||
558 | u32 val = readl(adapter->regs + A_TP_GLOBAL_CONFIG); | ||
559 | |||
560 | if (enable) | ||
561 | val |= csum_bit; | ||
562 | else | ||
563 | val &= ~csum_bit; | ||
564 | writel(val, adapter->regs + A_TP_GLOBAL_CONFIG); | ||
565 | } | ||
566 | |||
567 | void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable) | ||
568 | { | ||
569 | set_csum_offload(adapter, F_IP_CSUM, enable); | ||
570 | } | ||
571 | |||
572 | void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable) | ||
573 | { | ||
574 | set_csum_offload(adapter, F_UDP_CSUM, enable); | ||
575 | } | ||
576 | |||
577 | void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable) | ||
578 | { | ||
579 | set_csum_offload(adapter, F_TCP_CSUM, enable); | ||
580 | } | ||
581 | |||
582 | static void t1_tp_reset(adapter_t *adapter, unsigned int tp_clk) | ||
583 | { | ||
584 | u32 val; | ||
585 | |||
586 | val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | | ||
587 | F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; | ||
588 | val |= F_TP_IN_ESPI_CHECK_IP_CSUM | | ||
589 | F_TP_IN_ESPI_CHECK_TCP_CSUM; | ||
590 | writel(val, adapter->regs + A_TP_IN_CONFIG); | ||
591 | writel(F_TP_OUT_CSPI_CPL | | ||
592 | F_TP_OUT_ESPI_ETHERNET | | ||
593 | F_TP_OUT_ESPI_GENERATE_IP_CSUM | | ||
594 | F_TP_OUT_ESPI_GENERATE_TCP_CSUM, | ||
595 | adapter->regs + A_TP_OUT_CONFIG); | ||
596 | |||
597 | val = readl(adapter->regs + A_TP_GLOBAL_CONFIG); | ||
598 | val &= ~(F_IP_CSUM | F_UDP_CSUM | F_TCP_CSUM); | ||
599 | writel(val, adapter->regs + A_TP_GLOBAL_CONFIG); | ||
600 | |||
601 | /* | ||
602 | * Enable pause frame deadlock prevention. | ||
603 | */ | ||
604 | if (is_T2(adapter)) { | ||
605 | u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); | ||
606 | |||
607 | writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | | ||
608 | V_DROP_TICKS_CNT(drop_ticks) | | ||
609 | V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), | ||
610 | adapter->regs + A_TP_TX_DROP_CONFIG); | ||
611 | } | ||
612 | |||
613 | writel(F_TP_RESET, adapter->regs + A_TP_RESET); | ||
614 | } | ||
615 | |||
616 | int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, | ||
617 | struct adapter_params *p) | ||
618 | { | ||
619 | p->chip_version = bi->chip_term; | ||
620 | if (p->chip_version == CHBT_TERM_T1 || | ||
621 | p->chip_version == CHBT_TERM_T2) { | ||
622 | u32 val = readl(adapter->regs + A_TP_PC_CONFIG); | ||
623 | |||
624 | val = G_TP_PC_REV(val); | ||
625 | if (val == 2) | ||
626 | p->chip_revision = TERM_T1B; | ||
627 | else if (val == 3) | ||
628 | p->chip_revision = TERM_T2; | ||
629 | else | ||
630 | return -1; | ||
631 | } else | ||
632 | return -1; | ||
633 | return 0; | ||
634 | } | ||
635 | |||
636 | /* | ||
637 | * Enable board components other than the Chelsio chip, such as external MAC | ||
638 | * and PHY. | ||
639 | */ | ||
640 | static int board_init(adapter_t *adapter, const struct board_info *bi) | ||
641 | { | ||
642 | switch (bi->board) { | ||
643 | case CHBT_BOARD_N110: | ||
644 | case CHBT_BOARD_N210: | ||
645 | writel(V_TPIPAR(0xf), adapter->regs + A_TPI_PAR); | ||
646 | t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); | ||
647 | break; | ||
648 | } | ||
649 | return 0; | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * Initialize and configure the Terminator HW modules. Note that external | ||
654 | * MAC and PHYs are initialized separately. | ||
655 | */ | ||
656 | int t1_init_hw_modules(adapter_t *adapter) | ||
657 | { | ||
658 | int err = -EIO; | ||
659 | const struct board_info *bi = board_info(adapter); | ||
660 | |||
661 | if (!bi->clock_mc4) { | ||
662 | u32 val = readl(adapter->regs + A_MC4_CFG); | ||
663 | |||
664 | writel(val | F_READY | F_MC4_SLOW, adapter->regs + A_MC4_CFG); | ||
665 | writel(F_M_BUS_ENABLE | F_TCAM_RESET, | ||
666 | adapter->regs + A_MC5_CONFIG); | ||
667 | } | ||
668 | |||
669 | if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac, | ||
670 | bi->espi_nports)) | ||
671 | goto out_err; | ||
672 | |||
673 | t1_tp_reset(adapter, bi->clock_core); | ||
674 | |||
675 | err = t1_sge_configure(adapter->sge, &adapter->params.sge); | ||
676 | if (err) | ||
677 | goto out_err; | ||
678 | |||
679 | err = 0; | ||
680 | out_err: | ||
681 | return err; | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * Determine a card's PCI mode. | ||
686 | */ | ||
687 | static void __devinit get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p) | ||
688 | { | ||
689 | static unsigned short speed_map[] = { 33, 66, 100, 133 }; | ||
690 | u32 pci_mode; | ||
691 | |||
692 | pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode); | ||
693 | p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)]; | ||
694 | p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32; | ||
695 | p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0; | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Release the structures holding the SW per-Terminator-HW-module state. | ||
700 | */ | ||
701 | void t1_free_sw_modules(adapter_t *adapter) | ||
702 | { | ||
703 | unsigned int i; | ||
704 | |||
705 | for_each_port(adapter, i) { | ||
706 | struct cmac *mac = adapter->port[i].mac; | ||
707 | struct cphy *phy = adapter->port[i].phy; | ||
708 | |||
709 | if (mac) | ||
710 | mac->ops->destroy(mac); | ||
711 | if (phy) | ||
712 | phy->ops->destroy(phy); | ||
713 | } | ||
714 | |||
715 | if (adapter->sge) | ||
716 | t1_sge_destroy(adapter->sge); | ||
717 | if (adapter->espi) | ||
718 | t1_espi_destroy(adapter->espi); | ||
719 | } | ||
720 | |||
721 | static void __devinit init_link_config(struct link_config *lc, | ||
722 | const struct board_info *bi) | ||
723 | { | ||
724 | lc->supported = bi->caps; | ||
725 | lc->requested_speed = lc->speed = SPEED_INVALID; | ||
726 | lc->requested_duplex = lc->duplex = DUPLEX_INVALID; | ||
727 | lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; | ||
728 | if (lc->supported & SUPPORTED_Autoneg) { | ||
729 | lc->advertising = lc->supported; | ||
730 | lc->autoneg = AUTONEG_ENABLE; | ||
731 | lc->requested_fc |= PAUSE_AUTONEG; | ||
732 | } else { | ||
733 | lc->advertising = 0; | ||
734 | lc->autoneg = AUTONEG_DISABLE; | ||
735 | } | ||
736 | } | ||
737 | |||
738 | |||
739 | /* | ||
740 | * Allocate and initialize the data structures that hold the SW state of | ||
741 | * the Terminator HW modules. | ||
742 | */ | ||
743 | int __devinit t1_init_sw_modules(adapter_t *adapter, | ||
744 | const struct board_info *bi) | ||
745 | { | ||
746 | unsigned int i; | ||
747 | |||
748 | adapter->params.brd_info = bi; | ||
749 | adapter->params.nports = bi->port_number; | ||
750 | adapter->params.stats_update_period = bi->gmac->stats_update_period; | ||
751 | |||
752 | adapter->sge = t1_sge_create(adapter, &adapter->params.sge); | ||
753 | if (!adapter->sge) { | ||
754 | CH_ERR("%s: SGE initialization failed\n", | ||
755 | adapter->name); | ||
756 | goto error; | ||
757 | } | ||
758 | |||
759 | if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) { | ||
760 | CH_ERR("%s: ESPI initialization failed\n", | ||
761 | adapter->name); | ||
762 | goto error; | ||
763 | } | ||
764 | |||
765 | board_init(adapter, bi); | ||
766 | bi->mdio_ops->init(adapter, bi); | ||
767 | if (bi->gphy->reset) | ||
768 | bi->gphy->reset(adapter); | ||
769 | if (bi->gmac->reset) | ||
770 | bi->gmac->reset(adapter); | ||
771 | |||
772 | for_each_port(adapter, i) { | ||
773 | u8 hw_addr[6]; | ||
774 | struct cmac *mac; | ||
775 | int phy_addr = bi->mdio_phybaseaddr + i; | ||
776 | |||
777 | adapter->port[i].phy = bi->gphy->create(adapter, phy_addr, | ||
778 | bi->mdio_ops); | ||
779 | if (!adapter->port[i].phy) { | ||
780 | CH_ERR("%s: PHY %d initialization failed\n", | ||
781 | adapter->name, i); | ||
782 | goto error; | ||
783 | } | ||
784 | |||
785 | adapter->port[i].mac = mac = bi->gmac->create(adapter, i); | ||
786 | if (!mac) { | ||
787 | CH_ERR("%s: MAC %d initialization failed\n", | ||
788 | adapter->name, i); | ||
789 | goto error; | ||
790 | } | ||
791 | |||
792 | /* | ||
793 | * Get the port's MAC addresses either from the EEPROM if one | ||
794 | * exists or the one hardcoded in the MAC. | ||
795 | */ | ||
796 | if (vpd_macaddress_get(adapter, i, hw_addr)) { | ||
797 | CH_ERR("%s: could not read MAC address from VPD ROM\n", | ||
798 | adapter->port[i].dev->name); | ||
799 | goto error; | ||
800 | } | ||
801 | memcpy(adapter->port[i].dev->dev_addr, hw_addr, ETH_ALEN); | ||
802 | init_link_config(&adapter->port[i].link_config, bi); | ||
803 | } | ||
804 | |||
805 | get_pci_mode(adapter, &adapter->params.pci); | ||
806 | t1_interrupts_clear(adapter); | ||
807 | return 0; | ||
808 | |||
809 | error: | ||
810 | t1_free_sw_modules(adapter); | ||
811 | return -1; | ||
812 | } | ||
diff --git a/drivers/net/chelsio/suni1x10gexp_regs.h b/drivers/net/chelsio/suni1x10gexp_regs.h new file mode 100644 index 000000000000..81816c2b708a --- /dev/null +++ b/drivers/net/chelsio/suni1x10gexp_regs.h | |||
@@ -0,0 +1,213 @@ | |||
1 | /***************************************************************************** | ||
2 | * * | ||
3 | * File: suni1x10gexp_regs.h * | ||
4 | * $Revision: 1.9 $ * | ||
5 | * $Date: 2005/06/22 00:17:04 $ * | ||
6 | * Description: * | ||
7 | * PMC/SIERRA (pm3393) MAC-PHY functionality. * | ||
8 | * part of the Chelsio 10Gb Ethernet Driver. * | ||
9 | * * | ||
10 | * This program is free software; you can redistribute it and/or modify * | ||
11 | * it under the terms of the GNU General Public License, version 2, as * | ||
12 | * published by the Free Software Foundation. * | ||
13 | * * | ||
14 | * You should have received a copy of the GNU General Public License along * | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., * | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
17 | * * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * | ||
19 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * | ||
21 | * * | ||
22 | * http://www.chelsio.com * | ||
23 | * * | ||
24 | * Maintainers: maintainers@chelsio.com * | ||
25 | * * | ||
26 | * Authors: PMC/SIERRA * | ||
27 | * * | ||
28 | * History: * | ||
29 | * * | ||
30 | ****************************************************************************/ | ||
31 | |||
32 | #ifndef _CXGB_SUNI1x10GEXP_REGS_H_ | ||
33 | #define _CXGB_SUNI1x10GEXP_REGS_H_ | ||
34 | |||
35 | /******************************************************************************/ | ||
36 | /** S/UNI-1x10GE-XP REGISTER ADDRESS MAP **/ | ||
37 | /******************************************************************************/ | ||
38 | /* Refer to the Register Bit Masks bellow for the naming of each register and */ | ||
39 | /* to the S/UNI-1x10GE-XP Data Sheet for the signification of each bit */ | ||
40 | /******************************************************************************/ | ||
41 | |||
42 | #define SUNI1x10GEXP_REG_DEVICE_STATUS 0x0004 | ||
43 | #define SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS 0x000D | ||
44 | #define SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE 0x000E | ||
45 | #define SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE 0x0102 | ||
46 | #define SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS 0x0104 | ||
47 | #define SUNI1x10GEXP_REG_RXXG_CONFIG_1 0x2040 | ||
48 | #define SUNI1x10GEXP_REG_RXXG_CONFIG_3 0x2042 | ||
49 | #define SUNI1x10GEXP_REG_RXXG_INTERRUPT 0x2043 | ||
50 | #define SUNI1x10GEXP_REG_RXXG_MAX_FRAME_LENGTH 0x2045 | ||
51 | #define SUNI1x10GEXP_REG_RXXG_SA_15_0 0x2046 | ||
52 | #define SUNI1x10GEXP_REG_RXXG_SA_31_16 0x2047 | ||
53 | #define SUNI1x10GEXP_REG_RXXG_SA_47_32 0x2048 | ||
54 | #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_LOW 0x204D | ||
55 | #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_MID 0x204E | ||
56 | #define SUNI1x10GEXP_REG_RXXG_EXACT_MATCH_ADDR_1_HIGH 0x204F | ||
57 | #define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW 0x206A | ||
58 | #define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW 0x206B | ||
59 | #define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH 0x206C | ||
60 | #define SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH 0x206D | ||
61 | #define SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_0 0x206E | ||
62 | #define SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2 0x2070 | ||
63 | #define SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE 0x2088 | ||
64 | #define SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS 0x2089 | ||
65 | #define SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE 0x208B | ||
66 | #define SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS 0x208C | ||
67 | #define SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE 0x20C7 | ||
68 | #define SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS 0x20C8 | ||
69 | #define SUNI1x10GEXP_REG_MSTAT_CONTROL 0x2100 | ||
70 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_0 0x2101 | ||
71 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_1 0x2102 | ||
72 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_2 0x2103 | ||
73 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_ROLLOVER_3 0x2104 | ||
74 | #define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0 0x2105 | ||
75 | #define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1 0x2106 | ||
76 | #define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2 0x2107 | ||
77 | #define SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3 0x2108 | ||
78 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_0_LOW 0x2110 | ||
79 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW 0x2114 | ||
80 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_4_LOW 0x2120 | ||
81 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_5_LOW 0x2124 | ||
82 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_6_LOW 0x2128 | ||
83 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_8_LOW 0x2130 | ||
84 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_10_LOW 0x2138 | ||
85 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_11_LOW 0x213C | ||
86 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_12_LOW 0x2140 | ||
87 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_13_LOW 0x2144 | ||
88 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_15_LOW 0x214C | ||
89 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_16_LOW 0x2150 | ||
90 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_17_LOW 0x2154 | ||
91 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_18_LOW 0x2158 | ||
92 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW 0x2194 | ||
93 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_35_LOW 0x219C | ||
94 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_36_LOW 0x21A0 | ||
95 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_38_LOW 0x21A8 | ||
96 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_40_LOW 0x21B0 | ||
97 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_42_LOW 0x21B8 | ||
98 | #define SUNI1x10GEXP_REG_MSTAT_COUNTER_43_LOW 0x21BC | ||
99 | #define SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE 0x2209 | ||
100 | #define SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT 0x220A | ||
101 | #define SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK 0x2282 | ||
102 | #define SUNI1x10GEXP_REG_PL4ODP_INTERRUPT 0x2283 | ||
103 | #define SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS 0x2300 | ||
104 | #define SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE 0x2301 | ||
105 | #define SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK 0x2302 | ||
106 | #define SUNI1x10GEXP_REG_TXXG_CONFIG_1 0x3040 | ||
107 | #define SUNI1x10GEXP_REG_TXXG_CONFIG_3 0x3042 | ||
108 | #define SUNI1x10GEXP_REG_TXXG_INTERRUPT 0x3043 | ||
109 | #define SUNI1x10GEXP_REG_TXXG_MAX_FRAME_SIZE 0x3045 | ||
110 | #define SUNI1x10GEXP_REG_TXXG_SA_15_0 0x3047 | ||
111 | #define SUNI1x10GEXP_REG_TXXG_SA_31_16 0x3048 | ||
112 | #define SUNI1x10GEXP_REG_TXXG_SA_47_32 0x3049 | ||
113 | #define SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS 0x3084 | ||
114 | #define SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE 0x3085 | ||
115 | #define SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE 0x30C6 | ||
116 | #define SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS 0x30C7 | ||
117 | #define SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE 0x320C | ||
118 | #define SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION 0x320D | ||
119 | #define SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK 0x3282 | ||
120 | #define SUNI1x10GEXP_REG_PL4IDU_INTERRUPT 0x3283 | ||
121 | |||
122 | /******************************************************************************/ | ||
123 | /* -- End register offset definitions -- */ | ||
124 | /******************************************************************************/ | ||
125 | |||
126 | /******************************************************************************/ | ||
127 | /** SUNI-1x10GE-XP REGISTER BIT MASKS **/ | ||
128 | /******************************************************************************/ | ||
129 | |||
130 | /*---------------------------------------------------------------------------- | ||
131 | * Register 0x0004: S/UNI-1x10GE-XP Device Status | ||
132 | * Bit 9 TOP_SXRA_EXPIRED | ||
133 | * Bit 8 TOP_MDIO_BUSY | ||
134 | * Bit 7 TOP_DTRB | ||
135 | * Bit 6 TOP_EXPIRED | ||
136 | * Bit 5 TOP_PAUSED | ||
137 | * Bit 4 TOP_PL4_ID_DOOL | ||
138 | * Bit 3 TOP_PL4_IS_DOOL | ||
139 | * Bit 2 TOP_PL4_ID_ROOL | ||
140 | * Bit 1 TOP_PL4_IS_ROOL | ||
141 | * Bit 0 TOP_PL4_OUT_ROOL | ||
142 | *----------------------------------------------------------------------------*/ | ||
143 | #define SUNI1x10GEXP_BITMSK_TOP_SXRA_EXPIRED 0x0200 | ||
144 | #define SUNI1x10GEXP_BITMSK_TOP_EXPIRED 0x0040 | ||
145 | #define SUNI1x10GEXP_BITMSK_TOP_PL4_ID_DOOL 0x0010 | ||
146 | #define SUNI1x10GEXP_BITMSK_TOP_PL4_IS_DOOL 0x0008 | ||
147 | #define SUNI1x10GEXP_BITMSK_TOP_PL4_ID_ROOL 0x0004 | ||
148 | #define SUNI1x10GEXP_BITMSK_TOP_PL4_IS_ROOL 0x0002 | ||
149 | #define SUNI1x10GEXP_BITMSK_TOP_PL4_OUT_ROOL 0x0001 | ||
150 | |||
151 | /*---------------------------------------------------------------------------- | ||
152 | * Register 0x000E:PM3393 Global interrupt enable | ||
153 | * Bit 15 TOP_INTE | ||
154 | *----------------------------------------------------------------------------*/ | ||
155 | #define SUNI1x10GEXP_BITMSK_TOP_INTE 0x8000 | ||
156 | |||
157 | /*---------------------------------------------------------------------------- | ||
158 | * Register 0x2040: RXXG Configuration 1 | ||
159 | * Bit 15 RXXG_RXEN | ||
160 | * Bit 14 RXXG_ROCF | ||
161 | * Bit 13 RXXG_PAD_STRIP | ||
162 | * Bit 10 RXXG_PUREP | ||
163 | * Bit 9 RXXG_LONGP | ||
164 | * Bit 8 RXXG_PARF | ||
165 | * Bit 7 RXXG_FLCHK | ||
166 | * Bit 5 RXXG_PASS_CTRL | ||
167 | * Bit 3 RXXG_CRC_STRIP | ||
168 | * Bit 2-0 RXXG_MIFG | ||
169 | *----------------------------------------------------------------------------*/ | ||
170 | #define SUNI1x10GEXP_BITMSK_RXXG_RXEN 0x8000 | ||
171 | #define SUNI1x10GEXP_BITMSK_RXXG_PUREP 0x0400 | ||
172 | #define SUNI1x10GEXP_BITMSK_RXXG_FLCHK 0x0080 | ||
173 | #define SUNI1x10GEXP_BITMSK_RXXG_CRC_STRIP 0x0008 | ||
174 | |||
175 | /*---------------------------------------------------------------------------- | ||
176 | * Register 0x2070: RXXG Address Filter Control 2 | ||
177 | * Bit 1 RXXG_PMODE | ||
178 | * Bit 0 RXXG_MHASH_EN | ||
179 | *----------------------------------------------------------------------------*/ | ||
180 | #define SUNI1x10GEXP_BITMSK_RXXG_PMODE 0x0002 | ||
181 | #define SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN 0x0001 | ||
182 | |||
183 | /*---------------------------------------------------------------------------- | ||
184 | * Register 0x2100: MSTAT Control | ||
185 | * Bit 2 MSTAT_WRITE | ||
186 | * Bit 1 MSTAT_CLEAR | ||
187 | * Bit 0 MSTAT_SNAP | ||
188 | *----------------------------------------------------------------------------*/ | ||
189 | #define SUNI1x10GEXP_BITMSK_MSTAT_CLEAR 0x0002 | ||
190 | #define SUNI1x10GEXP_BITMSK_MSTAT_SNAP 0x0001 | ||
191 | |||
192 | /*---------------------------------------------------------------------------- | ||
193 | * Register 0x3040: TXXG Configuration Register 1 | ||
194 | * Bit 15 TXXG_TXEN0 | ||
195 | * Bit 13 TXXG_HOSTPAUSE | ||
196 | * Bit 12-7 TXXG_IPGT | ||
197 | * Bit 5 TXXG_32BIT_ALIGN | ||
198 | * Bit 4 TXXG_CRCEN | ||
199 | * Bit 3 TXXG_FCTX | ||
200 | * Bit 2 TXXG_FCRX | ||
201 | * Bit 1 TXXG_PADEN | ||
202 | * Bit 0 TXXG_SPRE | ||
203 | *----------------------------------------------------------------------------*/ | ||
204 | #define SUNI1x10GEXP_BITMSK_TXXG_TXEN0 0x8000 | ||
205 | #define SUNI1x10GEXP_BITOFF_TXXG_IPGT 7 | ||
206 | #define SUNI1x10GEXP_BITMSK_TXXG_32BIT_ALIGN 0x0020 | ||
207 | #define SUNI1x10GEXP_BITMSK_TXXG_CRCEN 0x0010 | ||
208 | #define SUNI1x10GEXP_BITMSK_TXXG_FCTX 0x0008 | ||
209 | #define SUNI1x10GEXP_BITMSK_TXXG_FCRX 0x0004 | ||
210 | #define SUNI1x10GEXP_BITMSK_TXXG_PADEN 0x0002 | ||
211 | |||
212 | #endif /* _CXGB_SUNI1x10GEXP_REGS_H_ */ | ||
213 | |||
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index d0fa2448761d..25cc20e415da 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | 3 | ||
4 | Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. | 4 | Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms of the GNU General Public License as published by the Free | 7 | under the terms of the GNU General Public License as published by the Free |
@@ -156,7 +156,7 @@ | |||
156 | 156 | ||
157 | #define DRV_NAME "e100" | 157 | #define DRV_NAME "e100" |
158 | #define DRV_EXT "-NAPI" | 158 | #define DRV_EXT "-NAPI" |
159 | #define DRV_VERSION "3.4.8-k2"DRV_EXT | 159 | #define DRV_VERSION "3.4.14-k2"DRV_EXT |
160 | #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" | 160 | #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" |
161 | #define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" | 161 | #define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" |
162 | #define PFX DRV_NAME ": " | 162 | #define PFX DRV_NAME ": " |
@@ -785,6 +785,7 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count) | |||
785 | } | 785 | } |
786 | 786 | ||
787 | #define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */ | 787 | #define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */ |
788 | #define E100_WAIT_SCB_FAST 20 /* delay like the old code */ | ||
788 | static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) | 789 | static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) |
789 | { | 790 | { |
790 | unsigned long flags; | 791 | unsigned long flags; |
@@ -798,7 +799,7 @@ static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) | |||
798 | if(likely(!readb(&nic->csr->scb.cmd_lo))) | 799 | if(likely(!readb(&nic->csr->scb.cmd_lo))) |
799 | break; | 800 | break; |
800 | cpu_relax(); | 801 | cpu_relax(); |
801 | if(unlikely(i > (E100_WAIT_SCB_TIMEOUT >> 1))) | 802 | if(unlikely(i > E100_WAIT_SCB_FAST)) |
802 | udelay(5); | 803 | udelay(5); |
803 | } | 804 | } |
804 | if(unlikely(i == E100_WAIT_SCB_TIMEOUT)) { | 805 | if(unlikely(i == E100_WAIT_SCB_TIMEOUT)) { |
@@ -902,8 +903,8 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data) | |||
902 | 903 | ||
903 | static void e100_get_defaults(struct nic *nic) | 904 | static void e100_get_defaults(struct nic *nic) |
904 | { | 905 | { |
905 | struct param_range rfds = { .min = 16, .max = 256, .count = 64 }; | 906 | struct param_range rfds = { .min = 16, .max = 256, .count = 256 }; |
906 | struct param_range cbs = { .min = 64, .max = 256, .count = 64 }; | 907 | struct param_range cbs = { .min = 64, .max = 256, .count = 128 }; |
907 | 908 | ||
908 | pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); | 909 | pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); |
909 | /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ | 910 | /* MAC type is encoded as rev ID; exception: ICH is treated as 82559 */ |
@@ -1006,25 +1007,213 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) | |||
1006 | c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); | 1007 | c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]); |
1007 | } | 1008 | } |
1008 | 1009 | ||
1010 | /********************************************************/ | ||
1011 | /* Micro code for 8086:1229 Rev 8 */ | ||
1012 | /********************************************************/ | ||
1013 | |||
1014 | /* Parameter values for the D101M B-step */ | ||
1015 | #define D101M_CPUSAVER_TIMER_DWORD 78 | ||
1016 | #define D101M_CPUSAVER_BUNDLE_DWORD 65 | ||
1017 | #define D101M_CPUSAVER_MIN_SIZE_DWORD 126 | ||
1018 | |||
1019 | #define D101M_B_RCVBUNDLE_UCODE \ | ||
1020 | {\ | ||
1021 | 0x00550215, 0xFFFF0437, 0xFFFFFFFF, 0x06A70789, 0xFFFFFFFF, 0x0558FFFF, \ | ||
1022 | 0x000C0001, 0x00101312, 0x000C0008, 0x00380216, \ | ||
1023 | 0x0010009C, 0x00204056, 0x002380CC, 0x00380056, \ | ||
1024 | 0x0010009C, 0x00244C0B, 0x00000800, 0x00124818, \ | ||
1025 | 0x00380438, 0x00000000, 0x00140000, 0x00380555, \ | ||
1026 | 0x00308000, 0x00100662, 0x00100561, 0x000E0408, \ | ||
1027 | 0x00134861, 0x000C0002, 0x00103093, 0x00308000, \ | ||
1028 | 0x00100624, 0x00100561, 0x000E0408, 0x00100861, \ | ||
1029 | 0x000C007E, 0x00222C21, 0x000C0002, 0x00103093, \ | ||
1030 | 0x00380C7A, 0x00080000, 0x00103090, 0x00380C7A, \ | ||
1031 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1032 | 0x0010009C, 0x00244C2D, 0x00010004, 0x00041000, \ | ||
1033 | 0x003A0437, 0x00044010, 0x0038078A, 0x00000000, \ | ||
1034 | 0x00100099, 0x00206C7A, 0x0010009C, 0x00244C48, \ | ||
1035 | 0x00130824, 0x000C0001, 0x00101213, 0x00260C75, \ | ||
1036 | 0x00041000, 0x00010004, 0x00130826, 0x000C0006, \ | ||
1037 | 0x002206A8, 0x0013C926, 0x00101313, 0x003806A8, \ | ||
1038 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1039 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1040 | 0x00080600, 0x00101B10, 0x00050004, 0x00100826, \ | ||
1041 | 0x00101210, 0x00380C34, 0x00000000, 0x00000000, \ | ||
1042 | 0x0021155B, 0x00100099, 0x00206559, 0x0010009C, \ | ||
1043 | 0x00244559, 0x00130836, 0x000C0000, 0x00220C62, \ | ||
1044 | 0x000C0001, 0x00101B13, 0x00229C0E, 0x00210C0E, \ | ||
1045 | 0x00226C0E, 0x00216C0E, 0x0022FC0E, 0x00215C0E, \ | ||
1046 | 0x00214C0E, 0x00380555, 0x00010004, 0x00041000, \ | ||
1047 | 0x00278C67, 0x00040800, 0x00018100, 0x003A0437, \ | ||
1048 | 0x00130826, 0x000C0001, 0x00220559, 0x00101313, \ | ||
1049 | 0x00380559, 0x00000000, 0x00000000, 0x00000000, \ | ||
1050 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1051 | 0x00000000, 0x00130831, 0x0010090B, 0x00124813, \ | ||
1052 | 0x000CFF80, 0x002606AB, 0x00041000, 0x00010004, \ | ||
1053 | 0x003806A8, 0x00000000, 0x00000000, 0x00000000, \ | ||
1054 | } | ||
1055 | |||
1056 | /********************************************************/ | ||
1057 | /* Micro code for 8086:1229 Rev 9 */ | ||
1058 | /********************************************************/ | ||
1059 | |||
1060 | /* Parameter values for the D101S */ | ||
1061 | #define D101S_CPUSAVER_TIMER_DWORD 78 | ||
1062 | #define D101S_CPUSAVER_BUNDLE_DWORD 67 | ||
1063 | #define D101S_CPUSAVER_MIN_SIZE_DWORD 128 | ||
1064 | |||
1065 | #define D101S_RCVBUNDLE_UCODE \ | ||
1066 | {\ | ||
1067 | 0x00550242, 0xFFFF047E, 0xFFFFFFFF, 0x06FF0818, 0xFFFFFFFF, 0x05A6FFFF, \ | ||
1068 | 0x000C0001, 0x00101312, 0x000C0008, 0x00380243, \ | ||
1069 | 0x0010009C, 0x00204056, 0x002380D0, 0x00380056, \ | ||
1070 | 0x0010009C, 0x00244F8B, 0x00000800, 0x00124818, \ | ||
1071 | 0x0038047F, 0x00000000, 0x00140000, 0x003805A3, \ | ||
1072 | 0x00308000, 0x00100610, 0x00100561, 0x000E0408, \ | ||
1073 | 0x00134861, 0x000C0002, 0x00103093, 0x00308000, \ | ||
1074 | 0x00100624, 0x00100561, 0x000E0408, 0x00100861, \ | ||
1075 | 0x000C007E, 0x00222FA1, 0x000C0002, 0x00103093, \ | ||
1076 | 0x00380F90, 0x00080000, 0x00103090, 0x00380F90, \ | ||
1077 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1078 | 0x0010009C, 0x00244FAD, 0x00010004, 0x00041000, \ | ||
1079 | 0x003A047E, 0x00044010, 0x00380819, 0x00000000, \ | ||
1080 | 0x00100099, 0x00206FFD, 0x0010009A, 0x0020AFFD, \ | ||
1081 | 0x0010009C, 0x00244FC8, 0x00130824, 0x000C0001, \ | ||
1082 | 0x00101213, 0x00260FF7, 0x00041000, 0x00010004, \ | ||
1083 | 0x00130826, 0x000C0006, 0x00220700, 0x0013C926, \ | ||
1084 | 0x00101313, 0x00380700, 0x00000000, 0x00000000, \ | ||
1085 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1086 | 0x00080600, 0x00101B10, 0x00050004, 0x00100826, \ | ||
1087 | 0x00101210, 0x00380FB6, 0x00000000, 0x00000000, \ | ||
1088 | 0x002115A9, 0x00100099, 0x002065A7, 0x0010009A, \ | ||
1089 | 0x0020A5A7, 0x0010009C, 0x002445A7, 0x00130836, \ | ||
1090 | 0x000C0000, 0x00220FE4, 0x000C0001, 0x00101B13, \ | ||
1091 | 0x00229F8E, 0x00210F8E, 0x00226F8E, 0x00216F8E, \ | ||
1092 | 0x0022FF8E, 0x00215F8E, 0x00214F8E, 0x003805A3, \ | ||
1093 | 0x00010004, 0x00041000, 0x00278FE9, 0x00040800, \ | ||
1094 | 0x00018100, 0x003A047E, 0x00130826, 0x000C0001, \ | ||
1095 | 0x002205A7, 0x00101313, 0x003805A7, 0x00000000, \ | ||
1096 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1097 | 0x00000000, 0x00000000, 0x00000000, 0x00130831, \ | ||
1098 | 0x0010090B, 0x00124813, 0x000CFF80, 0x00260703, \ | ||
1099 | 0x00041000, 0x00010004, 0x00380700 \ | ||
1100 | } | ||
1101 | |||
1102 | /********************************************************/ | ||
1103 | /* Micro code for the 8086:1229 Rev F/10 */ | ||
1104 | /********************************************************/ | ||
1105 | |||
1106 | /* Parameter values for the D102 E-step */ | ||
1107 | #define D102_E_CPUSAVER_TIMER_DWORD 42 | ||
1108 | #define D102_E_CPUSAVER_BUNDLE_DWORD 54 | ||
1109 | #define D102_E_CPUSAVER_MIN_SIZE_DWORD 46 | ||
1110 | |||
1111 | #define D102_E_RCVBUNDLE_UCODE \ | ||
1112 | {\ | ||
1113 | 0x007D028F, 0x0E4204F9, 0x14ED0C85, 0x14FA14E9, 0x0EF70E36, 0x1FFF1FFF, \ | ||
1114 | 0x00E014B9, 0x00000000, 0x00000000, 0x00000000, \ | ||
1115 | 0x00E014BD, 0x00000000, 0x00000000, 0x00000000, \ | ||
1116 | 0x00E014D5, 0x00000000, 0x00000000, 0x00000000, \ | ||
1117 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1118 | 0x00E014C1, 0x00000000, 0x00000000, 0x00000000, \ | ||
1119 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1120 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1121 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1122 | 0x00E014C8, 0x00000000, 0x00000000, 0x00000000, \ | ||
1123 | 0x00200600, 0x00E014EE, 0x00000000, 0x00000000, \ | ||
1124 | 0x0030FF80, 0x00940E46, 0x00038200, 0x00102000, \ | ||
1125 | 0x00E00E43, 0x00000000, 0x00000000, 0x00000000, \ | ||
1126 | 0x00300006, 0x00E014FB, 0x00000000, 0x00000000, \ | ||
1127 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1128 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1129 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1130 | 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, \ | ||
1131 | 0x00906EFD, 0x00900EFD, 0x00E00EF8, 0x00000000, \ | ||
1132 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1133 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1134 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1135 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1136 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1137 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1138 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1139 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1140 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1141 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1142 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1143 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1144 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1145 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ | ||
1146 | } | ||
1147 | |||
1009 | static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) | 1148 | static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) |
1010 | { | 1149 | { |
1011 | int i; | 1150 | /* *INDENT-OFF* */ |
1012 | static const u32 ucode[UCODE_SIZE] = { | 1151 | static struct { |
1013 | /* NFS packets are misinterpreted as TCO packets and | 1152 | u32 ucode[UCODE_SIZE + 1]; |
1014 | * incorrectly routed to the BMC over SMBus. This | 1153 | u8 mac; |
1015 | * microcode patch checks the fragmented IP bit in the | 1154 | u8 timer_dword; |
1016 | * NFS/UDP header to distinguish between NFS and TCO. */ | 1155 | u8 bundle_dword; |
1017 | 0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, | 1156 | u8 min_size_dword; |
1018 | 0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000, | 1157 | } ucode_opts[] = { |
1019 | 0x00906EFD, 0x00900EFD, 0x00E00EF8, | 1158 | { D101M_B_RCVBUNDLE_UCODE, |
1020 | }; | 1159 | mac_82559_D101M, |
1160 | D101M_CPUSAVER_TIMER_DWORD, | ||
1161 | D101M_CPUSAVER_BUNDLE_DWORD, | ||
1162 | D101M_CPUSAVER_MIN_SIZE_DWORD }, | ||
1163 | { D101S_RCVBUNDLE_UCODE, | ||
1164 | mac_82559_D101S, | ||
1165 | D101S_CPUSAVER_TIMER_DWORD, | ||
1166 | D101S_CPUSAVER_BUNDLE_DWORD, | ||
1167 | D101S_CPUSAVER_MIN_SIZE_DWORD }, | ||
1168 | { D102_E_RCVBUNDLE_UCODE, | ||
1169 | mac_82551_F, | ||
1170 | D102_E_CPUSAVER_TIMER_DWORD, | ||
1171 | D102_E_CPUSAVER_BUNDLE_DWORD, | ||
1172 | D102_E_CPUSAVER_MIN_SIZE_DWORD }, | ||
1173 | { D102_E_RCVBUNDLE_UCODE, | ||
1174 | mac_82551_10, | ||
1175 | D102_E_CPUSAVER_TIMER_DWORD, | ||
1176 | D102_E_CPUSAVER_BUNDLE_DWORD, | ||
1177 | D102_E_CPUSAVER_MIN_SIZE_DWORD }, | ||
1178 | { {0}, 0, 0, 0, 0} | ||
1179 | }, *opts; | ||
1180 | /* *INDENT-ON* */ | ||
1181 | |||
1182 | #define BUNDLESMALL 1 | ||
1183 | #define BUNDLEMAX 50 | ||
1184 | #define INTDELAY 15000 | ||
1185 | |||
1186 | opts = ucode_opts; | ||
1187 | |||
1188 | /* do not load u-code for ICH devices */ | ||
1189 | if (nic->flags & ich) | ||
1190 | return; | ||
1191 | |||
1192 | /* Search for ucode match against h/w rev_id */ | ||
1193 | while (opts->mac) { | ||
1194 | if (nic->mac == opts->mac) { | ||
1195 | int i; | ||
1196 | u32 *ucode = opts->ucode; | ||
1197 | |||
1198 | /* Insert user-tunable settings */ | ||
1199 | ucode[opts->timer_dword] &= 0xFFFF0000; | ||
1200 | ucode[opts->timer_dword] |= | ||
1201 | (u16) INTDELAY; | ||
1202 | ucode[opts->bundle_dword] &= 0xFFFF0000; | ||
1203 | ucode[opts->bundle_dword] |= (u16) BUNDLEMAX; | ||
1204 | ucode[opts->min_size_dword] &= 0xFFFF0000; | ||
1205 | ucode[opts->min_size_dword] |= | ||
1206 | (BUNDLESMALL) ? 0xFFFF : 0xFF80; | ||
1207 | |||
1208 | for(i = 0; i < UCODE_SIZE; i++) | ||
1209 | cb->u.ucode[i] = cpu_to_le32(ucode[i]); | ||
1210 | cb->command = cpu_to_le16(cb_ucode); | ||
1211 | return; | ||
1212 | } | ||
1213 | opts++; | ||
1214 | } | ||
1021 | 1215 | ||
1022 | if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) { | 1216 | cb->command = cpu_to_le16(cb_nop); |
1023 | for(i = 0; i < UCODE_SIZE; i++) | ||
1024 | cb->u.ucode[i] = cpu_to_le32(ucode[i]); | ||
1025 | cb->command = cpu_to_le16(cb_ucode); | ||
1026 | } else | ||
1027 | cb->command = cpu_to_le16(cb_nop); | ||
1028 | } | 1217 | } |
1029 | 1218 | ||
1030 | static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, | 1219 | static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, |
@@ -1307,14 +1496,15 @@ static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb, | |||
1307 | { | 1496 | { |
1308 | cb->command = nic->tx_command; | 1497 | cb->command = nic->tx_command; |
1309 | /* interrupt every 16 packets regardless of delay */ | 1498 | /* interrupt every 16 packets regardless of delay */ |
1310 | if((nic->cbs_avail & ~15) == nic->cbs_avail) cb->command |= cb_i; | 1499 | if((nic->cbs_avail & ~15) == nic->cbs_avail) |
1500 | cb->command |= cpu_to_le16(cb_i); | ||
1311 | cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd); | 1501 | cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd); |
1312 | cb->u.tcb.tcb_byte_count = 0; | 1502 | cb->u.tcb.tcb_byte_count = 0; |
1313 | cb->u.tcb.threshold = nic->tx_threshold; | 1503 | cb->u.tcb.threshold = nic->tx_threshold; |
1314 | cb->u.tcb.tbd_count = 1; | 1504 | cb->u.tcb.tbd_count = 1; |
1315 | cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev, | 1505 | cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev, |
1316 | skb->data, skb->len, PCI_DMA_TODEVICE)); | 1506 | skb->data, skb->len, PCI_DMA_TODEVICE)); |
1317 | // check for mapping failure? | 1507 | /* check for mapping failure? */ |
1318 | cb->u.tcb.tbd.size = cpu_to_le16(skb->len); | 1508 | cb->u.tcb.tbd.size = cpu_to_le16(skb->len); |
1319 | } | 1509 | } |
1320 | 1510 | ||
@@ -1539,7 +1729,7 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx, | |||
1539 | /* Don't indicate if hardware indicates errors */ | 1729 | /* Don't indicate if hardware indicates errors */ |
1540 | nic->net_stats.rx_dropped++; | 1730 | nic->net_stats.rx_dropped++; |
1541 | dev_kfree_skb_any(skb); | 1731 | dev_kfree_skb_any(skb); |
1542 | } else if(actual_size > nic->netdev->mtu + VLAN_ETH_HLEN) { | 1732 | } else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) { |
1543 | /* Don't indicate oversized frames */ | 1733 | /* Don't indicate oversized frames */ |
1544 | nic->rx_over_length_errors++; | 1734 | nic->rx_over_length_errors++; |
1545 | nic->net_stats.rx_dropped++; | 1735 | nic->net_stats.rx_dropped++; |
@@ -1706,6 +1896,7 @@ static int e100_poll(struct net_device *netdev, int *budget) | |||
1706 | static void e100_netpoll(struct net_device *netdev) | 1896 | static void e100_netpoll(struct net_device *netdev) |
1707 | { | 1897 | { |
1708 | struct nic *nic = netdev_priv(netdev); | 1898 | struct nic *nic = netdev_priv(netdev); |
1899 | |||
1709 | e100_disable_irq(nic); | 1900 | e100_disable_irq(nic); |
1710 | e100_intr(nic->pdev->irq, netdev, NULL); | 1901 | e100_intr(nic->pdev->irq, netdev, NULL); |
1711 | e100_tx_clean(nic); | 1902 | e100_tx_clean(nic); |
@@ -2108,6 +2299,8 @@ static void e100_diag_test(struct net_device *netdev, | |||
2108 | } | 2299 | } |
2109 | for(i = 0; i < E100_TEST_LEN; i++) | 2300 | for(i = 0; i < E100_TEST_LEN; i++) |
2110 | test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0; | 2301 | test->flags |= data[i] ? ETH_TEST_FL_FAILED : 0; |
2302 | |||
2303 | msleep_interruptible(4 * 1000); | ||
2111 | } | 2304 | } |
2112 | 2305 | ||
2113 | static int e100_phys_id(struct net_device *netdev, u32 data) | 2306 | static int e100_phys_id(struct net_device *netdev, u32 data) |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index b82fd15d0891..9b596e0bbf95 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2767,7 +2767,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
2767 | " next_to_use <%x>\n" | 2767 | " next_to_use <%x>\n" |
2768 | " next_to_clean <%x>\n" | 2768 | " next_to_clean <%x>\n" |
2769 | "buffer_info[next_to_clean]\n" | 2769 | "buffer_info[next_to_clean]\n" |
2770 | " dma <%zx>\n" | 2770 | " dma <%llx>\n" |
2771 | " time_stamp <%lx>\n" | 2771 | " time_stamp <%lx>\n" |
2772 | " next_to_watch <%x>\n" | 2772 | " next_to_watch <%x>\n" |
2773 | " jiffies <%lx>\n" | 2773 | " jiffies <%lx>\n" |
@@ -2776,7 +2776,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
2776 | E1000_READ_REG(&adapter->hw, TDT), | 2776 | E1000_READ_REG(&adapter->hw, TDT), |
2777 | tx_ring->next_to_use, | 2777 | tx_ring->next_to_use, |
2778 | i, | 2778 | i, |
2779 | tx_ring->buffer_info[i].dma, | 2779 | (unsigned long long)tx_ring->buffer_info[i].dma, |
2780 | tx_ring->buffer_info[i].time_stamp, | 2780 | tx_ring->buffer_info[i].time_stamp, |
2781 | eop, | 2781 | eop, |
2782 | jiffies, | 2782 | jiffies, |
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 1795425f512e..8c62ced2c9b2 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c | |||
@@ -1263,8 +1263,8 @@ speedo_init_rx_ring(struct net_device *dev) | |||
1263 | for (i = 0; i < RX_RING_SIZE; i++) { | 1263 | for (i = 0; i < RX_RING_SIZE; i++) { |
1264 | struct sk_buff *skb; | 1264 | struct sk_buff *skb; |
1265 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); | 1265 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); |
1266 | /* XXX: do we really want to call this before the NULL check? --hch */ | 1266 | if (skb) |
1267 | rx_align(skb); /* Align IP on 16 byte boundary */ | 1267 | rx_align(skb); /* Align IP on 16 byte boundary */ |
1268 | sp->rx_skbuff[i] = skb; | 1268 | sp->rx_skbuff[i] = skb; |
1269 | if (skb == NULL) | 1269 | if (skb == NULL) |
1270 | break; /* OK. Just initially short of Rx bufs. */ | 1270 | break; /* OK. Just initially short of Rx bufs. */ |
@@ -1654,8 +1654,8 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) | |||
1654 | struct sk_buff *skb; | 1654 | struct sk_buff *skb; |
1655 | /* Get a fresh skbuff to replace the consumed one. */ | 1655 | /* Get a fresh skbuff to replace the consumed one. */ |
1656 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); | 1656 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); |
1657 | /* XXX: do we really want to call this before the NULL check? --hch */ | 1657 | if (skb) |
1658 | rx_align(skb); /* Align IP on 16 byte boundary */ | 1658 | rx_align(skb); /* Align IP on 16 byte boundary */ |
1659 | sp->rx_skbuff[entry] = skb; | 1659 | sp->rx_skbuff[entry] = skb; |
1660 | if (skb == NULL) { | 1660 | if (skb == NULL) { |
1661 | sp->rx_ringp[entry] = NULL; | 1661 | sp->rx_ringp[entry] = NULL; |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 64f0f697c958..7d93948aec83 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -85,6 +85,16 @@ | |||
85 | * 0.33: 16 May 2005: Support for MCP51 added. | 85 | * 0.33: 16 May 2005: Support for MCP51 added. |
86 | * 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics. | 86 | * 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics. |
87 | * 0.35: 26 Jun 2005: Support for MCP55 added. | 87 | * 0.35: 26 Jun 2005: Support for MCP55 added. |
88 | * 0.36: 28 Jun 2005: Add jumbo frame support. | ||
89 | * 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list | ||
90 | * 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of | ||
91 | * per-packet flags. | ||
92 | * 0.39: 18 Jul 2005: Add 64bit descriptor support. | ||
93 | * 0.40: 19 Jul 2005: Add support for mac address change. | ||
94 | * 0.41: 30 Jul 2005: Write back original MAC in nv_close instead | ||
95 | * of nv_remove | ||
96 | * 0.42: 06 Aug 2005: Fix lack of link speed initialization | ||
97 | * in the second (and later) nv_open call | ||
88 | * | 98 | * |
89 | * Known bugs: | 99 | * Known bugs: |
90 | * We suspect that on some hardware no TX done interrupts are generated. | 100 | * We suspect that on some hardware no TX done interrupts are generated. |
@@ -96,7 +106,7 @@ | |||
96 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few | 106 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
97 | * superfluous timer interrupts from the nic. | 107 | * superfluous timer interrupts from the nic. |
98 | */ | 108 | */ |
99 | #define FORCEDETH_VERSION "0.35" | 109 | #define FORCEDETH_VERSION "0.41" |
100 | #define DRV_NAME "forcedeth" | 110 | #define DRV_NAME "forcedeth" |
101 | 111 | ||
102 | #include <linux/module.h> | 112 | #include <linux/module.h> |
@@ -131,11 +141,10 @@ | |||
131 | * Hardware access: | 141 | * Hardware access: |
132 | */ | 142 | */ |
133 | 143 | ||
134 | #define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */ | 144 | #define DEV_NEED_TIMERIRQ 0x0001 /* set the timer irq flag in the irq mask */ |
135 | #define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */ | 145 | #define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */ |
136 | #define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */ | 146 | #define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */ |
137 | #define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */ | 147 | #define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */ |
138 | #define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */ | ||
139 | 148 | ||
140 | enum { | 149 | enum { |
141 | NvRegIrqStatus = 0x000, | 150 | NvRegIrqStatus = 0x000, |
@@ -146,13 +155,16 @@ enum { | |||
146 | #define NVREG_IRQ_RX 0x0002 | 155 | #define NVREG_IRQ_RX 0x0002 |
147 | #define NVREG_IRQ_RX_NOBUF 0x0004 | 156 | #define NVREG_IRQ_RX_NOBUF 0x0004 |
148 | #define NVREG_IRQ_TX_ERR 0x0008 | 157 | #define NVREG_IRQ_TX_ERR 0x0008 |
149 | #define NVREG_IRQ_TX2 0x0010 | 158 | #define NVREG_IRQ_TX_OK 0x0010 |
150 | #define NVREG_IRQ_TIMER 0x0020 | 159 | #define NVREG_IRQ_TIMER 0x0020 |
151 | #define NVREG_IRQ_LINK 0x0040 | 160 | #define NVREG_IRQ_LINK 0x0040 |
161 | #define NVREG_IRQ_TX_ERROR 0x0080 | ||
152 | #define NVREG_IRQ_TX1 0x0100 | 162 | #define NVREG_IRQ_TX1 0x0100 |
153 | #define NVREG_IRQMASK_WANTED_1 0x005f | 163 | #define NVREG_IRQMASK_WANTED 0x00df |
154 | #define NVREG_IRQMASK_WANTED_2 0x0147 | 164 | |
155 | #define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) | 165 | #define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \ |
166 | NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \ | ||
167 | NVREG_IRQ_TX1)) | ||
156 | 168 | ||
157 | NvRegUnknownSetupReg6 = 0x008, | 169 | NvRegUnknownSetupReg6 = 0x008, |
158 | #define NVREG_UNKSETUP6_VAL 3 | 170 | #define NVREG_UNKSETUP6_VAL 3 |
@@ -286,6 +298,18 @@ struct ring_desc { | |||
286 | u32 FlagLen; | 298 | u32 FlagLen; |
287 | }; | 299 | }; |
288 | 300 | ||
301 | struct ring_desc_ex { | ||
302 | u32 PacketBufferHigh; | ||
303 | u32 PacketBufferLow; | ||
304 | u32 Reserved; | ||
305 | u32 FlagLen; | ||
306 | }; | ||
307 | |||
308 | typedef union _ring_type { | ||
309 | struct ring_desc* orig; | ||
310 | struct ring_desc_ex* ex; | ||
311 | } ring_type; | ||
312 | |||
289 | #define FLAG_MASK_V1 0xffff0000 | 313 | #define FLAG_MASK_V1 0xffff0000 |
290 | #define FLAG_MASK_V2 0xffffc000 | 314 | #define FLAG_MASK_V2 0xffffc000 |
291 | #define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) | 315 | #define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) |
@@ -293,7 +317,7 @@ struct ring_desc { | |||
293 | 317 | ||
294 | #define NV_TX_LASTPACKET (1<<16) | 318 | #define NV_TX_LASTPACKET (1<<16) |
295 | #define NV_TX_RETRYERROR (1<<19) | 319 | #define NV_TX_RETRYERROR (1<<19) |
296 | #define NV_TX_LASTPACKET1 (1<<24) | 320 | #define NV_TX_FORCED_INTERRUPT (1<<24) |
297 | #define NV_TX_DEFERRED (1<<26) | 321 | #define NV_TX_DEFERRED (1<<26) |
298 | #define NV_TX_CARRIERLOST (1<<27) | 322 | #define NV_TX_CARRIERLOST (1<<27) |
299 | #define NV_TX_LATECOLLISION (1<<28) | 323 | #define NV_TX_LATECOLLISION (1<<28) |
@@ -303,7 +327,7 @@ struct ring_desc { | |||
303 | 327 | ||
304 | #define NV_TX2_LASTPACKET (1<<29) | 328 | #define NV_TX2_LASTPACKET (1<<29) |
305 | #define NV_TX2_RETRYERROR (1<<18) | 329 | #define NV_TX2_RETRYERROR (1<<18) |
306 | #define NV_TX2_LASTPACKET1 (1<<23) | 330 | #define NV_TX2_FORCED_INTERRUPT (1<<30) |
307 | #define NV_TX2_DEFERRED (1<<25) | 331 | #define NV_TX2_DEFERRED (1<<25) |
308 | #define NV_TX2_CARRIERLOST (1<<26) | 332 | #define NV_TX2_CARRIERLOST (1<<26) |
309 | #define NV_TX2_LATECOLLISION (1<<27) | 333 | #define NV_TX2_LATECOLLISION (1<<27) |
@@ -379,9 +403,13 @@ struct ring_desc { | |||
379 | #define TX_LIMIT_START 62 | 403 | #define TX_LIMIT_START 62 |
380 | 404 | ||
381 | /* rx/tx mac addr + type + vlan + align + slack*/ | 405 | /* rx/tx mac addr + type + vlan + align + slack*/ |
382 | #define RX_NIC_BUFSIZE (ETH_DATA_LEN + 64) | 406 | #define NV_RX_HEADERS (64) |
383 | /* even more slack */ | 407 | /* even more slack. */ |
384 | #define RX_ALLOC_BUFSIZE (ETH_DATA_LEN + 128) | 408 | #define NV_RX_ALLOC_PAD (64) |
409 | |||
410 | /* maximum mtu size */ | ||
411 | #define NV_PKTLIMIT_1 ETH_DATA_LEN /* hard limit not known */ | ||
412 | #define NV_PKTLIMIT_2 9100 /* Actual limit according to NVidia: 9202 */ | ||
385 | 413 | ||
386 | #define OOM_REFILL (1+HZ/20) | 414 | #define OOM_REFILL (1+HZ/20) |
387 | #define POLL_WAIT (1+HZ/100) | 415 | #define POLL_WAIT (1+HZ/100) |
@@ -396,6 +424,7 @@ struct ring_desc { | |||
396 | */ | 424 | */ |
397 | #define DESC_VER_1 0x0 | 425 | #define DESC_VER_1 0x0 |
398 | #define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK) | 426 | #define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK) |
427 | #define DESC_VER_3 (0x02200|NVREG_TXRXCTL_RXCHECK) | ||
399 | 428 | ||
400 | /* PHY defines */ | 429 | /* PHY defines */ |
401 | #define PHY_OUI_MARVELL 0x5043 | 430 | #define PHY_OUI_MARVELL 0x5043 |
@@ -468,11 +497,12 @@ struct fe_priv { | |||
468 | /* rx specific fields. | 497 | /* rx specific fields. |
469 | * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); | 498 | * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); |
470 | */ | 499 | */ |
471 | struct ring_desc *rx_ring; | 500 | ring_type rx_ring; |
472 | unsigned int cur_rx, refill_rx; | 501 | unsigned int cur_rx, refill_rx; |
473 | struct sk_buff *rx_skbuff[RX_RING]; | 502 | struct sk_buff *rx_skbuff[RX_RING]; |
474 | dma_addr_t rx_dma[RX_RING]; | 503 | dma_addr_t rx_dma[RX_RING]; |
475 | unsigned int rx_buf_sz; | 504 | unsigned int rx_buf_sz; |
505 | unsigned int pkt_limit; | ||
476 | struct timer_list oom_kick; | 506 | struct timer_list oom_kick; |
477 | struct timer_list nic_poll; | 507 | struct timer_list nic_poll; |
478 | 508 | ||
@@ -484,7 +514,7 @@ struct fe_priv { | |||
484 | /* | 514 | /* |
485 | * tx specific fields. | 515 | * tx specific fields. |
486 | */ | 516 | */ |
487 | struct ring_desc *tx_ring; | 517 | ring_type tx_ring; |
488 | unsigned int next_tx, nic_tx; | 518 | unsigned int next_tx, nic_tx; |
489 | struct sk_buff *tx_skbuff[TX_RING]; | 519 | struct sk_buff *tx_skbuff[TX_RING]; |
490 | dma_addr_t tx_dma[TX_RING]; | 520 | dma_addr_t tx_dma[TX_RING]; |
@@ -519,6 +549,11 @@ static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) | |||
519 | & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); | 549 | & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); |
520 | } | 550 | } |
521 | 551 | ||
552 | static inline u32 nv_descr_getlength_ex(struct ring_desc_ex *prd, u32 v) | ||
553 | { | ||
554 | return le32_to_cpu(prd->FlagLen) & LEN_MASK_V2; | ||
555 | } | ||
556 | |||
522 | static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, | 557 | static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, |
523 | int delay, int delaymax, const char *msg) | 558 | int delay, int delaymax, const char *msg) |
524 | { | 559 | { |
@@ -792,7 +827,7 @@ static int nv_alloc_rx(struct net_device *dev) | |||
792 | nr = refill_rx % RX_RING; | 827 | nr = refill_rx % RX_RING; |
793 | if (np->rx_skbuff[nr] == NULL) { | 828 | if (np->rx_skbuff[nr] == NULL) { |
794 | 829 | ||
795 | skb = dev_alloc_skb(RX_ALLOC_BUFSIZE); | 830 | skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); |
796 | if (!skb) | 831 | if (!skb) |
797 | break; | 832 | break; |
798 | 833 | ||
@@ -803,9 +838,16 @@ static int nv_alloc_rx(struct net_device *dev) | |||
803 | } | 838 | } |
804 | np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, | 839 | np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, |
805 | PCI_DMA_FROMDEVICE); | 840 | PCI_DMA_FROMDEVICE); |
806 | np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); | 841 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
807 | wmb(); | 842 | np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); |
808 | np->rx_ring[nr].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL); | 843 | wmb(); |
844 | np->rx_ring.orig[nr].FlagLen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL); | ||
845 | } else { | ||
846 | np->rx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->rx_dma[nr]) >> 32; | ||
847 | np->rx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->rx_dma[nr]) & 0x0FFFFFFFF; | ||
848 | wmb(); | ||
849 | np->rx_ring.ex[nr].FlagLen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL); | ||
850 | } | ||
809 | dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", | 851 | dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", |
810 | dev->name, refill_rx); | 852 | dev->name, refill_rx); |
811 | refill_rx++; | 853 | refill_rx++; |
@@ -831,19 +873,37 @@ static void nv_do_rx_refill(unsigned long data) | |||
831 | enable_irq(dev->irq); | 873 | enable_irq(dev->irq); |
832 | } | 874 | } |
833 | 875 | ||
834 | static int nv_init_ring(struct net_device *dev) | 876 | static void nv_init_rx(struct net_device *dev) |
835 | { | 877 | { |
836 | struct fe_priv *np = get_nvpriv(dev); | 878 | struct fe_priv *np = get_nvpriv(dev); |
837 | int i; | 879 | int i; |
838 | 880 | ||
839 | np->next_tx = np->nic_tx = 0; | ||
840 | for (i = 0; i < TX_RING; i++) | ||
841 | np->tx_ring[i].FlagLen = 0; | ||
842 | |||
843 | np->cur_rx = RX_RING; | 881 | np->cur_rx = RX_RING; |
844 | np->refill_rx = 0; | 882 | np->refill_rx = 0; |
845 | for (i = 0; i < RX_RING; i++) | 883 | for (i = 0; i < RX_RING; i++) |
846 | np->rx_ring[i].FlagLen = 0; | 884 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
885 | np->rx_ring.orig[i].FlagLen = 0; | ||
886 | else | ||
887 | np->rx_ring.ex[i].FlagLen = 0; | ||
888 | } | ||
889 | |||
890 | static void nv_init_tx(struct net_device *dev) | ||
891 | { | ||
892 | struct fe_priv *np = get_nvpriv(dev); | ||
893 | int i; | ||
894 | |||
895 | np->next_tx = np->nic_tx = 0; | ||
896 | for (i = 0; i < TX_RING; i++) | ||
897 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) | ||
898 | np->tx_ring.orig[i].FlagLen = 0; | ||
899 | else | ||
900 | np->tx_ring.ex[i].FlagLen = 0; | ||
901 | } | ||
902 | |||
903 | static int nv_init_ring(struct net_device *dev) | ||
904 | { | ||
905 | nv_init_tx(dev); | ||
906 | nv_init_rx(dev); | ||
847 | return nv_alloc_rx(dev); | 907 | return nv_alloc_rx(dev); |
848 | } | 908 | } |
849 | 909 | ||
@@ -852,7 +912,10 @@ static void nv_drain_tx(struct net_device *dev) | |||
852 | struct fe_priv *np = get_nvpriv(dev); | 912 | struct fe_priv *np = get_nvpriv(dev); |
853 | int i; | 913 | int i; |
854 | for (i = 0; i < TX_RING; i++) { | 914 | for (i = 0; i < TX_RING; i++) { |
855 | np->tx_ring[i].FlagLen = 0; | 915 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
916 | np->tx_ring.orig[i].FlagLen = 0; | ||
917 | else | ||
918 | np->tx_ring.ex[i].FlagLen = 0; | ||
856 | if (np->tx_skbuff[i]) { | 919 | if (np->tx_skbuff[i]) { |
857 | pci_unmap_single(np->pci_dev, np->tx_dma[i], | 920 | pci_unmap_single(np->pci_dev, np->tx_dma[i], |
858 | np->tx_skbuff[i]->len, | 921 | np->tx_skbuff[i]->len, |
@@ -869,7 +932,10 @@ static void nv_drain_rx(struct net_device *dev) | |||
869 | struct fe_priv *np = get_nvpriv(dev); | 932 | struct fe_priv *np = get_nvpriv(dev); |
870 | int i; | 933 | int i; |
871 | for (i = 0; i < RX_RING; i++) { | 934 | for (i = 0; i < RX_RING; i++) { |
872 | np->rx_ring[i].FlagLen = 0; | 935 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
936 | np->rx_ring.orig[i].FlagLen = 0; | ||
937 | else | ||
938 | np->rx_ring.ex[i].FlagLen = 0; | ||
873 | wmb(); | 939 | wmb(); |
874 | if (np->rx_skbuff[i]) { | 940 | if (np->rx_skbuff[i]) { |
875 | pci_unmap_single(np->pci_dev, np->rx_dma[i], | 941 | pci_unmap_single(np->pci_dev, np->rx_dma[i], |
@@ -900,11 +966,19 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
900 | np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len, | 966 | np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len, |
901 | PCI_DMA_TODEVICE); | 967 | PCI_DMA_TODEVICE); |
902 | 968 | ||
903 | np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); | 969 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
970 | np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); | ||
971 | else { | ||
972 | np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; | ||
973 | np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; | ||
974 | } | ||
904 | 975 | ||
905 | spin_lock_irq(&np->lock); | 976 | spin_lock_irq(&np->lock); |
906 | wmb(); | 977 | wmb(); |
907 | np->tx_ring[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); | 978 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
979 | np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); | ||
980 | else | ||
981 | np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); | ||
908 | dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", | 982 | dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", |
909 | dev->name, np->next_tx); | 983 | dev->name, np->next_tx); |
910 | { | 984 | { |
@@ -942,7 +1016,10 @@ static void nv_tx_done(struct net_device *dev) | |||
942 | while (np->nic_tx != np->next_tx) { | 1016 | while (np->nic_tx != np->next_tx) { |
943 | i = np->nic_tx % TX_RING; | 1017 | i = np->nic_tx % TX_RING; |
944 | 1018 | ||
945 | Flags = le32_to_cpu(np->tx_ring[i].FlagLen); | 1019 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
1020 | Flags = le32_to_cpu(np->tx_ring.orig[i].FlagLen); | ||
1021 | else | ||
1022 | Flags = le32_to_cpu(np->tx_ring.ex[i].FlagLen); | ||
946 | 1023 | ||
947 | dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", | 1024 | dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", |
948 | dev->name, np->nic_tx, Flags); | 1025 | dev->name, np->nic_tx, Flags); |
@@ -993,9 +1070,56 @@ static void nv_tx_timeout(struct net_device *dev) | |||
993 | struct fe_priv *np = get_nvpriv(dev); | 1070 | struct fe_priv *np = get_nvpriv(dev); |
994 | u8 __iomem *base = get_hwbase(dev); | 1071 | u8 __iomem *base = get_hwbase(dev); |
995 | 1072 | ||
996 | dprintk(KERN_DEBUG "%s: Got tx_timeout. irq: %08x\n", dev->name, | 1073 | printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name, |
997 | readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK); | 1074 | readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK); |
998 | 1075 | ||
1076 | { | ||
1077 | int i; | ||
1078 | |||
1079 | printk(KERN_INFO "%s: Ring at %lx: next %d nic %d\n", | ||
1080 | dev->name, (unsigned long)np->ring_addr, | ||
1081 | np->next_tx, np->nic_tx); | ||
1082 | printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); | ||
1083 | for (i=0;i<0x400;i+= 32) { | ||
1084 | printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | ||
1085 | i, | ||
1086 | readl(base + i + 0), readl(base + i + 4), | ||
1087 | readl(base + i + 8), readl(base + i + 12), | ||
1088 | readl(base + i + 16), readl(base + i + 20), | ||
1089 | readl(base + i + 24), readl(base + i + 28)); | ||
1090 | } | ||
1091 | printk(KERN_INFO "%s: Dumping tx ring\n", dev->name); | ||
1092 | for (i=0;i<TX_RING;i+= 4) { | ||
1093 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { | ||
1094 | printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", | ||
1095 | i, | ||
1096 | le32_to_cpu(np->tx_ring.orig[i].PacketBuffer), | ||
1097 | le32_to_cpu(np->tx_ring.orig[i].FlagLen), | ||
1098 | le32_to_cpu(np->tx_ring.orig[i+1].PacketBuffer), | ||
1099 | le32_to_cpu(np->tx_ring.orig[i+1].FlagLen), | ||
1100 | le32_to_cpu(np->tx_ring.orig[i+2].PacketBuffer), | ||
1101 | le32_to_cpu(np->tx_ring.orig[i+2].FlagLen), | ||
1102 | le32_to_cpu(np->tx_ring.orig[i+3].PacketBuffer), | ||
1103 | le32_to_cpu(np->tx_ring.orig[i+3].FlagLen)); | ||
1104 | } else { | ||
1105 | printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", | ||
1106 | i, | ||
1107 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferHigh), | ||
1108 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferLow), | ||
1109 | le32_to_cpu(np->tx_ring.ex[i].FlagLen), | ||
1110 | le32_to_cpu(np->tx_ring.ex[i+1].PacketBufferHigh), | ||
1111 | le32_to_cpu(np->tx_ring.ex[i+1].PacketBufferLow), | ||
1112 | le32_to_cpu(np->tx_ring.ex[i+1].FlagLen), | ||
1113 | le32_to_cpu(np->tx_ring.ex[i+2].PacketBufferHigh), | ||
1114 | le32_to_cpu(np->tx_ring.ex[i+2].PacketBufferLow), | ||
1115 | le32_to_cpu(np->tx_ring.ex[i+2].FlagLen), | ||
1116 | le32_to_cpu(np->tx_ring.ex[i+3].PacketBufferHigh), | ||
1117 | le32_to_cpu(np->tx_ring.ex[i+3].PacketBufferLow), | ||
1118 | le32_to_cpu(np->tx_ring.ex[i+3].FlagLen)); | ||
1119 | } | ||
1120 | } | ||
1121 | } | ||
1122 | |||
999 | spin_lock_irq(&np->lock); | 1123 | spin_lock_irq(&np->lock); |
1000 | 1124 | ||
1001 | /* 1) stop tx engine */ | 1125 | /* 1) stop tx engine */ |
@@ -1009,7 +1133,10 @@ static void nv_tx_timeout(struct net_device *dev) | |||
1009 | printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); | 1133 | printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); |
1010 | nv_drain_tx(dev); | 1134 | nv_drain_tx(dev); |
1011 | np->next_tx = np->nic_tx = 0; | 1135 | np->next_tx = np->nic_tx = 0; |
1012 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | 1136 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
1137 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | ||
1138 | else | ||
1139 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); | ||
1013 | netif_wake_queue(dev); | 1140 | netif_wake_queue(dev); |
1014 | } | 1141 | } |
1015 | 1142 | ||
@@ -1084,8 +1211,13 @@ static void nv_rx_process(struct net_device *dev) | |||
1084 | break; /* we scanned the whole ring - do not continue */ | 1211 | break; /* we scanned the whole ring - do not continue */ |
1085 | 1212 | ||
1086 | i = np->cur_rx % RX_RING; | 1213 | i = np->cur_rx % RX_RING; |
1087 | Flags = le32_to_cpu(np->rx_ring[i].FlagLen); | 1214 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
1088 | len = nv_descr_getlength(&np->rx_ring[i], np->desc_ver); | 1215 | Flags = le32_to_cpu(np->rx_ring.orig[i].FlagLen); |
1216 | len = nv_descr_getlength(&np->rx_ring.orig[i], np->desc_ver); | ||
1217 | } else { | ||
1218 | Flags = le32_to_cpu(np->rx_ring.ex[i].FlagLen); | ||
1219 | len = nv_descr_getlength_ex(&np->rx_ring.ex[i], np->desc_ver); | ||
1220 | } | ||
1089 | 1221 | ||
1090 | dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", | 1222 | dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", |
1091 | dev->name, np->cur_rx, Flags); | 1223 | dev->name, np->cur_rx, Flags); |
@@ -1207,15 +1339,133 @@ next_pkt: | |||
1207 | } | 1339 | } |
1208 | } | 1340 | } |
1209 | 1341 | ||
1342 | static void set_bufsize(struct net_device *dev) | ||
1343 | { | ||
1344 | struct fe_priv *np = netdev_priv(dev); | ||
1345 | |||
1346 | if (dev->mtu <= ETH_DATA_LEN) | ||
1347 | np->rx_buf_sz = ETH_DATA_LEN + NV_RX_HEADERS; | ||
1348 | else | ||
1349 | np->rx_buf_sz = dev->mtu + NV_RX_HEADERS; | ||
1350 | } | ||
1351 | |||
1210 | /* | 1352 | /* |
1211 | * nv_change_mtu: dev->change_mtu function | 1353 | * nv_change_mtu: dev->change_mtu function |
1212 | * Called with dev_base_lock held for read. | 1354 | * Called with dev_base_lock held for read. |
1213 | */ | 1355 | */ |
1214 | static int nv_change_mtu(struct net_device *dev, int new_mtu) | 1356 | static int nv_change_mtu(struct net_device *dev, int new_mtu) |
1215 | { | 1357 | { |
1216 | if (new_mtu > ETH_DATA_LEN) | 1358 | struct fe_priv *np = get_nvpriv(dev); |
1359 | int old_mtu; | ||
1360 | |||
1361 | if (new_mtu < 64 || new_mtu > np->pkt_limit) | ||
1217 | return -EINVAL; | 1362 | return -EINVAL; |
1363 | |||
1364 | old_mtu = dev->mtu; | ||
1218 | dev->mtu = new_mtu; | 1365 | dev->mtu = new_mtu; |
1366 | |||
1367 | /* return early if the buffer sizes will not change */ | ||
1368 | if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN) | ||
1369 | return 0; | ||
1370 | if (old_mtu == new_mtu) | ||
1371 | return 0; | ||
1372 | |||
1373 | /* synchronized against open : rtnl_lock() held by caller */ | ||
1374 | if (netif_running(dev)) { | ||
1375 | u8 *base = get_hwbase(dev); | ||
1376 | /* | ||
1377 | * It seems that the nic preloads valid ring entries into an | ||
1378 | * internal buffer. The procedure for flushing everything is | ||
1379 | * guessed, there is probably a simpler approach. | ||
1380 | * Changing the MTU is a rare event, it shouldn't matter. | ||
1381 | */ | ||
1382 | disable_irq(dev->irq); | ||
1383 | spin_lock_bh(&dev->xmit_lock); | ||
1384 | spin_lock(&np->lock); | ||
1385 | /* stop engines */ | ||
1386 | nv_stop_rx(dev); | ||
1387 | nv_stop_tx(dev); | ||
1388 | nv_txrx_reset(dev); | ||
1389 | /* drain rx queue */ | ||
1390 | nv_drain_rx(dev); | ||
1391 | nv_drain_tx(dev); | ||
1392 | /* reinit driver view of the rx queue */ | ||
1393 | nv_init_rx(dev); | ||
1394 | nv_init_tx(dev); | ||
1395 | /* alloc new rx buffers */ | ||
1396 | set_bufsize(dev); | ||
1397 | if (nv_alloc_rx(dev)) { | ||
1398 | if (!np->in_shutdown) | ||
1399 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | ||
1400 | } | ||
1401 | /* reinit nic view of the rx queue */ | ||
1402 | writel(np->rx_buf_sz, base + NvRegOffloadConfig); | ||
1403 | writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); | ||
1404 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) | ||
1405 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | ||
1406 | else | ||
1407 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); | ||
1408 | writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), | ||
1409 | base + NvRegRingSizes); | ||
1410 | pci_push(base); | ||
1411 | writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl); | ||
1412 | pci_push(base); | ||
1413 | |||
1414 | /* restart rx engine */ | ||
1415 | nv_start_rx(dev); | ||
1416 | nv_start_tx(dev); | ||
1417 | spin_unlock(&np->lock); | ||
1418 | spin_unlock_bh(&dev->xmit_lock); | ||
1419 | enable_irq(dev->irq); | ||
1420 | } | ||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | static void nv_copy_mac_to_hw(struct net_device *dev) | ||
1425 | { | ||
1426 | u8 *base = get_hwbase(dev); | ||
1427 | u32 mac[2]; | ||
1428 | |||
1429 | mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + | ||
1430 | (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); | ||
1431 | mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); | ||
1432 | |||
1433 | writel(mac[0], base + NvRegMacAddrA); | ||
1434 | writel(mac[1], base + NvRegMacAddrB); | ||
1435 | } | ||
1436 | |||
1437 | /* | ||
1438 | * nv_set_mac_address: dev->set_mac_address function | ||
1439 | * Called with rtnl_lock() held. | ||
1440 | */ | ||
1441 | static int nv_set_mac_address(struct net_device *dev, void *addr) | ||
1442 | { | ||
1443 | struct fe_priv *np = get_nvpriv(dev); | ||
1444 | struct sockaddr *macaddr = (struct sockaddr*)addr; | ||
1445 | |||
1446 | if(!is_valid_ether_addr(macaddr->sa_data)) | ||
1447 | return -EADDRNOTAVAIL; | ||
1448 | |||
1449 | /* synchronized against open : rtnl_lock() held by caller */ | ||
1450 | memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN); | ||
1451 | |||
1452 | if (netif_running(dev)) { | ||
1453 | spin_lock_bh(&dev->xmit_lock); | ||
1454 | spin_lock_irq(&np->lock); | ||
1455 | |||
1456 | /* stop rx engine */ | ||
1457 | nv_stop_rx(dev); | ||
1458 | |||
1459 | /* set mac address */ | ||
1460 | nv_copy_mac_to_hw(dev); | ||
1461 | |||
1462 | /* restart rx engine */ | ||
1463 | nv_start_rx(dev); | ||
1464 | spin_unlock_irq(&np->lock); | ||
1465 | spin_unlock_bh(&dev->xmit_lock); | ||
1466 | } else { | ||
1467 | nv_copy_mac_to_hw(dev); | ||
1468 | } | ||
1219 | return 0; | 1469 | return 0; |
1220 | } | 1470 | } |
1221 | 1471 | ||
@@ -1470,7 +1720,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) | |||
1470 | if (!(events & np->irqmask)) | 1720 | if (!(events & np->irqmask)) |
1471 | break; | 1721 | break; |
1472 | 1722 | ||
1473 | if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX2|NVREG_IRQ_TX_ERR)) { | 1723 | if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) { |
1474 | spin_lock(&np->lock); | 1724 | spin_lock(&np->lock); |
1475 | nv_tx_done(dev); | 1725 | nv_tx_done(dev); |
1476 | spin_unlock(&np->lock); | 1726 | spin_unlock(&np->lock); |
@@ -1761,6 +2011,50 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
1761 | return 0; | 2011 | return 0; |
1762 | } | 2012 | } |
1763 | 2013 | ||
2014 | #define FORCEDETH_REGS_VER 1 | ||
2015 | #define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */ | ||
2016 | |||
2017 | static int nv_get_regs_len(struct net_device *dev) | ||
2018 | { | ||
2019 | return FORCEDETH_REGS_SIZE; | ||
2020 | } | ||
2021 | |||
2022 | static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) | ||
2023 | { | ||
2024 | struct fe_priv *np = get_nvpriv(dev); | ||
2025 | u8 __iomem *base = get_hwbase(dev); | ||
2026 | u32 *rbuf = buf; | ||
2027 | int i; | ||
2028 | |||
2029 | regs->version = FORCEDETH_REGS_VER; | ||
2030 | spin_lock_irq(&np->lock); | ||
2031 | for (i=0;i<FORCEDETH_REGS_SIZE/sizeof(u32);i++) | ||
2032 | rbuf[i] = readl(base + i*sizeof(u32)); | ||
2033 | spin_unlock_irq(&np->lock); | ||
2034 | } | ||
2035 | |||
2036 | static int nv_nway_reset(struct net_device *dev) | ||
2037 | { | ||
2038 | struct fe_priv *np = get_nvpriv(dev); | ||
2039 | int ret; | ||
2040 | |||
2041 | spin_lock_irq(&np->lock); | ||
2042 | if (np->autoneg) { | ||
2043 | int bmcr; | ||
2044 | |||
2045 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | ||
2046 | bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
2047 | mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); | ||
2048 | |||
2049 | ret = 0; | ||
2050 | } else { | ||
2051 | ret = -EINVAL; | ||
2052 | } | ||
2053 | spin_unlock_irq(&np->lock); | ||
2054 | |||
2055 | return ret; | ||
2056 | } | ||
2057 | |||
1764 | static struct ethtool_ops ops = { | 2058 | static struct ethtool_ops ops = { |
1765 | .get_drvinfo = nv_get_drvinfo, | 2059 | .get_drvinfo = nv_get_drvinfo, |
1766 | .get_link = ethtool_op_get_link, | 2060 | .get_link = ethtool_op_get_link, |
@@ -1768,6 +2062,9 @@ static struct ethtool_ops ops = { | |||
1768 | .set_wol = nv_set_wol, | 2062 | .set_wol = nv_set_wol, |
1769 | .get_settings = nv_get_settings, | 2063 | .get_settings = nv_get_settings, |
1770 | .set_settings = nv_set_settings, | 2064 | .set_settings = nv_set_settings, |
2065 | .get_regs_len = nv_get_regs_len, | ||
2066 | .get_regs = nv_get_regs, | ||
2067 | .nway_reset = nv_nway_reset, | ||
1771 | }; | 2068 | }; |
1772 | 2069 | ||
1773 | static int nv_open(struct net_device *dev) | 2070 | static int nv_open(struct net_device *dev) |
@@ -1792,6 +2089,7 @@ static int nv_open(struct net_device *dev) | |||
1792 | writel(0, base + NvRegAdapterControl); | 2089 | writel(0, base + NvRegAdapterControl); |
1793 | 2090 | ||
1794 | /* 2) initialize descriptor rings */ | 2091 | /* 2) initialize descriptor rings */ |
2092 | set_bufsize(dev); | ||
1795 | oom = nv_init_ring(dev); | 2093 | oom = nv_init_ring(dev); |
1796 | 2094 | ||
1797 | writel(0, base + NvRegLinkSpeed); | 2095 | writel(0, base + NvRegLinkSpeed); |
@@ -1802,20 +2100,14 @@ static int nv_open(struct net_device *dev) | |||
1802 | np->in_shutdown = 0; | 2100 | np->in_shutdown = 0; |
1803 | 2101 | ||
1804 | /* 3) set mac address */ | 2102 | /* 3) set mac address */ |
1805 | { | 2103 | nv_copy_mac_to_hw(dev); |
1806 | u32 mac[2]; | ||
1807 | |||
1808 | mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + | ||
1809 | (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); | ||
1810 | mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); | ||
1811 | |||
1812 | writel(mac[0], base + NvRegMacAddrA); | ||
1813 | writel(mac[1], base + NvRegMacAddrB); | ||
1814 | } | ||
1815 | 2104 | ||
1816 | /* 4) give hw rings */ | 2105 | /* 4) give hw rings */ |
1817 | writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); | 2106 | writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); |
1818 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | 2107 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
2108 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | ||
2109 | else | ||
2110 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); | ||
1819 | writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), | 2111 | writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), |
1820 | base + NvRegRingSizes); | 2112 | base + NvRegRingSizes); |
1821 | 2113 | ||
@@ -1837,7 +2129,7 @@ static int nv_open(struct net_device *dev) | |||
1837 | writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); | 2129 | writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); |
1838 | writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); | 2130 | writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); |
1839 | writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); | 2131 | writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); |
1840 | writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); | 2132 | writel(np->rx_buf_sz, base + NvRegOffloadConfig); |
1841 | 2133 | ||
1842 | writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus); | 2134 | writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus); |
1843 | get_random_bytes(&i, sizeof(i)); | 2135 | get_random_bytes(&i, sizeof(i)); |
@@ -1888,6 +2180,9 @@ static int nv_open(struct net_device *dev) | |||
1888 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); | 2180 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
1889 | dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); | 2181 | dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); |
1890 | } | 2182 | } |
2183 | /* set linkspeed to invalid value, thus force nv_update_linkspeed | ||
2184 | * to init hw */ | ||
2185 | np->linkspeed = 0; | ||
1891 | ret = nv_update_linkspeed(dev); | 2186 | ret = nv_update_linkspeed(dev); |
1892 | nv_start_rx(dev); | 2187 | nv_start_rx(dev); |
1893 | nv_start_tx(dev); | 2188 | nv_start_tx(dev); |
@@ -1942,6 +2237,12 @@ static int nv_close(struct net_device *dev) | |||
1942 | if (np->wolenabled) | 2237 | if (np->wolenabled) |
1943 | nv_start_rx(dev); | 2238 | nv_start_rx(dev); |
1944 | 2239 | ||
2240 | /* special op: write back the misordered MAC address - otherwise | ||
2241 | * the next nv_probe would see a wrong address. | ||
2242 | */ | ||
2243 | writel(np->orig_mac[0], base + NvRegMacAddrA); | ||
2244 | writel(np->orig_mac[1], base + NvRegMacAddrB); | ||
2245 | |||
1945 | /* FIXME: power down nic */ | 2246 | /* FIXME: power down nic */ |
1946 | 2247 | ||
1947 | return 0; | 2248 | return 0; |
@@ -2006,32 +2307,55 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2006 | } | 2307 | } |
2007 | 2308 | ||
2008 | /* handle different descriptor versions */ | 2309 | /* handle different descriptor versions */ |
2009 | if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || | 2310 | if (id->driver_data & DEV_HAS_HIGH_DMA) { |
2010 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || | 2311 | /* packet format 3: supports 40-bit addressing */ |
2011 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3 || | 2312 | np->desc_ver = DESC_VER_3; |
2012 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || | 2313 | if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) { |
2013 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) | 2314 | printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", |
2014 | np->desc_ver = DESC_VER_1; | 2315 | pci_name(pci_dev)); |
2015 | else | 2316 | } |
2317 | } else if (id->driver_data & DEV_HAS_LARGEDESC) { | ||
2318 | /* packet format 2: supports jumbo frames */ | ||
2016 | np->desc_ver = DESC_VER_2; | 2319 | np->desc_ver = DESC_VER_2; |
2320 | } else { | ||
2321 | /* original packet format */ | ||
2322 | np->desc_ver = DESC_VER_1; | ||
2323 | } | ||
2324 | |||
2325 | np->pkt_limit = NV_PKTLIMIT_1; | ||
2326 | if (id->driver_data & DEV_HAS_LARGEDESC) | ||
2327 | np->pkt_limit = NV_PKTLIMIT_2; | ||
2017 | 2328 | ||
2018 | err = -ENOMEM; | 2329 | err = -ENOMEM; |
2019 | np->base = ioremap(addr, NV_PCI_REGSZ); | 2330 | np->base = ioremap(addr, NV_PCI_REGSZ); |
2020 | if (!np->base) | 2331 | if (!np->base) |
2021 | goto out_relreg; | 2332 | goto out_relreg; |
2022 | dev->base_addr = (unsigned long)np->base; | 2333 | dev->base_addr = (unsigned long)np->base; |
2334 | |||
2023 | dev->irq = pci_dev->irq; | 2335 | dev->irq = pci_dev->irq; |
2024 | np->rx_ring = pci_alloc_consistent(pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), | 2336 | |
2025 | &np->ring_addr); | 2337 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
2026 | if (!np->rx_ring) | 2338 | np->rx_ring.orig = pci_alloc_consistent(pci_dev, |
2027 | goto out_unmap; | 2339 | sizeof(struct ring_desc) * (RX_RING + TX_RING), |
2028 | np->tx_ring = &np->rx_ring[RX_RING]; | 2340 | &np->ring_addr); |
2341 | if (!np->rx_ring.orig) | ||
2342 | goto out_unmap; | ||
2343 | np->tx_ring.orig = &np->rx_ring.orig[RX_RING]; | ||
2344 | } else { | ||
2345 | np->rx_ring.ex = pci_alloc_consistent(pci_dev, | ||
2346 | sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), | ||
2347 | &np->ring_addr); | ||
2348 | if (!np->rx_ring.ex) | ||
2349 | goto out_unmap; | ||
2350 | np->tx_ring.ex = &np->rx_ring.ex[RX_RING]; | ||
2351 | } | ||
2029 | 2352 | ||
2030 | dev->open = nv_open; | 2353 | dev->open = nv_open; |
2031 | dev->stop = nv_close; | 2354 | dev->stop = nv_close; |
2032 | dev->hard_start_xmit = nv_start_xmit; | 2355 | dev->hard_start_xmit = nv_start_xmit; |
2033 | dev->get_stats = nv_get_stats; | 2356 | dev->get_stats = nv_get_stats; |
2034 | dev->change_mtu = nv_change_mtu; | 2357 | dev->change_mtu = nv_change_mtu; |
2358 | dev->set_mac_address = nv_set_mac_address; | ||
2035 | dev->set_multicast_list = nv_set_multicast; | 2359 | dev->set_multicast_list = nv_set_multicast; |
2036 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2360 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2037 | dev->poll_controller = nv_poll_controller; | 2361 | dev->poll_controller = nv_poll_controller; |
@@ -2080,17 +2404,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2080 | 2404 | ||
2081 | if (np->desc_ver == DESC_VER_1) { | 2405 | if (np->desc_ver == DESC_VER_1) { |
2082 | np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; | 2406 | np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; |
2083 | if (id->driver_data & DEV_NEED_LASTPACKET1) | ||
2084 | np->tx_flags |= NV_TX_LASTPACKET1; | ||
2085 | } else { | 2407 | } else { |
2086 | np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; | 2408 | np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; |
2087 | if (id->driver_data & DEV_NEED_LASTPACKET1) | ||
2088 | np->tx_flags |= NV_TX2_LASTPACKET1; | ||
2089 | } | 2409 | } |
2090 | if (id->driver_data & DEV_IRQMASK_1) | 2410 | np->irqmask = NVREG_IRQMASK_WANTED; |
2091 | np->irqmask = NVREG_IRQMASK_WANTED_1; | ||
2092 | if (id->driver_data & DEV_IRQMASK_2) | ||
2093 | np->irqmask = NVREG_IRQMASK_WANTED_2; | ||
2094 | if (id->driver_data & DEV_NEED_TIMERIRQ) | 2411 | if (id->driver_data & DEV_NEED_TIMERIRQ) |
2095 | np->irqmask |= NVREG_IRQ_TIMER; | 2412 | np->irqmask |= NVREG_IRQ_TIMER; |
2096 | if (id->driver_data & DEV_NEED_LINKTIMER) { | 2413 | if (id->driver_data & DEV_NEED_LINKTIMER) { |
@@ -2155,8 +2472,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2155 | return 0; | 2472 | return 0; |
2156 | 2473 | ||
2157 | out_freering: | 2474 | out_freering: |
2158 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), | 2475 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
2159 | np->rx_ring, np->ring_addr); | 2476 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), |
2477 | np->rx_ring.orig, np->ring_addr); | ||
2478 | else | ||
2479 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), | ||
2480 | np->rx_ring.ex, np->ring_addr); | ||
2160 | pci_set_drvdata(pci_dev, NULL); | 2481 | pci_set_drvdata(pci_dev, NULL); |
2161 | out_unmap: | 2482 | out_unmap: |
2162 | iounmap(get_hwbase(dev)); | 2483 | iounmap(get_hwbase(dev)); |
@@ -2174,18 +2495,14 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) | |||
2174 | { | 2495 | { |
2175 | struct net_device *dev = pci_get_drvdata(pci_dev); | 2496 | struct net_device *dev = pci_get_drvdata(pci_dev); |
2176 | struct fe_priv *np = get_nvpriv(dev); | 2497 | struct fe_priv *np = get_nvpriv(dev); |
2177 | u8 __iomem *base = get_hwbase(dev); | ||
2178 | 2498 | ||
2179 | unregister_netdev(dev); | 2499 | unregister_netdev(dev); |
2180 | 2500 | ||
2181 | /* special op: write back the misordered MAC address - otherwise | ||
2182 | * the next nv_probe would see a wrong address. | ||
2183 | */ | ||
2184 | writel(np->orig_mac[0], base + NvRegMacAddrA); | ||
2185 | writel(np->orig_mac[1], base + NvRegMacAddrB); | ||
2186 | |||
2187 | /* free all structures */ | 2501 | /* free all structures */ |
2188 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), np->rx_ring, np->ring_addr); | 2502 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
2503 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), np->rx_ring.orig, np->ring_addr); | ||
2504 | else | ||
2505 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), np->rx_ring.ex, np->ring_addr); | ||
2189 | iounmap(get_hwbase(dev)); | 2506 | iounmap(get_hwbase(dev)); |
2190 | pci_release_regions(pci_dev); | 2507 | pci_release_regions(pci_dev); |
2191 | pci_disable_device(pci_dev); | 2508 | pci_disable_device(pci_dev); |
@@ -2195,109 +2512,64 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) | |||
2195 | 2512 | ||
2196 | static struct pci_device_id pci_tbl[] = { | 2513 | static struct pci_device_id pci_tbl[] = { |
2197 | { /* nForce Ethernet Controller */ | 2514 | { /* nForce Ethernet Controller */ |
2198 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2515 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1), |
2199 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_1, | 2516 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
2200 | .subvendor = PCI_ANY_ID, | ||
2201 | .subdevice = PCI_ANY_ID, | ||
2202 | .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2203 | }, | 2517 | }, |
2204 | { /* nForce2 Ethernet Controller */ | 2518 | { /* nForce2 Ethernet Controller */ |
2205 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2519 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2), |
2206 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_2, | 2520 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
2207 | .subvendor = PCI_ANY_ID, | ||
2208 | .subdevice = PCI_ANY_ID, | ||
2209 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2210 | }, | 2521 | }, |
2211 | { /* nForce3 Ethernet Controller */ | 2522 | { /* nForce3 Ethernet Controller */ |
2212 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2523 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3), |
2213 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_3, | 2524 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
2214 | .subvendor = PCI_ANY_ID, | ||
2215 | .subdevice = PCI_ANY_ID, | ||
2216 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2217 | }, | 2525 | }, |
2218 | { /* nForce3 Ethernet Controller */ | 2526 | { /* nForce3 Ethernet Controller */ |
2219 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2527 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4), |
2220 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_4, | 2528 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2221 | .subvendor = PCI_ANY_ID, | ||
2222 | .subdevice = PCI_ANY_ID, | ||
2223 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2224 | }, | 2529 | }, |
2225 | { /* nForce3 Ethernet Controller */ | 2530 | { /* nForce3 Ethernet Controller */ |
2226 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2531 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5), |
2227 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_5, | 2532 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2228 | .subvendor = PCI_ANY_ID, | ||
2229 | .subdevice = PCI_ANY_ID, | ||
2230 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2231 | }, | 2533 | }, |
2232 | { /* nForce3 Ethernet Controller */ | 2534 | { /* nForce3 Ethernet Controller */ |
2233 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2535 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6), |
2234 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_6, | 2536 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2235 | .subvendor = PCI_ANY_ID, | ||
2236 | .subdevice = PCI_ANY_ID, | ||
2237 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2238 | }, | 2537 | }, |
2239 | { /* nForce3 Ethernet Controller */ | 2538 | { /* nForce3 Ethernet Controller */ |
2240 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2539 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7), |
2241 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_7, | 2540 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2242 | .subvendor = PCI_ANY_ID, | ||
2243 | .subdevice = PCI_ANY_ID, | ||
2244 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2245 | }, | 2541 | }, |
2246 | { /* CK804 Ethernet Controller */ | 2542 | { /* CK804 Ethernet Controller */ |
2247 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2543 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), |
2248 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_8, | 2544 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2249 | .subvendor = PCI_ANY_ID, | ||
2250 | .subdevice = PCI_ANY_ID, | ||
2251 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2252 | }, | 2545 | }, |
2253 | { /* CK804 Ethernet Controller */ | 2546 | { /* CK804 Ethernet Controller */ |
2254 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2547 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), |
2255 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_9, | 2548 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2256 | .subvendor = PCI_ANY_ID, | ||
2257 | .subdevice = PCI_ANY_ID, | ||
2258 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2259 | }, | 2549 | }, |
2260 | { /* MCP04 Ethernet Controller */ | 2550 | { /* MCP04 Ethernet Controller */ |
2261 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2551 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), |
2262 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_10, | 2552 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2263 | .subvendor = PCI_ANY_ID, | ||
2264 | .subdevice = PCI_ANY_ID, | ||
2265 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2266 | }, | 2553 | }, |
2267 | { /* MCP04 Ethernet Controller */ | 2554 | { /* MCP04 Ethernet Controller */ |
2268 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2555 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), |
2269 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_11, | 2556 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2270 | .subvendor = PCI_ANY_ID, | ||
2271 | .subdevice = PCI_ANY_ID, | ||
2272 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2273 | }, | 2557 | }, |
2274 | { /* MCP51 Ethernet Controller */ | 2558 | { /* MCP51 Ethernet Controller */ |
2275 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2559 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), |
2276 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_12, | 2560 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, |
2277 | .subvendor = PCI_ANY_ID, | ||
2278 | .subdevice = PCI_ANY_ID, | ||
2279 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2280 | }, | 2561 | }, |
2281 | { /* MCP51 Ethernet Controller */ | 2562 | { /* MCP51 Ethernet Controller */ |
2282 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2563 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), |
2283 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_13, | 2564 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, |
2284 | .subvendor = PCI_ANY_ID, | ||
2285 | .subdevice = PCI_ANY_ID, | ||
2286 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2287 | }, | 2565 | }, |
2288 | { /* MCP55 Ethernet Controller */ | 2566 | { /* MCP55 Ethernet Controller */ |
2289 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2567 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), |
2290 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_14, | 2568 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2291 | .subvendor = PCI_ANY_ID, | ||
2292 | .subdevice = PCI_ANY_ID, | ||
2293 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2294 | }, | 2569 | }, |
2295 | { /* MCP55 Ethernet Controller */ | 2570 | { /* MCP55 Ethernet Controller */ |
2296 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2571 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), |
2297 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_15, | 2572 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2298 | .subvendor = PCI_ANY_ID, | ||
2299 | .subdevice = PCI_ANY_ID, | ||
2300 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2301 | }, | 2573 | }, |
2302 | {0,}, | 2574 | {0,}, |
2303 | }; | 2575 | }; |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index f9e3be96963c..0b230222bfea 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -308,12 +308,6 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) | |||
308 | { | 308 | { |
309 | struct sockaddr_ax25 *sa = addr; | 309 | struct sockaddr_ax25 *sa = addr; |
310 | 310 | ||
311 | if (sa->sax25_family != AF_AX25) | ||
312 | return -EINVAL; | ||
313 | |||
314 | if (!sa->sax25_ndigis) | ||
315 | return -EINVAL; | ||
316 | |||
317 | spin_lock_irq(&dev->xmit_lock); | 311 | spin_lock_irq(&dev->xmit_lock); |
318 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); | 312 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); |
319 | spin_unlock_irq(&dev->xmit_lock); | 313 | spin_unlock_irq(&dev->xmit_lock); |
@@ -668,6 +662,9 @@ static int sixpack_open(struct tty_struct *tty) | |||
668 | netif_start_queue(dev); | 662 | netif_start_queue(dev); |
669 | 663 | ||
670 | init_timer(&sp->tx_t); | 664 | init_timer(&sp->tx_t); |
665 | sp->tx_t.function = sp_xmit_on_air; | ||
666 | sp->tx_t.data = (unsigned long) sp; | ||
667 | |||
671 | init_timer(&sp->resync_t); | 668 | init_timer(&sp->resync_t); |
672 | 669 | ||
673 | spin_unlock_bh(&sp->lock); | 670 | spin_unlock_bh(&sp->lock); |
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 0cd54306e636..de087cd609d9 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MKISS | 1 | config MKISS |
2 | tristate "Serial port KISS driver" | 2 | tristate "Serial port KISS driver" |
3 | depends on AX25 && BROKEN_ON_SMP | 3 | depends on AX25 |
4 | ---help--- | 4 | ---help--- |
5 | KISS is a protocol used for the exchange of data between a computer | 5 | KISS is a protocol used for the exchange of data between a computer |
6 | and a Terminal Node Controller (a small embedded system commonly | 6 | and a Terminal Node Controller (a small embedded system commonly |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index a7f15d9f13e5..5298096afbdb 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/kmod.h> | 54 | #include <linux/kmod.h> |
55 | #include <linux/hdlcdrv.h> | 55 | #include <linux/hdlcdrv.h> |
56 | #include <linux/baycom.h> | 56 | #include <linux/baycom.h> |
57 | #include <linux/jiffies.h> | ||
57 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | 58 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) |
58 | /* prototypes for ax25_encapsulate and ax25_rebuild_header */ | 59 | /* prototypes for ax25_encapsulate and ax25_rebuild_header */ |
59 | #include <net/ax25.h> | 60 | #include <net/ax25.h> |
@@ -287,7 +288,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) | |||
287 | * measure the interrupt frequency | 288 | * measure the interrupt frequency |
288 | */ | 289 | */ |
289 | bc->debug_vals.cur_intcnt++; | 290 | bc->debug_vals.cur_intcnt++; |
290 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 291 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
291 | bc->debug_vals.last_jiffies = cur_jiffies; | 292 | bc->debug_vals.last_jiffies = cur_jiffies; |
292 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 293 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
293 | bc->debug_vals.cur_intcnt = 0; | 294 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 612ad452bee0..3b1bef1ee215 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c | |||
@@ -84,6 +84,7 @@ | |||
84 | #include <linux/baycom.h> | 84 | #include <linux/baycom.h> |
85 | #include <linux/parport.h> | 85 | #include <linux/parport.h> |
86 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
87 | #include <linux/jiffies.h> | ||
87 | 88 | ||
88 | #include <asm/bug.h> | 89 | #include <asm/bug.h> |
89 | #include <asm/system.h> | 90 | #include <asm/system.h> |
@@ -165,7 +166,7 @@ static void __inline__ baycom_int_freq(struct baycom_state *bc) | |||
165 | * measure the interrupt frequency | 166 | * measure the interrupt frequency |
166 | */ | 167 | */ |
167 | bc->debug_vals.cur_intcnt++; | 168 | bc->debug_vals.cur_intcnt++; |
168 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 169 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
169 | bc->debug_vals.last_jiffies = cur_jiffies; | 170 | bc->debug_vals.last_jiffies = cur_jiffies; |
170 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 171 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
171 | bc->debug_vals.cur_intcnt = 0; | 172 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 25f270b05378..232793d2ce6b 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c | |||
@@ -79,6 +79,7 @@ | |||
79 | #include <asm/io.h> | 79 | #include <asm/io.h> |
80 | #include <linux/hdlcdrv.h> | 80 | #include <linux/hdlcdrv.h> |
81 | #include <linux/baycom.h> | 81 | #include <linux/baycom.h> |
82 | #include <linux/jiffies.h> | ||
82 | 83 | ||
83 | /* --------------------------------------------------------------------- */ | 84 | /* --------------------------------------------------------------------- */ |
84 | 85 | ||
@@ -159,7 +160,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) | |||
159 | * measure the interrupt frequency | 160 | * measure the interrupt frequency |
160 | */ | 161 | */ |
161 | bc->debug_vals.cur_intcnt++; | 162 | bc->debug_vals.cur_intcnt++; |
162 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 163 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
163 | bc->debug_vals.last_jiffies = cur_jiffies; | 164 | bc->debug_vals.last_jiffies = cur_jiffies; |
164 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 165 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
165 | bc->debug_vals.cur_intcnt = 0; | 166 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index eead85d00962..be596a3eb3fd 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include <asm/io.h> | 69 | #include <asm/io.h> |
70 | #include <linux/hdlcdrv.h> | 70 | #include <linux/hdlcdrv.h> |
71 | #include <linux/baycom.h> | 71 | #include <linux/baycom.h> |
72 | #include <linux/jiffies.h> | ||
72 | 73 | ||
73 | /* --------------------------------------------------------------------- */ | 74 | /* --------------------------------------------------------------------- */ |
74 | 75 | ||
@@ -150,7 +151,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) | |||
150 | * measure the interrupt frequency | 151 | * measure the interrupt frequency |
151 | */ | 152 | */ |
152 | bc->debug_vals.cur_intcnt++; | 153 | bc->debug_vals.cur_intcnt++; |
153 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 154 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
154 | bc->debug_vals.last_jiffies = cur_jiffies; | 155 | bc->debug_vals.last_jiffies = cur_jiffies; |
155 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 156 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
156 | bc->debug_vals.cur_intcnt = 0; | 157 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index ba9f0580e1f9..2946e037a9b1 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c | |||
@@ -98,7 +98,7 @@ static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; | |||
98 | 98 | ||
99 | static char bpq_eth_addr[6]; | 99 | static char bpq_eth_addr[6]; |
100 | 100 | ||
101 | static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *); | 101 | static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *); |
102 | static int bpq_device_event(struct notifier_block *, unsigned long, void *); | 102 | static int bpq_device_event(struct notifier_block *, unsigned long, void *); |
103 | static const char *bpq_print_ethaddr(const unsigned char *); | 103 | static const char *bpq_print_ethaddr(const unsigned char *); |
104 | 104 | ||
@@ -165,7 +165,7 @@ static inline int dev_is_ethdev(struct net_device *dev) | |||
165 | /* | 165 | /* |
166 | * Receive an AX.25 frame via an ethernet interface. | 166 | * Receive an AX.25 frame via an ethernet interface. |
167 | */ | 167 | */ |
168 | static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) | 168 | static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev) |
169 | { | 169 | { |
170 | int len; | 170 | int len; |
171 | char * ptr; | 171 | char * ptr; |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 3035422f5ad8..63b1a2b86acb 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -1,30 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * MKISS Driver | 2 | * This program is free software; you can distribute it and/or modify it |
3 | * under the terms of the GNU General Public License (Version 2) as | ||
4 | * published by the Free Software Foundation. | ||
3 | * | 5 | * |
4 | * This module: | 6 | * This program is distributed in the hope it will be useful, but WITHOUT |
5 | * This module is free software; you can redistribute it and/or | 7 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
6 | * modify it under the terms of the GNU General Public License | 8 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
7 | * as published by the Free Software Foundation; either version | 9 | * for more details. |
8 | * 2 of the License, or (at your option) any later version. | ||
9 | * | 10 | * |
10 | * This module implements the AX.25 protocol for kernel-based | 11 | * You should have received a copy of the GNU General Public License along |
11 | * devices like TTYs. It interfaces between a raw TTY, and the | 12 | * with this program; if not, write to the Free Software Foundation, Inc., |
12 | * kernel's AX.25 protocol layers, just like slip.c. | 13 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
13 | * AX.25 needs to be separated from slip.c while slip.c is no | ||
14 | * longer a static kernel device since it is a module. | ||
15 | * This method clears the way to implement other kiss protocols | ||
16 | * like mkiss smack g8bpq ..... so far only mkiss is implemented. | ||
17 | * | 14 | * |
18 | * Hans Alblas <hans@esrac.ele.tue.nl> | 15 | * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl> |
19 | * | 16 | * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org> |
20 | * History | ||
21 | * Jonathan (G4KLX) Fixed to match Linux networking changes - 2.1.15. | ||
22 | * Matthias (DG2FEF) Added support for FlexNet CRC (on special request) | ||
23 | * Fixed bug in ax25_close(): dev_lock_wait() was | ||
24 | * called twice, causing a deadlock. | ||
25 | * Jeroen (PE1RXQ) Removed old MKISS_MAGIC stuff and calls to | ||
26 | * MOD_*_USE_COUNT | ||
27 | * Remove cli() and fix rtnl lock usage. | ||
28 | */ | 17 | */ |
29 | 18 | ||
30 | #include <linux/config.h> | 19 | #include <linux/config.h> |
@@ -46,177 +35,300 @@ | |||
46 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
47 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
48 | #include <linux/if_arp.h> | 37 | #include <linux/if_arp.h> |
38 | #include <linux/jiffies.h> | ||
49 | 39 | ||
50 | #include <net/ax25.h> | 40 | #include <net/ax25.h> |
51 | 41 | ||
52 | #include "mkiss.h" | ||
53 | |||
54 | #ifdef CONFIG_INET | 42 | #ifdef CONFIG_INET |
55 | #include <linux/ip.h> | 43 | #include <linux/ip.h> |
56 | #include <linux/tcp.h> | 44 | #include <linux/tcp.h> |
57 | #endif | 45 | #endif |
58 | 46 | ||
59 | static char banner[] __initdata = KERN_INFO "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; | 47 | #define AX_MTU 236 |
60 | 48 | ||
61 | typedef struct ax25_ctrl { | 49 | /* SLIP/KISS protocol characters. */ |
62 | struct ax_disp ctrl; /* */ | 50 | #define END 0300 /* indicates end of frame */ |
63 | struct net_device dev; /* the device */ | 51 | #define ESC 0333 /* indicates byte stuffing */ |
64 | } ax25_ctrl_t; | 52 | #define ESC_END 0334 /* ESC ESC_END means END 'data' */ |
65 | 53 | #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ | |
66 | static ax25_ctrl_t **ax25_ctrls; | 54 | |
67 | 55 | struct mkiss { | |
68 | int ax25_maxdev = AX25_MAXDEV; /* Can be overridden with insmod! */ | 56 | struct tty_struct *tty; /* ptr to TTY structure */ |
69 | 57 | struct net_device *dev; /* easy for intr handling */ | |
70 | static struct tty_ldisc ax_ldisc; | 58 | |
71 | 59 | /* These are pointers to the malloc()ed frame buffers. */ | |
72 | static int ax25_init(struct net_device *); | 60 | spinlock_t buflock;/* lock for rbuf and xbuf */ |
73 | static int kiss_esc(unsigned char *, unsigned char *, int); | 61 | unsigned char *rbuff; /* receiver buffer */ |
74 | static int kiss_esc_crc(unsigned char *, unsigned char *, unsigned short, int); | 62 | int rcount; /* received chars counter */ |
75 | static void kiss_unesc(struct ax_disp *, unsigned char); | 63 | unsigned char *xbuff; /* transmitter buffer */ |
64 | unsigned char *xhead; /* pointer to next byte to XMIT */ | ||
65 | int xleft; /* bytes left in XMIT queue */ | ||
66 | |||
67 | struct net_device_stats stats; | ||
68 | |||
69 | /* Detailed SLIP statistics. */ | ||
70 | int mtu; /* Our mtu (to spot changes!) */ | ||
71 | int buffsize; /* Max buffers sizes */ | ||
72 | |||
73 | unsigned long flags; /* Flag values/ mode etc */ | ||
74 | /* long req'd: used by set_bit --RR */ | ||
75 | #define AXF_INUSE 0 /* Channel in use */ | ||
76 | #define AXF_ESCAPE 1 /* ESC received */ | ||
77 | #define AXF_ERROR 2 /* Parity, etc. error */ | ||
78 | #define AXF_KEEPTEST 3 /* Keepalive test flag */ | ||
79 | #define AXF_OUTWAIT 4 /* is outpacket was flag */ | ||
80 | |||
81 | int mode; | ||
82 | int crcmode; /* MW: for FlexNet, SMACK etc. */ | ||
83 | #define CRC_MODE_NONE 0 | ||
84 | #define CRC_MODE_FLEX 1 | ||
85 | #define CRC_MODE_SMACK 2 | ||
86 | |||
87 | atomic_t refcnt; | ||
88 | struct semaphore dead_sem; | ||
89 | }; | ||
76 | 90 | ||
77 | /*---------------------------------------------------------------------------*/ | 91 | /*---------------------------------------------------------------------------*/ |
78 | 92 | ||
79 | static const unsigned short Crc_flex_table[] = { | 93 | static const unsigned short crc_flex_table[] = { |
80 | 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, | 94 | 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, |
81 | 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, | 95 | 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, |
82 | 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, | 96 | 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, |
83 | 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, | 97 | 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, |
84 | 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, | 98 | 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, |
85 | 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, | 99 | 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, |
86 | 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, | 100 | 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, |
87 | 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, | 101 | 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, |
88 | 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, | 102 | 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, |
89 | 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, | 103 | 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, |
90 | 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, | 104 | 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, |
91 | 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, | 105 | 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, |
92 | 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, | 106 | 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, |
93 | 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, | 107 | 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, |
94 | 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, | 108 | 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, |
95 | 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, | 109 | 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, |
96 | 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, | 110 | 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, |
97 | 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, | 111 | 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, |
98 | 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, | 112 | 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, |
99 | 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, | 113 | 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, |
100 | 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, | 114 | 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, |
101 | 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, | 115 | 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, |
102 | 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, | 116 | 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, |
103 | 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, | 117 | 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, |
104 | 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, | 118 | 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, |
105 | 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, | 119 | 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, |
106 | 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, | 120 | 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, |
107 | 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, | 121 | 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, |
108 | 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, | 122 | 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, |
109 | 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, | 123 | 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, |
110 | 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, | 124 | 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, |
111 | 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff | 125 | 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff |
112 | }; | 126 | }; |
113 | 127 | ||
114 | /*---------------------------------------------------------------------------*/ | ||
115 | |||
116 | static unsigned short calc_crc_flex(unsigned char *cp, int size) | 128 | static unsigned short calc_crc_flex(unsigned char *cp, int size) |
117 | { | 129 | { |
118 | unsigned short crc = 0xffff; | 130 | unsigned short crc = 0xffff; |
119 | |||
120 | while (size--) | ||
121 | crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; | ||
122 | 131 | ||
123 | return crc; | 132 | while (size--) |
124 | } | 133 | crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; |
125 | 134 | ||
126 | /*---------------------------------------------------------------------------*/ | 135 | return crc; |
136 | } | ||
127 | 137 | ||
128 | static int check_crc_flex(unsigned char *cp, int size) | 138 | static int check_crc_flex(unsigned char *cp, int size) |
129 | { | 139 | { |
130 | unsigned short crc = 0xffff; | 140 | unsigned short crc = 0xffff; |
131 | 141 | ||
132 | if (size < 3) | 142 | if (size < 3) |
133 | return -1; | 143 | return -1; |
134 | 144 | ||
135 | while (size--) | 145 | while (size--) |
136 | crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; | 146 | crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; |
137 | 147 | ||
138 | if ((crc & 0xffff) != 0x7070) | 148 | if ((crc & 0xffff) != 0x7070) |
139 | return -1; | 149 | return -1; |
140 | 150 | ||
141 | return 0; | 151 | return 0; |
142 | } | 152 | } |
143 | 153 | ||
144 | /*---------------------------------------------------------------------------*/ | 154 | /* |
155 | * Standard encapsulation | ||
156 | */ | ||
145 | 157 | ||
146 | /* Find a free channel, and link in this `tty' line. */ | 158 | static int kiss_esc(unsigned char *s, unsigned char *d, int len) |
147 | static inline struct ax_disp *ax_alloc(void) | ||
148 | { | 159 | { |
149 | ax25_ctrl_t *axp=NULL; | 160 | unsigned char *ptr = d; |
150 | int i; | 161 | unsigned char c; |
151 | 162 | ||
152 | for (i = 0; i < ax25_maxdev; i++) { | 163 | /* |
153 | axp = ax25_ctrls[i]; | 164 | * Send an initial END character to flush out any data that may have |
165 | * accumulated in the receiver due to line noise. | ||
166 | */ | ||
154 | 167 | ||
155 | /* Not allocated ? */ | 168 | *ptr++ = END; |
156 | if (axp == NULL) | ||
157 | break; | ||
158 | 169 | ||
159 | /* Not in use ? */ | 170 | while (len-- > 0) { |
160 | if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags)) | 171 | switch (c = *s++) { |
172 | case END: | ||
173 | *ptr++ = ESC; | ||
174 | *ptr++ = ESC_END; | ||
161 | break; | 175 | break; |
176 | case ESC: | ||
177 | *ptr++ = ESC; | ||
178 | *ptr++ = ESC_ESC; | ||
179 | break; | ||
180 | default: | ||
181 | *ptr++ = c; | ||
182 | break; | ||
183 | } | ||
162 | } | 184 | } |
163 | 185 | ||
164 | /* Sorry, too many, all slots in use */ | 186 | *ptr++ = END; |
165 | if (i >= ax25_maxdev) | 187 | |
166 | return NULL; | 188 | return ptr - d; |
189 | } | ||
190 | |||
191 | /* | ||
192 | * MW: | ||
193 | * OK its ugly, but tell me a better solution without copying the | ||
194 | * packet to a temporary buffer :-) | ||
195 | */ | ||
196 | static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, | ||
197 | int len) | ||
198 | { | ||
199 | unsigned char *ptr = d; | ||
200 | unsigned char c=0; | ||
201 | |||
202 | *ptr++ = END; | ||
203 | while (len > 0) { | ||
204 | if (len > 2) | ||
205 | c = *s++; | ||
206 | else if (len > 1) | ||
207 | c = crc >> 8; | ||
208 | else if (len > 0) | ||
209 | c = crc & 0xff; | ||
210 | |||
211 | len--; | ||
167 | 212 | ||
168 | /* If no channels are available, allocate one */ | 213 | switch (c) { |
169 | if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) { | 214 | case END: |
170 | axp = ax25_ctrls[i]; | 215 | *ptr++ = ESC; |
216 | *ptr++ = ESC_END; | ||
217 | break; | ||
218 | case ESC: | ||
219 | *ptr++ = ESC; | ||
220 | *ptr++ = ESC_ESC; | ||
221 | break; | ||
222 | default: | ||
223 | *ptr++ = c; | ||
224 | break; | ||
225 | } | ||
171 | } | 226 | } |
172 | memset(axp, 0, sizeof(ax25_ctrl_t)); | 227 | *ptr++ = END; |
173 | 228 | ||
174 | /* Initialize channel control data */ | 229 | return ptr - d; |
175 | set_bit(AXF_INUSE, &axp->ctrl.flags); | 230 | } |
176 | sprintf(axp->dev.name, "ax%d", i++); | 231 | |
177 | axp->ctrl.tty = NULL; | 232 | /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ |
178 | axp->dev.base_addr = i; | 233 | static void ax_bump(struct mkiss *ax) |
179 | axp->dev.priv = (void *)&axp->ctrl; | 234 | { |
180 | axp->dev.next = NULL; | 235 | struct sk_buff *skb; |
181 | axp->dev.init = ax25_init; | 236 | int count; |
182 | 237 | ||
183 | if (axp != NULL) { | 238 | spin_lock_bh(&ax->buflock); |
184 | /* | 239 | if (ax->rbuff[0] > 0x0f) { |
185 | * register device so that it can be ifconfig'ed | 240 | if (ax->rbuff[0] & 0x20) { |
186 | * ax25_init() will be called as a side-effect | 241 | ax->crcmode = CRC_MODE_FLEX; |
187 | * SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl ! | 242 | if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { |
188 | */ | 243 | ax->stats.rx_errors++; |
189 | if (register_netdev(&axp->dev) == 0) { | 244 | return; |
190 | /* (Re-)Set the INUSE bit. Very Important! */ | 245 | } |
191 | set_bit(AXF_INUSE, &axp->ctrl.flags); | 246 | ax->rcount -= 2; |
192 | axp->ctrl.dev = &axp->dev; | 247 | /* dl9sau bugfix: the trailling two bytes flexnet crc |
193 | axp->dev.priv = (void *) &axp->ctrl; | 248 | * will not be passed to the kernel. thus we have |
194 | 249 | * to correct the kissparm signature, because it | |
195 | return &axp->ctrl; | 250 | * indicates a crc but there's none |
196 | } else { | 251 | */ |
197 | clear_bit(AXF_INUSE,&axp->ctrl.flags); | 252 | *ax->rbuff &= ~0x20; |
198 | printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n"); | ||
199 | } | 253 | } |
254 | } | ||
255 | spin_unlock_bh(&ax->buflock); | ||
256 | |||
257 | count = ax->rcount; | ||
258 | |||
259 | if ((skb = dev_alloc_skb(count)) == NULL) { | ||
260 | printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", | ||
261 | ax->dev->name); | ||
262 | ax->stats.rx_dropped++; | ||
263 | return; | ||
200 | } | 264 | } |
201 | 265 | ||
202 | return NULL; | 266 | spin_lock_bh(&ax->buflock); |
267 | memcpy(skb_put(skb,count), ax->rbuff, count); | ||
268 | spin_unlock_bh(&ax->buflock); | ||
269 | skb->protocol = ax25_type_trans(skb, ax->dev); | ||
270 | netif_rx(skb); | ||
271 | ax->dev->last_rx = jiffies; | ||
272 | ax->stats.rx_packets++; | ||
273 | ax->stats.rx_bytes += count; | ||
203 | } | 274 | } |
204 | 275 | ||
205 | /* Free an AX25 channel. */ | 276 | static void kiss_unesc(struct mkiss *ax, unsigned char s) |
206 | static inline void ax_free(struct ax_disp *ax) | ||
207 | { | 277 | { |
208 | /* Free all AX25 frame buffers. */ | 278 | switch (s) { |
209 | if (ax->rbuff) | 279 | case END: |
210 | kfree(ax->rbuff); | 280 | /* drop keeptest bit = VSV */ |
211 | ax->rbuff = NULL; | 281 | if (test_bit(AXF_KEEPTEST, &ax->flags)) |
212 | if (ax->xbuff) | 282 | clear_bit(AXF_KEEPTEST, &ax->flags); |
213 | kfree(ax->xbuff); | 283 | |
214 | ax->xbuff = NULL; | 284 | if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) |
215 | if (!test_and_clear_bit(AXF_INUSE, &ax->flags)) | 285 | ax_bump(ax); |
216 | printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name); | 286 | |
287 | clear_bit(AXF_ESCAPE, &ax->flags); | ||
288 | ax->rcount = 0; | ||
289 | return; | ||
290 | |||
291 | case ESC: | ||
292 | set_bit(AXF_ESCAPE, &ax->flags); | ||
293 | return; | ||
294 | case ESC_ESC: | ||
295 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
296 | s = ESC; | ||
297 | break; | ||
298 | case ESC_END: | ||
299 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
300 | s = END; | ||
301 | break; | ||
302 | } | ||
303 | |||
304 | spin_lock_bh(&ax->buflock); | ||
305 | if (!test_bit(AXF_ERROR, &ax->flags)) { | ||
306 | if (ax->rcount < ax->buffsize) { | ||
307 | ax->rbuff[ax->rcount++] = s; | ||
308 | spin_unlock_bh(&ax->buflock); | ||
309 | return; | ||
310 | } | ||
311 | |||
312 | ax->stats.rx_over_errors++; | ||
313 | set_bit(AXF_ERROR, &ax->flags); | ||
314 | } | ||
315 | spin_unlock_bh(&ax->buflock); | ||
316 | } | ||
317 | |||
318 | static int ax_set_mac_address(struct net_device *dev, void *addr) | ||
319 | { | ||
320 | struct sockaddr_ax25 *sa = addr; | ||
321 | |||
322 | spin_lock_irq(&dev->xmit_lock); | ||
323 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); | ||
324 | spin_unlock_irq(&dev->xmit_lock); | ||
325 | |||
326 | return 0; | ||
217 | } | 327 | } |
218 | 328 | ||
219 | static void ax_changedmtu(struct ax_disp *ax) | 329 | /*---------------------------------------------------------------------------*/ |
330 | |||
331 | static void ax_changedmtu(struct mkiss *ax) | ||
220 | { | 332 | { |
221 | struct net_device *dev = ax->dev; | 333 | struct net_device *dev = ax->dev; |
222 | unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; | 334 | unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; |
@@ -236,7 +348,8 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
236 | rbuff = kmalloc(len + 4, GFP_ATOMIC); | 348 | rbuff = kmalloc(len + 4, GFP_ATOMIC); |
237 | 349 | ||
238 | if (xbuff == NULL || rbuff == NULL) { | 350 | if (xbuff == NULL || rbuff == NULL) { |
239 | printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n", | 351 | printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, " |
352 | "MTU change cancelled.\n", | ||
240 | ax->dev->name); | 353 | ax->dev->name); |
241 | dev->mtu = ax->mtu; | 354 | dev->mtu = ax->mtu; |
242 | if (xbuff != NULL) | 355 | if (xbuff != NULL) |
@@ -258,7 +371,7 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
258 | memcpy(ax->xbuff, ax->xhead, ax->xleft); | 371 | memcpy(ax->xbuff, ax->xhead, ax->xleft); |
259 | } else { | 372 | } else { |
260 | ax->xleft = 0; | 373 | ax->xleft = 0; |
261 | ax->tx_dropped++; | 374 | ax->stats.tx_dropped++; |
262 | } | 375 | } |
263 | } | 376 | } |
264 | 377 | ||
@@ -269,7 +382,7 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
269 | memcpy(ax->rbuff, orbuff, ax->rcount); | 382 | memcpy(ax->rbuff, orbuff, ax->rcount); |
270 | } else { | 383 | } else { |
271 | ax->rcount = 0; | 384 | ax->rcount = 0; |
272 | ax->rx_over_errors++; | 385 | ax->stats.rx_over_errors++; |
273 | set_bit(AXF_ERROR, &ax->flags); | 386 | set_bit(AXF_ERROR, &ax->flags); |
274 | } | 387 | } |
275 | } | 388 | } |
@@ -279,72 +392,14 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
279 | 392 | ||
280 | spin_unlock_bh(&ax->buflock); | 393 | spin_unlock_bh(&ax->buflock); |
281 | 394 | ||
282 | if (oxbuff != NULL) | 395 | kfree(oxbuff); |
283 | kfree(oxbuff); | 396 | kfree(orbuff); |
284 | if (orbuff != NULL) | ||
285 | kfree(orbuff); | ||
286 | } | ||
287 | |||
288 | |||
289 | /* Set the "sending" flag. This must be atomic. */ | ||
290 | static inline void ax_lock(struct ax_disp *ax) | ||
291 | { | ||
292 | netif_stop_queue(ax->dev); | ||
293 | } | ||
294 | |||
295 | |||
296 | /* Clear the "sending" flag. This must be atomic. */ | ||
297 | static inline void ax_unlock(struct ax_disp *ax) | ||
298 | { | ||
299 | netif_start_queue(ax->dev); | ||
300 | } | ||
301 | |||
302 | /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ | ||
303 | static void ax_bump(struct ax_disp *ax) | ||
304 | { | ||
305 | struct sk_buff *skb; | ||
306 | int count; | ||
307 | |||
308 | spin_lock_bh(&ax->buflock); | ||
309 | if (ax->rbuff[0] > 0x0f) { | ||
310 | if (ax->rbuff[0] & 0x20) { | ||
311 | ax->crcmode = CRC_MODE_FLEX; | ||
312 | if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { | ||
313 | ax->rx_errors++; | ||
314 | return; | ||
315 | } | ||
316 | ax->rcount -= 2; | ||
317 | /* dl9sau bugfix: the trailling two bytes flexnet crc | ||
318 | * will not be passed to the kernel. thus we have | ||
319 | * to correct the kissparm signature, because it | ||
320 | * indicates a crc but there's none | ||
321 | */ | ||
322 | *ax->rbuff &= ~0x20; | ||
323 | } | ||
324 | } | ||
325 | spin_unlock_bh(&ax->buflock); | ||
326 | |||
327 | count = ax->rcount; | ||
328 | |||
329 | if ((skb = dev_alloc_skb(count)) == NULL) { | ||
330 | printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); | ||
331 | ax->rx_dropped++; | ||
332 | return; | ||
333 | } | ||
334 | |||
335 | spin_lock_bh(&ax->buflock); | ||
336 | memcpy(skb_put(skb,count), ax->rbuff, count); | ||
337 | spin_unlock_bh(&ax->buflock); | ||
338 | skb->protocol = ax25_type_trans(skb, ax->dev); | ||
339 | netif_rx(skb); | ||
340 | ax->dev->last_rx = jiffies; | ||
341 | ax->rx_packets++; | ||
342 | ax->rx_bytes+=count; | ||
343 | } | 397 | } |
344 | 398 | ||
345 | /* Encapsulate one AX.25 packet and stuff into a TTY queue. */ | 399 | /* Encapsulate one AX.25 packet and stuff into a TTY queue. */ |
346 | static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | 400 | static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) |
347 | { | 401 | { |
402 | struct mkiss *ax = netdev_priv(dev); | ||
348 | unsigned char *p; | 403 | unsigned char *p; |
349 | int actual, count; | 404 | int actual, count; |
350 | 405 | ||
@@ -354,8 +409,8 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | |||
354 | if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ | 409 | if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ |
355 | len = ax->mtu; | 410 | len = ax->mtu; |
356 | printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); | 411 | printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); |
357 | ax->tx_dropped++; | 412 | ax->stats.tx_dropped++; |
358 | ax_unlock(ax); | 413 | netif_start_queue(dev); |
359 | return; | 414 | return; |
360 | } | 415 | } |
361 | 416 | ||
@@ -376,10 +431,11 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | |||
376 | break; | 431 | break; |
377 | } | 432 | } |
378 | 433 | ||
379 | ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); | 434 | set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); |
380 | actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); | 435 | actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); |
381 | ax->tx_packets++; | 436 | ax->stats.tx_packets++; |
382 | ax->tx_bytes+=actual; | 437 | ax->stats.tx_bytes += actual; |
438 | |||
383 | ax->dev->trans_start = jiffies; | 439 | ax->dev->trans_start = jiffies; |
384 | ax->xleft = count - actual; | 440 | ax->xleft = count - actual; |
385 | ax->xhead = ax->xbuff + actual; | 441 | ax->xhead = ax->xbuff + actual; |
@@ -387,37 +443,10 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | |||
387 | spin_unlock_bh(&ax->buflock); | 443 | spin_unlock_bh(&ax->buflock); |
388 | } | 444 | } |
389 | 445 | ||
390 | /* | ||
391 | * Called by the driver when there's room for more data. If we have | ||
392 | * more packets to send, we send them here. | ||
393 | */ | ||
394 | static void ax25_write_wakeup(struct tty_struct *tty) | ||
395 | { | ||
396 | int actual; | ||
397 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | ||
398 | |||
399 | /* First make sure we're connected. */ | ||
400 | if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) | ||
401 | return; | ||
402 | if (ax->xleft <= 0) { | ||
403 | /* Now serial buffer is almost free & we can start | ||
404 | * transmission of another packet | ||
405 | */ | ||
406 | tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | ||
407 | |||
408 | netif_wake_queue(ax->dev); | ||
409 | return; | ||
410 | } | ||
411 | |||
412 | actual = tty->driver->write(tty, ax->xhead, ax->xleft); | ||
413 | ax->xleft -= actual; | ||
414 | ax->xhead += actual; | ||
415 | } | ||
416 | |||
417 | /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ | 446 | /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ |
418 | static int ax_xmit(struct sk_buff *skb, struct net_device *dev) | 447 | static int ax_xmit(struct sk_buff *skb, struct net_device *dev) |
419 | { | 448 | { |
420 | struct ax_disp *ax = netdev_priv(dev); | 449 | struct mkiss *ax = netdev_priv(dev); |
421 | 450 | ||
422 | if (!netif_running(dev)) { | 451 | if (!netif_running(dev)) { |
423 | printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); | 452 | printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); |
@@ -429,7 +458,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) | |||
429 | * May be we must check transmitter timeout here ? | 458 | * May be we must check transmitter timeout here ? |
430 | * 14 Oct 1994 Dmitry Gorodchanin. | 459 | * 14 Oct 1994 Dmitry Gorodchanin. |
431 | */ | 460 | */ |
432 | if (jiffies - dev->trans_start < 20 * HZ) { | 461 | if (time_before(jiffies, dev->trans_start + 20 * HZ)) { |
433 | /* 20 sec timeout not reached */ | 462 | /* 20 sec timeout not reached */ |
434 | return 1; | 463 | return 1; |
435 | } | 464 | } |
@@ -439,20 +468,30 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) | |||
439 | "bad line quality" : "driver error"); | 468 | "bad line quality" : "driver error"); |
440 | 469 | ||
441 | ax->xleft = 0; | 470 | ax->xleft = 0; |
442 | ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | 471 | clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); |
443 | ax_unlock(ax); | 472 | netif_start_queue(dev); |
444 | } | 473 | } |
445 | 474 | ||
446 | /* We were not busy, so we are now... :-) */ | 475 | /* We were not busy, so we are now... :-) */ |
447 | if (skb != NULL) { | 476 | if (skb != NULL) { |
448 | ax_lock(ax); | 477 | netif_stop_queue(dev); |
449 | ax_encaps(ax, skb->data, skb->len); | 478 | ax_encaps(dev, skb->data, skb->len); |
450 | kfree_skb(skb); | 479 | kfree_skb(skb); |
451 | } | 480 | } |
452 | 481 | ||
453 | return 0; | 482 | return 0; |
454 | } | 483 | } |
455 | 484 | ||
485 | static int ax_open_dev(struct net_device *dev) | ||
486 | { | ||
487 | struct mkiss *ax = netdev_priv(dev); | ||
488 | |||
489 | if (ax->tty == NULL) | ||
490 | return -ENODEV; | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
456 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | 495 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) |
457 | 496 | ||
458 | /* Return the frame type ID */ | 497 | /* Return the frame type ID */ |
@@ -481,7 +520,7 @@ static int ax_rebuild_header(struct sk_buff *skb) | |||
481 | /* Open the low-level part of the AX25 channel. Easy! */ | 520 | /* Open the low-level part of the AX25 channel. Easy! */ |
482 | static int ax_open(struct net_device *dev) | 521 | static int ax_open(struct net_device *dev) |
483 | { | 522 | { |
484 | struct ax_disp *ax = netdev_priv(dev); | 523 | struct mkiss *ax = netdev_priv(dev); |
485 | unsigned long len; | 524 | unsigned long len; |
486 | 525 | ||
487 | if (ax->tty == NULL) | 526 | if (ax->tty == NULL) |
@@ -518,7 +557,6 @@ static int ax_open(struct net_device *dev) | |||
518 | 557 | ||
519 | spin_lock_init(&ax->buflock); | 558 | spin_lock_init(&ax->buflock); |
520 | 559 | ||
521 | netif_start_queue(dev); | ||
522 | return 0; | 560 | return 0; |
523 | 561 | ||
524 | noxbuff: | 562 | noxbuff: |
@@ -532,68 +570,100 @@ norbuff: | |||
532 | /* Close the low-level part of the AX25 channel. Easy! */ | 570 | /* Close the low-level part of the AX25 channel. Easy! */ |
533 | static int ax_close(struct net_device *dev) | 571 | static int ax_close(struct net_device *dev) |
534 | { | 572 | { |
535 | struct ax_disp *ax = netdev_priv(dev); | 573 | struct mkiss *ax = netdev_priv(dev); |
536 | 574 | ||
537 | if (ax->tty == NULL) | 575 | if (ax->tty) |
538 | return -EBUSY; | 576 | clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); |
539 | |||
540 | ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | ||
541 | 577 | ||
542 | netif_stop_queue(dev); | 578 | netif_stop_queue(dev); |
543 | 579 | ||
544 | return 0; | 580 | return 0; |
545 | } | 581 | } |
546 | 582 | ||
547 | static int ax25_receive_room(struct tty_struct *tty) | 583 | static struct net_device_stats *ax_get_stats(struct net_device *dev) |
548 | { | 584 | { |
549 | return 65536; /* We can handle an infinite amount of data. :-) */ | 585 | struct mkiss *ax = netdev_priv(dev); |
586 | |||
587 | return &ax->stats; | ||
588 | } | ||
589 | |||
590 | static void ax_setup(struct net_device *dev) | ||
591 | { | ||
592 | static char ax25_bcast[AX25_ADDR_LEN] = | ||
593 | {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1}; | ||
594 | static char ax25_test[AX25_ADDR_LEN] = | ||
595 | {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1}; | ||
596 | |||
597 | /* Finish setting up the DEVICE info. */ | ||
598 | dev->mtu = AX_MTU; | ||
599 | dev->hard_start_xmit = ax_xmit; | ||
600 | dev->open = ax_open_dev; | ||
601 | dev->stop = ax_close; | ||
602 | dev->get_stats = ax_get_stats; | ||
603 | dev->set_mac_address = ax_set_mac_address; | ||
604 | dev->hard_header_len = 0; | ||
605 | dev->addr_len = 0; | ||
606 | dev->type = ARPHRD_AX25; | ||
607 | dev->tx_queue_len = 10; | ||
608 | dev->hard_header = ax_header; | ||
609 | dev->rebuild_header = ax_rebuild_header; | ||
610 | |||
611 | memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); | ||
612 | memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); | ||
613 | |||
614 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; | ||
550 | } | 615 | } |
551 | 616 | ||
552 | /* | 617 | /* |
553 | * Handle the 'receiver data ready' interrupt. | 618 | * We have a potential race on dereferencing tty->disc_data, because the tty |
554 | * This function is called by the 'tty_io' module in the kernel when | 619 | * layer provides no locking at all - thus one cpu could be running |
555 | * a block of data has been received, which can now be decapsulated | 620 | * sixpack_receive_buf while another calls sixpack_close, which zeroes |
556 | * and sent on to the AX.25 layer for further processing. | 621 | * tty->disc_data and frees the memory that sixpack_receive_buf is using. The |
622 | * best way to fix this is to use a rwlock in the tty struct, but for now we | ||
623 | * use a single global rwlock for all ttys in ppp line discipline. | ||
557 | */ | 624 | */ |
558 | static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) | 625 | static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; |
626 | |||
627 | static struct mkiss *mkiss_get(struct tty_struct *tty) | ||
559 | { | 628 | { |
560 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | 629 | struct mkiss *ax; |
561 | 630 | ||
562 | if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) | 631 | read_lock(&disc_data_lock); |
563 | return; | 632 | ax = tty->disc_data; |
633 | if (ax) | ||
634 | atomic_inc(&ax->refcnt); | ||
635 | read_unlock(&disc_data_lock); | ||
564 | 636 | ||
565 | /* | 637 | return ax; |
566 | * Argh! mtu change time! - costs us the packet part received | 638 | } |
567 | * at the change | ||
568 | */ | ||
569 | if (ax->mtu != ax->dev->mtu + 73) | ||
570 | ax_changedmtu(ax); | ||
571 | |||
572 | /* Read the characters out of the buffer */ | ||
573 | while (count--) { | ||
574 | if (fp != NULL && *fp++) { | ||
575 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) | ||
576 | ax->rx_errors++; | ||
577 | cp++; | ||
578 | continue; | ||
579 | } | ||
580 | 639 | ||
581 | kiss_unesc(ax, *cp++); | 640 | static void mkiss_put(struct mkiss *ax) |
582 | } | 641 | { |
642 | if (atomic_dec_and_test(&ax->refcnt)) | ||
643 | up(&ax->dead_sem); | ||
583 | } | 644 | } |
584 | 645 | ||
585 | static int ax25_open(struct tty_struct *tty) | 646 | static int mkiss_open(struct tty_struct *tty) |
586 | { | 647 | { |
587 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | 648 | struct net_device *dev; |
649 | struct mkiss *ax; | ||
588 | int err; | 650 | int err; |
589 | 651 | ||
590 | /* First make sure we're not already connected. */ | 652 | if (!capable(CAP_NET_ADMIN)) |
591 | if (ax && ax->magic == AX25_MAGIC) | 653 | return -EPERM; |
592 | return -EEXIST; | ||
593 | 654 | ||
594 | /* OK. Find a free AX25 channel to use. */ | 655 | dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); |
595 | if ((ax = ax_alloc()) == NULL) | 656 | if (!dev) { |
596 | return -ENFILE; | 657 | err = -ENOMEM; |
658 | goto out; | ||
659 | } | ||
660 | |||
661 | ax = netdev_priv(dev); | ||
662 | ax->dev = dev; | ||
663 | |||
664 | spin_lock_init(&ax->buflock); | ||
665 | atomic_set(&ax->refcnt, 1); | ||
666 | init_MUTEX_LOCKED(&ax->dead_sem); | ||
597 | 667 | ||
598 | ax->tty = tty; | 668 | ax->tty = tty; |
599 | tty->disc_data = ax; | 669 | tty->disc_data = ax; |
@@ -602,283 +672,212 @@ static int ax25_open(struct tty_struct *tty) | |||
602 | tty->driver->flush_buffer(tty); | 672 | tty->driver->flush_buffer(tty); |
603 | 673 | ||
604 | /* Restore default settings */ | 674 | /* Restore default settings */ |
605 | ax->dev->type = ARPHRD_AX25; | 675 | dev->type = ARPHRD_AX25; |
606 | 676 | ||
607 | /* Perform the low-level AX25 initialization. */ | 677 | /* Perform the low-level AX25 initialization. */ |
608 | if ((err = ax_open(ax->dev))) | 678 | if ((err = ax_open(ax->dev))) { |
609 | return err; | 679 | goto out_free_netdev; |
680 | } | ||
610 | 681 | ||
611 | /* Done. We have linked the TTY line to a channel. */ | 682 | if (register_netdev(dev)) |
612 | return ax->dev->base_addr; | 683 | goto out_free_buffers; |
613 | } | ||
614 | 684 | ||
615 | static void ax25_close(struct tty_struct *tty) | 685 | netif_start_queue(dev); |
616 | { | ||
617 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | ||
618 | 686 | ||
619 | /* First make sure we're connected. */ | 687 | /* Done. We have linked the TTY line to a channel. */ |
620 | if (ax == NULL || ax->magic != AX25_MAGIC) | 688 | return 0; |
621 | return; | ||
622 | 689 | ||
623 | unregister_netdev(ax->dev); | 690 | out_free_buffers: |
691 | kfree(ax->rbuff); | ||
692 | kfree(ax->xbuff); | ||
624 | 693 | ||
625 | tty->disc_data = NULL; | 694 | out_free_netdev: |
626 | ax->tty = NULL; | 695 | free_netdev(dev); |
627 | 696 | ||
628 | ax_free(ax); | 697 | out: |
698 | return err; | ||
629 | } | 699 | } |
630 | 700 | ||
631 | 701 | static void mkiss_close(struct tty_struct *tty) | |
632 | static struct net_device_stats *ax_get_stats(struct net_device *dev) | ||
633 | { | 702 | { |
634 | static struct net_device_stats stats; | 703 | struct mkiss *ax; |
635 | struct ax_disp *ax = netdev_priv(dev); | ||
636 | |||
637 | memset(&stats, 0, sizeof(struct net_device_stats)); | ||
638 | |||
639 | stats.rx_packets = ax->rx_packets; | ||
640 | stats.tx_packets = ax->tx_packets; | ||
641 | stats.rx_bytes = ax->rx_bytes; | ||
642 | stats.tx_bytes = ax->tx_bytes; | ||
643 | stats.rx_dropped = ax->rx_dropped; | ||
644 | stats.tx_dropped = ax->tx_dropped; | ||
645 | stats.tx_errors = ax->tx_errors; | ||
646 | stats.rx_errors = ax->rx_errors; | ||
647 | stats.rx_over_errors = ax->rx_over_errors; | ||
648 | |||
649 | return &stats; | ||
650 | } | ||
651 | 704 | ||
705 | write_lock(&disc_data_lock); | ||
706 | ax = tty->disc_data; | ||
707 | tty->disc_data = NULL; | ||
708 | write_unlock(&disc_data_lock); | ||
652 | 709 | ||
653 | /************************************************************************ | 710 | if (ax == 0) |
654 | * STANDARD ENCAPSULATION * | 711 | return; |
655 | ************************************************************************/ | ||
656 | |||
657 | static int kiss_esc(unsigned char *s, unsigned char *d, int len) | ||
658 | { | ||
659 | unsigned char *ptr = d; | ||
660 | unsigned char c; | ||
661 | 712 | ||
662 | /* | 713 | /* |
663 | * Send an initial END character to flush out any | 714 | * We have now ensured that nobody can start using ap from now on, but |
664 | * data that may have accumulated in the receiver | 715 | * we have to wait for all existing users to finish. |
665 | * due to line noise. | ||
666 | */ | 716 | */ |
717 | if (!atomic_dec_and_test(&ax->refcnt)) | ||
718 | down(&ax->dead_sem); | ||
667 | 719 | ||
668 | *ptr++ = END; | 720 | unregister_netdev(ax->dev); |
669 | |||
670 | while (len-- > 0) { | ||
671 | switch (c = *s++) { | ||
672 | case END: | ||
673 | *ptr++ = ESC; | ||
674 | *ptr++ = ESC_END; | ||
675 | break; | ||
676 | case ESC: | ||
677 | *ptr++ = ESC; | ||
678 | *ptr++ = ESC_ESC; | ||
679 | break; | ||
680 | default: | ||
681 | *ptr++ = c; | ||
682 | break; | ||
683 | } | ||
684 | } | ||
685 | 721 | ||
686 | *ptr++ = END; | 722 | /* Free all AX25 frame buffers. */ |
723 | kfree(ax->rbuff); | ||
724 | kfree(ax->xbuff); | ||
687 | 725 | ||
688 | return ptr - d; | 726 | ax->tty = NULL; |
689 | } | 727 | } |
690 | 728 | ||
691 | /* | 729 | /* Perform I/O control on an active ax25 channel. */ |
692 | * MW: | 730 | static int mkiss_ioctl(struct tty_struct *tty, struct file *file, |
693 | * OK its ugly, but tell me a better solution without copying the | 731 | unsigned int cmd, unsigned long arg) |
694 | * packet to a temporary buffer :-) | ||
695 | */ | ||
696 | static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len) | ||
697 | { | 732 | { |
698 | unsigned char *ptr = d; | 733 | struct mkiss *ax = mkiss_get(tty); |
699 | unsigned char c=0; | 734 | struct net_device *dev = ax->dev; |
700 | 735 | unsigned int tmp, err; | |
701 | *ptr++ = END; | ||
702 | while (len > 0) { | ||
703 | if (len > 2) | ||
704 | c = *s++; | ||
705 | else if (len > 1) | ||
706 | c = crc >> 8; | ||
707 | else if (len > 0) | ||
708 | c = crc & 0xff; | ||
709 | 736 | ||
710 | len--; | 737 | /* First make sure we're connected. */ |
738 | if (ax == NULL) | ||
739 | return -ENXIO; | ||
711 | 740 | ||
712 | switch (c) { | 741 | switch (cmd) { |
713 | case END: | 742 | case SIOCGIFNAME: |
714 | *ptr++ = ESC; | 743 | err = copy_to_user((void __user *) arg, ax->dev->name, |
715 | *ptr++ = ESC_END; | 744 | strlen(ax->dev->name) + 1) ? -EFAULT : 0; |
716 | break; | 745 | break; |
717 | case ESC: | 746 | |
718 | *ptr++ = ESC; | 747 | case SIOCGIFENCAP: |
719 | *ptr++ = ESC_ESC; | 748 | err = put_user(4, (int __user *) arg); |
720 | break; | 749 | break; |
721 | default: | 750 | |
722 | *ptr++ = c; | 751 | case SIOCSIFENCAP: |
723 | break; | 752 | if (get_user(tmp, (int __user *) arg)) { |
753 | err = -EFAULT; | ||
754 | break; | ||
724 | } | 755 | } |
725 | } | ||
726 | *ptr++ = END; | ||
727 | return ptr - d; | ||
728 | } | ||
729 | 756 | ||
730 | static void kiss_unesc(struct ax_disp *ax, unsigned char s) | 757 | ax->mode = tmp; |
731 | { | 758 | dev->addr_len = AX25_ADDR_LEN; |
732 | switch (s) { | 759 | dev->hard_header_len = AX25_KISS_HEADER_LEN + |
733 | case END: | 760 | AX25_MAX_HEADER_LEN + 3; |
734 | /* drop keeptest bit = VSV */ | 761 | dev->type = ARPHRD_AX25; |
735 | if (test_bit(AXF_KEEPTEST, &ax->flags)) | ||
736 | clear_bit(AXF_KEEPTEST, &ax->flags); | ||
737 | 762 | ||
738 | if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) | 763 | err = 0; |
739 | ax_bump(ax); | 764 | break; |
740 | 765 | ||
741 | clear_bit(AXF_ESCAPE, &ax->flags); | 766 | case SIOCSIFHWADDR: { |
742 | ax->rcount = 0; | 767 | char addr[AX25_ADDR_LEN]; |
743 | return; | 768 | printk(KERN_INFO "In SIOCSIFHWADDR"); |
744 | 769 | ||
745 | case ESC: | 770 | if (copy_from_user(&addr, |
746 | set_bit(AXF_ESCAPE, &ax->flags); | 771 | (void __user *) arg, AX25_ADDR_LEN)) { |
747 | return; | 772 | err = -EFAULT; |
748 | case ESC_ESC: | ||
749 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
750 | s = ESC; | ||
751 | break; | 773 | break; |
752 | case ESC_END: | ||
753 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
754 | s = END; | ||
755 | break; | ||
756 | } | ||
757 | |||
758 | spin_lock_bh(&ax->buflock); | ||
759 | if (!test_bit(AXF_ERROR, &ax->flags)) { | ||
760 | if (ax->rcount < ax->buffsize) { | ||
761 | ax->rbuff[ax->rcount++] = s; | ||
762 | spin_unlock_bh(&ax->buflock); | ||
763 | return; | ||
764 | } | 774 | } |
765 | 775 | ||
766 | ax->rx_over_errors++; | 776 | spin_lock_irq(&dev->xmit_lock); |
767 | set_bit(AXF_ERROR, &ax->flags); | 777 | memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); |
778 | spin_unlock_irq(&dev->xmit_lock); | ||
779 | |||
780 | err = 0; | ||
781 | break; | ||
782 | } | ||
783 | default: | ||
784 | err = -ENOIOCTLCMD; | ||
768 | } | 785 | } |
769 | spin_unlock_bh(&ax->buflock); | ||
770 | } | ||
771 | 786 | ||
787 | mkiss_put(ax); | ||
772 | 788 | ||
773 | static int ax_set_mac_address(struct net_device *dev, void __user *addr) | 789 | return err; |
774 | { | ||
775 | if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN)) | ||
776 | return -EFAULT; | ||
777 | return 0; | ||
778 | } | 790 | } |
779 | 791 | ||
780 | static int ax_set_dev_mac_address(struct net_device *dev, void *addr) | 792 | /* |
793 | * Handle the 'receiver data ready' interrupt. | ||
794 | * This function is called by the 'tty_io' module in the kernel when | ||
795 | * a block of data has been received, which can now be decapsulated | ||
796 | * and sent on to the AX.25 layer for further processing. | ||
797 | */ | ||
798 | static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | ||
799 | char *fp, int count) | ||
781 | { | 800 | { |
782 | struct sockaddr *sa = addr; | 801 | struct mkiss *ax = mkiss_get(tty); |
783 | |||
784 | memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN); | ||
785 | 802 | ||
786 | return 0; | 803 | if (!ax) |
787 | } | 804 | return; |
788 | |||
789 | |||
790 | /* Perform I/O control on an active ax25 channel. */ | ||
791 | static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void __user *arg) | ||
792 | { | ||
793 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | ||
794 | unsigned int tmp; | ||
795 | 805 | ||
796 | /* First make sure we're connected. */ | 806 | /* |
797 | if (ax == NULL || ax->magic != AX25_MAGIC) | 807 | * Argh! mtu change time! - costs us the packet part received |
798 | return -EINVAL; | 808 | * at the change |
809 | */ | ||
810 | if (ax->mtu != ax->dev->mtu + 73) | ||
811 | ax_changedmtu(ax); | ||
799 | 812 | ||
800 | switch (cmd) { | 813 | /* Read the characters out of the buffer */ |
801 | case SIOCGIFNAME: | 814 | while (count--) { |
802 | if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1)) | 815 | if (fp != NULL && *fp++) { |
803 | return -EFAULT; | 816 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) |
804 | return 0; | 817 | ax->stats.rx_errors++; |
805 | 818 | cp++; | |
806 | case SIOCGIFENCAP: | 819 | continue; |
807 | return put_user(4, (int __user *)arg); | 820 | } |
808 | |||
809 | case SIOCSIFENCAP: | ||
810 | if (get_user(tmp, (int __user *)arg)) | ||
811 | return -EFAULT; | ||
812 | ax->mode = tmp; | ||
813 | ax->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */ | ||
814 | ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3; | ||
815 | ax->dev->type = ARPHRD_AX25; | ||
816 | return 0; | ||
817 | |||
818 | case SIOCSIFHWADDR: | ||
819 | return ax_set_mac_address(ax->dev, arg); | ||
820 | 821 | ||
821 | default: | 822 | kiss_unesc(ax, *cp++); |
822 | return -ENOIOCTLCMD; | ||
823 | } | 823 | } |
824 | |||
825 | mkiss_put(ax); | ||
826 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) | ||
827 | && tty->driver->unthrottle) | ||
828 | tty->driver->unthrottle(tty); | ||
824 | } | 829 | } |
825 | 830 | ||
826 | static int ax_open_dev(struct net_device *dev) | 831 | static int mkiss_receive_room(struct tty_struct *tty) |
827 | { | 832 | { |
828 | struct ax_disp *ax = netdev_priv(dev); | 833 | return 65536; /* We can handle an infinite amount of data. :-) */ |
829 | |||
830 | if (ax->tty == NULL) | ||
831 | return -ENODEV; | ||
832 | |||
833 | return 0; | ||
834 | } | 834 | } |
835 | 835 | ||
836 | 836 | /* | |
837 | /* Initialize the driver. Called by network startup. */ | 837 | * Called by the driver when there's room for more data. If we have |
838 | static int ax25_init(struct net_device *dev) | 838 | * more packets to send, we send them here. |
839 | */ | ||
840 | static void mkiss_write_wakeup(struct tty_struct *tty) | ||
839 | { | 841 | { |
840 | struct ax_disp *ax = netdev_priv(dev); | 842 | struct mkiss *ax = mkiss_get(tty); |
841 | 843 | int actual; | |
842 | static char ax25_bcast[AX25_ADDR_LEN] = | ||
843 | {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1}; | ||
844 | static char ax25_test[AX25_ADDR_LEN] = | ||
845 | {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1}; | ||
846 | |||
847 | if (ax == NULL) /* Allocation failed ?? */ | ||
848 | return -ENODEV; | ||
849 | 844 | ||
850 | /* Set up the "AX25 Control Block". (And clear statistics) */ | 845 | if (!ax) |
851 | memset(ax, 0, sizeof (struct ax_disp)); | 846 | return; |
852 | ax->magic = AX25_MAGIC; | ||
853 | ax->dev = dev; | ||
854 | 847 | ||
855 | /* Finish setting up the DEVICE info. */ | 848 | if (ax->xleft <= 0) { |
856 | dev->mtu = AX_MTU; | 849 | /* Now serial buffer is almost free & we can start |
857 | dev->hard_start_xmit = ax_xmit; | 850 | * transmission of another packet |
858 | dev->open = ax_open_dev; | 851 | */ |
859 | dev->stop = ax_close; | 852 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
860 | dev->get_stats = ax_get_stats; | ||
861 | dev->set_mac_address = ax_set_dev_mac_address; | ||
862 | dev->hard_header_len = 0; | ||
863 | dev->addr_len = 0; | ||
864 | dev->type = ARPHRD_AX25; | ||
865 | dev->tx_queue_len = 10; | ||
866 | dev->hard_header = ax_header; | ||
867 | dev->rebuild_header = ax_rebuild_header; | ||
868 | 853 | ||
869 | memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); | 854 | netif_wake_queue(ax->dev); |
870 | memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); | 855 | goto out; |
856 | } | ||
871 | 857 | ||
872 | /* New-style flags. */ | 858 | actual = tty->driver->write(tty, ax->xhead, ax->xleft); |
873 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; | 859 | ax->xleft -= actual; |
860 | ax->xhead += actual; | ||
874 | 861 | ||
875 | return 0; | 862 | out: |
863 | mkiss_put(ax); | ||
876 | } | 864 | } |
877 | 865 | ||
866 | static struct tty_ldisc ax_ldisc = { | ||
867 | .magic = TTY_LDISC_MAGIC, | ||
868 | .name = "mkiss", | ||
869 | .open = mkiss_open, | ||
870 | .close = mkiss_close, | ||
871 | .ioctl = mkiss_ioctl, | ||
872 | .receive_buf = mkiss_receive_buf, | ||
873 | .receive_room = mkiss_receive_room, | ||
874 | .write_wakeup = mkiss_write_wakeup | ||
875 | }; | ||
878 | 876 | ||
879 | /* ******************************************************************** */ | 877 | static char banner[] __initdata = KERN_INFO \ |
880 | /* * Init MKISS driver * */ | 878 | "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; |
881 | /* ******************************************************************** */ | 879 | static char msg_regfail[] __initdata = KERN_ERR \ |
880 | "mkiss: can't register line discipline (err = %d)\n"; | ||
882 | 881 | ||
883 | static int __init mkiss_init_driver(void) | 882 | static int __init mkiss_init_driver(void) |
884 | { | 883 | { |
@@ -886,64 +885,27 @@ static int __init mkiss_init_driver(void) | |||
886 | 885 | ||
887 | printk(banner); | 886 | printk(banner); |
888 | 887 | ||
889 | if (ax25_maxdev < 4) | 888 | if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) |
890 | ax25_maxdev = 4; /* Sanity */ | 889 | printk(msg_regfail); |
891 | 890 | ||
892 | if ((ax25_ctrls = kmalloc(sizeof(void *) * ax25_maxdev, GFP_KERNEL)) == NULL) { | ||
893 | printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array!\n"); | ||
894 | return -ENOMEM; | ||
895 | } | ||
896 | |||
897 | /* Clear the pointer array, we allocate devices when we need them */ | ||
898 | memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */ | ||
899 | |||
900 | /* Fill in our line protocol discipline, and register it */ | ||
901 | ax_ldisc.magic = TTY_LDISC_MAGIC; | ||
902 | ax_ldisc.name = "mkiss"; | ||
903 | ax_ldisc.open = ax25_open; | ||
904 | ax_ldisc.close = ax25_close; | ||
905 | ax_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *, | ||
906 | unsigned int, unsigned long))ax25_disp_ioctl; | ||
907 | ax_ldisc.receive_buf = ax25_receive_buf; | ||
908 | ax_ldisc.receive_room = ax25_receive_room; | ||
909 | ax_ldisc.write_wakeup = ax25_write_wakeup; | ||
910 | |||
911 | if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) { | ||
912 | printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status); | ||
913 | kfree(ax25_ctrls); | ||
914 | } | ||
915 | return status; | 891 | return status; |
916 | } | 892 | } |
917 | 893 | ||
894 | static const char msg_unregfail[] __exitdata = KERN_ERR \ | ||
895 | "mkiss: can't unregister line discipline (err = %d)\n"; | ||
896 | |||
918 | static void __exit mkiss_exit_driver(void) | 897 | static void __exit mkiss_exit_driver(void) |
919 | { | 898 | { |
920 | int i; | 899 | int ret; |
921 | |||
922 | for (i = 0; i < ax25_maxdev; i++) { | ||
923 | if (ax25_ctrls[i]) { | ||
924 | /* | ||
925 | * VSV = if dev->start==0, then device | ||
926 | * unregistered while close proc. | ||
927 | */ | ||
928 | if (netif_running(&ax25_ctrls[i]->dev)) | ||
929 | unregister_netdev(&ax25_ctrls[i]->dev); | ||
930 | kfree(ax25_ctrls[i]); | ||
931 | } | ||
932 | } | ||
933 | 900 | ||
934 | kfree(ax25_ctrls); | 901 | if ((ret = tty_unregister_ldisc(N_AX25))) |
935 | ax25_ctrls = NULL; | 902 | printk(msg_unregfail, ret); |
936 | |||
937 | if ((i = tty_unregister_ldisc(N_AX25))) | ||
938 | printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i); | ||
939 | } | 903 | } |
940 | 904 | ||
941 | MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>"); | 905 | MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>"); |
942 | MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); | 906 | MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); |
943 | MODULE_PARM(ax25_maxdev, "i"); | ||
944 | MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices"); | ||
945 | MODULE_LICENSE("GPL"); | 907 | MODULE_LICENSE("GPL"); |
946 | MODULE_ALIAS_LDISC(N_AX25); | 908 | MODULE_ALIAS_LDISC(N_AX25); |
909 | |||
947 | module_init(mkiss_init_driver); | 910 | module_init(mkiss_init_driver); |
948 | module_exit(mkiss_exit_driver); | 911 | module_exit(mkiss_exit_driver); |
949 | |||
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index c7fb3675c09d..0de3bb906174 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c | |||
@@ -1253,7 +1253,7 @@ static int emac_init_tah(struct ocp_enet_private *fep) | |||
1253 | TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | | 1253 | TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | |
1254 | TAH_MR_DIG); | 1254 | TAH_MR_DIG); |
1255 | 1255 | ||
1256 | iounmap(&tahp); | 1256 | iounmap(tahp); |
1257 | 1257 | ||
1258 | return 0; | 1258 | return 0; |
1259 | } | 1259 | } |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index c39b0609742a..32d5fabd4b10 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -1144,7 +1144,7 @@ static void ibmveth_proc_unregister_driver(void) | |||
1144 | 1144 | ||
1145 | static struct vio_device_id ibmveth_device_table[] __devinitdata= { | 1145 | static struct vio_device_id ibmveth_device_table[] __devinitdata= { |
1146 | { "network", "IBM,l-lan"}, | 1146 | { "network", "IBM,l-lan"}, |
1147 | { 0,} | 1147 | { "", "" } |
1148 | }; | 1148 | }; |
1149 | 1149 | ||
1150 | MODULE_DEVICE_TABLE(vio, ibmveth_device_table); | 1150 | MODULE_DEVICE_TABLE(vio, ibmveth_device_table); |
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 55af32e9bf08..183ba97785b0 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -1370,7 +1370,7 @@ static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1370 | */ | 1370 | */ |
1371 | static struct vio_device_id veth_device_table[] __devinitdata = { | 1371 | static struct vio_device_id veth_device_table[] __devinitdata = { |
1372 | { "vlan", "" }, | 1372 | { "vlan", "" }, |
1373 | { NULL, NULL } | 1373 | { "", "" } |
1374 | }; | 1374 | }; |
1375 | MODULE_DEVICE_TABLE(vio, veth_device_table); | 1375 | MODULE_DEVICE_TABLE(vio, veth_device_table); |
1376 | 1376 | ||
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index f8d3385c7842..c83271b38621 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h | |||
@@ -119,7 +119,7 @@ struct ixgb_adapter; | |||
119 | * so a DMA handle can be stored along with the buffer */ | 119 | * so a DMA handle can be stored along with the buffer */ |
120 | struct ixgb_buffer { | 120 | struct ixgb_buffer { |
121 | struct sk_buff *skb; | 121 | struct sk_buff *skb; |
122 | uint64_t dma; | 122 | dma_addr_t dma; |
123 | unsigned long time_stamp; | 123 | unsigned long time_stamp; |
124 | uint16_t length; | 124 | uint16_t length; |
125 | uint16_t next_to_watch; | 125 | uint16_t next_to_watch; |
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index 3aae110c5560..661a46b95a61 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c | |||
@@ -565,24 +565,6 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw, | |||
565 | } | 565 | } |
566 | } | 566 | } |
567 | 567 | ||
568 | /****************************************************************************** | ||
569 | * return the compatibility flags from EEPROM | ||
570 | * | ||
571 | * hw - Struct containing variables accessed by shared code | ||
572 | * | ||
573 | * Returns: | ||
574 | * compatibility flags if EEPROM contents are valid, 0 otherwise | ||
575 | ******************************************************************************/ | ||
576 | uint16_t | ||
577 | ixgb_get_ee_compatibility(struct ixgb_hw *hw) | ||
578 | { | ||
579 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
580 | |||
581 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
582 | return (le16_to_cpu(ee_map->compatibility)); | ||
583 | |||
584 | return(0); | ||
585 | } | ||
586 | 568 | ||
587 | /****************************************************************************** | 569 | /****************************************************************************** |
588 | * return the Printed Board Assembly number from EEPROM | 570 | * return the Printed Board Assembly number from EEPROM |
@@ -602,81 +584,6 @@ ixgb_get_ee_pba_number(struct ixgb_hw *hw) | |||
602 | return(0); | 584 | return(0); |
603 | } | 585 | } |
604 | 586 | ||
605 | /****************************************************************************** | ||
606 | * return the Initialization Control Word 1 from EEPROM | ||
607 | * | ||
608 | * hw - Struct containing variables accessed by shared code | ||
609 | * | ||
610 | * Returns: | ||
611 | * Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise | ||
612 | ******************************************************************************/ | ||
613 | uint16_t | ||
614 | ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw) | ||
615 | { | ||
616 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
617 | |||
618 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
619 | return (le16_to_cpu(ee_map->init_ctrl_reg_1)); | ||
620 | |||
621 | return(0); | ||
622 | } | ||
623 | |||
624 | /****************************************************************************** | ||
625 | * return the Initialization Control Word 2 from EEPROM | ||
626 | * | ||
627 | * hw - Struct containing variables accessed by shared code | ||
628 | * | ||
629 | * Returns: | ||
630 | * Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise | ||
631 | ******************************************************************************/ | ||
632 | uint16_t | ||
633 | ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw) | ||
634 | { | ||
635 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
636 | |||
637 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
638 | return (le16_to_cpu(ee_map->init_ctrl_reg_2)); | ||
639 | |||
640 | return(0); | ||
641 | } | ||
642 | |||
643 | /****************************************************************************** | ||
644 | * return the Subsystem Id from EEPROM | ||
645 | * | ||
646 | * hw - Struct containing variables accessed by shared code | ||
647 | * | ||
648 | * Returns: | ||
649 | * Subsystem Id if EEPROM contents are valid, 0 otherwise | ||
650 | ******************************************************************************/ | ||
651 | uint16_t | ||
652 | ixgb_get_ee_subsystem_id(struct ixgb_hw *hw) | ||
653 | { | ||
654 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
655 | |||
656 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
657 | return (le16_to_cpu(ee_map->subsystem_id)); | ||
658 | |||
659 | return(0); | ||
660 | } | ||
661 | |||
662 | /****************************************************************************** | ||
663 | * return the Sub Vendor Id from EEPROM | ||
664 | * | ||
665 | * hw - Struct containing variables accessed by shared code | ||
666 | * | ||
667 | * Returns: | ||
668 | * Sub Vendor Id if EEPROM contents are valid, 0 otherwise | ||
669 | ******************************************************************************/ | ||
670 | uint16_t | ||
671 | ixgb_get_ee_subvendor_id(struct ixgb_hw *hw) | ||
672 | { | ||
673 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
674 | |||
675 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
676 | return (le16_to_cpu(ee_map->subvendor_id)); | ||
677 | |||
678 | return(0); | ||
679 | } | ||
680 | 587 | ||
681 | /****************************************************************************** | 588 | /****************************************************************************** |
682 | * return the Device Id from EEPROM | 589 | * return the Device Id from EEPROM |
@@ -694,81 +601,6 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw) | |||
694 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | 601 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) |
695 | return (le16_to_cpu(ee_map->device_id)); | 602 | return (le16_to_cpu(ee_map->device_id)); |
696 | 603 | ||
697 | return(0); | 604 | return (0); |
698 | } | ||
699 | |||
700 | /****************************************************************************** | ||
701 | * return the Vendor Id from EEPROM | ||
702 | * | ||
703 | * hw - Struct containing variables accessed by shared code | ||
704 | * | ||
705 | * Returns: | ||
706 | * Device Id if EEPROM contents are valid, 0 otherwise | ||
707 | ******************************************************************************/ | ||
708 | uint16_t | ||
709 | ixgb_get_ee_vendor_id(struct ixgb_hw *hw) | ||
710 | { | ||
711 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
712 | |||
713 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
714 | return (le16_to_cpu(ee_map->vendor_id)); | ||
715 | |||
716 | return(0); | ||
717 | } | ||
718 | |||
719 | /****************************************************************************** | ||
720 | * return the Software Defined Pins Register from EEPROM | ||
721 | * | ||
722 | * hw - Struct containing variables accessed by shared code | ||
723 | * | ||
724 | * Returns: | ||
725 | * SDP Register if EEPROM contents are valid, 0 otherwise | ||
726 | ******************************************************************************/ | ||
727 | uint16_t | ||
728 | ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw) | ||
729 | { | ||
730 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
731 | |||
732 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
733 | return (le16_to_cpu(ee_map->swdpins_reg)); | ||
734 | |||
735 | return(0); | ||
736 | } | 605 | } |
737 | 606 | ||
738 | /****************************************************************************** | ||
739 | * return the D3 Power Management Bits from EEPROM | ||
740 | * | ||
741 | * hw - Struct containing variables accessed by shared code | ||
742 | * | ||
743 | * Returns: | ||
744 | * D3 Power Management Bits if EEPROM contents are valid, 0 otherwise | ||
745 | ******************************************************************************/ | ||
746 | uint8_t | ||
747 | ixgb_get_ee_d3_power(struct ixgb_hw *hw) | ||
748 | { | ||
749 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
750 | |||
751 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
752 | return (le16_to_cpu(ee_map->d3_power)); | ||
753 | |||
754 | return(0); | ||
755 | } | ||
756 | |||
757 | /****************************************************************************** | ||
758 | * return the D0 Power Management Bits from EEPROM | ||
759 | * | ||
760 | * hw - Struct containing variables accessed by shared code | ||
761 | * | ||
762 | * Returns: | ||
763 | * D0 Power Management Bits if EEPROM contents are valid, 0 otherwise | ||
764 | ******************************************************************************/ | ||
765 | uint8_t | ||
766 | ixgb_get_ee_d0_power(struct ixgb_hw *hw) | ||
767 | { | ||
768 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
769 | |||
770 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
771 | return (le16_to_cpu(ee_map->d0_power)); | ||
772 | |||
773 | return(0); | ||
774 | } | ||
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 3fa113854eeb..9d026ed77ddd 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c | |||
@@ -98,10 +98,10 @@ static struct ixgb_stats ixgb_gstrings_stats[] = { | |||
98 | static int | 98 | static int |
99 | ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 99 | ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
100 | { | 100 | { |
101 | struct ixgb_adapter *adapter = netdev->priv; | 101 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
102 | 102 | ||
103 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | 103 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); |
104 | ecmd->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | 104 | ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); |
105 | ecmd->port = PORT_FIBRE; | 105 | ecmd->port = PORT_FIBRE; |
106 | ecmd->transceiver = XCVR_EXTERNAL; | 106 | ecmd->transceiver = XCVR_EXTERNAL; |
107 | 107 | ||
@@ -120,7 +120,7 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
120 | static int | 120 | static int |
121 | ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 121 | ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
122 | { | 122 | { |
123 | struct ixgb_adapter *adapter = netdev->priv; | 123 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
124 | 124 | ||
125 | if(ecmd->autoneg == AUTONEG_ENABLE || | 125 | if(ecmd->autoneg == AUTONEG_ENABLE || |
126 | ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL) | 126 | ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL) |
@@ -130,6 +130,12 @@ ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
130 | ixgb_down(adapter, TRUE); | 130 | ixgb_down(adapter, TRUE); |
131 | ixgb_reset(adapter); | 131 | ixgb_reset(adapter); |
132 | ixgb_up(adapter); | 132 | ixgb_up(adapter); |
133 | /* be optimistic about our link, since we were up before */ | ||
134 | adapter->link_speed = 10000; | ||
135 | adapter->link_duplex = FULL_DUPLEX; | ||
136 | netif_carrier_on(netdev); | ||
137 | netif_wake_queue(netdev); | ||
138 | |||
133 | } else | 139 | } else |
134 | ixgb_reset(adapter); | 140 | ixgb_reset(adapter); |
135 | 141 | ||
@@ -140,7 +146,7 @@ static void | |||
140 | ixgb_get_pauseparam(struct net_device *netdev, | 146 | ixgb_get_pauseparam(struct net_device *netdev, |
141 | struct ethtool_pauseparam *pause) | 147 | struct ethtool_pauseparam *pause) |
142 | { | 148 | { |
143 | struct ixgb_adapter *adapter = netdev->priv; | 149 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
144 | struct ixgb_hw *hw = &adapter->hw; | 150 | struct ixgb_hw *hw = &adapter->hw; |
145 | 151 | ||
146 | pause->autoneg = AUTONEG_DISABLE; | 152 | pause->autoneg = AUTONEG_DISABLE; |
@@ -159,7 +165,7 @@ static int | |||
159 | ixgb_set_pauseparam(struct net_device *netdev, | 165 | ixgb_set_pauseparam(struct net_device *netdev, |
160 | struct ethtool_pauseparam *pause) | 166 | struct ethtool_pauseparam *pause) |
161 | { | 167 | { |
162 | struct ixgb_adapter *adapter = netdev->priv; | 168 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
163 | struct ixgb_hw *hw = &adapter->hw; | 169 | struct ixgb_hw *hw = &adapter->hw; |
164 | 170 | ||
165 | if(pause->autoneg == AUTONEG_ENABLE) | 171 | if(pause->autoneg == AUTONEG_ENABLE) |
@@ -177,6 +183,11 @@ ixgb_set_pauseparam(struct net_device *netdev, | |||
177 | if(netif_running(adapter->netdev)) { | 183 | if(netif_running(adapter->netdev)) { |
178 | ixgb_down(adapter, TRUE); | 184 | ixgb_down(adapter, TRUE); |
179 | ixgb_up(adapter); | 185 | ixgb_up(adapter); |
186 | /* be optimistic about our link, since we were up before */ | ||
187 | adapter->link_speed = 10000; | ||
188 | adapter->link_duplex = FULL_DUPLEX; | ||
189 | netif_carrier_on(netdev); | ||
190 | netif_wake_queue(netdev); | ||
180 | } else | 191 | } else |
181 | ixgb_reset(adapter); | 192 | ixgb_reset(adapter); |
182 | 193 | ||
@@ -186,19 +197,26 @@ ixgb_set_pauseparam(struct net_device *netdev, | |||
186 | static uint32_t | 197 | static uint32_t |
187 | ixgb_get_rx_csum(struct net_device *netdev) | 198 | ixgb_get_rx_csum(struct net_device *netdev) |
188 | { | 199 | { |
189 | struct ixgb_adapter *adapter = netdev->priv; | 200 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
201 | |||
190 | return adapter->rx_csum; | 202 | return adapter->rx_csum; |
191 | } | 203 | } |
192 | 204 | ||
193 | static int | 205 | static int |
194 | ixgb_set_rx_csum(struct net_device *netdev, uint32_t data) | 206 | ixgb_set_rx_csum(struct net_device *netdev, uint32_t data) |
195 | { | 207 | { |
196 | struct ixgb_adapter *adapter = netdev->priv; | 208 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
209 | |||
197 | adapter->rx_csum = data; | 210 | adapter->rx_csum = data; |
198 | 211 | ||
199 | if(netif_running(netdev)) { | 212 | if(netif_running(netdev)) { |
200 | ixgb_down(adapter,TRUE); | 213 | ixgb_down(adapter,TRUE); |
201 | ixgb_up(adapter); | 214 | ixgb_up(adapter); |
215 | /* be optimistic about our link, since we were up before */ | ||
216 | adapter->link_speed = 10000; | ||
217 | adapter->link_duplex = FULL_DUPLEX; | ||
218 | netif_carrier_on(netdev); | ||
219 | netif_wake_queue(netdev); | ||
202 | } else | 220 | } else |
203 | ixgb_reset(adapter); | 221 | ixgb_reset(adapter); |
204 | return 0; | 222 | return 0; |
@@ -246,14 +264,15 @@ static void | |||
246 | ixgb_get_regs(struct net_device *netdev, | 264 | ixgb_get_regs(struct net_device *netdev, |
247 | struct ethtool_regs *regs, void *p) | 265 | struct ethtool_regs *regs, void *p) |
248 | { | 266 | { |
249 | struct ixgb_adapter *adapter = netdev->priv; | 267 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
250 | struct ixgb_hw *hw = &adapter->hw; | 268 | struct ixgb_hw *hw = &adapter->hw; |
251 | uint32_t *reg = p; | 269 | uint32_t *reg = p; |
252 | uint32_t *reg_start = reg; | 270 | uint32_t *reg_start = reg; |
253 | uint8_t i; | 271 | uint8_t i; |
254 | 272 | ||
255 | /* the 1 (one) below indicates an attempt at versioning, if the | 273 | /* the 1 (one) below indicates an attempt at versioning, if the |
256 | * interface in ethtool or the driver this 1 should be incremented */ | 274 | * interface in ethtool or the driver changes, this 1 should be |
275 | * incremented */ | ||
257 | regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; | 276 | regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; |
258 | 277 | ||
259 | /* General Registers */ | 278 | /* General Registers */ |
@@ -283,7 +302,8 @@ ixgb_get_regs(struct net_device *netdev, | |||
283 | *reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */ | 302 | *reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */ |
284 | *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */ | 303 | *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */ |
285 | 304 | ||
286 | for (i = 0; i < IXGB_RAR_ENTRIES; i++) { | 305 | /* there are 16 RAR entries in hardware, we only use 3 */ |
306 | for(i = 0; i < 16; i++) { | ||
287 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ | 307 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ |
288 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ | 308 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ |
289 | } | 309 | } |
@@ -391,7 +411,7 @@ static int | |||
391 | ixgb_get_eeprom(struct net_device *netdev, | 411 | ixgb_get_eeprom(struct net_device *netdev, |
392 | struct ethtool_eeprom *eeprom, uint8_t *bytes) | 412 | struct ethtool_eeprom *eeprom, uint8_t *bytes) |
393 | { | 413 | { |
394 | struct ixgb_adapter *adapter = netdev->priv; | 414 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
395 | struct ixgb_hw *hw = &adapter->hw; | 415 | struct ixgb_hw *hw = &adapter->hw; |
396 | uint16_t *eeprom_buff; | 416 | uint16_t *eeprom_buff; |
397 | int i, max_len, first_word, last_word; | 417 | int i, max_len, first_word, last_word; |
@@ -439,7 +459,7 @@ static int | |||
439 | ixgb_set_eeprom(struct net_device *netdev, | 459 | ixgb_set_eeprom(struct net_device *netdev, |
440 | struct ethtool_eeprom *eeprom, uint8_t *bytes) | 460 | struct ethtool_eeprom *eeprom, uint8_t *bytes) |
441 | { | 461 | { |
442 | struct ixgb_adapter *adapter = netdev->priv; | 462 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
443 | struct ixgb_hw *hw = &adapter->hw; | 463 | struct ixgb_hw *hw = &adapter->hw; |
444 | uint16_t *eeprom_buff; | 464 | uint16_t *eeprom_buff; |
445 | void *ptr; | 465 | void *ptr; |
@@ -497,7 +517,7 @@ static void | |||
497 | ixgb_get_drvinfo(struct net_device *netdev, | 517 | ixgb_get_drvinfo(struct net_device *netdev, |
498 | struct ethtool_drvinfo *drvinfo) | 518 | struct ethtool_drvinfo *drvinfo) |
499 | { | 519 | { |
500 | struct ixgb_adapter *adapter = netdev->priv; | 520 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
501 | 521 | ||
502 | strncpy(drvinfo->driver, ixgb_driver_name, 32); | 522 | strncpy(drvinfo->driver, ixgb_driver_name, 32); |
503 | strncpy(drvinfo->version, ixgb_driver_version, 32); | 523 | strncpy(drvinfo->version, ixgb_driver_version, 32); |
@@ -512,7 +532,7 @@ static void | |||
512 | ixgb_get_ringparam(struct net_device *netdev, | 532 | ixgb_get_ringparam(struct net_device *netdev, |
513 | struct ethtool_ringparam *ring) | 533 | struct ethtool_ringparam *ring) |
514 | { | 534 | { |
515 | struct ixgb_adapter *adapter = netdev->priv; | 535 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
516 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; | 536 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; |
517 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; | 537 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; |
518 | 538 | ||
@@ -530,7 +550,7 @@ static int | |||
530 | ixgb_set_ringparam(struct net_device *netdev, | 550 | ixgb_set_ringparam(struct net_device *netdev, |
531 | struct ethtool_ringparam *ring) | 551 | struct ethtool_ringparam *ring) |
532 | { | 552 | { |
533 | struct ixgb_adapter *adapter = netdev->priv; | 553 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
534 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; | 554 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; |
535 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; | 555 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; |
536 | struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new; | 556 | struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new; |
@@ -573,6 +593,11 @@ ixgb_set_ringparam(struct net_device *netdev, | |||
573 | adapter->tx_ring = tx_new; | 593 | adapter->tx_ring = tx_new; |
574 | if((err = ixgb_up(adapter))) | 594 | if((err = ixgb_up(adapter))) |
575 | return err; | 595 | return err; |
596 | /* be optimistic about our link, since we were up before */ | ||
597 | adapter->link_speed = 10000; | ||
598 | adapter->link_duplex = FULL_DUPLEX; | ||
599 | netif_carrier_on(netdev); | ||
600 | netif_wake_queue(netdev); | ||
576 | } | 601 | } |
577 | 602 | ||
578 | return 0; | 603 | return 0; |
@@ -607,7 +632,7 @@ ixgb_led_blink_callback(unsigned long data) | |||
607 | static int | 632 | static int |
608 | ixgb_phys_id(struct net_device *netdev, uint32_t data) | 633 | ixgb_phys_id(struct net_device *netdev, uint32_t data) |
609 | { | 634 | { |
610 | struct ixgb_adapter *adapter = netdev->priv; | 635 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
611 | 636 | ||
612 | if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) | 637 | if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) |
613 | data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); | 638 | data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); |
@@ -643,7 +668,7 @@ static void | |||
643 | ixgb_get_ethtool_stats(struct net_device *netdev, | 668 | ixgb_get_ethtool_stats(struct net_device *netdev, |
644 | struct ethtool_stats *stats, uint64_t *data) | 669 | struct ethtool_stats *stats, uint64_t *data) |
645 | { | 670 | { |
646 | struct ixgb_adapter *adapter = netdev->priv; | 671 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
647 | int i; | 672 | int i; |
648 | 673 | ||
649 | ixgb_update_stats(adapter); | 674 | ixgb_update_stats(adapter); |
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h index 97898efe7cc8..8bcf31ed10c2 100644 --- a/drivers/net/ixgb/ixgb_hw.h +++ b/drivers/net/ixgb/ixgb_hw.h | |||
@@ -822,17 +822,8 @@ extern void ixgb_clear_vfta(struct ixgb_hw *hw); | |||
822 | 822 | ||
823 | /* Access functions to eeprom data */ | 823 | /* Access functions to eeprom data */ |
824 | void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr); | 824 | void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr); |
825 | uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw); | ||
826 | uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw); | 825 | uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw); |
827 | uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw); | ||
828 | uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw); | ||
829 | uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw *hw); | ||
830 | uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw *hw); | ||
831 | uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw); | 826 | uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw); |
832 | uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw *hw); | ||
833 | uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw); | ||
834 | uint8_t ixgb_get_ee_d3_power(struct ixgb_hw *hw); | ||
835 | uint8_t ixgb_get_ee_d0_power(struct ixgb_hw *hw); | ||
836 | boolean_t ixgb_get_eeprom_data(struct ixgb_hw *hw); | 827 | boolean_t ixgb_get_eeprom_data(struct ixgb_hw *hw); |
837 | uint16_t ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index); | 828 | uint16_t ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index); |
838 | 829 | ||
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 097b90ccf575..5c555373adbe 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #include "ixgb.h" | 29 | #include "ixgb.h" |
30 | 30 | ||
31 | /* Change Log | 31 | /* Change Log |
32 | * 1.0.96 04/19/05 | ||
33 | * - Make needlessly global code static -- bunk@stusta.de | ||
34 | * - ethtool cleanup -- shemminger@osdl.org | ||
35 | * - Support for MODULE_VERSION -- linville@tuxdriver.com | ||
36 | * - add skb_header_cloned check to the tso path -- herbert@apana.org.au | ||
32 | * 1.0.88 01/05/05 | 37 | * 1.0.88 01/05/05 |
33 | * - include fix to the condition that determines when to quit NAPI - Robert Olsson | 38 | * - include fix to the condition that determines when to quit NAPI - Robert Olsson |
34 | * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down | 39 | * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down |
@@ -47,10 +52,9 @@ char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; | |||
47 | #else | 52 | #else |
48 | #define DRIVERNAPI "-NAPI" | 53 | #define DRIVERNAPI "-NAPI" |
49 | #endif | 54 | #endif |
50 | 55 | #define DRV_VERSION "1.0.100-k2"DRIVERNAPI | |
51 | #define DRV_VERSION "1.0.95-k2"DRIVERNAPI | ||
52 | char ixgb_driver_version[] = DRV_VERSION; | 56 | char ixgb_driver_version[] = DRV_VERSION; |
53 | char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; | 57 | static char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; |
54 | 58 | ||
55 | /* ixgb_pci_tbl - PCI Device ID Table | 59 | /* ixgb_pci_tbl - PCI Device ID Table |
56 | * | 60 | * |
@@ -145,10 +149,12 @@ MODULE_LICENSE("GPL"); | |||
145 | MODULE_VERSION(DRV_VERSION); | 149 | MODULE_VERSION(DRV_VERSION); |
146 | 150 | ||
147 | /* some defines for controlling descriptor fetches in h/w */ | 151 | /* some defines for controlling descriptor fetches in h/w */ |
148 | #define RXDCTL_PTHRESH_DEFAULT 128 /* chip considers prefech below this */ | ||
149 | #define RXDCTL_HTHRESH_DEFAULT 16 /* chip will only prefetch if tail is | ||
150 | pushed this many descriptors from head */ | ||
151 | #define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ | 152 | #define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ |
153 | #define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below | ||
154 | * this */ | ||
155 | #define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail | ||
156 | * is pushed this many descriptors | ||
157 | * from head */ | ||
152 | 158 | ||
153 | /** | 159 | /** |
154 | * ixgb_init_module - Driver Registration Routine | 160 | * ixgb_init_module - Driver Registration Routine |
@@ -376,7 +382,7 @@ ixgb_probe(struct pci_dev *pdev, | |||
376 | SET_NETDEV_DEV(netdev, &pdev->dev); | 382 | SET_NETDEV_DEV(netdev, &pdev->dev); |
377 | 383 | ||
378 | pci_set_drvdata(pdev, netdev); | 384 | pci_set_drvdata(pdev, netdev); |
379 | adapter = netdev->priv; | 385 | adapter = netdev_priv(netdev); |
380 | adapter->netdev = netdev; | 386 | adapter->netdev = netdev; |
381 | adapter->pdev = pdev; | 387 | adapter->pdev = pdev; |
382 | adapter->hw.back = adapter; | 388 | adapter->hw.back = adapter; |
@@ -512,7 +518,7 @@ static void __devexit | |||
512 | ixgb_remove(struct pci_dev *pdev) | 518 | ixgb_remove(struct pci_dev *pdev) |
513 | { | 519 | { |
514 | struct net_device *netdev = pci_get_drvdata(pdev); | 520 | struct net_device *netdev = pci_get_drvdata(pdev); |
515 | struct ixgb_adapter *adapter = netdev->priv; | 521 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
516 | 522 | ||
517 | unregister_netdev(netdev); | 523 | unregister_netdev(netdev); |
518 | 524 | ||
@@ -583,7 +589,7 @@ ixgb_sw_init(struct ixgb_adapter *adapter) | |||
583 | static int | 589 | static int |
584 | ixgb_open(struct net_device *netdev) | 590 | ixgb_open(struct net_device *netdev) |
585 | { | 591 | { |
586 | struct ixgb_adapter *adapter = netdev->priv; | 592 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
587 | int err; | 593 | int err; |
588 | 594 | ||
589 | /* allocate transmit descriptors */ | 595 | /* allocate transmit descriptors */ |
@@ -626,7 +632,7 @@ err_setup_tx: | |||
626 | static int | 632 | static int |
627 | ixgb_close(struct net_device *netdev) | 633 | ixgb_close(struct net_device *netdev) |
628 | { | 634 | { |
629 | struct ixgb_adapter *adapter = netdev->priv; | 635 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
630 | 636 | ||
631 | ixgb_down(adapter, TRUE); | 637 | ixgb_down(adapter, TRUE); |
632 | 638 | ||
@@ -1017,7 +1023,7 @@ ixgb_clean_rx_ring(struct ixgb_adapter *adapter) | |||
1017 | static int | 1023 | static int |
1018 | ixgb_set_mac(struct net_device *netdev, void *p) | 1024 | ixgb_set_mac(struct net_device *netdev, void *p) |
1019 | { | 1025 | { |
1020 | struct ixgb_adapter *adapter = netdev->priv; | 1026 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1021 | struct sockaddr *addr = p; | 1027 | struct sockaddr *addr = p; |
1022 | 1028 | ||
1023 | if(!is_valid_ether_addr(addr->sa_data)) | 1029 | if(!is_valid_ether_addr(addr->sa_data)) |
@@ -1043,7 +1049,7 @@ ixgb_set_mac(struct net_device *netdev, void *p) | |||
1043 | static void | 1049 | static void |
1044 | ixgb_set_multi(struct net_device *netdev) | 1050 | ixgb_set_multi(struct net_device *netdev) |
1045 | { | 1051 | { |
1046 | struct ixgb_adapter *adapter = netdev->priv; | 1052 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1047 | struct ixgb_hw *hw = &adapter->hw; | 1053 | struct ixgb_hw *hw = &adapter->hw; |
1048 | struct dev_mc_list *mc_ptr; | 1054 | struct dev_mc_list *mc_ptr; |
1049 | uint32_t rctl; | 1055 | uint32_t rctl; |
@@ -1371,7 +1377,7 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags) | |||
1371 | static int | 1377 | static int |
1372 | ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 1378 | ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
1373 | { | 1379 | { |
1374 | struct ixgb_adapter *adapter = netdev->priv; | 1380 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1375 | unsigned int first; | 1381 | unsigned int first; |
1376 | unsigned int tx_flags = 0; | 1382 | unsigned int tx_flags = 0; |
1377 | unsigned long flags; | 1383 | unsigned long flags; |
@@ -1425,7 +1431,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1425 | static void | 1431 | static void |
1426 | ixgb_tx_timeout(struct net_device *netdev) | 1432 | ixgb_tx_timeout(struct net_device *netdev) |
1427 | { | 1433 | { |
1428 | struct ixgb_adapter *adapter = netdev->priv; | 1434 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1429 | 1435 | ||
1430 | /* Do the reset outside of interrupt context */ | 1436 | /* Do the reset outside of interrupt context */ |
1431 | schedule_work(&adapter->tx_timeout_task); | 1437 | schedule_work(&adapter->tx_timeout_task); |
@@ -1434,7 +1440,7 @@ ixgb_tx_timeout(struct net_device *netdev) | |||
1434 | static void | 1440 | static void |
1435 | ixgb_tx_timeout_task(struct net_device *netdev) | 1441 | ixgb_tx_timeout_task(struct net_device *netdev) |
1436 | { | 1442 | { |
1437 | struct ixgb_adapter *adapter = netdev->priv; | 1443 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1438 | 1444 | ||
1439 | ixgb_down(adapter, TRUE); | 1445 | ixgb_down(adapter, TRUE); |
1440 | ixgb_up(adapter); | 1446 | ixgb_up(adapter); |
@@ -1451,7 +1457,7 @@ ixgb_tx_timeout_task(struct net_device *netdev) | |||
1451 | static struct net_device_stats * | 1457 | static struct net_device_stats * |
1452 | ixgb_get_stats(struct net_device *netdev) | 1458 | ixgb_get_stats(struct net_device *netdev) |
1453 | { | 1459 | { |
1454 | struct ixgb_adapter *adapter = netdev->priv; | 1460 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1455 | 1461 | ||
1456 | return &adapter->net_stats; | 1462 | return &adapter->net_stats; |
1457 | } | 1463 | } |
@@ -1467,7 +1473,7 @@ ixgb_get_stats(struct net_device *netdev) | |||
1467 | static int | 1473 | static int |
1468 | ixgb_change_mtu(struct net_device *netdev, int new_mtu) | 1474 | ixgb_change_mtu(struct net_device *netdev, int new_mtu) |
1469 | { | 1475 | { |
1470 | struct ixgb_adapter *adapter = netdev->priv; | 1476 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1471 | int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; | 1477 | int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; |
1472 | int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; | 1478 | int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; |
1473 | 1479 | ||
@@ -1522,7 +1528,8 @@ ixgb_update_stats(struct ixgb_adapter *adapter) | |||
1522 | 1528 | ||
1523 | multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32); | 1529 | multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32); |
1524 | /* fix up multicast stats by removing broadcasts */ | 1530 | /* fix up multicast stats by removing broadcasts */ |
1525 | multi -= bcast; | 1531 | if(multi >= bcast) |
1532 | multi -= bcast; | ||
1526 | 1533 | ||
1527 | adapter->stats.mprcl += (multi & 0xFFFFFFFF); | 1534 | adapter->stats.mprcl += (multi & 0xFFFFFFFF); |
1528 | adapter->stats.mprch += (multi >> 32); | 1535 | adapter->stats.mprch += (multi >> 32); |
@@ -1641,7 +1648,7 @@ static irqreturn_t | |||
1641 | ixgb_intr(int irq, void *data, struct pt_regs *regs) | 1648 | ixgb_intr(int irq, void *data, struct pt_regs *regs) |
1642 | { | 1649 | { |
1643 | struct net_device *netdev = data; | 1650 | struct net_device *netdev = data; |
1644 | struct ixgb_adapter *adapter = netdev->priv; | 1651 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1645 | struct ixgb_hw *hw = &adapter->hw; | 1652 | struct ixgb_hw *hw = &adapter->hw; |
1646 | uint32_t icr = IXGB_READ_REG(hw, ICR); | 1653 | uint32_t icr = IXGB_READ_REG(hw, ICR); |
1647 | #ifndef CONFIG_IXGB_NAPI | 1654 | #ifndef CONFIG_IXGB_NAPI |
@@ -1688,7 +1695,7 @@ ixgb_intr(int irq, void *data, struct pt_regs *regs) | |||
1688 | static int | 1695 | static int |
1689 | ixgb_clean(struct net_device *netdev, int *budget) | 1696 | ixgb_clean(struct net_device *netdev, int *budget) |
1690 | { | 1697 | { |
1691 | struct ixgb_adapter *adapter = netdev->priv; | 1698 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1692 | int work_to_do = min(*budget, netdev->quota); | 1699 | int work_to_do = min(*budget, netdev->quota); |
1693 | int tx_cleaned; | 1700 | int tx_cleaned; |
1694 | int work_done = 0; | 1701 | int work_done = 0; |
@@ -2017,7 +2024,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | |||
2017 | static void | 2024 | static void |
2018 | ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) | 2025 | ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) |
2019 | { | 2026 | { |
2020 | struct ixgb_adapter *adapter = netdev->priv; | 2027 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2021 | uint32_t ctrl, rctl; | 2028 | uint32_t ctrl, rctl; |
2022 | 2029 | ||
2023 | ixgb_irq_disable(adapter); | 2030 | ixgb_irq_disable(adapter); |
@@ -2055,7 +2062,7 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) | |||
2055 | static void | 2062 | static void |
2056 | ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) | 2063 | ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) |
2057 | { | 2064 | { |
2058 | struct ixgb_adapter *adapter = netdev->priv; | 2065 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2059 | uint32_t vfta, index; | 2066 | uint32_t vfta, index; |
2060 | 2067 | ||
2061 | /* add VID to filter table */ | 2068 | /* add VID to filter table */ |
@@ -2069,7 +2076,7 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) | |||
2069 | static void | 2076 | static void |
2070 | ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) | 2077 | ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) |
2071 | { | 2078 | { |
2072 | struct ixgb_adapter *adapter = netdev->priv; | 2079 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2073 | uint32_t vfta, index; | 2080 | uint32_t vfta, index; |
2074 | 2081 | ||
2075 | ixgb_irq_disable(adapter); | 2082 | ixgb_irq_disable(adapter); |
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 7fec613e1675..8423cb6875f0 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c | |||
@@ -1,5 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * sonic.c | 2 | * jazzsonic.c |
3 | * | ||
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, and (from the mac68k project) introduced | ||
7 | * dhd's support for 16-bit cards. | ||
3 | * | 8 | * |
4 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
5 | * | 10 | * |
@@ -28,8 +33,8 @@ | |||
28 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
29 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
30 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
31 | #include <linux/bitops.h> | ||
32 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | #include <linux/dma-mapping.h> | ||
33 | 38 | ||
34 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
35 | #include <asm/system.h> | 40 | #include <asm/system.h> |
@@ -44,22 +49,20 @@ static struct platform_device *jazz_sonic_device; | |||
44 | 49 | ||
45 | #define SONIC_MEM_SIZE 0x100 | 50 | #define SONIC_MEM_SIZE 0x100 |
46 | 51 | ||
47 | #define SREGS_PAD(n) u16 n; | ||
48 | |||
49 | #include "sonic.h" | 52 | #include "sonic.h" |
50 | 53 | ||
51 | /* | 54 | /* |
52 | * Macros to access SONIC registers | 55 | * Macros to access SONIC registers |
53 | */ | 56 | */ |
54 | #define SONIC_READ(reg) (*((volatile unsigned int *)base_addr+reg)) | 57 | #define SONIC_READ(reg) (*((volatile unsigned int *)dev->base_addr+reg)) |
55 | 58 | ||
56 | #define SONIC_WRITE(reg,val) \ | 59 | #define SONIC_WRITE(reg,val) \ |
57 | do { \ | 60 | do { \ |
58 | *((volatile unsigned int *)base_addr+(reg)) = (val); \ | 61 | *((volatile unsigned int *)dev->base_addr+(reg)) = (val); \ |
59 | } while (0) | 62 | } while (0) |
60 | 63 | ||
61 | 64 | ||
62 | /* use 0 for production, 1 for verification, >2 for debug */ | 65 | /* use 0 for production, 1 for verification, >1 for debug */ |
63 | #ifdef SONIC_DEBUG | 66 | #ifdef SONIC_DEBUG |
64 | static unsigned int sonic_debug = SONIC_DEBUG; | 67 | static unsigned int sonic_debug = SONIC_DEBUG; |
65 | #else | 68 | #else |
@@ -85,18 +88,18 @@ static unsigned short known_revisions[] = | |||
85 | 0xffff /* end of list */ | 88 | 0xffff /* end of list */ |
86 | }; | 89 | }; |
87 | 90 | ||
88 | static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | 91 | static int __init sonic_probe1(struct net_device *dev) |
89 | unsigned int irq) | ||
90 | { | 92 | { |
91 | static unsigned version_printed; | 93 | static unsigned version_printed; |
92 | unsigned int silicon_revision; | 94 | unsigned int silicon_revision; |
93 | unsigned int val; | 95 | unsigned int val; |
94 | struct sonic_local *lp; | 96 | struct sonic_local *lp = netdev_priv(dev); |
95 | int err = -ENODEV; | 97 | int err = -ENODEV; |
96 | int i; | 98 | int i; |
97 | 99 | ||
98 | if (!request_mem_region(base_addr, SONIC_MEM_SIZE, jazz_sonic_string)) | 100 | if (!request_mem_region(dev->base_addr, SONIC_MEM_SIZE, jazz_sonic_string)) |
99 | return -EBUSY; | 101 | return -EBUSY; |
102 | |||
100 | /* | 103 | /* |
101 | * get the Silicon Revision ID. If this is one of the known | 104 | * get the Silicon Revision ID. If this is one of the known |
102 | * one assume that we found a SONIC ethernet controller at | 105 | * one assume that we found a SONIC ethernet controller at |
@@ -120,11 +123,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | |||
120 | if (sonic_debug && version_printed++ == 0) | 123 | if (sonic_debug && version_printed++ == 0) |
121 | printk(version); | 124 | printk(version); |
122 | 125 | ||
123 | printk("%s: Sonic ethernet found at 0x%08lx, ", dev->name, base_addr); | 126 | printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr); |
124 | |||
125 | /* Fill in the 'dev' fields. */ | ||
126 | dev->base_addr = base_addr; | ||
127 | dev->irq = irq; | ||
128 | 127 | ||
129 | /* | 128 | /* |
130 | * Put the sonic into software reset, then | 129 | * Put the sonic into software reset, then |
@@ -138,84 +137,44 @@ static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | |||
138 | dev->dev_addr[i*2+1] = val >> 8; | 137 | dev->dev_addr[i*2+1] = val >> 8; |
139 | } | 138 | } |
140 | 139 | ||
141 | printk("HW Address "); | ||
142 | for (i = 0; i < 6; i++) { | ||
143 | printk("%2.2x", dev->dev_addr[i]); | ||
144 | if (i<5) | ||
145 | printk(":"); | ||
146 | } | ||
147 | |||
148 | printk(" IRQ %d\n", irq); | ||
149 | |||
150 | err = -ENOMEM; | 140 | err = -ENOMEM; |
151 | 141 | ||
152 | /* Initialize the device structure. */ | 142 | /* Initialize the device structure. */ |
153 | if (dev->priv == NULL) { | ||
154 | /* | ||
155 | * the memory be located in the same 64kb segment | ||
156 | */ | ||
157 | lp = NULL; | ||
158 | i = 0; | ||
159 | do { | ||
160 | lp = kmalloc(sizeof(*lp), GFP_KERNEL); | ||
161 | if ((unsigned long) lp >> 16 | ||
162 | != ((unsigned long)lp + sizeof(*lp) ) >> 16) { | ||
163 | /* FIXME, free the memory later */ | ||
164 | kfree(lp); | ||
165 | lp = NULL; | ||
166 | } | ||
167 | } while (lp == NULL && i++ < 20); | ||
168 | |||
169 | if (lp == NULL) { | ||
170 | printk("%s: couldn't allocate memory for descriptors\n", | ||
171 | dev->name); | ||
172 | goto out; | ||
173 | } | ||
174 | 143 | ||
175 | memset(lp, 0, sizeof(struct sonic_local)); | 144 | lp->dma_bitmode = SONIC_BITMODE32; |
176 | |||
177 | /* get the virtual dma address */ | ||
178 | lp->cda_laddr = vdma_alloc(CPHYSADDR(lp),sizeof(*lp)); | ||
179 | if (lp->cda_laddr == ~0UL) { | ||
180 | printk("%s: couldn't get DMA page entry for " | ||
181 | "descriptors\n", dev->name); | ||
182 | goto out1; | ||
183 | } | ||
184 | |||
185 | lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda); | ||
186 | lp->rra_laddr = lp->tda_laddr + sizeof (lp->tda); | ||
187 | lp->rda_laddr = lp->rra_laddr + sizeof (lp->rra); | ||
188 | |||
189 | /* allocate receive buffer area */ | ||
190 | /* FIXME, maybe we should use skbs */ | ||
191 | lp->rba = kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL); | ||
192 | if (!lp->rba) { | ||
193 | printk("%s: couldn't allocate receive buffers\n", | ||
194 | dev->name); | ||
195 | goto out2; | ||
196 | } | ||
197 | 145 | ||
198 | /* get virtual dma address */ | 146 | /* Allocate the entire chunk of memory for the descriptors. |
199 | lp->rba_laddr = vdma_alloc(CPHYSADDR(lp->rba), | 147 | Note that this cannot cross a 64K boundary. */ |
200 | SONIC_NUM_RRS * SONIC_RBSIZE); | 148 | if ((lp->descriptors = dma_alloc_coherent(lp->device, |
201 | if (lp->rba_laddr == ~0UL) { | 149 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
202 | printk("%s: couldn't get DMA page entry for receive " | 150 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { |
203 | "buffers\n",dev->name); | 151 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id); |
204 | goto out3; | 152 | goto out; |
205 | } | ||
206 | |||
207 | /* now convert pointer to KSEG1 pointer */ | ||
208 | lp->rba = (char *)KSEG1ADDR(lp->rba); | ||
209 | flush_cache_all(); | ||
210 | dev->priv = (struct sonic_local *)KSEG1ADDR(lp); | ||
211 | } | 153 | } |
212 | 154 | ||
213 | lp = (struct sonic_local *)dev->priv; | 155 | /* Now set up the pointers to point to the appropriate places */ |
156 | lp->cda = lp->descriptors; | ||
157 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA | ||
158 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
159 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
160 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
161 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
162 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
163 | |||
164 | lp->cda_laddr = lp->descriptors_laddr; | ||
165 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | ||
166 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
167 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
168 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
169 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
170 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
171 | |||
214 | dev->open = sonic_open; | 172 | dev->open = sonic_open; |
215 | dev->stop = sonic_close; | 173 | dev->stop = sonic_close; |
216 | dev->hard_start_xmit = sonic_send_packet; | 174 | dev->hard_start_xmit = sonic_send_packet; |
217 | dev->get_stats = sonic_get_stats; | 175 | dev->get_stats = sonic_get_stats; |
218 | dev->set_multicast_list = &sonic_multicast_list; | 176 | dev->set_multicast_list = &sonic_multicast_list; |
177 | dev->tx_timeout = sonic_tx_timeout; | ||
219 | dev->watchdog_timeo = TX_TIMEOUT; | 178 | dev->watchdog_timeo = TX_TIMEOUT; |
220 | 179 | ||
221 | /* | 180 | /* |
@@ -226,14 +185,8 @@ static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | |||
226 | SONIC_WRITE(SONIC_MPT,0xffff); | 185 | SONIC_WRITE(SONIC_MPT,0xffff); |
227 | 186 | ||
228 | return 0; | 187 | return 0; |
229 | out3: | ||
230 | kfree(lp->rba); | ||
231 | out2: | ||
232 | vdma_free(lp->cda_laddr); | ||
233 | out1: | ||
234 | kfree(lp); | ||
235 | out: | 188 | out: |
236 | release_region(base_addr, SONIC_MEM_SIZE); | 189 | release_region(dev->base_addr, SONIC_MEM_SIZE); |
237 | return err; | 190 | return err; |
238 | } | 191 | } |
239 | 192 | ||
@@ -245,7 +198,6 @@ static int __init jazz_sonic_probe(struct device *device) | |||
245 | { | 198 | { |
246 | struct net_device *dev; | 199 | struct net_device *dev; |
247 | struct sonic_local *lp; | 200 | struct sonic_local *lp; |
248 | unsigned long base_addr; | ||
249 | int err = 0; | 201 | int err = 0; |
250 | int i; | 202 | int i; |
251 | 203 | ||
@@ -255,21 +207,26 @@ static int __init jazz_sonic_probe(struct device *device) | |||
255 | if (mips_machgroup != MACH_GROUP_JAZZ) | 207 | if (mips_machgroup != MACH_GROUP_JAZZ) |
256 | return -ENODEV; | 208 | return -ENODEV; |
257 | 209 | ||
258 | dev = alloc_etherdev(0); | 210 | dev = alloc_etherdev(sizeof(struct sonic_local)); |
259 | if (!dev) | 211 | if (!dev) |
260 | return -ENOMEM; | 212 | return -ENOMEM; |
261 | 213 | ||
214 | lp = netdev_priv(dev); | ||
215 | lp->device = device; | ||
216 | SET_NETDEV_DEV(dev, device); | ||
217 | SET_MODULE_OWNER(dev); | ||
218 | |||
262 | netdev_boot_setup_check(dev); | 219 | netdev_boot_setup_check(dev); |
263 | base_addr = dev->base_addr; | ||
264 | 220 | ||
265 | if (base_addr >= KSEG0) { /* Check a single specified location. */ | 221 | if (dev->base_addr >= KSEG0) { /* Check a single specified location. */ |
266 | err = sonic_probe1(dev, base_addr, dev->irq); | 222 | err = sonic_probe1(dev); |
267 | } else if (base_addr != 0) { /* Don't probe at all. */ | 223 | } else if (dev->base_addr != 0) { /* Don't probe at all. */ |
268 | err = -ENXIO; | 224 | err = -ENXIO; |
269 | } else { | 225 | } else { |
270 | for (i = 0; sonic_portlist[i].port; i++) { | 226 | for (i = 0; sonic_portlist[i].port; i++) { |
271 | int io = sonic_portlist[i].port; | 227 | dev->base_addr = sonic_portlist[i].port; |
272 | if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0) | 228 | dev->irq = sonic_portlist[i].irq; |
229 | if (sonic_probe1(dev) == 0) | ||
273 | break; | 230 | break; |
274 | } | 231 | } |
275 | if (!sonic_portlist[i].port) | 232 | if (!sonic_portlist[i].port) |
@@ -281,14 +238,17 @@ static int __init jazz_sonic_probe(struct device *device) | |||
281 | if (err) | 238 | if (err) |
282 | goto out1; | 239 | goto out1; |
283 | 240 | ||
241 | printk("%s: MAC ", dev->name); | ||
242 | for (i = 0; i < 6; i++) { | ||
243 | printk("%2.2x", dev->dev_addr[i]); | ||
244 | if (i < 5) | ||
245 | printk(":"); | ||
246 | } | ||
247 | printk(" IRQ %d\n", dev->irq); | ||
248 | |||
284 | return 0; | 249 | return 0; |
285 | 250 | ||
286 | out1: | 251 | out1: |
287 | lp = dev->priv; | ||
288 | vdma_free(lp->rba_laddr); | ||
289 | kfree(lp->rba); | ||
290 | vdma_free(lp->cda_laddr); | ||
291 | kfree(lp); | ||
292 | release_region(dev->base_addr, SONIC_MEM_SIZE); | 252 | release_region(dev->base_addr, SONIC_MEM_SIZE); |
293 | out: | 253 | out: |
294 | free_netdev(dev); | 254 | free_netdev(dev); |
@@ -296,21 +256,22 @@ out: | |||
296 | return err; | 256 | return err; |
297 | } | 257 | } |
298 | 258 | ||
299 | /* | 259 | MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); |
300 | * SONIC uses a normal IRQ | 260 | module_param(sonic_debug, int, 0); |
301 | */ | 261 | MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); |
302 | #define sonic_request_irq request_irq | ||
303 | #define sonic_free_irq free_irq | ||
304 | 262 | ||
305 | #define sonic_chiptomem(x) KSEG1ADDR(vdma_log2phys(x)) | 263 | #define SONIC_IRQ_FLAG SA_INTERRUPT |
306 | 264 | ||
307 | #include "sonic.c" | 265 | #include "sonic.c" |
308 | 266 | ||
309 | static int __devexit jazz_sonic_device_remove (struct device *device) | 267 | static int __devexit jazz_sonic_device_remove (struct device *device) |
310 | { | 268 | { |
311 | struct net_device *dev = device->driver_data; | 269 | struct net_device *dev = device->driver_data; |
270 | struct sonic_local* lp = netdev_priv(dev); | ||
312 | 271 | ||
313 | unregister_netdev (dev); | 272 | unregister_netdev (dev); |
273 | dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
274 | lp->descriptors, lp->descriptors_laddr); | ||
314 | release_region (dev->base_addr, SONIC_MEM_SIZE); | 275 | release_region (dev->base_addr, SONIC_MEM_SIZE); |
315 | free_netdev (dev); | 276 | free_netdev (dev); |
316 | 277 | ||
@@ -323,7 +284,7 @@ static struct device_driver jazz_sonic_driver = { | |||
323 | .probe = jazz_sonic_probe, | 284 | .probe = jazz_sonic_probe, |
324 | .remove = __devexit_p(jazz_sonic_device_remove), | 285 | .remove = __devexit_p(jazz_sonic_device_remove), |
325 | }; | 286 | }; |
326 | 287 | ||
327 | static void jazz_sonic_platform_release (struct device *device) | 288 | static void jazz_sonic_platform_release (struct device *device) |
328 | { | 289 | { |
329 | struct platform_device *pldev; | 290 | struct platform_device *pldev; |
@@ -336,10 +297,11 @@ static void jazz_sonic_platform_release (struct device *device) | |||
336 | static int __init jazz_sonic_init_module(void) | 297 | static int __init jazz_sonic_init_module(void) |
337 | { | 298 | { |
338 | struct platform_device *pldev; | 299 | struct platform_device *pldev; |
300 | int err; | ||
339 | 301 | ||
340 | if (driver_register(&jazz_sonic_driver)) { | 302 | if ((err = driver_register(&jazz_sonic_driver))) { |
341 | printk(KERN_ERR "Driver registration failed\n"); | 303 | printk(KERN_ERR "Driver registration failed\n"); |
342 | return -ENOMEM; | 304 | return err; |
343 | } | 305 | } |
344 | 306 | ||
345 | jazz_sonic_device = NULL; | 307 | jazz_sonic_device = NULL; |
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 1f61f0cc95d8..690a1aae0b34 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -68,6 +68,7 @@ static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); | |||
68 | * of largesending device modulo TCP checksum, which is ignored for loopback. | 68 | * of largesending device modulo TCP checksum, which is ignored for loopback. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | #ifdef LOOPBACK_TSO | ||
71 | static void emulate_large_send_offload(struct sk_buff *skb) | 72 | static void emulate_large_send_offload(struct sk_buff *skb) |
72 | { | 73 | { |
73 | struct iphdr *iph = skb->nh.iph; | 74 | struct iphdr *iph = skb->nh.iph; |
@@ -119,6 +120,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) | |||
119 | 120 | ||
120 | dev_kfree_skb(skb); | 121 | dev_kfree_skb(skb); |
121 | } | 122 | } |
123 | #endif /* LOOPBACK_TSO */ | ||
122 | 124 | ||
123 | /* | 125 | /* |
124 | * The higher levels take care of making this non-reentrant (it's | 126 | * The higher levels take care of making this non-reentrant (it's |
@@ -130,12 +132,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
130 | 132 | ||
131 | skb_orphan(skb); | 133 | skb_orphan(skb); |
132 | 134 | ||
133 | skb->protocol=eth_type_trans(skb,dev); | 135 | skb->protocol = eth_type_trans(skb,dev); |
134 | skb->dev=dev; | 136 | skb->dev = dev; |
135 | #ifndef LOOPBACK_MUST_CHECKSUM | 137 | #ifndef LOOPBACK_MUST_CHECKSUM |
136 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 138 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
137 | #endif | 139 | #endif |
138 | 140 | ||
141 | #ifdef LOOPBACK_TSO | ||
139 | if (skb_shinfo(skb)->tso_size) { | 142 | if (skb_shinfo(skb)->tso_size) { |
140 | BUG_ON(skb->protocol != htons(ETH_P_IP)); | 143 | BUG_ON(skb->protocol != htons(ETH_P_IP)); |
141 | BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); | 144 | BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); |
@@ -143,14 +146,14 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
143 | emulate_large_send_offload(skb); | 146 | emulate_large_send_offload(skb); |
144 | return 0; | 147 | return 0; |
145 | } | 148 | } |
146 | 149 | #endif | |
147 | dev->last_rx = jiffies; | 150 | dev->last_rx = jiffies; |
148 | 151 | ||
149 | lb_stats = &per_cpu(loopback_stats, get_cpu()); | 152 | lb_stats = &per_cpu(loopback_stats, get_cpu()); |
150 | lb_stats->rx_bytes += skb->len; | 153 | lb_stats->rx_bytes += skb->len; |
151 | lb_stats->tx_bytes += skb->len; | 154 | lb_stats->tx_bytes = lb_stats->rx_bytes; |
152 | lb_stats->rx_packets++; | 155 | lb_stats->rx_packets++; |
153 | lb_stats->tx_packets++; | 156 | lb_stats->tx_packets = lb_stats->rx_packets; |
154 | put_cpu(); | 157 | put_cpu(); |
155 | 158 | ||
156 | netif_rx(skb); | 159 | netif_rx(skb); |
@@ -208,9 +211,12 @@ struct net_device loopback_dev = { | |||
208 | .type = ARPHRD_LOOPBACK, /* 0x0001*/ | 211 | .type = ARPHRD_LOOPBACK, /* 0x0001*/ |
209 | .rebuild_header = eth_rebuild_header, | 212 | .rebuild_header = eth_rebuild_header, |
210 | .flags = IFF_LOOPBACK, | 213 | .flags = IFF_LOOPBACK, |
211 | .features = NETIF_F_SG|NETIF_F_FRAGLIST | 214 | .features = NETIF_F_SG | NETIF_F_FRAGLIST |
212 | |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA | 215 | #ifdef LOOPBACK_TSO |
213 | |NETIF_F_LLTX, | 216 | | NETIF_F_TSO |
217 | #endif | ||
218 | | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | ||
219 | | NETIF_F_LLTX, | ||
214 | .ethtool_ops = &loopback_ethtool_ops, | 220 | .ethtool_ops = &loopback_ethtool_ops, |
215 | }; | 221 | }; |
216 | 222 | ||
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index be28c65de729..405e18365ede 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -1,6 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * macsonic.c | 2 | * macsonic.c |
3 | * | 3 | * |
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, converted to unified driver model, made it work as | ||
7 | * a module again, and from the mac68k project, introduced more 32-bit cards | ||
8 | * and dhd's support for 16-bit cards. | ||
9 | * | ||
4 | * (C) 1998 Alan Cox | 10 | * (C) 1998 Alan Cox |
5 | * | 11 | * |
6 | * Debugging Andreas Ehliar, Michael Schmitz | 12 | * Debugging Andreas Ehliar, Michael Schmitz |
@@ -26,8 +32,8 @@ | |||
26 | */ | 32 | */ |
27 | 33 | ||
28 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/module.h> | ||
29 | #include <linux/types.h> | 36 | #include <linux/types.h> |
30 | #include <linux/ctype.h> | ||
31 | #include <linux/fcntl.h> | 37 | #include <linux/fcntl.h> |
32 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
33 | #include <linux/init.h> | 39 | #include <linux/init.h> |
@@ -41,8 +47,8 @@ | |||
41 | #include <linux/netdevice.h> | 47 | #include <linux/netdevice.h> |
42 | #include <linux/etherdevice.h> | 48 | #include <linux/etherdevice.h> |
43 | #include <linux/skbuff.h> | 49 | #include <linux/skbuff.h> |
44 | #include <linux/module.h> | 50 | #include <linux/device.h> |
45 | #include <linux/bitops.h> | 51 | #include <linux/dma-mapping.h> |
46 | 52 | ||
47 | #include <asm/bootinfo.h> | 53 | #include <asm/bootinfo.h> |
48 | #include <asm/system.h> | 54 | #include <asm/system.h> |
@@ -54,25 +60,28 @@ | |||
54 | #include <asm/macints.h> | 60 | #include <asm/macints.h> |
55 | #include <asm/mac_via.h> | 61 | #include <asm/mac_via.h> |
56 | 62 | ||
57 | #define SREGS_PAD(n) u16 n; | 63 | static char mac_sonic_string[] = "macsonic"; |
64 | static struct platform_device *mac_sonic_device; | ||
58 | 65 | ||
59 | #include "sonic.h" | 66 | #include "sonic.h" |
60 | 67 | ||
61 | #define SONIC_READ(reg) \ | 68 | /* These should basically be bus-size and endian independent (since |
62 | nubus_readl(base_addr+(reg)) | 69 | the SONIC is at least smart enough that it uses the same endianness |
63 | #define SONIC_WRITE(reg,val) \ | 70 | as the host, unlike certain less enlightened Macintosh NICs) */ |
64 | nubus_writel((val), base_addr+(reg)) | 71 | #define SONIC_READ(reg) (nubus_readw(dev->base_addr + (reg * 4) \ |
65 | #define sonic_read(dev, reg) \ | 72 | + lp->reg_offset)) |
66 | nubus_readl((dev)->base_addr+(reg)) | 73 | #define SONIC_WRITE(reg,val) (nubus_writew(val, dev->base_addr + (reg * 4) \ |
67 | #define sonic_write(dev, reg, val) \ | 74 | + lp->reg_offset)) |
68 | nubus_writel((val), (dev)->base_addr+(reg)) | 75 | |
69 | 76 | /* use 0 for production, 1 for verification, >1 for debug */ | |
77 | #ifdef SONIC_DEBUG | ||
78 | static unsigned int sonic_debug = SONIC_DEBUG; | ||
79 | #else | ||
80 | static unsigned int sonic_debug = 1; | ||
81 | #endif | ||
70 | 82 | ||
71 | static int sonic_debug; | ||
72 | static int sonic_version_printed; | 83 | static int sonic_version_printed; |
73 | 84 | ||
74 | static int reg_offset; | ||
75 | |||
76 | extern int mac_onboard_sonic_probe(struct net_device* dev); | 85 | extern int mac_onboard_sonic_probe(struct net_device* dev); |
77 | extern int mac_nubus_sonic_probe(struct net_device* dev); | 86 | extern int mac_nubus_sonic_probe(struct net_device* dev); |
78 | 87 | ||
@@ -108,40 +117,6 @@ enum macsonic_type { | |||
108 | 117 | ||
109 | #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr) | 118 | #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr) |
110 | 119 | ||
111 | struct net_device * __init macsonic_probe(int unit) | ||
112 | { | ||
113 | struct net_device *dev = alloc_etherdev(0); | ||
114 | int err; | ||
115 | |||
116 | if (!dev) | ||
117 | return ERR_PTR(-ENOMEM); | ||
118 | |||
119 | if (unit >= 0) | ||
120 | sprintf(dev->name, "eth%d", unit); | ||
121 | |||
122 | SET_MODULE_OWNER(dev); | ||
123 | |||
124 | /* This will catch fatal stuff like -ENOMEM as well as success */ | ||
125 | err = mac_onboard_sonic_probe(dev); | ||
126 | if (err == 0) | ||
127 | goto found; | ||
128 | if (err != -ENODEV) | ||
129 | goto out; | ||
130 | err = mac_nubus_sonic_probe(dev); | ||
131 | if (err) | ||
132 | goto out; | ||
133 | found: | ||
134 | err = register_netdev(dev); | ||
135 | if (err) | ||
136 | goto out1; | ||
137 | return dev; | ||
138 | out1: | ||
139 | kfree(dev->priv); | ||
140 | out: | ||
141 | free_netdev(dev); | ||
142 | return ERR_PTR(err); | ||
143 | } | ||
144 | |||
145 | /* | 120 | /* |
146 | * For reversing the PROM address | 121 | * For reversing the PROM address |
147 | */ | 122 | */ |
@@ -160,103 +135,55 @@ static inline void bit_reverse_addr(unsigned char addr[6]) | |||
160 | 135 | ||
161 | int __init macsonic_init(struct net_device* dev) | 136 | int __init macsonic_init(struct net_device* dev) |
162 | { | 137 | { |
163 | struct sonic_local* lp = NULL; | 138 | struct sonic_local* lp = netdev_priv(dev); |
164 | int i; | ||
165 | 139 | ||
166 | /* Allocate the entire chunk of memory for the descriptors. | 140 | /* Allocate the entire chunk of memory for the descriptors. |
167 | Note that this cannot cross a 64K boundary. */ | 141 | Note that this cannot cross a 64K boundary. */ |
168 | for (i = 0; i < 20; i++) { | 142 | if ((lp->descriptors = dma_alloc_coherent(lp->device, |
169 | unsigned long desc_base, desc_top; | 143 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
170 | if((lp = kmalloc(sizeof(struct sonic_local), GFP_KERNEL | GFP_DMA)) == NULL) { | 144 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { |
171 | printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name); | 145 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id); |
172 | return -ENOMEM; | ||
173 | } | ||
174 | |||
175 | desc_base = (unsigned long) lp; | ||
176 | desc_top = desc_base + sizeof(struct sonic_local); | ||
177 | if ((desc_top & 0xffff) >= (desc_base & 0xffff)) | ||
178 | break; | ||
179 | /* Hmm. try again (FIXME: does this actually work?) */ | ||
180 | kfree(lp); | ||
181 | printk(KERN_DEBUG | ||
182 | "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n", | ||
183 | dev->name, desc_base, desc_top); | ||
184 | } | ||
185 | |||
186 | if (lp == NULL) { | ||
187 | printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n", | ||
188 | dev->name); | ||
189 | return -ENOMEM; | 146 | return -ENOMEM; |
190 | } | 147 | } |
191 | |||
192 | dev->priv = lp; | ||
193 | |||
194 | #if 0 | ||
195 | /* this code is only here as a curiousity... mainly, where the | ||
196 | fuck did SONIC_BUS_SCALE come from, and what was it supposed | ||
197 | to do? the normal allocation works great for 32 bit stuffs.. */ | ||
198 | 148 | ||
199 | /* Now set up the pointers to point to the appropriate places */ | 149 | /* Now set up the pointers to point to the appropriate places */ |
200 | lp->cda = lp->sonic_desc; | 150 | lp->cda = lp->descriptors; |
201 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA * SONIC_BUS_SCALE(lp->dma_bitmode)); | 151 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA |
152 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
202 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | 153 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS |
203 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | 154 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
204 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | 155 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS |
205 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | 156 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
206 | 157 | ||
207 | #endif | 158 | lp->cda_laddr = lp->descriptors_laddr; |
208 | 159 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | |
209 | memset(lp, 0, sizeof(struct sonic_local)); | 160 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
210 | 161 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | |
211 | lp->cda_laddr = (unsigned int)&(lp->cda); | 162 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
212 | lp->tda_laddr = (unsigned int)lp->tda; | 163 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS |
213 | lp->rra_laddr = (unsigned int)lp->rra; | 164 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
214 | lp->rda_laddr = (unsigned int)lp->rda; | ||
215 | |||
216 | /* FIXME, maybe we should use skbs */ | ||
217 | if ((lp->rba = (char *) | ||
218 | kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) { | ||
219 | printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name); | ||
220 | dev->priv = NULL; | ||
221 | kfree(lp); | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | |||
225 | lp->rba_laddr = (unsigned int)lp->rba; | ||
226 | |||
227 | { | ||
228 | int rs, ds; | ||
229 | |||
230 | /* almost always 12*4096, but let's not take chances */ | ||
231 | rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096; | ||
232 | /* almost always under a page, but let's not take chances */ | ||
233 | ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096; | ||
234 | kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER); | ||
235 | kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER); | ||
236 | } | ||
237 | |||
238 | #if 0 | ||
239 | flush_cache_all(); | ||
240 | #endif | ||
241 | 165 | ||
242 | dev->open = sonic_open; | 166 | dev->open = sonic_open; |
243 | dev->stop = sonic_close; | 167 | dev->stop = sonic_close; |
244 | dev->hard_start_xmit = sonic_send_packet; | 168 | dev->hard_start_xmit = sonic_send_packet; |
245 | dev->get_stats = sonic_get_stats; | 169 | dev->get_stats = sonic_get_stats; |
246 | dev->set_multicast_list = &sonic_multicast_list; | 170 | dev->set_multicast_list = &sonic_multicast_list; |
171 | dev->tx_timeout = sonic_tx_timeout; | ||
172 | dev->watchdog_timeo = TX_TIMEOUT; | ||
247 | 173 | ||
248 | /* | 174 | /* |
249 | * clear tally counter | 175 | * clear tally counter |
250 | */ | 176 | */ |
251 | sonic_write(dev, SONIC_CRCT, 0xffff); | 177 | SONIC_WRITE(SONIC_CRCT, 0xffff); |
252 | sonic_write(dev, SONIC_FAET, 0xffff); | 178 | SONIC_WRITE(SONIC_FAET, 0xffff); |
253 | sonic_write(dev, SONIC_MPT, 0xffff); | 179 | SONIC_WRITE(SONIC_MPT, 0xffff); |
254 | 180 | ||
255 | return 0; | 181 | return 0; |
256 | } | 182 | } |
257 | 183 | ||
258 | int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | 184 | int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) |
259 | { | 185 | { |
186 | struct sonic_local *lp = netdev_priv(dev); | ||
260 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; | 187 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; |
261 | int i; | 188 | int i; |
262 | 189 | ||
@@ -270,6 +197,7 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | |||
270 | why this is so. */ | 197 | why this is so. */ |
271 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && | 198 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && |
272 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && | 199 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && |
200 | memcmp(dev->dev_addr, "\x00\x80\x19", 3) && | ||
273 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) | 201 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) |
274 | bit_reverse_addr(dev->dev_addr); | 202 | bit_reverse_addr(dev->dev_addr); |
275 | else | 203 | else |
@@ -281,22 +209,23 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | |||
281 | the card... */ | 209 | the card... */ |
282 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && | 210 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && |
283 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && | 211 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && |
212 | memcmp(dev->dev_addr, "\x00\x80\x19", 3) && | ||
284 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) | 213 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) |
285 | { | 214 | { |
286 | unsigned short val; | 215 | unsigned short val; |
287 | 216 | ||
288 | printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n"); | 217 | printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n"); |
289 | 218 | ||
290 | sonic_write(dev, SONIC_CMD, SONIC_CR_RST); | 219 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
291 | sonic_write(dev, SONIC_CEP, 15); | 220 | SONIC_WRITE(SONIC_CEP, 15); |
292 | 221 | ||
293 | val = sonic_read(dev, SONIC_CAP2); | 222 | val = SONIC_READ(SONIC_CAP2); |
294 | dev->dev_addr[5] = val >> 8; | 223 | dev->dev_addr[5] = val >> 8; |
295 | dev->dev_addr[4] = val & 0xff; | 224 | dev->dev_addr[4] = val & 0xff; |
296 | val = sonic_read(dev, SONIC_CAP1); | 225 | val = SONIC_READ(SONIC_CAP1); |
297 | dev->dev_addr[3] = val >> 8; | 226 | dev->dev_addr[3] = val >> 8; |
298 | dev->dev_addr[2] = val & 0xff; | 227 | dev->dev_addr[2] = val & 0xff; |
299 | val = sonic_read(dev, SONIC_CAP0); | 228 | val = SONIC_READ(SONIC_CAP0); |
300 | dev->dev_addr[1] = val >> 8; | 229 | dev->dev_addr[1] = val >> 8; |
301 | dev->dev_addr[0] = val & 0xff; | 230 | dev->dev_addr[0] = val & 0xff; |
302 | 231 | ||
@@ -311,6 +240,7 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | |||
311 | 240 | ||
312 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && | 241 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && |
313 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && | 242 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && |
243 | memcmp(dev->dev_addr, "\x00\x80\x19", 3) && | ||
314 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) | 244 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) |
315 | { | 245 | { |
316 | /* | 246 | /* |
@@ -325,8 +255,9 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
325 | { | 255 | { |
326 | /* Bwahahaha */ | 256 | /* Bwahahaha */ |
327 | static int once_is_more_than_enough; | 257 | static int once_is_more_than_enough; |
328 | int i; | 258 | struct sonic_local* lp = netdev_priv(dev); |
329 | int dma_bitmode; | 259 | int sr; |
260 | int commslot = 0; | ||
330 | 261 | ||
331 | if (once_is_more_than_enough) | 262 | if (once_is_more_than_enough) |
332 | return -ENODEV; | 263 | return -ENODEV; |
@@ -335,20 +266,18 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
335 | if (!MACH_IS_MAC) | 266 | if (!MACH_IS_MAC) |
336 | return -ENODEV; | 267 | return -ENODEV; |
337 | 268 | ||
338 | printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. "); | ||
339 | |||
340 | if (macintosh_config->ether_type != MAC_ETHER_SONIC) | 269 | if (macintosh_config->ether_type != MAC_ETHER_SONIC) |
341 | { | ||
342 | printk("none.\n"); | ||
343 | return -ENODEV; | 270 | return -ENODEV; |
344 | } | 271 | |
345 | 272 | printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. "); | |
273 | |||
346 | /* Bogus probing, on the models which may or may not have | 274 | /* Bogus probing, on the models which may or may not have |
347 | Ethernet (BTW, the Ethernet *is* always at the same | 275 | Ethernet (BTW, the Ethernet *is* always at the same |
348 | address, and nothing else lives there, at least if Apple's | 276 | address, and nothing else lives there, at least if Apple's |
349 | documentation is to be believed) */ | 277 | documentation is to be believed) */ |
350 | if (macintosh_config->ident == MAC_MODEL_Q630 || | 278 | if (macintosh_config->ident == MAC_MODEL_Q630 || |
351 | macintosh_config->ident == MAC_MODEL_P588 || | 279 | macintosh_config->ident == MAC_MODEL_P588 || |
280 | macintosh_config->ident == MAC_MODEL_P575 || | ||
352 | macintosh_config->ident == MAC_MODEL_C610) { | 281 | macintosh_config->ident == MAC_MODEL_C610) { |
353 | unsigned long flags; | 282 | unsigned long flags; |
354 | int card_present; | 283 | int card_present; |
@@ -361,13 +290,13 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
361 | printk("none.\n"); | 290 | printk("none.\n"); |
362 | return -ENODEV; | 291 | return -ENODEV; |
363 | } | 292 | } |
293 | commslot = 1; | ||
364 | } | 294 | } |
365 | 295 | ||
366 | printk("yes\n"); | 296 | printk("yes\n"); |
367 | 297 | ||
368 | /* Danger! My arms are flailing wildly! You *must* set this | 298 | /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset |
369 | before using sonic_read() */ | 299 | * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ |
370 | |||
371 | dev->base_addr = ONBOARD_SONIC_REGISTERS; | 300 | dev->base_addr = ONBOARD_SONIC_REGISTERS; |
372 | if (via_alt_mapping) | 301 | if (via_alt_mapping) |
373 | dev->irq = IRQ_AUTO_3; | 302 | dev->irq = IRQ_AUTO_3; |
@@ -379,84 +308,66 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
379 | sonic_version_printed = 1; | 308 | sonic_version_printed = 1; |
380 | } | 309 | } |
381 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", | 310 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", |
382 | dev->name, dev->base_addr); | 311 | lp->device->bus_id, dev->base_addr); |
383 | |||
384 | /* Now do a song and dance routine in an attempt to determine | ||
385 | the bus width */ | ||
386 | 312 | ||
387 | /* The PowerBook's SONIC is 16 bit always. */ | 313 | /* The PowerBook's SONIC is 16 bit always. */ |
388 | if (macintosh_config->ident == MAC_MODEL_PB520) { | 314 | if (macintosh_config->ident == MAC_MODEL_PB520) { |
389 | reg_offset = 0; | 315 | lp->reg_offset = 0; |
390 | dma_bitmode = 0; | 316 | lp->dma_bitmode = SONIC_BITMODE16; |
391 | } else if (macintosh_config->ident == MAC_MODEL_C610) { | 317 | sr = SONIC_READ(SONIC_SR); |
392 | reg_offset = 0; | 318 | } else if (commslot) { |
393 | dma_bitmode = 1; | ||
394 | } else { | ||
395 | /* Some of the comm-slot cards are 16 bit. But some | 319 | /* Some of the comm-slot cards are 16 bit. But some |
396 | of them are not. The 32-bit cards use offset 2 and | 320 | of them are not. The 32-bit cards use offset 2 and |
397 | pad with zeroes or sometimes ones (I think...) | 321 | have known revisions, we try reading the revision |
398 | Therefore, if we try offset 0 and get a silicon | 322 | register at offset 2, if we don't get a known revision |
399 | revision of 0, we assume 16 bit. */ | 323 | we assume 16 bit at offset 0. */ |
400 | int sr; | 324 | lp->reg_offset = 2; |
401 | 325 | lp->dma_bitmode = SONIC_BITMODE16; | |
402 | /* Technically this is not necessary since we zeroed | 326 | |
403 | it above */ | 327 | sr = SONIC_READ(SONIC_SR); |
404 | reg_offset = 0; | 328 | if (sr == 0x0004 || sr == 0x0006 || sr == 0x0100 || sr == 0x0101) |
405 | dma_bitmode = 0; | 329 | /* 83932 is 0x0004 or 0x0006, 83934 is 0x0100 or 0x0101 */ |
406 | sr = sonic_read(dev, SONIC_SR); | 330 | lp->dma_bitmode = SONIC_BITMODE32; |
407 | if (sr == 0 || sr == 0xffff) { | 331 | else { |
408 | reg_offset = 2; | 332 | lp->dma_bitmode = SONIC_BITMODE16; |
409 | /* 83932 is 0x0004, 83934 is 0x0100 or 0x0101 */ | 333 | lp->reg_offset = 0; |
410 | sr = sonic_read(dev, SONIC_SR); | 334 | sr = SONIC_READ(SONIC_SR); |
411 | dma_bitmode = 1; | ||
412 | |||
413 | } | 335 | } |
414 | printk(KERN_INFO | 336 | } else { |
415 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | 337 | /* All onboard cards are at offset 2 with 32 bit DMA. */ |
416 | dev->name, sr, dma_bitmode?32:16, reg_offset); | 338 | lp->reg_offset = 2; |
339 | lp->dma_bitmode = SONIC_BITMODE32; | ||
340 | sr = SONIC_READ(SONIC_SR); | ||
417 | } | 341 | } |
418 | 342 | printk(KERN_INFO | |
343 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | ||
344 | lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset); | ||
419 | 345 | ||
420 | /* this carries my sincere apologies -- by the time I got to updating | 346 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ |
421 | the driver, support for "reg_offsets" appeares nowhere in the sonic | 347 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id, |
422 | code, going back for over a year. Fortunately, my Mac does't seem | 348 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); |
423 | to use whatever this was. | 349 | #endif |
424 | 350 | ||
425 | If you know how this is supposed to be implemented, either fix it, | ||
426 | or contact me (sammy@oh.verio.com) to explain what it is. --Sam */ | ||
427 | |||
428 | if(reg_offset) { | ||
429 | printk("%s: register offset unsupported. please fix this if you know what it is.\n", dev->name); | ||
430 | return -ENODEV; | ||
431 | } | ||
432 | |||
433 | /* Software reset, then initialize control registers. */ | 351 | /* Software reset, then initialize control registers. */ |
434 | sonic_write(dev, SONIC_CMD, SONIC_CR_RST); | 352 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
435 | sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS | | 353 | |
436 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS | | 354 | SONIC_WRITE(SONIC_DCR, SONIC_DCR_EXBUS | SONIC_DCR_BMS | |
437 | (dma_bitmode ? SONIC_DCR_DW : 0)); | 355 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | |
356 | (lp->dma_bitmode ? SONIC_DCR_DW : 0)); | ||
438 | 357 | ||
439 | /* This *must* be written back to in order to restore the | 358 | /* This *must* be written back to in order to restore the |
440 | extended programmable output bits */ | 359 | * extended programmable output bits, as it may not have been |
441 | sonic_write(dev, SONIC_DCR2, 0); | 360 | * initialised since the hardware reset. */ |
361 | SONIC_WRITE(SONIC_DCR2, 0); | ||
442 | 362 | ||
443 | /* Clear *and* disable interrupts to be on the safe side */ | 363 | /* Clear *and* disable interrupts to be on the safe side */ |
444 | sonic_write(dev, SONIC_ISR,0x7fff); | 364 | SONIC_WRITE(SONIC_IMR, 0); |
445 | sonic_write(dev, SONIC_IMR,0); | 365 | SONIC_WRITE(SONIC_ISR, 0x7fff); |
446 | 366 | ||
447 | /* Now look for the MAC address. */ | 367 | /* Now look for the MAC address. */ |
448 | if (mac_onboard_sonic_ethernet_addr(dev) != 0) | 368 | if (mac_onboard_sonic_ethernet_addr(dev) != 0) |
449 | return -ENODEV; | 369 | return -ENODEV; |
450 | 370 | ||
451 | printk(KERN_INFO "MAC "); | ||
452 | for (i = 0; i < 6; i++) { | ||
453 | printk("%2.2x", dev->dev_addr[i]); | ||
454 | if (i < 5) | ||
455 | printk(":"); | ||
456 | } | ||
457 | |||
458 | printk(" IRQ %d\n", dev->irq); | ||
459 | |||
460 | /* Shared init code */ | 371 | /* Shared init code */ |
461 | return macsonic_init(dev); | 372 | return macsonic_init(dev); |
462 | } | 373 | } |
@@ -468,8 +379,10 @@ int __init mac_nubus_sonic_ethernet_addr(struct net_device* dev, | |||
468 | int i; | 379 | int i; |
469 | for(i = 0; i < 6; i++) | 380 | for(i = 0; i < 6; i++) |
470 | dev->dev_addr[i] = SONIC_READ_PROM(i); | 381 | dev->dev_addr[i] = SONIC_READ_PROM(i); |
471 | /* For now we are going to assume that they're all bit-reversed */ | 382 | |
472 | bit_reverse_addr(dev->dev_addr); | 383 | /* Some of the addresses are bit-reversed */ |
384 | if (id != MACSONIC_DAYNA) | ||
385 | bit_reverse_addr(dev->dev_addr); | ||
473 | 386 | ||
474 | return 0; | 387 | return 0; |
475 | } | 388 | } |
@@ -487,6 +400,15 @@ int __init macsonic_ident(struct nubus_dev* ndev) | |||
487 | else | 400 | else |
488 | return MACSONIC_APPLE; | 401 | return MACSONIC_APPLE; |
489 | } | 402 | } |
403 | |||
404 | if (ndev->dr_hw == NUBUS_DRHW_SMC9194 && | ||
405 | ndev->dr_sw == NUBUS_DRSW_DAYNA) | ||
406 | return MACSONIC_DAYNA; | ||
407 | |||
408 | if (ndev->dr_hw == NUBUS_DRHW_SONIC_LC && | ||
409 | ndev->dr_sw == 0) { /* huh? */ | ||
410 | return MACSONIC_APPLE16; | ||
411 | } | ||
490 | return -1; | 412 | return -1; |
491 | } | 413 | } |
492 | 414 | ||
@@ -494,12 +416,12 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
494 | { | 416 | { |
495 | static int slots; | 417 | static int slots; |
496 | struct nubus_dev* ndev = NULL; | 418 | struct nubus_dev* ndev = NULL; |
419 | struct sonic_local* lp = netdev_priv(dev); | ||
497 | unsigned long base_addr, prom_addr; | 420 | unsigned long base_addr, prom_addr; |
498 | u16 sonic_dcr; | 421 | u16 sonic_dcr; |
499 | int id; | 422 | int id = -1; |
500 | int i; | 423 | int reg_offset, dma_bitmode; |
501 | int dma_bitmode; | 424 | |
502 | |||
503 | /* Find the first SONIC that hasn't been initialized already */ | 425 | /* Find the first SONIC that hasn't been initialized already */ |
504 | while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, | 426 | while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, |
505 | NUBUS_TYPE_ETHERNET, ndev)) != NULL) | 427 | NUBUS_TYPE_ETHERNET, ndev)) != NULL) |
@@ -521,51 +443,52 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
521 | case MACSONIC_DUODOCK: | 443 | case MACSONIC_DUODOCK: |
522 | base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS; | 444 | base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS; |
523 | prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE; | 445 | prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE; |
524 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 | 446 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 | |
525 | | SONIC_DCR_TFT0; | 447 | SONIC_DCR_TFT0; |
526 | reg_offset = 2; | 448 | reg_offset = 2; |
527 | dma_bitmode = 1; | 449 | dma_bitmode = SONIC_BITMODE32; |
528 | break; | 450 | break; |
529 | case MACSONIC_APPLE: | 451 | case MACSONIC_APPLE: |
530 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | 452 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; |
531 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; | 453 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; |
532 | sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0; | 454 | sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0; |
533 | reg_offset = 0; | 455 | reg_offset = 0; |
534 | dma_bitmode = 1; | 456 | dma_bitmode = SONIC_BITMODE32; |
535 | break; | 457 | break; |
536 | case MACSONIC_APPLE16: | 458 | case MACSONIC_APPLE16: |
537 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | 459 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; |
538 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; | 460 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; |
539 | sonic_dcr = SONIC_DCR_EXBUS | 461 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | |
540 | | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | 462 | SONIC_DCR_PO1 | SONIC_DCR_BMS; |
541 | | SONIC_DCR_PO1 | SONIC_DCR_BMS; | ||
542 | reg_offset = 0; | 463 | reg_offset = 0; |
543 | dma_bitmode = 0; | 464 | dma_bitmode = SONIC_BITMODE16; |
544 | break; | 465 | break; |
545 | case MACSONIC_DAYNALINK: | 466 | case MACSONIC_DAYNALINK: |
546 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | 467 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; |
547 | prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE; | 468 | prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE; |
548 | sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | 469 | sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | |
549 | | SONIC_DCR_PO1 | SONIC_DCR_BMS; | 470 | SONIC_DCR_PO1 | SONIC_DCR_BMS; |
550 | reg_offset = 0; | 471 | reg_offset = 0; |
551 | dma_bitmode = 0; | 472 | dma_bitmode = SONIC_BITMODE16; |
552 | break; | 473 | break; |
553 | case MACSONIC_DAYNA: | 474 | case MACSONIC_DAYNA: |
554 | base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS; | 475 | base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS; |
555 | prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR; | 476 | prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR; |
556 | sonic_dcr = SONIC_DCR_BMS | 477 | sonic_dcr = SONIC_DCR_BMS | |
557 | | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1; | 478 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1; |
558 | reg_offset = 0; | 479 | reg_offset = 0; |
559 | dma_bitmode = 0; | 480 | dma_bitmode = SONIC_BITMODE16; |
560 | break; | 481 | break; |
561 | default: | 482 | default: |
562 | printk(KERN_ERR "macsonic: WTF, id is %d\n", id); | 483 | printk(KERN_ERR "macsonic: WTF, id is %d\n", id); |
563 | return -ENODEV; | 484 | return -ENODEV; |
564 | } | 485 | } |
565 | 486 | ||
566 | /* Danger! My arms are flailing wildly! You *must* set this | 487 | /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset |
567 | before using sonic_read() */ | 488 | * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ |
568 | dev->base_addr = base_addr; | 489 | dev->base_addr = base_addr; |
490 | lp->reg_offset = reg_offset; | ||
491 | lp->dma_bitmode = dma_bitmode; | ||
569 | dev->irq = SLOT2IRQ(ndev->board->slot); | 492 | dev->irq = SLOT2IRQ(ndev->board->slot); |
570 | 493 | ||
571 | if (!sonic_version_printed) { | 494 | if (!sonic_version_printed) { |
@@ -573,29 +496,66 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
573 | sonic_version_printed = 1; | 496 | sonic_version_printed = 1; |
574 | } | 497 | } |
575 | printk(KERN_INFO "%s: %s in slot %X\n", | 498 | printk(KERN_INFO "%s: %s in slot %X\n", |
576 | dev->name, ndev->board->name, ndev->board->slot); | 499 | lp->device->bus_id, ndev->board->name, ndev->board->slot); |
577 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | 500 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", |
578 | dev->name, sonic_read(dev, SONIC_SR), dma_bitmode?32:16, reg_offset); | 501 | lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset); |
579 | 502 | ||
580 | if(reg_offset) { | 503 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ |
581 | printk("%s: register offset unsupported. please fix this if you know what it is.\n", dev->name); | 504 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id, |
582 | return -ENODEV; | 505 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); |
583 | } | 506 | #endif |
584 | 507 | ||
585 | /* Software reset, then initialize control registers. */ | 508 | /* Software reset, then initialize control registers. */ |
586 | sonic_write(dev, SONIC_CMD, SONIC_CR_RST); | 509 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
587 | sonic_write(dev, SONIC_DCR, sonic_dcr | 510 | SONIC_WRITE(SONIC_DCR, sonic_dcr | (dma_bitmode ? SONIC_DCR_DW : 0)); |
588 | | (dma_bitmode ? SONIC_DCR_DW : 0)); | 511 | /* This *must* be written back to in order to restore the |
512 | * extended programmable output bits, since it may not have been | ||
513 | * initialised since the hardware reset. */ | ||
514 | SONIC_WRITE(SONIC_DCR2, 0); | ||
589 | 515 | ||
590 | /* Clear *and* disable interrupts to be on the safe side */ | 516 | /* Clear *and* disable interrupts to be on the safe side */ |
591 | sonic_write(dev, SONIC_ISR,0x7fff); | 517 | SONIC_WRITE(SONIC_IMR, 0); |
592 | sonic_write(dev, SONIC_IMR,0); | 518 | SONIC_WRITE(SONIC_ISR, 0x7fff); |
593 | 519 | ||
594 | /* Now look for the MAC address. */ | 520 | /* Now look for the MAC address. */ |
595 | if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0) | 521 | if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0) |
596 | return -ENODEV; | 522 | return -ENODEV; |
597 | 523 | ||
598 | printk(KERN_INFO "MAC "); | 524 | /* Shared init code */ |
525 | return macsonic_init(dev); | ||
526 | } | ||
527 | |||
528 | static int __init mac_sonic_probe(struct device *device) | ||
529 | { | ||
530 | struct net_device *dev; | ||
531 | struct sonic_local *lp; | ||
532 | int err; | ||
533 | int i; | ||
534 | |||
535 | dev = alloc_etherdev(sizeof(struct sonic_local)); | ||
536 | if (!dev) | ||
537 | return -ENOMEM; | ||
538 | |||
539 | lp = netdev_priv(dev); | ||
540 | lp->device = device; | ||
541 | SET_NETDEV_DEV(dev, device); | ||
542 | SET_MODULE_OWNER(dev); | ||
543 | |||
544 | /* This will catch fatal stuff like -ENOMEM as well as success */ | ||
545 | err = mac_onboard_sonic_probe(dev); | ||
546 | if (err == 0) | ||
547 | goto found; | ||
548 | if (err != -ENODEV) | ||
549 | goto out; | ||
550 | err = mac_nubus_sonic_probe(dev); | ||
551 | if (err) | ||
552 | goto out; | ||
553 | found: | ||
554 | err = register_netdev(dev); | ||
555 | if (err) | ||
556 | goto out; | ||
557 | |||
558 | printk("%s: MAC ", dev->name); | ||
599 | for (i = 0; i < 6; i++) { | 559 | for (i = 0; i < 6; i++) { |
600 | printk("%2.2x", dev->dev_addr[i]); | 560 | printk("%2.2x", dev->dev_addr[i]); |
601 | if (i < 5) | 561 | if (i < 5) |
@@ -603,55 +563,95 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
603 | } | 563 | } |
604 | printk(" IRQ %d\n", dev->irq); | 564 | printk(" IRQ %d\n", dev->irq); |
605 | 565 | ||
606 | /* Shared init code */ | 566 | return 0; |
607 | return macsonic_init(dev); | ||
608 | } | ||
609 | 567 | ||
610 | #ifdef MODULE | 568 | out: |
611 | static struct net_device *dev_macsonic; | 569 | free_netdev(dev); |
612 | 570 | ||
613 | MODULE_PARM(sonic_debug, "i"); | 571 | return err; |
572 | } | ||
573 | |||
574 | MODULE_DESCRIPTION("Macintosh SONIC ethernet driver"); | ||
575 | module_param(sonic_debug, int, 0); | ||
614 | MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); | 576 | MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); |
615 | 577 | ||
616 | int | 578 | #define SONIC_IRQ_FLAG IRQ_FLG_FAST |
617 | init_module(void) | 579 | |
580 | #include "sonic.c" | ||
581 | |||
582 | static int __devexit mac_sonic_device_remove (struct device *device) | ||
618 | { | 583 | { |
619 | dev_macsonic = macsonic_probe(-1); | 584 | struct net_device *dev = device->driver_data; |
620 | if (IS_ERR(dev_macsonic)) { | 585 | struct sonic_local* lp = netdev_priv(dev); |
621 | printk(KERN_WARNING "macsonic.c: No card found\n"); | 586 | |
622 | return PTR_ERR(dev_macsonic); | 587 | unregister_netdev (dev); |
623 | } | 588 | dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
589 | lp->descriptors, lp->descriptors_laddr); | ||
590 | free_netdev (dev); | ||
591 | |||
624 | return 0; | 592 | return 0; |
625 | } | 593 | } |
626 | 594 | ||
627 | void | 595 | static struct device_driver mac_sonic_driver = { |
628 | cleanup_module(void) | 596 | .name = mac_sonic_string, |
597 | .bus = &platform_bus_type, | ||
598 | .probe = mac_sonic_probe, | ||
599 | .remove = __devexit_p(mac_sonic_device_remove), | ||
600 | }; | ||
601 | |||
602 | static void mac_sonic_platform_release(struct device *device) | ||
629 | { | 603 | { |
630 | unregister_netdev(dev_macsonic); | 604 | struct platform_device *pldev; |
631 | kfree(dev_macsonic->priv); | 605 | |
632 | free_netdev(dev_macsonic); | 606 | /* free device */ |
607 | pldev = to_platform_device (device); | ||
608 | kfree (pldev); | ||
633 | } | 609 | } |
634 | #endif /* MODULE */ | ||
635 | 610 | ||
611 | static int __init mac_sonic_init_module(void) | ||
612 | { | ||
613 | struct platform_device *pldev; | ||
614 | int err; | ||
636 | 615 | ||
637 | #define vdma_alloc(foo, bar) ((u32)foo) | 616 | if ((err = driver_register(&mac_sonic_driver))) { |
638 | #define vdma_free(baz) | 617 | printk(KERN_ERR "Driver registration failed\n"); |
639 | #define sonic_chiptomem(bat) (bat) | 618 | return err; |
640 | #define PHYSADDR(quux) (quux) | 619 | } |
641 | #define CPHYSADDR(quux) (quux) | ||
642 | 620 | ||
643 | #define sonic_request_irq request_irq | 621 | mac_sonic_device = NULL; |
644 | #define sonic_free_irq free_irq | ||
645 | 622 | ||
646 | #include "sonic.c" | 623 | if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) { |
624 | goto out_unregister; | ||
625 | } | ||
647 | 626 | ||
648 | /* | 627 | memset(pldev, 0, sizeof (*pldev)); |
649 | * Local variables: | 628 | pldev->name = mac_sonic_string; |
650 | * compile-command: "m68k-linux-gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -c -o macsonic.o macsonic.c" | 629 | pldev->id = 0; |
651 | * version-control: t | 630 | pldev->dev.release = mac_sonic_platform_release; |
652 | * kept-new-versions: 5 | 631 | mac_sonic_device = pldev; |
653 | * c-indent-level: 8 | 632 | |
654 | * tab-width: 8 | 633 | if (platform_device_register (pldev)) { |
655 | * End: | 634 | kfree(pldev); |
656 | * | 635 | mac_sonic_device = NULL; |
657 | */ | 636 | } |
637 | |||
638 | return 0; | ||
639 | |||
640 | out_unregister: | ||
641 | platform_device_unregister(pldev); | ||
642 | |||
643 | return -ENOMEM; | ||
644 | } | ||
645 | |||
646 | static void __exit mac_sonic_cleanup_module(void) | ||
647 | { | ||
648 | driver_unregister(&mac_sonic_driver); | ||
649 | |||
650 | if (mac_sonic_device) { | ||
651 | platform_device_unregister(mac_sonic_device); | ||
652 | mac_sonic_device = NULL; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | module_init(mac_sonic_init_module); | ||
657 | module_exit(mac_sonic_cleanup_module); | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 0405e1f0d3df..fb6b232069d6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -1157,16 +1157,20 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1157 | if (!skb_shinfo(skb)->nr_frags) { | 1157 | if (!skb_shinfo(skb)->nr_frags) { |
1158 | linear: | 1158 | linear: |
1159 | if (skb->ip_summed != CHECKSUM_HW) { | 1159 | if (skb->ip_summed != CHECKSUM_HW) { |
1160 | /* Errata BTS #50, IHL must be 5 if no HW checksum */ | ||
1160 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | | 1161 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | |
1161 | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; | 1162 | ETH_TX_FIRST_DESC | |
1163 | ETH_TX_LAST_DESC | | ||
1164 | 5 << ETH_TX_IHL_SHIFT; | ||
1162 | pkt_info.l4i_chk = 0; | 1165 | pkt_info.l4i_chk = 0; |
1163 | } else { | 1166 | } else { |
1164 | u32 ipheader = skb->nh.iph->ihl << 11; | ||
1165 | 1167 | ||
1166 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | | 1168 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | |
1167 | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC | | 1169 | ETH_TX_FIRST_DESC | |
1168 | ETH_GEN_TCP_UDP_CHECKSUM | | 1170 | ETH_TX_LAST_DESC | |
1169 | ETH_GEN_IP_V_4_CHECKSUM | ipheader; | 1171 | ETH_GEN_TCP_UDP_CHECKSUM | |
1172 | ETH_GEN_IP_V_4_CHECKSUM | | ||
1173 | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; | ||
1170 | /* CPU already calculated pseudo header checksum. */ | 1174 | /* CPU already calculated pseudo header checksum. */ |
1171 | if (skb->nh.iph->protocol == IPPROTO_UDP) { | 1175 | if (skb->nh.iph->protocol == IPPROTO_UDP) { |
1172 | pkt_info.cmd_sts |= ETH_UDP_FRAME; | 1176 | pkt_info.cmd_sts |= ETH_UDP_FRAME; |
@@ -1193,7 +1197,6 @@ linear: | |||
1193 | stats->tx_bytes += pkt_info.byte_cnt; | 1197 | stats->tx_bytes += pkt_info.byte_cnt; |
1194 | } else { | 1198 | } else { |
1195 | unsigned int frag; | 1199 | unsigned int frag; |
1196 | u32 ipheader; | ||
1197 | 1200 | ||
1198 | /* Since hardware can't handle unaligned fragments smaller | 1201 | /* Since hardware can't handle unaligned fragments smaller |
1199 | * than 9 bytes, if we find any, we linearize the skb | 1202 | * than 9 bytes, if we find any, we linearize the skb |
@@ -1222,12 +1225,16 @@ linear: | |||
1222 | DMA_TO_DEVICE); | 1225 | DMA_TO_DEVICE); |
1223 | pkt_info.l4i_chk = 0; | 1226 | pkt_info.l4i_chk = 0; |
1224 | pkt_info.return_info = 0; | 1227 | pkt_info.return_info = 0; |
1225 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC; | ||
1226 | 1228 | ||
1227 | if (skb->ip_summed == CHECKSUM_HW) { | 1229 | if (skb->ip_summed != CHECKSUM_HW) |
1228 | ipheader = skb->nh.iph->ihl << 11; | 1230 | /* Errata BTS #50, IHL must be 5 if no HW checksum */ |
1229 | pkt_info.cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | | 1231 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC | |
1230 | ETH_GEN_IP_V_4_CHECKSUM | ipheader; | 1232 | 5 << ETH_TX_IHL_SHIFT; |
1233 | else { | ||
1234 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC | | ||
1235 | ETH_GEN_TCP_UDP_CHECKSUM | | ||
1236 | ETH_GEN_IP_V_4_CHECKSUM | | ||
1237 | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; | ||
1231 | /* CPU already calculated pseudo header checksum. */ | 1238 | /* CPU already calculated pseudo header checksum. */ |
1232 | if (skb->nh.iph->protocol == IPPROTO_UDP) { | 1239 | if (skb->nh.iph->protocol == IPPROTO_UDP) { |
1233 | pkt_info.cmd_sts |= ETH_UDP_FRAME; | 1240 | pkt_info.cmd_sts |= ETH_UDP_FRAME; |
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 57c4f8fbfdb6..7678b59c2952 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h | |||
@@ -49,7 +49,7 @@ | |||
49 | /* Checksum offload for Tx works for most packets, but | 49 | /* Checksum offload for Tx works for most packets, but |
50 | * fails if previous packet sent did not use hw csum | 50 | * fails if previous packet sent did not use hw csum |
51 | */ | 51 | */ |
52 | #undef MV643XX_CHECKSUM_OFFLOAD_TX | 52 | #define MV643XX_CHECKSUM_OFFLOAD_TX |
53 | #define MV643XX_NAPI | 53 | #define MV643XX_NAPI |
54 | #define MV643XX_TX_FAST_REFILL | 54 | #define MV643XX_TX_FAST_REFILL |
55 | #undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ | 55 | #undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ |
@@ -217,6 +217,8 @@ | |||
217 | #define ETH_TX_ENABLE_INTERRUPT (BIT23) | 217 | #define ETH_TX_ENABLE_INTERRUPT (BIT23) |
218 | #define ETH_AUTO_MODE (BIT30) | 218 | #define ETH_AUTO_MODE (BIT30) |
219 | 219 | ||
220 | #define ETH_TX_IHL_SHIFT 11 | ||
221 | |||
220 | /* typedefs */ | 222 | /* typedefs */ |
221 | 223 | ||
222 | typedef enum _eth_func_ret_status { | 224 | typedef enum _eth_func_ret_status { |
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 4a391ea0f58a..a1ac4bd1696e 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c | |||
@@ -486,9 +486,9 @@ struct netdrv_private { | |||
486 | MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); | 486 | MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); |
487 | MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver"); | 487 | MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver"); |
488 | MODULE_LICENSE("GPL"); | 488 | MODULE_LICENSE("GPL"); |
489 | MODULE_PARM (multicast_filter_limit, "i"); | 489 | module_param(multicast_filter_limit, int, 0); |
490 | MODULE_PARM (max_interrupt_work, "i"); | 490 | module_param(max_interrupt_work, int, 0); |
491 | MODULE_PARM (media, "1-" __MODULE_STRING(8) "i"); | 491 | module_param_array(media, int, NULL, 0); |
492 | MODULE_PARM_DESC (multicast_filter_limit, "pci-skeleton maximum number of filtered multicast addresses"); | 492 | MODULE_PARM_DESC (multicast_filter_limit, "pci-skeleton maximum number of filtered multicast addresses"); |
493 | MODULE_PARM_DESC (max_interrupt_work, "pci-skeleton maximum events handled per interrupt"); | 493 | MODULE_PARM_DESC (max_interrupt_work, "pci-skeleton maximum events handled per interrupt"); |
494 | MODULE_PARM_DESC (media, "pci-skeleton: Bits 0-3: media type, bit 17: full duplex"); | 494 | MODULE_PARM_DESC (media, "pci-skeleton: Bits 0-3: media type, bit 17: full duplex"); |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9d8197bb293a..384a736a0d2f 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -134,7 +134,7 @@ typedef struct local_info_t { | |||
134 | u_char mc_filter[8]; | 134 | u_char mc_filter[8]; |
135 | } local_info_t; | 135 | } local_info_t; |
136 | 136 | ||
137 | #define MC_FILTERBREAK 64 | 137 | #define MC_FILTERBREAK 8 |
138 | 138 | ||
139 | /*====================================================================*/ | 139 | /*====================================================================*/ |
140 | /* | 140 | /* |
@@ -1012,7 +1012,7 @@ static void fjn_reset(struct net_device *dev) | |||
1012 | outb(BANK_1U, ioaddr + CONFIG_1); | 1012 | outb(BANK_1U, ioaddr + CONFIG_1); |
1013 | 1013 | ||
1014 | /* set the multicast table to accept none. */ | 1014 | /* set the multicast table to accept none. */ |
1015 | for (i = 0; i < 6; i++) | 1015 | for (i = 0; i < 8; i++) |
1016 | outb(0x00, ioaddr + MAR_ADR + i); | 1016 | outb(0x00, ioaddr + MAR_ADR + i); |
1017 | 1017 | ||
1018 | /* Switch to bank 2 (runtime mode) */ | 1018 | /* Switch to bank 2 (runtime mode) */ |
@@ -1269,6 +1269,16 @@ static void set_rx_mode(struct net_device *dev) | |||
1269 | u_long flags; | 1269 | u_long flags; |
1270 | int i; | 1270 | int i; |
1271 | 1271 | ||
1272 | int saved_config_0 = inb(ioaddr + CONFIG_0); | ||
1273 | |||
1274 | local_irq_save(flags); | ||
1275 | |||
1276 | /* Disable Tx and Rx */ | ||
1277 | if (sram_config == 0) | ||
1278 | outb(CONFIG0_RST, ioaddr + CONFIG_0); | ||
1279 | else | ||
1280 | outb(CONFIG0_RST_1, ioaddr + CONFIG_0); | ||
1281 | |||
1272 | if (dev->flags & IFF_PROMISC) { | 1282 | if (dev->flags & IFF_PROMISC) { |
1273 | /* Unconditionally log net taps. */ | 1283 | /* Unconditionally log net taps. */ |
1274 | printk("%s: Promiscuous mode enabled.\n", dev->name); | 1284 | printk("%s: Promiscuous mode enabled.\n", dev->name); |
@@ -1290,20 +1300,23 @@ static void set_rx_mode(struct net_device *dev) | |||
1290 | for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; | 1300 | for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; |
1291 | i++, mclist = mclist->next) { | 1301 | i++, mclist = mclist->next) { |
1292 | unsigned int bit = | 1302 | unsigned int bit = |
1293 | ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f; | 1303 | ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26; |
1294 | mc_filter[bit >> 3] |= (1 << bit); | 1304 | mc_filter[bit >> 3] |= (1 << (bit & 7)); |
1295 | } | 1305 | } |
1306 | outb(2, ioaddr + RX_MODE); /* Use normal mode. */ | ||
1296 | } | 1307 | } |
1297 | 1308 | ||
1298 | local_irq_save(flags); | ||
1299 | if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { | 1309 | if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { |
1300 | int saved_bank = inb(ioaddr + CONFIG_1); | 1310 | int saved_bank = inb(ioaddr + CONFIG_1); |
1301 | /* Switch to bank 1 and set the multicast table. */ | 1311 | /* Switch to bank 1 and set the multicast table. */ |
1302 | outb(0xe4, ioaddr + CONFIG_1); | 1312 | outb(0xe4, ioaddr + CONFIG_1); |
1303 | for (i = 0; i < 8; i++) | 1313 | for (i = 0; i < 8; i++) |
1304 | outb(mc_filter[i], ioaddr + 8 + i); | 1314 | outb(mc_filter[i], ioaddr + MAR_ADR + i); |
1305 | memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); | 1315 | memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); |
1306 | outb(saved_bank, ioaddr + CONFIG_1); | 1316 | outb(saved_bank, ioaddr + CONFIG_1); |
1307 | } | 1317 | } |
1318 | |||
1319 | outb(saved_config_0, ioaddr + CONFIG_0); | ||
1320 | |||
1308 | local_irq_restore(flags); | 1321 | local_irq_restore(flags); |
1309 | } | 1322 | } |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig new file mode 100644 index 000000000000..6a2fe3583478 --- /dev/null +++ b/drivers/net/phy/Kconfig | |||
@@ -0,0 +1,57 @@ | |||
1 | # | ||
2 | # PHY Layer Configuration | ||
3 | # | ||
4 | |||
5 | menu "PHY device support" | ||
6 | |||
7 | config PHYLIB | ||
8 | tristate "PHY Device support and infrastructure" | ||
9 | depends on NET_ETHERNET | ||
10 | help | ||
11 | Ethernet controllers are usually attached to PHY | ||
12 | devices. This option provides infrastructure for | ||
13 | managing PHY devices. | ||
14 | |||
15 | config PHYCONTROL | ||
16 | bool " Support for automatically handling PHY state changes" | ||
17 | depends on PHYLIB | ||
18 | help | ||
19 | Adds code to perform all the work for keeping PHY link | ||
20 | state (speed/duplex/etc) up-to-date. Also handles | ||
21 | interrupts. | ||
22 | |||
23 | comment "MII PHY device drivers" | ||
24 | depends on PHYLIB | ||
25 | |||
26 | config MARVELL_PHY | ||
27 | tristate "Drivers for Marvell PHYs" | ||
28 | depends on PHYLIB | ||
29 | ---help--- | ||
30 | Currently has a driver for the 88E1011S | ||
31 | |||
32 | config DAVICOM_PHY | ||
33 | tristate "Drivers for Davicom PHYs" | ||
34 | depends on PHYLIB | ||
35 | ---help--- | ||
36 | Currently supports dm9161e and dm9131 | ||
37 | |||
38 | config QSEMI_PHY | ||
39 | tristate "Drivers for Quality Semiconductor PHYs" | ||
40 | depends on PHYLIB | ||
41 | ---help--- | ||
42 | Currently supports the qs6612 | ||
43 | |||
44 | config LXT_PHY | ||
45 | tristate "Drivers for the Intel LXT PHYs" | ||
46 | depends on PHYLIB | ||
47 | ---help--- | ||
48 | Currently supports the lxt970, lxt971 | ||
49 | |||
50 | config CICADA_PHY | ||
51 | tristate "Drivers for the Cicada PHYs" | ||
52 | depends on PHYLIB | ||
53 | ---help--- | ||
54 | Currently supports the cis8204 | ||
55 | |||
56 | endmenu | ||
57 | |||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile new file mode 100644 index 000000000000..e4116a5fbb4c --- /dev/null +++ b/drivers/net/phy/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # Makefile for Linux PHY drivers | ||
2 | |||
3 | libphy-objs := phy.o phy_device.o mdio_bus.o | ||
4 | |||
5 | obj-$(CONFIG_PHYLIB) += libphy.o | ||
6 | obj-$(CONFIG_MARVELL_PHY) += marvell.o | ||
7 | obj-$(CONFIG_DAVICOM_PHY) += davicom.o | ||
8 | obj-$(CONFIG_CICADA_PHY) += cicada.o | ||
9 | obj-$(CONFIG_LXT_PHY) += lxt.o | ||
10 | obj-$(CONFIG_QSEMI_PHY) += qsemi.o | ||
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c new file mode 100644 index 000000000000..c47fb2ecd147 --- /dev/null +++ b/drivers/net/phy/cicada.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/cicada.c | ||
3 | * | ||
4 | * Driver for Cicada PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* Cicada Extended Control Register 1 */ | ||
42 | #define MII_CIS8201_EXT_CON1 0x17 | ||
43 | #define MII_CIS8201_EXTCON1_INIT 0x0000 | ||
44 | |||
45 | /* Cicada Interrupt Mask Register */ | ||
46 | #define MII_CIS8201_IMASK 0x19 | ||
47 | #define MII_CIS8201_IMASK_IEN 0x8000 | ||
48 | #define MII_CIS8201_IMASK_SPEED 0x4000 | ||
49 | #define MII_CIS8201_IMASK_LINK 0x2000 | ||
50 | #define MII_CIS8201_IMASK_DUPLEX 0x1000 | ||
51 | #define MII_CIS8201_IMASK_MASK 0xf000 | ||
52 | |||
53 | /* Cicada Interrupt Status Register */ | ||
54 | #define MII_CIS8201_ISTAT 0x1a | ||
55 | #define MII_CIS8201_ISTAT_STATUS 0x8000 | ||
56 | #define MII_CIS8201_ISTAT_SPEED 0x4000 | ||
57 | #define MII_CIS8201_ISTAT_LINK 0x2000 | ||
58 | #define MII_CIS8201_ISTAT_DUPLEX 0x1000 | ||
59 | |||
60 | /* Cicada Auxiliary Control/Status Register */ | ||
61 | #define MII_CIS8201_AUX_CONSTAT 0x1c | ||
62 | #define MII_CIS8201_AUXCONSTAT_INIT 0x0004 | ||
63 | #define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 | ||
64 | #define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 | ||
65 | #define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 | ||
66 | #define MII_CIS8201_AUXCONSTAT_100 0x0008 | ||
67 | |||
68 | MODULE_DESCRIPTION("Cicadia PHY driver"); | ||
69 | MODULE_AUTHOR("Andy Fleming"); | ||
70 | MODULE_LICENSE("GPL"); | ||
71 | |||
72 | static int cis820x_config_init(struct phy_device *phydev) | ||
73 | { | ||
74 | int err; | ||
75 | |||
76 | err = phy_write(phydev, MII_CIS8201_AUX_CONSTAT, | ||
77 | MII_CIS8201_AUXCONSTAT_INIT); | ||
78 | |||
79 | if (err < 0) | ||
80 | return err; | ||
81 | |||
82 | err = phy_write(phydev, MII_CIS8201_EXT_CON1, | ||
83 | MII_CIS8201_EXTCON1_INIT); | ||
84 | |||
85 | return err; | ||
86 | } | ||
87 | |||
88 | static int cis820x_ack_interrupt(struct phy_device *phydev) | ||
89 | { | ||
90 | int err = phy_read(phydev, MII_CIS8201_ISTAT); | ||
91 | |||
92 | return (err < 0) ? err : 0; | ||
93 | } | ||
94 | |||
95 | static int cis820x_config_intr(struct phy_device *phydev) | ||
96 | { | ||
97 | int err; | ||
98 | |||
99 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
100 | err = phy_write(phydev, MII_CIS8201_IMASK, | ||
101 | MII_CIS8201_IMASK_MASK); | ||
102 | else | ||
103 | err = phy_write(phydev, MII_CIS8201_IMASK, 0); | ||
104 | |||
105 | return err; | ||
106 | } | ||
107 | |||
108 | /* Cicada 820x */ | ||
109 | static struct phy_driver cis8204_driver = { | ||
110 | .phy_id = 0x000fc440, | ||
111 | .name = "Cicada Cis8204", | ||
112 | .phy_id_mask = 0x000fffc0, | ||
113 | .features = PHY_GBIT_FEATURES, | ||
114 | .flags = PHY_HAS_INTERRUPT, | ||
115 | .config_init = &cis820x_config_init, | ||
116 | .config_aneg = &genphy_config_aneg, | ||
117 | .read_status = &genphy_read_status, | ||
118 | .ack_interrupt = &cis820x_ack_interrupt, | ||
119 | .config_intr = &cis820x_config_intr, | ||
120 | .driver = { .owner = THIS_MODULE,}, | ||
121 | }; | ||
122 | |||
123 | static int __init cis8204_init(void) | ||
124 | { | ||
125 | return phy_driver_register(&cis8204_driver); | ||
126 | } | ||
127 | |||
128 | static void __exit cis8204_exit(void) | ||
129 | { | ||
130 | phy_driver_unregister(&cis8204_driver); | ||
131 | } | ||
132 | |||
133 | module_init(cis8204_init); | ||
134 | module_exit(cis8204_exit); | ||
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c new file mode 100644 index 000000000000..6caf499fae32 --- /dev/null +++ b/drivers/net/phy/davicom.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/davicom.c | ||
3 | * | ||
4 | * Driver for Davicom PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | #define MII_DM9161_SCR 0x10 | ||
42 | #define MII_DM9161_SCR_INIT 0x0610 | ||
43 | |||
44 | /* DM9161 Interrupt Register */ | ||
45 | #define MII_DM9161_INTR 0x15 | ||
46 | #define MII_DM9161_INTR_PEND 0x8000 | ||
47 | #define MII_DM9161_INTR_DPLX_MASK 0x0800 | ||
48 | #define MII_DM9161_INTR_SPD_MASK 0x0400 | ||
49 | #define MII_DM9161_INTR_LINK_MASK 0x0200 | ||
50 | #define MII_DM9161_INTR_MASK 0x0100 | ||
51 | #define MII_DM9161_INTR_DPLX_CHANGE 0x0010 | ||
52 | #define MII_DM9161_INTR_SPD_CHANGE 0x0008 | ||
53 | #define MII_DM9161_INTR_LINK_CHANGE 0x0004 | ||
54 | #define MII_DM9161_INTR_INIT 0x0000 | ||
55 | #define MII_DM9161_INTR_STOP \ | ||
56 | (MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ | ||
57 | | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) | ||
58 | |||
59 | /* DM9161 10BT Configuration/Status */ | ||
60 | #define MII_DM9161_10BTCSR 0x12 | ||
61 | #define MII_DM9161_10BTCSR_INIT 0x7800 | ||
62 | |||
63 | MODULE_DESCRIPTION("Davicom PHY driver"); | ||
64 | MODULE_AUTHOR("Andy Fleming"); | ||
65 | MODULE_LICENSE("GPL"); | ||
66 | |||
67 | |||
68 | #define DM9161_DELAY 1 | ||
69 | static int dm9161_config_intr(struct phy_device *phydev) | ||
70 | { | ||
71 | int temp; | ||
72 | |||
73 | temp = phy_read(phydev, MII_DM9161_INTR); | ||
74 | |||
75 | if (temp < 0) | ||
76 | return temp; | ||
77 | |||
78 | if(PHY_INTERRUPT_ENABLED == phydev->interrupts ) | ||
79 | temp &= ~(MII_DM9161_INTR_STOP); | ||
80 | else | ||
81 | temp |= MII_DM9161_INTR_STOP; | ||
82 | |||
83 | temp = phy_write(phydev, MII_DM9161_INTR, temp); | ||
84 | |||
85 | return temp; | ||
86 | } | ||
87 | |||
88 | static int dm9161_config_aneg(struct phy_device *phydev) | ||
89 | { | ||
90 | int err; | ||
91 | |||
92 | /* Isolate the PHY */ | ||
93 | err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); | ||
94 | |||
95 | if (err < 0) | ||
96 | return err; | ||
97 | |||
98 | /* Configure the new settings */ | ||
99 | err = genphy_config_aneg(phydev); | ||
100 | |||
101 | if (err < 0) | ||
102 | return err; | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int dm9161_config_init(struct phy_device *phydev) | ||
108 | { | ||
109 | int err; | ||
110 | |||
111 | /* Isolate the PHY */ | ||
112 | err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); | ||
113 | |||
114 | if (err < 0) | ||
115 | return err; | ||
116 | |||
117 | /* Do not bypass the scrambler/descrambler */ | ||
118 | err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT); | ||
119 | |||
120 | if (err < 0) | ||
121 | return err; | ||
122 | |||
123 | /* Clear 10BTCSR to default */ | ||
124 | err = phy_write(phydev, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT); | ||
125 | |||
126 | if (err < 0) | ||
127 | return err; | ||
128 | |||
129 | /* Reconnect the PHY, and enable Autonegotiation */ | ||
130 | err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE); | ||
131 | |||
132 | if (err < 0) | ||
133 | return err; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int dm9161_ack_interrupt(struct phy_device *phydev) | ||
139 | { | ||
140 | int err = phy_read(phydev, MII_DM9161_INTR); | ||
141 | |||
142 | return (err < 0) ? err : 0; | ||
143 | } | ||
144 | |||
145 | static struct phy_driver dm9161_driver = { | ||
146 | .phy_id = 0x0181b880, | ||
147 | .name = "Davicom DM9161E", | ||
148 | .phy_id_mask = 0x0ffffff0, | ||
149 | .features = PHY_BASIC_FEATURES, | ||
150 | .config_init = dm9161_config_init, | ||
151 | .config_aneg = dm9161_config_aneg, | ||
152 | .read_status = genphy_read_status, | ||
153 | .driver = { .owner = THIS_MODULE,}, | ||
154 | }; | ||
155 | |||
156 | static struct phy_driver dm9131_driver = { | ||
157 | .phy_id = 0x00181b80, | ||
158 | .name = "Davicom DM9131", | ||
159 | .phy_id_mask = 0x0ffffff0, | ||
160 | .features = PHY_BASIC_FEATURES, | ||
161 | .flags = PHY_HAS_INTERRUPT, | ||
162 | .config_aneg = genphy_config_aneg, | ||
163 | .read_status = genphy_read_status, | ||
164 | .ack_interrupt = dm9161_ack_interrupt, | ||
165 | .config_intr = dm9161_config_intr, | ||
166 | .driver = { .owner = THIS_MODULE,}, | ||
167 | }; | ||
168 | |||
169 | static int __init davicom_init(void) | ||
170 | { | ||
171 | int ret; | ||
172 | |||
173 | ret = phy_driver_register(&dm9161_driver); | ||
174 | if (ret) | ||
175 | goto err1; | ||
176 | |||
177 | ret = phy_driver_register(&dm9131_driver); | ||
178 | if (ret) | ||
179 | goto err2; | ||
180 | return 0; | ||
181 | |||
182 | err2: | ||
183 | phy_driver_unregister(&dm9161_driver); | ||
184 | err1: | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static void __exit davicom_exit(void) | ||
189 | { | ||
190 | phy_driver_unregister(&dm9161_driver); | ||
191 | phy_driver_unregister(&dm9131_driver); | ||
192 | } | ||
193 | |||
194 | module_init(davicom_init); | ||
195 | module_exit(davicom_exit); | ||
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c new file mode 100644 index 000000000000..4c840448ec86 --- /dev/null +++ b/drivers/net/phy/lxt.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/lxt.c | ||
3 | * | ||
4 | * Driver for Intel LXT PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* The Level one LXT970 is used by many boards */ | ||
42 | |||
43 | #define MII_LXT970_IER 17 /* Interrupt Enable Register */ | ||
44 | |||
45 | #define MII_LXT970_IER_IEN 0x0002 | ||
46 | |||
47 | #define MII_LXT970_ISR 18 /* Interrupt Status Register */ | ||
48 | |||
49 | #define MII_LXT970_CONFIG 19 /* Configuration Register */ | ||
50 | |||
51 | /* ------------------------------------------------------------------------- */ | ||
52 | /* The Level one LXT971 is used on some of my custom boards */ | ||
53 | |||
54 | /* register definitions for the 971 */ | ||
55 | #define MII_LXT971_IER 18 /* Interrupt Enable Register */ | ||
56 | #define MII_LXT971_IER_IEN 0x00f2 | ||
57 | |||
58 | #define MII_LXT971_ISR 19 /* Interrupt Status Register */ | ||
59 | |||
60 | |||
61 | MODULE_DESCRIPTION("Intel LXT PHY driver"); | ||
62 | MODULE_AUTHOR("Andy Fleming"); | ||
63 | MODULE_LICENSE("GPL"); | ||
64 | |||
65 | static int lxt970_ack_interrupt(struct phy_device *phydev) | ||
66 | { | ||
67 | int err; | ||
68 | |||
69 | err = phy_read(phydev, MII_BMSR); | ||
70 | |||
71 | if (err < 0) | ||
72 | return err; | ||
73 | |||
74 | err = phy_read(phydev, MII_LXT970_ISR); | ||
75 | |||
76 | if (err < 0) | ||
77 | return err; | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int lxt970_config_intr(struct phy_device *phydev) | ||
83 | { | ||
84 | int err; | ||
85 | |||
86 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
87 | err = phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN); | ||
88 | else | ||
89 | err = phy_write(phydev, MII_LXT970_IER, 0); | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | |||
94 | static int lxt970_config_init(struct phy_device *phydev) | ||
95 | { | ||
96 | int err; | ||
97 | |||
98 | err = phy_write(phydev, MII_LXT970_CONFIG, 0); | ||
99 | |||
100 | return err; | ||
101 | } | ||
102 | |||
103 | |||
104 | static int lxt971_ack_interrupt(struct phy_device *phydev) | ||
105 | { | ||
106 | int err = phy_read(phydev, MII_LXT971_ISR); | ||
107 | |||
108 | if (err < 0) | ||
109 | return err; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int lxt971_config_intr(struct phy_device *phydev) | ||
115 | { | ||
116 | int err; | ||
117 | |||
118 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
119 | err = phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN); | ||
120 | else | ||
121 | err = phy_write(phydev, MII_LXT971_IER, 0); | ||
122 | |||
123 | return err; | ||
124 | } | ||
125 | |||
126 | static struct phy_driver lxt970_driver = { | ||
127 | .phy_id = 0x07810000, | ||
128 | .name = "LXT970", | ||
129 | .phy_id_mask = 0x0fffffff, | ||
130 | .features = PHY_BASIC_FEATURES, | ||
131 | .flags = PHY_HAS_INTERRUPT, | ||
132 | .config_init = lxt970_config_init, | ||
133 | .config_aneg = genphy_config_aneg, | ||
134 | .read_status = genphy_read_status, | ||
135 | .ack_interrupt = lxt970_ack_interrupt, | ||
136 | .config_intr = lxt970_config_intr, | ||
137 | .driver = { .owner = THIS_MODULE,}, | ||
138 | }; | ||
139 | |||
140 | static struct phy_driver lxt971_driver = { | ||
141 | .phy_id = 0x0001378e, | ||
142 | .name = "LXT971", | ||
143 | .phy_id_mask = 0x0fffffff, | ||
144 | .features = PHY_BASIC_FEATURES, | ||
145 | .flags = PHY_HAS_INTERRUPT, | ||
146 | .config_aneg = genphy_config_aneg, | ||
147 | .read_status = genphy_read_status, | ||
148 | .ack_interrupt = lxt971_ack_interrupt, | ||
149 | .config_intr = lxt971_config_intr, | ||
150 | .driver = { .owner = THIS_MODULE,}, | ||
151 | }; | ||
152 | |||
153 | static int __init lxt_init(void) | ||
154 | { | ||
155 | int ret; | ||
156 | |||
157 | ret = phy_driver_register(&lxt970_driver); | ||
158 | if (ret) | ||
159 | goto err1; | ||
160 | |||
161 | ret = phy_driver_register(&lxt971_driver); | ||
162 | if (ret) | ||
163 | goto err2; | ||
164 | return 0; | ||
165 | |||
166 | err2: | ||
167 | phy_driver_unregister(&lxt970_driver); | ||
168 | err1: | ||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static void __exit lxt_exit(void) | ||
173 | { | ||
174 | phy_driver_unregister(&lxt970_driver); | ||
175 | phy_driver_unregister(&lxt971_driver); | ||
176 | } | ||
177 | |||
178 | module_init(lxt_init); | ||
179 | module_exit(lxt_exit); | ||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c new file mode 100644 index 000000000000..4a72b025006b --- /dev/null +++ b/drivers/net/phy/marvell.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/marvell.c | ||
3 | * | ||
4 | * Driver for Marvell PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | #define MII_M1011_IEVENT 0x13 | ||
42 | #define MII_M1011_IEVENT_CLEAR 0x0000 | ||
43 | |||
44 | #define MII_M1011_IMASK 0x12 | ||
45 | #define MII_M1011_IMASK_INIT 0x6400 | ||
46 | #define MII_M1011_IMASK_CLEAR 0x0000 | ||
47 | |||
48 | MODULE_DESCRIPTION("Marvell PHY driver"); | ||
49 | MODULE_AUTHOR("Andy Fleming"); | ||
50 | MODULE_LICENSE("GPL"); | ||
51 | |||
52 | static int marvell_ack_interrupt(struct phy_device *phydev) | ||
53 | { | ||
54 | int err; | ||
55 | |||
56 | /* Clear the interrupts by reading the reg */ | ||
57 | err = phy_read(phydev, MII_M1011_IEVENT); | ||
58 | |||
59 | if (err < 0) | ||
60 | return err; | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int marvell_config_intr(struct phy_device *phydev) | ||
66 | { | ||
67 | int err; | ||
68 | |||
69 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
70 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); | ||
71 | else | ||
72 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); | ||
73 | |||
74 | return err; | ||
75 | } | ||
76 | |||
77 | static int marvell_config_aneg(struct phy_device *phydev) | ||
78 | { | ||
79 | int err; | ||
80 | |||
81 | /* The Marvell PHY has an errata which requires | ||
82 | * that certain registers get written in order | ||
83 | * to restart autonegotiation */ | ||
84 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
85 | |||
86 | if (err < 0) | ||
87 | return err; | ||
88 | |||
89 | err = phy_write(phydev, 0x1d, 0x1f); | ||
90 | if (err < 0) | ||
91 | return err; | ||
92 | |||
93 | err = phy_write(phydev, 0x1e, 0x200c); | ||
94 | if (err < 0) | ||
95 | return err; | ||
96 | |||
97 | err = phy_write(phydev, 0x1d, 0x5); | ||
98 | if (err < 0) | ||
99 | return err; | ||
100 | |||
101 | err = phy_write(phydev, 0x1e, 0); | ||
102 | if (err < 0) | ||
103 | return err; | ||
104 | |||
105 | err = phy_write(phydev, 0x1e, 0x100); | ||
106 | if (err < 0) | ||
107 | return err; | ||
108 | |||
109 | |||
110 | err = genphy_config_aneg(phydev); | ||
111 | |||
112 | return err; | ||
113 | } | ||
114 | |||
115 | |||
116 | static struct phy_driver m88e1101_driver = { | ||
117 | .phy_id = 0x01410c00, | ||
118 | .phy_id_mask = 0xffffff00, | ||
119 | .name = "Marvell 88E1101", | ||
120 | .features = PHY_GBIT_FEATURES, | ||
121 | .flags = PHY_HAS_INTERRUPT, | ||
122 | .config_aneg = &marvell_config_aneg, | ||
123 | .read_status = &genphy_read_status, | ||
124 | .ack_interrupt = &marvell_ack_interrupt, | ||
125 | .config_intr = &marvell_config_intr, | ||
126 | .driver = { .owner = THIS_MODULE,}, | ||
127 | }; | ||
128 | |||
129 | static int __init marvell_init(void) | ||
130 | { | ||
131 | return phy_driver_register(&m88e1101_driver); | ||
132 | } | ||
133 | |||
134 | static void __exit marvell_exit(void) | ||
135 | { | ||
136 | phy_driver_unregister(&m88e1101_driver); | ||
137 | } | ||
138 | |||
139 | module_init(marvell_init); | ||
140 | module_exit(marvell_exit); | ||
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c new file mode 100644 index 000000000000..41f62c0c5fcb --- /dev/null +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/mdio_bus.c | ||
3 | * | ||
4 | * MDIO Bus interface | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* mdiobus_register | ||
42 | * | ||
43 | * description: Called by a bus driver to bring up all the PHYs | ||
44 | * on a given bus, and attach them to the bus | ||
45 | */ | ||
46 | int mdiobus_register(struct mii_bus *bus) | ||
47 | { | ||
48 | int i; | ||
49 | int err = 0; | ||
50 | |||
51 | spin_lock_init(&bus->mdio_lock); | ||
52 | |||
53 | if (NULL == bus || NULL == bus->name || | ||
54 | NULL == bus->read || | ||
55 | NULL == bus->write) | ||
56 | return -EINVAL; | ||
57 | |||
58 | if (bus->reset) | ||
59 | bus->reset(bus); | ||
60 | |||
61 | for (i = 0; i < PHY_MAX_ADDR; i++) { | ||
62 | struct phy_device *phydev; | ||
63 | |||
64 | phydev = get_phy_device(bus, i); | ||
65 | |||
66 | if (IS_ERR(phydev)) | ||
67 | return PTR_ERR(phydev); | ||
68 | |||
69 | /* There's a PHY at this address | ||
70 | * We need to set: | ||
71 | * 1) IRQ | ||
72 | * 2) bus_id | ||
73 | * 3) parent | ||
74 | * 4) bus | ||
75 | * 5) mii_bus | ||
76 | * And, we need to register it */ | ||
77 | if (phydev) { | ||
78 | phydev->irq = bus->irq[i]; | ||
79 | |||
80 | phydev->dev.parent = bus->dev; | ||
81 | phydev->dev.bus = &mdio_bus_type; | ||
82 | sprintf(phydev->dev.bus_id, "phy%d:%d", bus->id, i); | ||
83 | |||
84 | phydev->bus = bus; | ||
85 | |||
86 | err = device_register(&phydev->dev); | ||
87 | |||
88 | if (err) | ||
89 | printk(KERN_ERR "phy %d failed to register\n", | ||
90 | i); | ||
91 | } | ||
92 | |||
93 | bus->phy_map[i] = phydev; | ||
94 | } | ||
95 | |||
96 | pr_info("%s: probed\n", bus->name); | ||
97 | |||
98 | return err; | ||
99 | } | ||
100 | EXPORT_SYMBOL(mdiobus_register); | ||
101 | |||
102 | void mdiobus_unregister(struct mii_bus *bus) | ||
103 | { | ||
104 | int i; | ||
105 | |||
106 | for (i = 0; i < PHY_MAX_ADDR; i++) { | ||
107 | if (bus->phy_map[i]) { | ||
108 | device_unregister(&bus->phy_map[i]->dev); | ||
109 | kfree(bus->phy_map[i]); | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | EXPORT_SYMBOL(mdiobus_unregister); | ||
114 | |||
115 | /* mdio_bus_match | ||
116 | * | ||
117 | * description: Given a PHY device, and a PHY driver, return 1 if | ||
118 | * the driver supports the device. Otherwise, return 0 | ||
119 | */ | ||
120 | static int mdio_bus_match(struct device *dev, struct device_driver *drv) | ||
121 | { | ||
122 | struct phy_device *phydev = to_phy_device(dev); | ||
123 | struct phy_driver *phydrv = to_phy_driver(drv); | ||
124 | |||
125 | return (phydrv->phy_id == (phydev->phy_id & phydrv->phy_id_mask)); | ||
126 | } | ||
127 | |||
128 | /* Suspend and resume. Copied from platform_suspend and | ||
129 | * platform_resume | ||
130 | */ | ||
131 | static int mdio_bus_suspend(struct device * dev, u32 state) | ||
132 | { | ||
133 | int ret = 0; | ||
134 | struct device_driver *drv = dev->driver; | ||
135 | |||
136 | if (drv && drv->suspend) { | ||
137 | ret = drv->suspend(dev, state, SUSPEND_DISABLE); | ||
138 | if (ret == 0) | ||
139 | ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE); | ||
140 | if (ret == 0) | ||
141 | ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN); | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static int mdio_bus_resume(struct device * dev) | ||
147 | { | ||
148 | int ret = 0; | ||
149 | struct device_driver *drv = dev->driver; | ||
150 | |||
151 | if (drv && drv->resume) { | ||
152 | ret = drv->resume(dev, RESUME_POWER_ON); | ||
153 | if (ret == 0) | ||
154 | ret = drv->resume(dev, RESUME_RESTORE_STATE); | ||
155 | if (ret == 0) | ||
156 | ret = drv->resume(dev, RESUME_ENABLE); | ||
157 | } | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | struct bus_type mdio_bus_type = { | ||
162 | .name = "mdio_bus", | ||
163 | .match = mdio_bus_match, | ||
164 | .suspend = mdio_bus_suspend, | ||
165 | .resume = mdio_bus_resume, | ||
166 | }; | ||
167 | |||
168 | int __init mdio_bus_init(void) | ||
169 | { | ||
170 | return bus_register(&mdio_bus_type); | ||
171 | } | ||
172 | |||
173 | void __exit mdio_bus_exit(void) | ||
174 | { | ||
175 | bus_unregister(&mdio_bus_type); | ||
176 | } | ||
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c new file mode 100644 index 000000000000..d9e11f93bf3a --- /dev/null +++ b/drivers/net/phy/phy.c | |||
@@ -0,0 +1,871 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/phy.c | ||
3 | * | ||
4 | * Framework for configuring and reading PHY devices | ||
5 | * Based on code in sungem_phy.c and gianfar_phy.c | ||
6 | * | ||
7 | * Author: Andy Fleming | ||
8 | * | ||
9 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/config.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/unistd.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/etherdevice.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/version.h> | ||
34 | #include <linux/mii.h> | ||
35 | #include <linux/ethtool.h> | ||
36 | #include <linux/phy.h> | ||
37 | |||
38 | #include <asm/io.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | |||
42 | /* Convenience function to print out the current phy status | ||
43 | */ | ||
44 | void phy_print_status(struct phy_device *phydev) | ||
45 | { | ||
46 | pr_info("%s: Link is %s", phydev->dev.bus_id, | ||
47 | phydev->link ? "Up" : "Down"); | ||
48 | if (phydev->link) | ||
49 | printk(" - %d/%s", phydev->speed, | ||
50 | DUPLEX_FULL == phydev->duplex ? | ||
51 | "Full" : "Half"); | ||
52 | |||
53 | printk("\n"); | ||
54 | } | ||
55 | EXPORT_SYMBOL(phy_print_status); | ||
56 | |||
57 | |||
58 | /* Convenience functions for reading/writing a given PHY | ||
59 | * register. They MUST NOT be called from interrupt context, | ||
60 | * because the bus read/write functions may wait for an interrupt | ||
61 | * to conclude the operation. */ | ||
62 | int phy_read(struct phy_device *phydev, u16 regnum) | ||
63 | { | ||
64 | int retval; | ||
65 | struct mii_bus *bus = phydev->bus; | ||
66 | |||
67 | spin_lock_bh(&bus->mdio_lock); | ||
68 | retval = bus->read(bus, phydev->addr, regnum); | ||
69 | spin_unlock_bh(&bus->mdio_lock); | ||
70 | |||
71 | return retval; | ||
72 | } | ||
73 | EXPORT_SYMBOL(phy_read); | ||
74 | |||
75 | int phy_write(struct phy_device *phydev, u16 regnum, u16 val) | ||
76 | { | ||
77 | int err; | ||
78 | struct mii_bus *bus = phydev->bus; | ||
79 | |||
80 | spin_lock_bh(&bus->mdio_lock); | ||
81 | err = bus->write(bus, phydev->addr, regnum, val); | ||
82 | spin_unlock_bh(&bus->mdio_lock); | ||
83 | |||
84 | return err; | ||
85 | } | ||
86 | EXPORT_SYMBOL(phy_write); | ||
87 | |||
88 | |||
89 | int phy_clear_interrupt(struct phy_device *phydev) | ||
90 | { | ||
91 | int err = 0; | ||
92 | |||
93 | if (phydev->drv->ack_interrupt) | ||
94 | err = phydev->drv->ack_interrupt(phydev); | ||
95 | |||
96 | return err; | ||
97 | } | ||
98 | |||
99 | |||
100 | int phy_config_interrupt(struct phy_device *phydev, u32 interrupts) | ||
101 | { | ||
102 | int err = 0; | ||
103 | |||
104 | phydev->interrupts = interrupts; | ||
105 | if (phydev->drv->config_intr) | ||
106 | err = phydev->drv->config_intr(phydev); | ||
107 | |||
108 | return err; | ||
109 | } | ||
110 | |||
111 | |||
112 | /* phy_aneg_done | ||
113 | * | ||
114 | * description: Reads the status register and returns 0 either if | ||
115 | * auto-negotiation is incomplete, or if there was an error. | ||
116 | * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done. | ||
117 | */ | ||
118 | static inline int phy_aneg_done(struct phy_device *phydev) | ||
119 | { | ||
120 | int retval; | ||
121 | |||
122 | retval = phy_read(phydev, MII_BMSR); | ||
123 | |||
124 | return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); | ||
125 | } | ||
126 | |||
127 | /* A structure for mapping a particular speed and duplex | ||
128 | * combination to a particular SUPPORTED and ADVERTISED value */ | ||
129 | struct phy_setting { | ||
130 | int speed; | ||
131 | int duplex; | ||
132 | u32 setting; | ||
133 | }; | ||
134 | |||
135 | /* A mapping of all SUPPORTED settings to speed/duplex */ | ||
136 | static struct phy_setting settings[] = { | ||
137 | { | ||
138 | .speed = 10000, | ||
139 | .duplex = DUPLEX_FULL, | ||
140 | .setting = SUPPORTED_10000baseT_Full, | ||
141 | }, | ||
142 | { | ||
143 | .speed = SPEED_1000, | ||
144 | .duplex = DUPLEX_FULL, | ||
145 | .setting = SUPPORTED_1000baseT_Full, | ||
146 | }, | ||
147 | { | ||
148 | .speed = SPEED_1000, | ||
149 | .duplex = DUPLEX_HALF, | ||
150 | .setting = SUPPORTED_1000baseT_Half, | ||
151 | }, | ||
152 | { | ||
153 | .speed = SPEED_100, | ||
154 | .duplex = DUPLEX_FULL, | ||
155 | .setting = SUPPORTED_100baseT_Full, | ||
156 | }, | ||
157 | { | ||
158 | .speed = SPEED_100, | ||
159 | .duplex = DUPLEX_HALF, | ||
160 | .setting = SUPPORTED_100baseT_Half, | ||
161 | }, | ||
162 | { | ||
163 | .speed = SPEED_10, | ||
164 | .duplex = DUPLEX_FULL, | ||
165 | .setting = SUPPORTED_10baseT_Full, | ||
166 | }, | ||
167 | { | ||
168 | .speed = SPEED_10, | ||
169 | .duplex = DUPLEX_HALF, | ||
170 | .setting = SUPPORTED_10baseT_Half, | ||
171 | }, | ||
172 | }; | ||
173 | |||
174 | #define MAX_NUM_SETTINGS (sizeof(settings)/sizeof(struct phy_setting)) | ||
175 | |||
176 | /* phy_find_setting | ||
177 | * | ||
178 | * description: Searches the settings array for the setting which | ||
179 | * matches the desired speed and duplex, and returns the index | ||
180 | * of that setting. Returns the index of the last setting if | ||
181 | * none of the others match. | ||
182 | */ | ||
183 | static inline int phy_find_setting(int speed, int duplex) | ||
184 | { | ||
185 | int idx = 0; | ||
186 | |||
187 | while (idx < ARRAY_SIZE(settings) && | ||
188 | (settings[idx].speed != speed || | ||
189 | settings[idx].duplex != duplex)) | ||
190 | idx++; | ||
191 | |||
192 | return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; | ||
193 | } | ||
194 | |||
195 | /* phy_find_valid | ||
196 | * idx: The first index in settings[] to search | ||
197 | * features: A mask of the valid settings | ||
198 | * | ||
199 | * description: Returns the index of the first valid setting less | ||
200 | * than or equal to the one pointed to by idx, as determined by | ||
201 | * the mask in features. Returns the index of the last setting | ||
202 | * if nothing else matches. | ||
203 | */ | ||
204 | static inline int phy_find_valid(int idx, u32 features) | ||
205 | { | ||
206 | while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) | ||
207 | idx++; | ||
208 | |||
209 | return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; | ||
210 | } | ||
211 | |||
212 | /* phy_sanitize_settings | ||
213 | * | ||
214 | * description: Make sure the PHY is set to supported speeds and | ||
215 | * duplexes. Drop down by one in this order: 1000/FULL, | ||
216 | * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF | ||
217 | */ | ||
218 | void phy_sanitize_settings(struct phy_device *phydev) | ||
219 | { | ||
220 | u32 features = phydev->supported; | ||
221 | int idx; | ||
222 | |||
223 | /* Sanitize settings based on PHY capabilities */ | ||
224 | if ((features & SUPPORTED_Autoneg) == 0) | ||
225 | phydev->autoneg = 0; | ||
226 | |||
227 | idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex), | ||
228 | features); | ||
229 | |||
230 | phydev->speed = settings[idx].speed; | ||
231 | phydev->duplex = settings[idx].duplex; | ||
232 | } | ||
233 | EXPORT_SYMBOL(phy_sanitize_settings); | ||
234 | |||
235 | /* phy_ethtool_sset: | ||
236 | * A generic ethtool sset function. Handles all the details | ||
237 | * | ||
238 | * A few notes about parameter checking: | ||
239 | * - We don't set port or transceiver, so we don't care what they | ||
240 | * were set to. | ||
241 | * - phy_start_aneg() will make sure forced settings are sane, and | ||
242 | * choose the next best ones from the ones selected, so we don't | ||
243 | * care if ethtool tries to give us bad values | ||
244 | * | ||
245 | * A note about the PHYCONTROL Layer. If you turn off | ||
246 | * CONFIG_PHYCONTROL, you will need to read the PHY status | ||
247 | * registers after this function completes, and update your | ||
248 | * controller manually. | ||
249 | */ | ||
250 | int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) | ||
251 | { | ||
252 | if (cmd->phy_address != phydev->addr) | ||
253 | return -EINVAL; | ||
254 | |||
255 | /* We make sure that we don't pass unsupported | ||
256 | * values in to the PHY */ | ||
257 | cmd->advertising &= phydev->supported; | ||
258 | |||
259 | /* Verify the settings we care about. */ | ||
260 | if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) | ||
261 | return -EINVAL; | ||
262 | |||
263 | if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0) | ||
264 | return -EINVAL; | ||
265 | |||
266 | if (cmd->autoneg == AUTONEG_DISABLE | ||
267 | && ((cmd->speed != SPEED_1000 | ||
268 | && cmd->speed != SPEED_100 | ||
269 | && cmd->speed != SPEED_10) | ||
270 | || (cmd->duplex != DUPLEX_HALF | ||
271 | && cmd->duplex != DUPLEX_FULL))) | ||
272 | return -EINVAL; | ||
273 | |||
274 | phydev->autoneg = cmd->autoneg; | ||
275 | |||
276 | phydev->speed = cmd->speed; | ||
277 | |||
278 | phydev->advertising = cmd->advertising; | ||
279 | |||
280 | if (AUTONEG_ENABLE == cmd->autoneg) | ||
281 | phydev->advertising |= ADVERTISED_Autoneg; | ||
282 | else | ||
283 | phydev->advertising &= ~ADVERTISED_Autoneg; | ||
284 | |||
285 | phydev->duplex = cmd->duplex; | ||
286 | |||
287 | /* Restart the PHY */ | ||
288 | phy_start_aneg(phydev); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) | ||
294 | { | ||
295 | cmd->supported = phydev->supported; | ||
296 | |||
297 | cmd->advertising = phydev->advertising; | ||
298 | |||
299 | cmd->speed = phydev->speed; | ||
300 | cmd->duplex = phydev->duplex; | ||
301 | cmd->port = PORT_MII; | ||
302 | cmd->phy_address = phydev->addr; | ||
303 | cmd->transceiver = XCVR_EXTERNAL; | ||
304 | cmd->autoneg = phydev->autoneg; | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | |||
310 | /* Note that this function is currently incompatible with the | ||
311 | * PHYCONTROL layer. It changes registers without regard to | ||
312 | * current state. Use at own risk | ||
313 | */ | ||
314 | int phy_mii_ioctl(struct phy_device *phydev, | ||
315 | struct mii_ioctl_data *mii_data, int cmd) | ||
316 | { | ||
317 | u16 val = mii_data->val_in; | ||
318 | |||
319 | switch (cmd) { | ||
320 | case SIOCGMIIPHY: | ||
321 | mii_data->phy_id = phydev->addr; | ||
322 | break; | ||
323 | case SIOCGMIIREG: | ||
324 | mii_data->val_out = phy_read(phydev, mii_data->reg_num); | ||
325 | break; | ||
326 | |||
327 | case SIOCSMIIREG: | ||
328 | if (!capable(CAP_NET_ADMIN)) | ||
329 | return -EPERM; | ||
330 | |||
331 | if (mii_data->phy_id == phydev->addr) { | ||
332 | switch(mii_data->reg_num) { | ||
333 | case MII_BMCR: | ||
334 | if (val & (BMCR_RESET|BMCR_ANENABLE)) | ||
335 | phydev->autoneg = AUTONEG_DISABLE; | ||
336 | else | ||
337 | phydev->autoneg = AUTONEG_ENABLE; | ||
338 | if ((!phydev->autoneg) && (val & BMCR_FULLDPLX)) | ||
339 | phydev->duplex = DUPLEX_FULL; | ||
340 | else | ||
341 | phydev->duplex = DUPLEX_HALF; | ||
342 | break; | ||
343 | case MII_ADVERTISE: | ||
344 | phydev->advertising = val; | ||
345 | break; | ||
346 | default: | ||
347 | /* do nothing */ | ||
348 | break; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | phy_write(phydev, mii_data->reg_num, val); | ||
353 | |||
354 | if (mii_data->reg_num == MII_BMCR | ||
355 | && val & BMCR_RESET | ||
356 | && phydev->drv->config_init) | ||
357 | phydev->drv->config_init(phydev); | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | /* phy_start_aneg | ||
365 | * | ||
366 | * description: Sanitizes the settings (if we're not | ||
367 | * autonegotiating them), and then calls the driver's | ||
368 | * config_aneg function. If the PHYCONTROL Layer is operating, | ||
369 | * we change the state to reflect the beginning of | ||
370 | * Auto-negotiation or forcing. | ||
371 | */ | ||
372 | int phy_start_aneg(struct phy_device *phydev) | ||
373 | { | ||
374 | int err; | ||
375 | |||
376 | spin_lock(&phydev->lock); | ||
377 | |||
378 | if (AUTONEG_DISABLE == phydev->autoneg) | ||
379 | phy_sanitize_settings(phydev); | ||
380 | |||
381 | err = phydev->drv->config_aneg(phydev); | ||
382 | |||
383 | #ifdef CONFIG_PHYCONTROL | ||
384 | if (err < 0) | ||
385 | goto out_unlock; | ||
386 | |||
387 | if (phydev->state != PHY_HALTED) { | ||
388 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
389 | phydev->state = PHY_AN; | ||
390 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
391 | } else { | ||
392 | phydev->state = PHY_FORCING; | ||
393 | phydev->link_timeout = PHY_FORCE_TIMEOUT; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | out_unlock: | ||
398 | #endif | ||
399 | spin_unlock(&phydev->lock); | ||
400 | return err; | ||
401 | } | ||
402 | EXPORT_SYMBOL(phy_start_aneg); | ||
403 | |||
404 | |||
405 | #ifdef CONFIG_PHYCONTROL | ||
406 | static void phy_change(void *data); | ||
407 | static void phy_timer(unsigned long data); | ||
408 | |||
409 | /* phy_start_machine: | ||
410 | * | ||
411 | * description: The PHY infrastructure can run a state machine | ||
412 | * which tracks whether the PHY is starting up, negotiating, | ||
413 | * etc. This function starts the timer which tracks the state | ||
414 | * of the PHY. If you want to be notified when the state | ||
415 | * changes, pass in the callback, otherwise, pass NULL. If you | ||
416 | * want to maintain your own state machine, do not call this | ||
417 | * function. */ | ||
418 | void phy_start_machine(struct phy_device *phydev, | ||
419 | void (*handler)(struct net_device *)) | ||
420 | { | ||
421 | phydev->adjust_state = handler; | ||
422 | |||
423 | init_timer(&phydev->phy_timer); | ||
424 | phydev->phy_timer.function = &phy_timer; | ||
425 | phydev->phy_timer.data = (unsigned long) phydev; | ||
426 | mod_timer(&phydev->phy_timer, jiffies + HZ); | ||
427 | } | ||
428 | |||
429 | /* phy_stop_machine | ||
430 | * | ||
431 | * description: Stops the state machine timer, sets the state to | ||
432 | * UP (unless it wasn't up yet), and then frees the interrupt, | ||
433 | * if it is in use. This function must be called BEFORE | ||
434 | * phy_detach. | ||
435 | */ | ||
436 | void phy_stop_machine(struct phy_device *phydev) | ||
437 | { | ||
438 | del_timer_sync(&phydev->phy_timer); | ||
439 | |||
440 | spin_lock(&phydev->lock); | ||
441 | if (phydev->state > PHY_UP) | ||
442 | phydev->state = PHY_UP; | ||
443 | spin_unlock(&phydev->lock); | ||
444 | |||
445 | if (phydev->irq != PHY_POLL) | ||
446 | phy_stop_interrupts(phydev); | ||
447 | |||
448 | phydev->adjust_state = NULL; | ||
449 | } | ||
450 | |||
451 | /* phy_force_reduction | ||
452 | * | ||
453 | * description: Reduces the speed/duplex settings by | ||
454 | * one notch. The order is so: | ||
455 | * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF, | ||
456 | * 10/FULL, 10/HALF. The function bottoms out at 10/HALF. | ||
457 | */ | ||
458 | static void phy_force_reduction(struct phy_device *phydev) | ||
459 | { | ||
460 | int idx; | ||
461 | |||
462 | idx = phy_find_setting(phydev->speed, phydev->duplex); | ||
463 | |||
464 | idx++; | ||
465 | |||
466 | idx = phy_find_valid(idx, phydev->supported); | ||
467 | |||
468 | phydev->speed = settings[idx].speed; | ||
469 | phydev->duplex = settings[idx].duplex; | ||
470 | |||
471 | pr_info("Trying %d/%s\n", phydev->speed, | ||
472 | DUPLEX_FULL == phydev->duplex ? | ||
473 | "FULL" : "HALF"); | ||
474 | } | ||
475 | |||
476 | |||
477 | /* phy_error: | ||
478 | * | ||
479 | * Moves the PHY to the HALTED state in response to a read | ||
480 | * or write error, and tells the controller the link is down. | ||
481 | * Must not be called from interrupt context, or while the | ||
482 | * phydev->lock is held. | ||
483 | */ | ||
484 | void phy_error(struct phy_device *phydev) | ||
485 | { | ||
486 | spin_lock(&phydev->lock); | ||
487 | phydev->state = PHY_HALTED; | ||
488 | spin_unlock(&phydev->lock); | ||
489 | } | ||
490 | |||
491 | /* phy_interrupt | ||
492 | * | ||
493 | * description: When a PHY interrupt occurs, the handler disables | ||
494 | * interrupts, and schedules a work task to clear the interrupt. | ||
495 | */ | ||
496 | static irqreturn_t phy_interrupt(int irq, void *phy_dat, struct pt_regs *regs) | ||
497 | { | ||
498 | struct phy_device *phydev = phy_dat; | ||
499 | |||
500 | /* The MDIO bus is not allowed to be written in interrupt | ||
501 | * context, so we need to disable the irq here. A work | ||
502 | * queue will write the PHY to disable and clear the | ||
503 | * interrupt, and then reenable the irq line. */ | ||
504 | disable_irq_nosync(irq); | ||
505 | |||
506 | schedule_work(&phydev->phy_queue); | ||
507 | |||
508 | return IRQ_HANDLED; | ||
509 | } | ||
510 | |||
511 | /* Enable the interrupts from the PHY side */ | ||
512 | int phy_enable_interrupts(struct phy_device *phydev) | ||
513 | { | ||
514 | int err; | ||
515 | |||
516 | err = phy_clear_interrupt(phydev); | ||
517 | |||
518 | if (err < 0) | ||
519 | return err; | ||
520 | |||
521 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); | ||
522 | |||
523 | return err; | ||
524 | } | ||
525 | EXPORT_SYMBOL(phy_enable_interrupts); | ||
526 | |||
527 | /* Disable the PHY interrupts from the PHY side */ | ||
528 | int phy_disable_interrupts(struct phy_device *phydev) | ||
529 | { | ||
530 | int err; | ||
531 | |||
532 | /* Disable PHY interrupts */ | ||
533 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); | ||
534 | |||
535 | if (err) | ||
536 | goto phy_err; | ||
537 | |||
538 | /* Clear the interrupt */ | ||
539 | err = phy_clear_interrupt(phydev); | ||
540 | |||
541 | if (err) | ||
542 | goto phy_err; | ||
543 | |||
544 | return 0; | ||
545 | |||
546 | phy_err: | ||
547 | phy_error(phydev); | ||
548 | |||
549 | return err; | ||
550 | } | ||
551 | EXPORT_SYMBOL(phy_disable_interrupts); | ||
552 | |||
553 | /* phy_start_interrupts | ||
554 | * | ||
555 | * description: Request the interrupt for the given PHY. If | ||
556 | * this fails, then we set irq to PHY_POLL. | ||
557 | * Otherwise, we enable the interrupts in the PHY. | ||
558 | * Returns 0 on success. | ||
559 | * This should only be called with a valid IRQ number. | ||
560 | */ | ||
561 | int phy_start_interrupts(struct phy_device *phydev) | ||
562 | { | ||
563 | int err = 0; | ||
564 | |||
565 | INIT_WORK(&phydev->phy_queue, phy_change, phydev); | ||
566 | |||
567 | if (request_irq(phydev->irq, phy_interrupt, | ||
568 | SA_SHIRQ, | ||
569 | "phy_interrupt", | ||
570 | phydev) < 0) { | ||
571 | printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", | ||
572 | phydev->bus->name, | ||
573 | phydev->irq); | ||
574 | phydev->irq = PHY_POLL; | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | err = phy_enable_interrupts(phydev); | ||
579 | |||
580 | return err; | ||
581 | } | ||
582 | EXPORT_SYMBOL(phy_start_interrupts); | ||
583 | |||
584 | int phy_stop_interrupts(struct phy_device *phydev) | ||
585 | { | ||
586 | int err; | ||
587 | |||
588 | err = phy_disable_interrupts(phydev); | ||
589 | |||
590 | if (err) | ||
591 | phy_error(phydev); | ||
592 | |||
593 | free_irq(phydev->irq, phydev); | ||
594 | |||
595 | return err; | ||
596 | } | ||
597 | EXPORT_SYMBOL(phy_stop_interrupts); | ||
598 | |||
599 | |||
600 | /* Scheduled by the phy_interrupt/timer to handle PHY changes */ | ||
601 | static void phy_change(void *data) | ||
602 | { | ||
603 | int err; | ||
604 | struct phy_device *phydev = data; | ||
605 | |||
606 | err = phy_disable_interrupts(phydev); | ||
607 | |||
608 | if (err) | ||
609 | goto phy_err; | ||
610 | |||
611 | spin_lock(&phydev->lock); | ||
612 | if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) | ||
613 | phydev->state = PHY_CHANGELINK; | ||
614 | spin_unlock(&phydev->lock); | ||
615 | |||
616 | enable_irq(phydev->irq); | ||
617 | |||
618 | /* Reenable interrupts */ | ||
619 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); | ||
620 | |||
621 | if (err) | ||
622 | goto irq_enable_err; | ||
623 | |||
624 | return; | ||
625 | |||
626 | irq_enable_err: | ||
627 | disable_irq(phydev->irq); | ||
628 | phy_err: | ||
629 | phy_error(phydev); | ||
630 | } | ||
631 | |||
632 | /* Bring down the PHY link, and stop checking the status. */ | ||
633 | void phy_stop(struct phy_device *phydev) | ||
634 | { | ||
635 | spin_lock(&phydev->lock); | ||
636 | |||
637 | if (PHY_HALTED == phydev->state) | ||
638 | goto out_unlock; | ||
639 | |||
640 | if (phydev->irq != PHY_POLL) { | ||
641 | /* Clear any pending interrupts */ | ||
642 | phy_clear_interrupt(phydev); | ||
643 | |||
644 | /* Disable PHY Interrupts */ | ||
645 | phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); | ||
646 | } | ||
647 | |||
648 | phydev->state = PHY_HALTED; | ||
649 | |||
650 | out_unlock: | ||
651 | spin_unlock(&phydev->lock); | ||
652 | } | ||
653 | |||
654 | |||
655 | /* phy_start | ||
656 | * | ||
657 | * description: Indicates the attached device's readiness to | ||
658 | * handle PHY-related work. Used during startup to start the | ||
659 | * PHY, and after a call to phy_stop() to resume operation. | ||
660 | * Also used to indicate the MDIO bus has cleared an error | ||
661 | * condition. | ||
662 | */ | ||
663 | void phy_start(struct phy_device *phydev) | ||
664 | { | ||
665 | spin_lock(&phydev->lock); | ||
666 | |||
667 | switch (phydev->state) { | ||
668 | case PHY_STARTING: | ||
669 | phydev->state = PHY_PENDING; | ||
670 | break; | ||
671 | case PHY_READY: | ||
672 | phydev->state = PHY_UP; | ||
673 | break; | ||
674 | case PHY_HALTED: | ||
675 | phydev->state = PHY_RESUMING; | ||
676 | default: | ||
677 | break; | ||
678 | } | ||
679 | spin_unlock(&phydev->lock); | ||
680 | } | ||
681 | EXPORT_SYMBOL(phy_stop); | ||
682 | EXPORT_SYMBOL(phy_start); | ||
683 | |||
684 | /* PHY timer which handles the state machine */ | ||
685 | static void phy_timer(unsigned long data) | ||
686 | { | ||
687 | struct phy_device *phydev = (struct phy_device *)data; | ||
688 | int needs_aneg = 0; | ||
689 | int err = 0; | ||
690 | |||
691 | spin_lock(&phydev->lock); | ||
692 | |||
693 | if (phydev->adjust_state) | ||
694 | phydev->adjust_state(phydev->attached_dev); | ||
695 | |||
696 | switch(phydev->state) { | ||
697 | case PHY_DOWN: | ||
698 | case PHY_STARTING: | ||
699 | case PHY_READY: | ||
700 | case PHY_PENDING: | ||
701 | break; | ||
702 | case PHY_UP: | ||
703 | needs_aneg = 1; | ||
704 | |||
705 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
706 | |||
707 | break; | ||
708 | case PHY_AN: | ||
709 | /* Check if negotiation is done. Break | ||
710 | * if there's an error */ | ||
711 | err = phy_aneg_done(phydev); | ||
712 | if (err < 0) | ||
713 | break; | ||
714 | |||
715 | /* If auto-negotiation is done, we change to | ||
716 | * either RUNNING, or NOLINK */ | ||
717 | if (err > 0) { | ||
718 | err = phy_read_status(phydev); | ||
719 | |||
720 | if (err) | ||
721 | break; | ||
722 | |||
723 | if (phydev->link) { | ||
724 | phydev->state = PHY_RUNNING; | ||
725 | netif_carrier_on(phydev->attached_dev); | ||
726 | } else { | ||
727 | phydev->state = PHY_NOLINK; | ||
728 | netif_carrier_off(phydev->attached_dev); | ||
729 | } | ||
730 | |||
731 | phydev->adjust_link(phydev->attached_dev); | ||
732 | |||
733 | } else if (0 == phydev->link_timeout--) { | ||
734 | /* The counter expired, so either we | ||
735 | * switch to forced mode, or the | ||
736 | * magic_aneg bit exists, and we try aneg | ||
737 | * again */ | ||
738 | if (!(phydev->drv->flags & PHY_HAS_MAGICANEG)) { | ||
739 | int idx; | ||
740 | |||
741 | /* We'll start from the | ||
742 | * fastest speed, and work | ||
743 | * our way down */ | ||
744 | idx = phy_find_valid(0, | ||
745 | phydev->supported); | ||
746 | |||
747 | phydev->speed = settings[idx].speed; | ||
748 | phydev->duplex = settings[idx].duplex; | ||
749 | |||
750 | phydev->autoneg = AUTONEG_DISABLE; | ||
751 | phydev->state = PHY_FORCING; | ||
752 | phydev->link_timeout = | ||
753 | PHY_FORCE_TIMEOUT; | ||
754 | |||
755 | pr_info("Trying %d/%s\n", | ||
756 | phydev->speed, | ||
757 | DUPLEX_FULL == | ||
758 | phydev->duplex ? | ||
759 | "FULL" : "HALF"); | ||
760 | } | ||
761 | |||
762 | needs_aneg = 1; | ||
763 | } | ||
764 | break; | ||
765 | case PHY_NOLINK: | ||
766 | err = phy_read_status(phydev); | ||
767 | |||
768 | if (err) | ||
769 | break; | ||
770 | |||
771 | if (phydev->link) { | ||
772 | phydev->state = PHY_RUNNING; | ||
773 | netif_carrier_on(phydev->attached_dev); | ||
774 | phydev->adjust_link(phydev->attached_dev); | ||
775 | } | ||
776 | break; | ||
777 | case PHY_FORCING: | ||
778 | err = phy_read_status(phydev); | ||
779 | |||
780 | if (err) | ||
781 | break; | ||
782 | |||
783 | if (phydev->link) { | ||
784 | phydev->state = PHY_RUNNING; | ||
785 | netif_carrier_on(phydev->attached_dev); | ||
786 | } else { | ||
787 | if (0 == phydev->link_timeout--) { | ||
788 | phy_force_reduction(phydev); | ||
789 | needs_aneg = 1; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | phydev->adjust_link(phydev->attached_dev); | ||
794 | break; | ||
795 | case PHY_RUNNING: | ||
796 | /* Only register a CHANGE if we are | ||
797 | * polling */ | ||
798 | if (PHY_POLL == phydev->irq) | ||
799 | phydev->state = PHY_CHANGELINK; | ||
800 | break; | ||
801 | case PHY_CHANGELINK: | ||
802 | err = phy_read_status(phydev); | ||
803 | |||
804 | if (err) | ||
805 | break; | ||
806 | |||
807 | if (phydev->link) { | ||
808 | phydev->state = PHY_RUNNING; | ||
809 | netif_carrier_on(phydev->attached_dev); | ||
810 | } else { | ||
811 | phydev->state = PHY_NOLINK; | ||
812 | netif_carrier_off(phydev->attached_dev); | ||
813 | } | ||
814 | |||
815 | phydev->adjust_link(phydev->attached_dev); | ||
816 | |||
817 | if (PHY_POLL != phydev->irq) | ||
818 | err = phy_config_interrupt(phydev, | ||
819 | PHY_INTERRUPT_ENABLED); | ||
820 | break; | ||
821 | case PHY_HALTED: | ||
822 | if (phydev->link) { | ||
823 | phydev->link = 0; | ||
824 | netif_carrier_off(phydev->attached_dev); | ||
825 | phydev->adjust_link(phydev->attached_dev); | ||
826 | } | ||
827 | break; | ||
828 | case PHY_RESUMING: | ||
829 | |||
830 | err = phy_clear_interrupt(phydev); | ||
831 | |||
832 | if (err) | ||
833 | break; | ||
834 | |||
835 | err = phy_config_interrupt(phydev, | ||
836 | PHY_INTERRUPT_ENABLED); | ||
837 | |||
838 | if (err) | ||
839 | break; | ||
840 | |||
841 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
842 | err = phy_aneg_done(phydev); | ||
843 | if (err < 0) | ||
844 | break; | ||
845 | |||
846 | /* err > 0 if AN is done. | ||
847 | * Otherwise, it's 0, and we're | ||
848 | * still waiting for AN */ | ||
849 | if (err > 0) { | ||
850 | phydev->state = PHY_RUNNING; | ||
851 | } else { | ||
852 | phydev->state = PHY_AN; | ||
853 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
854 | } | ||
855 | } else | ||
856 | phydev->state = PHY_RUNNING; | ||
857 | break; | ||
858 | } | ||
859 | |||
860 | spin_unlock(&phydev->lock); | ||
861 | |||
862 | if (needs_aneg) | ||
863 | err = phy_start_aneg(phydev); | ||
864 | |||
865 | if (err < 0) | ||
866 | phy_error(phydev); | ||
867 | |||
868 | mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ); | ||
869 | } | ||
870 | |||
871 | #endif /* CONFIG_PHYCONTROL */ | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c new file mode 100644 index 000000000000..33f7bdb5857c --- /dev/null +++ b/drivers/net/phy/phy_device.c | |||
@@ -0,0 +1,696 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/phy_device.c | ||
3 | * | ||
4 | * Framework for finding and configuring PHYs. | ||
5 | * Also contains generic PHY driver | ||
6 | * | ||
7 | * Author: Andy Fleming | ||
8 | * | ||
9 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/config.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/unistd.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/etherdevice.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/version.h> | ||
34 | #include <linux/mii.h> | ||
35 | #include <linux/ethtool.h> | ||
36 | #include <linux/phy.h> | ||
37 | |||
38 | #include <asm/io.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | |||
42 | static struct phy_driver genphy_driver; | ||
43 | extern int mdio_bus_init(void); | ||
44 | extern void mdio_bus_exit(void); | ||
45 | |||
46 | /* get_phy_device | ||
47 | * | ||
48 | * description: Reads the ID registers of the PHY at addr on the | ||
49 | * bus, then allocates and returns the phy_device to | ||
50 | * represent it. | ||
51 | */ | ||
52 | struct phy_device * get_phy_device(struct mii_bus *bus, int addr) | ||
53 | { | ||
54 | int phy_reg; | ||
55 | u32 phy_id; | ||
56 | struct phy_device *dev = NULL; | ||
57 | |||
58 | /* Grab the bits from PHYIR1, and put them | ||
59 | * in the upper half */ | ||
60 | phy_reg = bus->read(bus, addr, MII_PHYSID1); | ||
61 | |||
62 | if (phy_reg < 0) | ||
63 | return ERR_PTR(phy_reg); | ||
64 | |||
65 | phy_id = (phy_reg & 0xffff) << 16; | ||
66 | |||
67 | /* Grab the bits from PHYIR2, and put them in the lower half */ | ||
68 | phy_reg = bus->read(bus, addr, MII_PHYSID2); | ||
69 | |||
70 | if (phy_reg < 0) | ||
71 | return ERR_PTR(phy_reg); | ||
72 | |||
73 | phy_id |= (phy_reg & 0xffff); | ||
74 | |||
75 | /* If the phy_id is all Fs, there is no device there */ | ||
76 | if (0xffffffff == phy_id) | ||
77 | return NULL; | ||
78 | |||
79 | /* Otherwise, we allocate the device, and initialize the | ||
80 | * default values */ | ||
81 | dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); | ||
82 | |||
83 | if (NULL == dev) | ||
84 | return ERR_PTR(-ENOMEM); | ||
85 | |||
86 | dev->speed = 0; | ||
87 | dev->duplex = -1; | ||
88 | dev->pause = dev->asym_pause = 0; | ||
89 | dev->link = 1; | ||
90 | |||
91 | dev->autoneg = AUTONEG_ENABLE; | ||
92 | |||
93 | dev->addr = addr; | ||
94 | dev->phy_id = phy_id; | ||
95 | dev->bus = bus; | ||
96 | |||
97 | dev->state = PHY_DOWN; | ||
98 | |||
99 | spin_lock_init(&dev->lock); | ||
100 | |||
101 | return dev; | ||
102 | } | ||
103 | |||
104 | #ifdef CONFIG_PHYCONTROL | ||
105 | /* phy_prepare_link: | ||
106 | * | ||
107 | * description: Tells the PHY infrastructure to handle the | ||
108 | * gory details on monitoring link status (whether through | ||
109 | * polling or an interrupt), and to call back to the | ||
110 | * connected device driver when the link status changes. | ||
111 | * If you want to monitor your own link state, don't call | ||
112 | * this function */ | ||
113 | void phy_prepare_link(struct phy_device *phydev, | ||
114 | void (*handler)(struct net_device *)) | ||
115 | { | ||
116 | phydev->adjust_link = handler; | ||
117 | } | ||
118 | |||
119 | /* phy_connect: | ||
120 | * | ||
121 | * description: Convenience function for connecting ethernet | ||
122 | * devices to PHY devices. The default behavior is for | ||
123 | * the PHY infrastructure to handle everything, and only notify | ||
124 | * the connected driver when the link status changes. If you | ||
125 | * don't want, or can't use the provided functionality, you may | ||
126 | * choose to call only the subset of functions which provide | ||
127 | * the desired functionality. | ||
128 | */ | ||
129 | struct phy_device * phy_connect(struct net_device *dev, const char *phy_id, | ||
130 | void (*handler)(struct net_device *), u32 flags) | ||
131 | { | ||
132 | struct phy_device *phydev; | ||
133 | |||
134 | phydev = phy_attach(dev, phy_id, flags); | ||
135 | |||
136 | if (IS_ERR(phydev)) | ||
137 | return phydev; | ||
138 | |||
139 | phy_prepare_link(phydev, handler); | ||
140 | |||
141 | phy_start_machine(phydev, NULL); | ||
142 | |||
143 | if (phydev->irq > 0) | ||
144 | phy_start_interrupts(phydev); | ||
145 | |||
146 | return phydev; | ||
147 | } | ||
148 | EXPORT_SYMBOL(phy_connect); | ||
149 | |||
150 | void phy_disconnect(struct phy_device *phydev) | ||
151 | { | ||
152 | if (phydev->irq > 0) | ||
153 | phy_stop_interrupts(phydev); | ||
154 | |||
155 | phy_stop_machine(phydev); | ||
156 | |||
157 | phydev->adjust_link = NULL; | ||
158 | |||
159 | phy_detach(phydev); | ||
160 | } | ||
161 | EXPORT_SYMBOL(phy_disconnect); | ||
162 | |||
163 | #endif /* CONFIG_PHYCONTROL */ | ||
164 | |||
165 | /* phy_attach: | ||
166 | * | ||
167 | * description: Called by drivers to attach to a particular PHY | ||
168 | * device. The phy_device is found, and properly hooked up | ||
169 | * to the phy_driver. If no driver is attached, then the | ||
170 | * genphy_driver is used. The phy_device is given a ptr to | ||
171 | * the attaching device, and given a callback for link status | ||
172 | * change. The phy_device is returned to the attaching | ||
173 | * driver. | ||
174 | */ | ||
175 | static int phy_compare_id(struct device *dev, void *data) | ||
176 | { | ||
177 | return strcmp((char *)data, dev->bus_id) ? 0 : 1; | ||
178 | } | ||
179 | |||
180 | struct phy_device *phy_attach(struct net_device *dev, | ||
181 | const char *phy_id, u32 flags) | ||
182 | { | ||
183 | struct bus_type *bus = &mdio_bus_type; | ||
184 | struct phy_device *phydev; | ||
185 | struct device *d; | ||
186 | |||
187 | /* Search the list of PHY devices on the mdio bus for the | ||
188 | * PHY with the requested name */ | ||
189 | d = bus_find_device(bus, NULL, (void *)phy_id, phy_compare_id); | ||
190 | |||
191 | if (d) { | ||
192 | phydev = to_phy_device(d); | ||
193 | } else { | ||
194 | printk(KERN_ERR "%s not found\n", phy_id); | ||
195 | return ERR_PTR(-ENODEV); | ||
196 | } | ||
197 | |||
198 | /* Assume that if there is no driver, that it doesn't | ||
199 | * exist, and we should use the genphy driver. */ | ||
200 | if (NULL == d->driver) { | ||
201 | int err; | ||
202 | down_write(&d->bus->subsys.rwsem); | ||
203 | d->driver = &genphy_driver.driver; | ||
204 | |||
205 | err = d->driver->probe(d); | ||
206 | |||
207 | if (err < 0) | ||
208 | return ERR_PTR(err); | ||
209 | |||
210 | device_bind_driver(d); | ||
211 | up_write(&d->bus->subsys.rwsem); | ||
212 | } | ||
213 | |||
214 | if (phydev->attached_dev) { | ||
215 | printk(KERN_ERR "%s: %s already attached\n", | ||
216 | dev->name, phy_id); | ||
217 | return ERR_PTR(-EBUSY); | ||
218 | } | ||
219 | |||
220 | phydev->attached_dev = dev; | ||
221 | |||
222 | phydev->dev_flags = flags; | ||
223 | |||
224 | return phydev; | ||
225 | } | ||
226 | EXPORT_SYMBOL(phy_attach); | ||
227 | |||
228 | void phy_detach(struct phy_device *phydev) | ||
229 | { | ||
230 | phydev->attached_dev = NULL; | ||
231 | |||
232 | /* If the device had no specific driver before (i.e. - it | ||
233 | * was using the generic driver), we unbind the device | ||
234 | * from the generic driver so that there's a chance a | ||
235 | * real driver could be loaded */ | ||
236 | if (phydev->dev.driver == &genphy_driver.driver) { | ||
237 | down_write(&phydev->dev.bus->subsys.rwsem); | ||
238 | device_release_driver(&phydev->dev); | ||
239 | up_write(&phydev->dev.bus->subsys.rwsem); | ||
240 | } | ||
241 | } | ||
242 | EXPORT_SYMBOL(phy_detach); | ||
243 | |||
244 | |||
245 | /* Generic PHY support and helper functions */ | ||
246 | |||
247 | /* genphy_config_advert | ||
248 | * | ||
249 | * description: Writes MII_ADVERTISE with the appropriate values, | ||
250 | * after sanitizing the values to make sure we only advertise | ||
251 | * what is supported | ||
252 | */ | ||
253 | int genphy_config_advert(struct phy_device *phydev) | ||
254 | { | ||
255 | u32 advertise; | ||
256 | int adv; | ||
257 | int err; | ||
258 | |||
259 | /* Only allow advertising what | ||
260 | * this PHY supports */ | ||
261 | phydev->advertising &= phydev->supported; | ||
262 | advertise = phydev->advertising; | ||
263 | |||
264 | /* Setup standard advertisement */ | ||
265 | adv = phy_read(phydev, MII_ADVERTISE); | ||
266 | |||
267 | if (adv < 0) | ||
268 | return adv; | ||
269 | |||
270 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | | ||
271 | ADVERTISE_PAUSE_ASYM); | ||
272 | if (advertise & ADVERTISED_10baseT_Half) | ||
273 | adv |= ADVERTISE_10HALF; | ||
274 | if (advertise & ADVERTISED_10baseT_Full) | ||
275 | adv |= ADVERTISE_10FULL; | ||
276 | if (advertise & ADVERTISED_100baseT_Half) | ||
277 | adv |= ADVERTISE_100HALF; | ||
278 | if (advertise & ADVERTISED_100baseT_Full) | ||
279 | adv |= ADVERTISE_100FULL; | ||
280 | if (advertise & ADVERTISED_Pause) | ||
281 | adv |= ADVERTISE_PAUSE_CAP; | ||
282 | if (advertise & ADVERTISED_Asym_Pause) | ||
283 | adv |= ADVERTISE_PAUSE_ASYM; | ||
284 | |||
285 | err = phy_write(phydev, MII_ADVERTISE, adv); | ||
286 | |||
287 | if (err < 0) | ||
288 | return err; | ||
289 | |||
290 | /* Configure gigabit if it's supported */ | ||
291 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | ||
292 | SUPPORTED_1000baseT_Full)) { | ||
293 | adv = phy_read(phydev, MII_CTRL1000); | ||
294 | |||
295 | if (adv < 0) | ||
296 | return adv; | ||
297 | |||
298 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
299 | if (advertise & SUPPORTED_1000baseT_Half) | ||
300 | adv |= ADVERTISE_1000HALF; | ||
301 | if (advertise & SUPPORTED_1000baseT_Full) | ||
302 | adv |= ADVERTISE_1000FULL; | ||
303 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
304 | |||
305 | if (err < 0) | ||
306 | return err; | ||
307 | } | ||
308 | |||
309 | return adv; | ||
310 | } | ||
311 | EXPORT_SYMBOL(genphy_config_advert); | ||
312 | |||
313 | /* genphy_setup_forced | ||
314 | * | ||
315 | * description: Configures MII_BMCR to force speed/duplex | ||
316 | * to the values in phydev. Assumes that the values are valid. | ||
317 | * Please see phy_sanitize_settings() */ | ||
318 | int genphy_setup_forced(struct phy_device *phydev) | ||
319 | { | ||
320 | int ctl = BMCR_RESET; | ||
321 | |||
322 | phydev->pause = phydev->asym_pause = 0; | ||
323 | |||
324 | if (SPEED_1000 == phydev->speed) | ||
325 | ctl |= BMCR_SPEED1000; | ||
326 | else if (SPEED_100 == phydev->speed) | ||
327 | ctl |= BMCR_SPEED100; | ||
328 | |||
329 | if (DUPLEX_FULL == phydev->duplex) | ||
330 | ctl |= BMCR_FULLDPLX; | ||
331 | |||
332 | ctl = phy_write(phydev, MII_BMCR, ctl); | ||
333 | |||
334 | if (ctl < 0) | ||
335 | return ctl; | ||
336 | |||
337 | /* We just reset the device, so we'd better configure any | ||
338 | * settings the PHY requires to operate */ | ||
339 | if (phydev->drv->config_init) | ||
340 | ctl = phydev->drv->config_init(phydev); | ||
341 | |||
342 | return ctl; | ||
343 | } | ||
344 | |||
345 | |||
346 | /* Enable and Restart Autonegotiation */ | ||
347 | int genphy_restart_aneg(struct phy_device *phydev) | ||
348 | { | ||
349 | int ctl; | ||
350 | |||
351 | ctl = phy_read(phydev, MII_BMCR); | ||
352 | |||
353 | if (ctl < 0) | ||
354 | return ctl; | ||
355 | |||
356 | ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
357 | |||
358 | /* Don't isolate the PHY if we're negotiating */ | ||
359 | ctl &= ~(BMCR_ISOLATE); | ||
360 | |||
361 | ctl = phy_write(phydev, MII_BMCR, ctl); | ||
362 | |||
363 | return ctl; | ||
364 | } | ||
365 | |||
366 | |||
367 | /* genphy_config_aneg | ||
368 | * | ||
369 | * description: If auto-negotiation is enabled, we configure the | ||
370 | * advertising, and then restart auto-negotiation. If it is not | ||
371 | * enabled, then we write the BMCR | ||
372 | */ | ||
373 | int genphy_config_aneg(struct phy_device *phydev) | ||
374 | { | ||
375 | int err = 0; | ||
376 | |||
377 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
378 | err = genphy_config_advert(phydev); | ||
379 | |||
380 | if (err < 0) | ||
381 | return err; | ||
382 | |||
383 | err = genphy_restart_aneg(phydev); | ||
384 | } else | ||
385 | err = genphy_setup_forced(phydev); | ||
386 | |||
387 | return err; | ||
388 | } | ||
389 | EXPORT_SYMBOL(genphy_config_aneg); | ||
390 | |||
391 | /* genphy_update_link | ||
392 | * | ||
393 | * description: Update the value in phydev->link to reflect the | ||
394 | * current link value. In order to do this, we need to read | ||
395 | * the status register twice, keeping the second value | ||
396 | */ | ||
397 | int genphy_update_link(struct phy_device *phydev) | ||
398 | { | ||
399 | int status; | ||
400 | |||
401 | /* Do a fake read */ | ||
402 | status = phy_read(phydev, MII_BMSR); | ||
403 | |||
404 | if (status < 0) | ||
405 | return status; | ||
406 | |||
407 | /* Read link and autonegotiation status */ | ||
408 | status = phy_read(phydev, MII_BMSR); | ||
409 | |||
410 | if (status < 0) | ||
411 | return status; | ||
412 | |||
413 | if ((status & BMSR_LSTATUS) == 0) | ||
414 | phydev->link = 0; | ||
415 | else | ||
416 | phydev->link = 1; | ||
417 | |||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | /* genphy_read_status | ||
422 | * | ||
423 | * description: Check the link, then figure out the current state | ||
424 | * by comparing what we advertise with what the link partner | ||
425 | * advertises. Start by checking the gigabit possibilities, | ||
426 | * then move on to 10/100. | ||
427 | */ | ||
428 | int genphy_read_status(struct phy_device *phydev) | ||
429 | { | ||
430 | int adv; | ||
431 | int err; | ||
432 | int lpa; | ||
433 | int lpagb = 0; | ||
434 | |||
435 | /* Update the link, but return if there | ||
436 | * was an error */ | ||
437 | err = genphy_update_link(phydev); | ||
438 | if (err) | ||
439 | return err; | ||
440 | |||
441 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
442 | if (phydev->supported & (SUPPORTED_1000baseT_Half | ||
443 | | SUPPORTED_1000baseT_Full)) { | ||
444 | lpagb = phy_read(phydev, MII_STAT1000); | ||
445 | |||
446 | if (lpagb < 0) | ||
447 | return lpagb; | ||
448 | |||
449 | adv = phy_read(phydev, MII_CTRL1000); | ||
450 | |||
451 | if (adv < 0) | ||
452 | return adv; | ||
453 | |||
454 | lpagb &= adv << 2; | ||
455 | } | ||
456 | |||
457 | lpa = phy_read(phydev, MII_LPA); | ||
458 | |||
459 | if (lpa < 0) | ||
460 | return lpa; | ||
461 | |||
462 | adv = phy_read(phydev, MII_ADVERTISE); | ||
463 | |||
464 | if (adv < 0) | ||
465 | return adv; | ||
466 | |||
467 | lpa &= adv; | ||
468 | |||
469 | phydev->speed = SPEED_10; | ||
470 | phydev->duplex = DUPLEX_HALF; | ||
471 | phydev->pause = phydev->asym_pause = 0; | ||
472 | |||
473 | if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { | ||
474 | phydev->speed = SPEED_1000; | ||
475 | |||
476 | if (lpagb & LPA_1000FULL) | ||
477 | phydev->duplex = DUPLEX_FULL; | ||
478 | } else if (lpa & (LPA_100FULL | LPA_100HALF)) { | ||
479 | phydev->speed = SPEED_100; | ||
480 | |||
481 | if (lpa & LPA_100FULL) | ||
482 | phydev->duplex = DUPLEX_FULL; | ||
483 | } else | ||
484 | if (lpa & LPA_10FULL) | ||
485 | phydev->duplex = DUPLEX_FULL; | ||
486 | |||
487 | if (phydev->duplex == DUPLEX_FULL){ | ||
488 | phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; | ||
489 | phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; | ||
490 | } | ||
491 | } else { | ||
492 | int bmcr = phy_read(phydev, MII_BMCR); | ||
493 | if (bmcr < 0) | ||
494 | return bmcr; | ||
495 | |||
496 | if (bmcr & BMCR_FULLDPLX) | ||
497 | phydev->duplex = DUPLEX_FULL; | ||
498 | else | ||
499 | phydev->duplex = DUPLEX_HALF; | ||
500 | |||
501 | if (bmcr & BMCR_SPEED1000) | ||
502 | phydev->speed = SPEED_1000; | ||
503 | else if (bmcr & BMCR_SPEED100) | ||
504 | phydev->speed = SPEED_100; | ||
505 | else | ||
506 | phydev->speed = SPEED_10; | ||
507 | |||
508 | phydev->pause = phydev->asym_pause = 0; | ||
509 | } | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | EXPORT_SYMBOL(genphy_read_status); | ||
514 | |||
515 | static int genphy_config_init(struct phy_device *phydev) | ||
516 | { | ||
517 | u32 val; | ||
518 | u32 features; | ||
519 | |||
520 | /* For now, I'll claim that the generic driver supports | ||
521 | * all possible port types */ | ||
522 | features = (SUPPORTED_TP | SUPPORTED_MII | ||
523 | | SUPPORTED_AUI | SUPPORTED_FIBRE | | ||
524 | SUPPORTED_BNC); | ||
525 | |||
526 | /* Do we support autonegotiation? */ | ||
527 | val = phy_read(phydev, MII_BMSR); | ||
528 | |||
529 | if (val < 0) | ||
530 | return val; | ||
531 | |||
532 | if (val & BMSR_ANEGCAPABLE) | ||
533 | features |= SUPPORTED_Autoneg; | ||
534 | |||
535 | if (val & BMSR_100FULL) | ||
536 | features |= SUPPORTED_100baseT_Full; | ||
537 | if (val & BMSR_100HALF) | ||
538 | features |= SUPPORTED_100baseT_Half; | ||
539 | if (val & BMSR_10FULL) | ||
540 | features |= SUPPORTED_10baseT_Full; | ||
541 | if (val & BMSR_10HALF) | ||
542 | features |= SUPPORTED_10baseT_Half; | ||
543 | |||
544 | if (val & BMSR_ESTATEN) { | ||
545 | val = phy_read(phydev, MII_ESTATUS); | ||
546 | |||
547 | if (val < 0) | ||
548 | return val; | ||
549 | |||
550 | if (val & ESTATUS_1000_TFULL) | ||
551 | features |= SUPPORTED_1000baseT_Full; | ||
552 | if (val & ESTATUS_1000_THALF) | ||
553 | features |= SUPPORTED_1000baseT_Half; | ||
554 | } | ||
555 | |||
556 | phydev->supported = features; | ||
557 | phydev->advertising = features; | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | |||
563 | /* phy_probe | ||
564 | * | ||
565 | * description: Take care of setting up the phy_device structure, | ||
566 | * set the state to READY (the driver's init function should | ||
567 | * set it to STARTING if needed). | ||
568 | */ | ||
569 | static int phy_probe(struct device *dev) | ||
570 | { | ||
571 | struct phy_device *phydev; | ||
572 | struct phy_driver *phydrv; | ||
573 | struct device_driver *drv; | ||
574 | int err = 0; | ||
575 | |||
576 | phydev = to_phy_device(dev); | ||
577 | |||
578 | /* Make sure the driver is held. | ||
579 | * XXX -- Is this correct? */ | ||
580 | drv = get_driver(phydev->dev.driver); | ||
581 | phydrv = to_phy_driver(drv); | ||
582 | phydev->drv = phydrv; | ||
583 | |||
584 | /* Disable the interrupt if the PHY doesn't support it */ | ||
585 | if (!(phydrv->flags & PHY_HAS_INTERRUPT)) | ||
586 | phydev->irq = PHY_POLL; | ||
587 | |||
588 | spin_lock(&phydev->lock); | ||
589 | |||
590 | /* Start out supporting everything. Eventually, | ||
591 | * a controller will attach, and may modify one | ||
592 | * or both of these values */ | ||
593 | phydev->supported = phydrv->features; | ||
594 | phydev->advertising = phydrv->features; | ||
595 | |||
596 | /* Set the state to READY by default */ | ||
597 | phydev->state = PHY_READY; | ||
598 | |||
599 | if (phydev->drv->probe) | ||
600 | err = phydev->drv->probe(phydev); | ||
601 | |||
602 | spin_unlock(&phydev->lock); | ||
603 | |||
604 | if (err < 0) | ||
605 | return err; | ||
606 | |||
607 | if (phydev->drv->config_init) | ||
608 | err = phydev->drv->config_init(phydev); | ||
609 | |||
610 | return err; | ||
611 | } | ||
612 | |||
613 | static int phy_remove(struct device *dev) | ||
614 | { | ||
615 | struct phy_device *phydev; | ||
616 | |||
617 | phydev = to_phy_device(dev); | ||
618 | |||
619 | spin_lock(&phydev->lock); | ||
620 | phydev->state = PHY_DOWN; | ||
621 | spin_unlock(&phydev->lock); | ||
622 | |||
623 | if (phydev->drv->remove) | ||
624 | phydev->drv->remove(phydev); | ||
625 | |||
626 | put_driver(dev->driver); | ||
627 | phydev->drv = NULL; | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | int phy_driver_register(struct phy_driver *new_driver) | ||
633 | { | ||
634 | int retval; | ||
635 | |||
636 | memset(&new_driver->driver, 0, sizeof(new_driver->driver)); | ||
637 | new_driver->driver.name = new_driver->name; | ||
638 | new_driver->driver.bus = &mdio_bus_type; | ||
639 | new_driver->driver.probe = phy_probe; | ||
640 | new_driver->driver.remove = phy_remove; | ||
641 | |||
642 | retval = driver_register(&new_driver->driver); | ||
643 | |||
644 | if (retval) { | ||
645 | printk(KERN_ERR "%s: Error %d in registering driver\n", | ||
646 | new_driver->name, retval); | ||
647 | |||
648 | return retval; | ||
649 | } | ||
650 | |||
651 | pr_info("%s: Registered new driver\n", new_driver->name); | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | EXPORT_SYMBOL(phy_driver_register); | ||
656 | |||
657 | void phy_driver_unregister(struct phy_driver *drv) | ||
658 | { | ||
659 | driver_unregister(&drv->driver); | ||
660 | } | ||
661 | EXPORT_SYMBOL(phy_driver_unregister); | ||
662 | |||
663 | static struct phy_driver genphy_driver = { | ||
664 | .phy_id = 0xffffffff, | ||
665 | .phy_id_mask = 0xffffffff, | ||
666 | .name = "Generic PHY", | ||
667 | .config_init = genphy_config_init, | ||
668 | .features = 0, | ||
669 | .config_aneg = genphy_config_aneg, | ||
670 | .read_status = genphy_read_status, | ||
671 | .driver = {.owner= THIS_MODULE, }, | ||
672 | }; | ||
673 | |||
674 | static int __init phy_init(void) | ||
675 | { | ||
676 | int rc; | ||
677 | |||
678 | rc = mdio_bus_init(); | ||
679 | if (rc) | ||
680 | return rc; | ||
681 | |||
682 | rc = phy_driver_register(&genphy_driver); | ||
683 | if (rc) | ||
684 | mdio_bus_exit(); | ||
685 | |||
686 | return rc; | ||
687 | } | ||
688 | |||
689 | static void __exit phy_exit(void) | ||
690 | { | ||
691 | phy_driver_unregister(&genphy_driver); | ||
692 | mdio_bus_exit(); | ||
693 | } | ||
694 | |||
695 | subsys_initcall(phy_init); | ||
696 | module_exit(phy_exit); | ||
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c new file mode 100644 index 000000000000..d461ba457631 --- /dev/null +++ b/drivers/net/phy/qsemi.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/qsemi.c | ||
3 | * | ||
4 | * Driver for Quality Semiconductor PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* ------------------------------------------------------------------------- */ | ||
42 | /* The Quality Semiconductor QS6612 is used on the RPX CLLF */ | ||
43 | |||
44 | /* register definitions */ | ||
45 | |||
46 | #define MII_QS6612_MCR 17 /* Mode Control Register */ | ||
47 | #define MII_QS6612_FTR 27 /* Factory Test Register */ | ||
48 | #define MII_QS6612_MCO 28 /* Misc. Control Register */ | ||
49 | #define MII_QS6612_ISR 29 /* Interrupt Source Register */ | ||
50 | #define MII_QS6612_IMR 30 /* Interrupt Mask Register */ | ||
51 | #define MII_QS6612_IMR_INIT 0x003a | ||
52 | #define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ | ||
53 | |||
54 | #define QS6612_PCR_AN_COMPLETE 0x1000 | ||
55 | #define QS6612_PCR_RLBEN 0x0200 | ||
56 | #define QS6612_PCR_DCREN 0x0100 | ||
57 | #define QS6612_PCR_4B5BEN 0x0040 | ||
58 | #define QS6612_PCR_TX_ISOLATE 0x0020 | ||
59 | #define QS6612_PCR_MLT3_DIS 0x0002 | ||
60 | #define QS6612_PCR_SCRM_DESCRM 0x0001 | ||
61 | |||
62 | MODULE_DESCRIPTION("Quality Semiconductor PHY driver"); | ||
63 | MODULE_AUTHOR("Andy Fleming"); | ||
64 | MODULE_LICENSE("GPL"); | ||
65 | |||
66 | /* Returns 0, unless there's a write error */ | ||
67 | static int qs6612_config_init(struct phy_device *phydev) | ||
68 | { | ||
69 | /* The PHY powers up isolated on the RPX, | ||
70 | * so send a command to allow operation. | ||
71 | * XXX - My docs indicate this should be 0x0940 | ||
72 | * ...or something. The current value sets three | ||
73 | * reserved bits, bit 11, which specifies it should be | ||
74 | * set to one, bit 10, which specifies it should be set | ||
75 | * to 0, and bit 7, which doesn't specify. However, my | ||
76 | * docs are preliminary, and I will leave it like this | ||
77 | * until someone more knowledgable corrects me or it. | ||
78 | * -- Andy Fleming | ||
79 | */ | ||
80 | return phy_write(phydev, MII_QS6612_PCR, 0x0dc0); | ||
81 | } | ||
82 | |||
83 | static int qs6612_ack_interrupt(struct phy_device *phydev) | ||
84 | { | ||
85 | int err; | ||
86 | |||
87 | err = phy_read(phydev, MII_QS6612_ISR); | ||
88 | |||
89 | if (err < 0) | ||
90 | return err; | ||
91 | |||
92 | err = phy_read(phydev, MII_BMSR); | ||
93 | |||
94 | if (err < 0) | ||
95 | return err; | ||
96 | |||
97 | err = phy_read(phydev, MII_EXPANSION); | ||
98 | |||
99 | if (err < 0) | ||
100 | return err; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int qs6612_config_intr(struct phy_device *phydev) | ||
106 | { | ||
107 | int err; | ||
108 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
109 | err = phy_write(phydev, MII_QS6612_IMR, | ||
110 | MII_QS6612_IMR_INIT); | ||
111 | else | ||
112 | err = phy_write(phydev, MII_QS6612_IMR, 0); | ||
113 | |||
114 | return err; | ||
115 | |||
116 | } | ||
117 | |||
118 | static struct phy_driver qs6612_driver = { | ||
119 | .phy_id = 0x00181440, | ||
120 | .name = "QS6612", | ||
121 | .phy_id_mask = 0xfffffff0, | ||
122 | .features = PHY_BASIC_FEATURES, | ||
123 | .flags = PHY_HAS_INTERRUPT, | ||
124 | .config_init = qs6612_config_init, | ||
125 | .config_aneg = genphy_config_aneg, | ||
126 | .read_status = genphy_read_status, | ||
127 | .ack_interrupt = qs6612_ack_interrupt, | ||
128 | .config_intr = qs6612_config_intr, | ||
129 | .driver = { .owner = THIS_MODULE,}, | ||
130 | }; | ||
131 | |||
132 | static int __init qs6612_init(void) | ||
133 | { | ||
134 | return phy_driver_register(&qs6612_driver); | ||
135 | } | ||
136 | |||
137 | static void __exit qs6612_exit(void) | ||
138 | { | ||
139 | phy_driver_unregister(&qs6612_driver); | ||
140 | } | ||
141 | |||
142 | module_init(qs6612_init); | ||
143 | module_exit(qs6612_exit); | ||
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index a32668e88e09..bb71638a7c44 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1657,7 +1657,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
1657 | skb->dev = ppp->dev; | 1657 | skb->dev = ppp->dev; |
1658 | skb->protocol = htons(npindex_to_ethertype[npi]); | 1658 | skb->protocol = htons(npindex_to_ethertype[npi]); |
1659 | skb->mac.raw = skb->data; | 1659 | skb->mac.raw = skb->data; |
1660 | skb->input_dev = ppp->dev; | ||
1661 | netif_rx(skb); | 1660 | netif_rx(skb); |
1662 | ppp->dev->last_rx = jiffies; | 1661 | ppp->dev->last_rx = jiffies; |
1663 | } | 1662 | } |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index ce1a9bf7b9a7..82f236cc3b9b 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -377,7 +377,8 @@ abort_kfree: | |||
377 | ***********************************************************************/ | 377 | ***********************************************************************/ |
378 | static int pppoe_rcv(struct sk_buff *skb, | 378 | static int pppoe_rcv(struct sk_buff *skb, |
379 | struct net_device *dev, | 379 | struct net_device *dev, |
380 | struct packet_type *pt) | 380 | struct packet_type *pt, |
381 | struct net_device *orig_dev) | ||
381 | 382 | ||
382 | { | 383 | { |
383 | struct pppoe_hdr *ph; | 384 | struct pppoe_hdr *ph; |
@@ -426,7 +427,8 @@ out: | |||
426 | ***********************************************************************/ | 427 | ***********************************************************************/ |
427 | static int pppoe_disc_rcv(struct sk_buff *skb, | 428 | static int pppoe_disc_rcv(struct sk_buff *skb, |
428 | struct net_device *dev, | 429 | struct net_device *dev, |
429 | struct packet_type *pt) | 430 | struct packet_type *pt, |
431 | struct net_device *orig_dev) | ||
430 | 432 | ||
431 | { | 433 | { |
432 | struct pppoe_hdr *ph; | 434 | struct pppoe_hdr *ph; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index d5afe05cd826..f0471d102e3c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -187,6 +187,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = { | |||
187 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), }, | 187 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), }, |
188 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), }, | 188 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), }, |
189 | { PCI_DEVICE(0x16ec, 0x0116), }, | 189 | { PCI_DEVICE(0x16ec, 0x0116), }, |
190 | { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, }, | ||
190 | {0,}, | 191 | {0,}, |
191 | }; | 192 | }; |
192 | 193 | ||
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 12a86f96d973..ec1a18d189a1 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c | |||
@@ -1429,6 +1429,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1429 | { | 1429 | { |
1430 | struct rr_private *rrpriv = netdev_priv(dev); | 1430 | struct rr_private *rrpriv = netdev_priv(dev); |
1431 | struct rr_regs __iomem *regs = rrpriv->regs; | 1431 | struct rr_regs __iomem *regs = rrpriv->regs; |
1432 | struct hippi_cb *hcb = (struct hippi_cb *) skb->cb; | ||
1432 | struct ring_ctrl *txctrl; | 1433 | struct ring_ctrl *txctrl; |
1433 | unsigned long flags; | 1434 | unsigned long flags; |
1434 | u32 index, len = skb->len; | 1435 | u32 index, len = skb->len; |
@@ -1460,7 +1461,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1460 | ifield = (u32 *)skb_push(skb, 8); | 1461 | ifield = (u32 *)skb_push(skb, 8); |
1461 | 1462 | ||
1462 | ifield[0] = 0; | 1463 | ifield[0] = 0; |
1463 | ifield[1] = skb->private.ifield; | 1464 | ifield[1] = hcb->ifield; |
1464 | 1465 | ||
1465 | /* | 1466 | /* |
1466 | * We don't need the lock before we are actually going to start | 1467 | * We don't need the lock before we are actually going to start |
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 7092ca6b277e..2234a8f05eb2 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
@@ -62,6 +62,7 @@ typedef struct _XENA_dev_config { | |||
62 | #define ADAPTER_STATUS_RMAC_REMOTE_FAULT BIT(6) | 62 | #define ADAPTER_STATUS_RMAC_REMOTE_FAULT BIT(6) |
63 | #define ADAPTER_STATUS_RMAC_LOCAL_FAULT BIT(7) | 63 | #define ADAPTER_STATUS_RMAC_LOCAL_FAULT BIT(7) |
64 | #define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8) | 64 | #define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8) |
65 | #define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE vBIT(0x0F,8,8) | ||
65 | #define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8) | 66 | #define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8) |
66 | #define ADAPTER_STATUS_MC_DRAM_READY BIT(24) | 67 | #define ADAPTER_STATUS_MC_DRAM_READY BIT(24) |
67 | #define ADAPTER_STATUS_MC_QUEUES_READY BIT(25) | 68 | #define ADAPTER_STATUS_MC_QUEUES_READY BIT(25) |
@@ -77,21 +78,34 @@ typedef struct _XENA_dev_config { | |||
77 | #define ADAPTER_ECC_EN BIT(55) | 78 | #define ADAPTER_ECC_EN BIT(55) |
78 | 79 | ||
79 | u64 serr_source; | 80 | u64 serr_source; |
80 | #define SERR_SOURCE_PIC BIT(0) | 81 | #define SERR_SOURCE_PIC BIT(0) |
81 | #define SERR_SOURCE_TXDMA BIT(1) | 82 | #define SERR_SOURCE_TXDMA BIT(1) |
82 | #define SERR_SOURCE_RXDMA BIT(2) | 83 | #define SERR_SOURCE_RXDMA BIT(2) |
83 | #define SERR_SOURCE_MAC BIT(3) | 84 | #define SERR_SOURCE_MAC BIT(3) |
84 | #define SERR_SOURCE_MC BIT(4) | 85 | #define SERR_SOURCE_MC BIT(4) |
85 | #define SERR_SOURCE_XGXS BIT(5) | 86 | #define SERR_SOURCE_XGXS BIT(5) |
86 | #define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \ | 87 | #define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \ |
87 | SERR_SOURCE_TXDMA | \ | 88 | SERR_SOURCE_TXDMA | \ |
88 | SERR_SOURCE_RXDMA | \ | 89 | SERR_SOURCE_RXDMA | \ |
89 | SERR_SOURCE_MAC | \ | 90 | SERR_SOURCE_MAC | \ |
90 | SERR_SOURCE_MC | \ | 91 | SERR_SOURCE_MC | \ |
91 | SERR_SOURCE_XGXS) | 92 | SERR_SOURCE_XGXS) |
92 | 93 | ||
93 | 94 | u64 pci_mode; | |
94 | u8 unused_0[0x800 - 0x120]; | 95 | #define GET_PCI_MODE(val) ((val & vBIT(0xF, 0, 4)) >> 60) |
96 | #define PCI_MODE_PCI_33 0 | ||
97 | #define PCI_MODE_PCI_66 0x1 | ||
98 | #define PCI_MODE_PCIX_M1_66 0x2 | ||
99 | #define PCI_MODE_PCIX_M1_100 0x3 | ||
100 | #define PCI_MODE_PCIX_M1_133 0x4 | ||
101 | #define PCI_MODE_PCIX_M2_66 0x5 | ||
102 | #define PCI_MODE_PCIX_M2_100 0x6 | ||
103 | #define PCI_MODE_PCIX_M2_133 0x7 | ||
104 | #define PCI_MODE_UNSUPPORTED BIT(0) | ||
105 | #define PCI_MODE_32_BITS BIT(8) | ||
106 | #define PCI_MODE_UNKNOWN_MODE BIT(9) | ||
107 | |||
108 | u8 unused_0[0x800 - 0x128]; | ||
95 | 109 | ||
96 | /* PCI-X Controller registers */ | 110 | /* PCI-X Controller registers */ |
97 | u64 pic_int_status; | 111 | u64 pic_int_status; |
@@ -153,7 +167,11 @@ typedef struct _XENA_dev_config { | |||
153 | u8 unused4[0x08]; | 167 | u8 unused4[0x08]; |
154 | 168 | ||
155 | u64 gpio_int_reg; | 169 | u64 gpio_int_reg; |
170 | #define GPIO_INT_REG_LINK_DOWN BIT(1) | ||
171 | #define GPIO_INT_REG_LINK_UP BIT(2) | ||
156 | u64 gpio_int_mask; | 172 | u64 gpio_int_mask; |
173 | #define GPIO_INT_MASK_LINK_DOWN BIT(1) | ||
174 | #define GPIO_INT_MASK_LINK_UP BIT(2) | ||
157 | u64 gpio_alarms; | 175 | u64 gpio_alarms; |
158 | 176 | ||
159 | u8 unused5[0x38]; | 177 | u8 unused5[0x38]; |
@@ -223,19 +241,16 @@ typedef struct _XENA_dev_config { | |||
223 | u64 xmsi_data; | 241 | u64 xmsi_data; |
224 | 242 | ||
225 | u64 rx_mat; | 243 | u64 rx_mat; |
244 | #define RX_MAT_SET(ring, msi) vBIT(msi, (8 * ring), 8) | ||
226 | 245 | ||
227 | u8 unused6[0x8]; | 246 | u8 unused6[0x8]; |
228 | 247 | ||
229 | u64 tx_mat0_7; | 248 | u64 tx_mat0_n[0x8]; |
230 | u64 tx_mat8_15; | 249 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) |
231 | u64 tx_mat16_23; | ||
232 | u64 tx_mat24_31; | ||
233 | u64 tx_mat32_39; | ||
234 | u64 tx_mat40_47; | ||
235 | u64 tx_mat48_55; | ||
236 | u64 tx_mat56_63; | ||
237 | 250 | ||
238 | u8 unused_1[0x10]; | 251 | u8 unused_1[0x8]; |
252 | u64 stat_byte_cnt; | ||
253 | #define STAT_BC(n) vBIT(n,4,12) | ||
239 | 254 | ||
240 | /* Automated statistics collection */ | 255 | /* Automated statistics collection */ |
241 | u64 stat_cfg; | 256 | u64 stat_cfg; |
@@ -246,6 +261,7 @@ typedef struct _XENA_dev_config { | |||
246 | #define STAT_TRSF_PER(n) TBD | 261 | #define STAT_TRSF_PER(n) TBD |
247 | #define PER_SEC 0x208d5 | 262 | #define PER_SEC 0x208d5 |
248 | #define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32) | 263 | #define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32) |
264 | #define SET_UPDT_CLICKS(val) vBIT(val, 32, 32) | ||
249 | 265 | ||
250 | u64 stat_addr; | 266 | u64 stat_addr; |
251 | 267 | ||
@@ -267,8 +283,15 @@ typedef struct _XENA_dev_config { | |||
267 | 283 | ||
268 | u64 gpio_control; | 284 | u64 gpio_control; |
269 | #define GPIO_CTRL_GPIO_0 BIT(8) | 285 | #define GPIO_CTRL_GPIO_0 BIT(8) |
286 | u64 misc_control; | ||
287 | #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) | ||
288 | |||
289 | u8 unused7_1[0x240 - 0x208]; | ||
290 | |||
291 | u64 wreq_split_mask; | ||
292 | #define WREQ_SPLIT_MASK_SET_MASK(val) vBIT(val, 52, 12) | ||
270 | 293 | ||
271 | u8 unused7[0x600]; | 294 | u8 unused7_2[0x800 - 0x248]; |
272 | 295 | ||
273 | /* TxDMA registers */ | 296 | /* TxDMA registers */ |
274 | u64 txdma_int_status; | 297 | u64 txdma_int_status; |
@@ -290,6 +313,7 @@ typedef struct _XENA_dev_config { | |||
290 | 313 | ||
291 | u64 pcc_err_reg; | 314 | u64 pcc_err_reg; |
292 | #define PCC_FB_ECC_DB_ERR vBIT(0xFF, 16, 8) | 315 | #define PCC_FB_ECC_DB_ERR vBIT(0xFF, 16, 8) |
316 | #define PCC_ENABLE_FOUR vBIT(0x0F,0,8) | ||
293 | 317 | ||
294 | u64 pcc_err_mask; | 318 | u64 pcc_err_mask; |
295 | u64 pcc_err_alarm; | 319 | u64 pcc_err_alarm; |
@@ -468,6 +492,7 @@ typedef struct _XENA_dev_config { | |||
468 | #define PRC_CTRL_NO_SNOOP (BIT(22)|BIT(23)) | 492 | #define PRC_CTRL_NO_SNOOP (BIT(22)|BIT(23)) |
469 | #define PRC_CTRL_NO_SNOOP_DESC BIT(22) | 493 | #define PRC_CTRL_NO_SNOOP_DESC BIT(22) |
470 | #define PRC_CTRL_NO_SNOOP_BUFF BIT(23) | 494 | #define PRC_CTRL_NO_SNOOP_BUFF BIT(23) |
495 | #define PRC_CTRL_BIMODAL_INTERRUPT BIT(37) | ||
471 | #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24) | 496 | #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24) |
472 | 497 | ||
473 | u64 prc_alarm_action; | 498 | u64 prc_alarm_action; |
@@ -691,6 +716,10 @@ typedef struct _XENA_dev_config { | |||
691 | #define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) | 716 | #define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) |
692 | #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) | 717 | #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) |
693 | #define MC_ERR_REG_SM_ERR BIT(31) | 718 | #define MC_ERR_REG_SM_ERR BIT(31) |
719 | #define MC_ERR_REG_ECC_ALL_SNG (BIT(6) | \ | ||
720 | BIT(7) | BIT(17) | BIT(19)) | ||
721 | #define MC_ERR_REG_ECC_ALL_DBL (BIT(14) | \ | ||
722 | BIT(15) | BIT(18) | BIT(20)) | ||
694 | u64 mc_err_mask; | 723 | u64 mc_err_mask; |
695 | u64 mc_err_alarm; | 724 | u64 mc_err_alarm; |
696 | 725 | ||
@@ -736,7 +765,19 @@ typedef struct _XENA_dev_config { | |||
736 | u64 mc_rldram_test_d1; | 765 | u64 mc_rldram_test_d1; |
737 | u8 unused24[0x300 - 0x288]; | 766 | u8 unused24[0x300 - 0x288]; |
738 | u64 mc_rldram_test_d2; | 767 | u64 mc_rldram_test_d2; |
739 | u8 unused25[0x700 - 0x308]; | 768 | |
769 | u8 unused24_1[0x360 - 0x308]; | ||
770 | u64 mc_rldram_ctrl; | ||
771 | #define MC_RLDRAM_ENABLE_ODT BIT(7) | ||
772 | |||
773 | u8 unused24_2[0x640 - 0x368]; | ||
774 | u64 mc_rldram_ref_per_herc; | ||
775 | #define MC_RLDRAM_SET_REF_PERIOD(val) vBIT(val, 0, 16) | ||
776 | |||
777 | u8 unused24_3[0x660 - 0x648]; | ||
778 | u64 mc_rldram_mrs_herc; | ||
779 | |||
780 | u8 unused25[0x700 - 0x668]; | ||
740 | u64 mc_debug_ctrl; | 781 | u64 mc_debug_ctrl; |
741 | 782 | ||
742 | u8 unused26[0x3000 - 0x2f08]; | 783 | u8 unused26[0x3000 - 0x2f08]; |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ea638b162d3f..7ca78228b104 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -11,29 +11,28 @@ | |||
11 | * See the file COPYING in this distribution for more information. | 11 | * See the file COPYING in this distribution for more information. |
12 | * | 12 | * |
13 | * Credits: | 13 | * Credits: |
14 | * Jeff Garzik : For pointing out the improper error condition | 14 | * Jeff Garzik : For pointing out the improper error condition |
15 | * check in the s2io_xmit routine and also some | 15 | * check in the s2io_xmit routine and also some |
16 | * issues in the Tx watch dog function. Also for | 16 | * issues in the Tx watch dog function. Also for |
17 | * patiently answering all those innumerable | 17 | * patiently answering all those innumerable |
18 | * questions regaring the 2.6 porting issues. | 18 | * questions regaring the 2.6 porting issues. |
19 | * Stephen Hemminger : Providing proper 2.6 porting mechanism for some | 19 | * Stephen Hemminger : Providing proper 2.6 porting mechanism for some |
20 | * macros available only in 2.6 Kernel. | 20 | * macros available only in 2.6 Kernel. |
21 | * Francois Romieu : For pointing out all code part that were | 21 | * Francois Romieu : For pointing out all code part that were |
22 | * deprecated and also styling related comments. | 22 | * deprecated and also styling related comments. |
23 | * Grant Grundler : For helping me get rid of some Architecture | 23 | * Grant Grundler : For helping me get rid of some Architecture |
24 | * dependent code. | 24 | * dependent code. |
25 | * Christopher Hellwig : Some more 2.6 specific issues in the driver. | 25 | * Christopher Hellwig : Some more 2.6 specific issues in the driver. |
26 | * | 26 | * |
27 | * The module loadable parameters that are supported by the driver and a brief | 27 | * The module loadable parameters that are supported by the driver and a brief |
28 | * explaination of all the variables. | 28 | * explaination of all the variables. |
29 | * rx_ring_num : This can be used to program the number of receive rings used | 29 | * rx_ring_num : This can be used to program the number of receive rings used |
30 | * in the driver. | 30 | * in the driver. |
31 | * rx_ring_len: This defines the number of descriptors each ring can have. This | 31 | * rx_ring_len: This defines the number of descriptors each ring can have. This |
32 | * is also an array of size 8. | 32 | * is also an array of size 8. |
33 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. | 33 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. |
34 | * tx_fifo_len: This too is an array of 8. Each element defines the number of | 34 | * tx_fifo_len: This too is an array of 8. Each element defines the number of |
35 | * Tx descriptors that can be associated with each corresponding FIFO. | 35 | * Tx descriptors that can be associated with each corresponding FIFO. |
36 | * in PCI Configuration space. | ||
37 | ************************************************************************/ | 36 | ************************************************************************/ |
38 | 37 | ||
39 | #include <linux/config.h> | 38 | #include <linux/config.h> |
@@ -56,27 +55,39 @@ | |||
56 | #include <linux/ethtool.h> | 55 | #include <linux/ethtool.h> |
57 | #include <linux/version.h> | 56 | #include <linux/version.h> |
58 | #include <linux/workqueue.h> | 57 | #include <linux/workqueue.h> |
58 | #include <linux/if_vlan.h> | ||
59 | 59 | ||
60 | #include <asm/io.h> | ||
61 | #include <asm/system.h> | 60 | #include <asm/system.h> |
62 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
62 | #include <asm/io.h> | ||
63 | 63 | ||
64 | /* local include */ | 64 | /* local include */ |
65 | #include "s2io.h" | 65 | #include "s2io.h" |
66 | #include "s2io-regs.h" | 66 | #include "s2io-regs.h" |
67 | 67 | ||
68 | /* S2io Driver name & version. */ | 68 | /* S2io Driver name & version. */ |
69 | static char s2io_driver_name[] = "s2io"; | 69 | static char s2io_driver_name[] = "Neterion"; |
70 | static char s2io_driver_version[] = "Version 1.7.7.1"; | 70 | static char s2io_driver_version[] = "Version 2.0.3.1"; |
71 | |||
72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) && | ||
77 | (GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK)); | ||
71 | 78 | ||
72 | /* | 79 | return ret; |
80 | } | ||
81 | |||
82 | /* | ||
73 | * Cards with following subsystem_id have a link state indication | 83 | * Cards with following subsystem_id have a link state indication |
74 | * problem, 600B, 600C, 600D, 640B, 640C and 640D. | 84 | * problem, 600B, 600C, 600D, 640B, 640C and 640D. |
75 | * macro below identifies these cards given the subsystem_id. | 85 | * macro below identifies these cards given the subsystem_id. |
76 | */ | 86 | */ |
77 | #define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \ | 87 | #define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \ |
78 | (((subid >= 0x600B) && (subid <= 0x600D)) || \ | 88 | (dev_type == XFRAME_I_DEVICE) ? \ |
79 | ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0 | 89 | ((((subid >= 0x600B) && (subid <= 0x600D)) || \ |
90 | ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0 | ||
80 | 91 | ||
81 | #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ | 92 | #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ |
82 | ADAPTER_STATUS_RMAC_LOCAL_FAULT))) | 93 | ADAPTER_STATUS_RMAC_LOCAL_FAULT))) |
@@ -86,9 +97,12 @@ static char s2io_driver_version[] = "Version 1.7.7.1"; | |||
86 | static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) | 97 | static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) |
87 | { | 98 | { |
88 | int level = 0; | 99 | int level = 0; |
89 | if ((sp->pkt_cnt[ring] - rxb_size) > 16) { | 100 | mac_info_t *mac_control; |
101 | |||
102 | mac_control = &sp->mac_control; | ||
103 | if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) { | ||
90 | level = LOW; | 104 | level = LOW; |
91 | if ((sp->pkt_cnt[ring] - rxb_size) < MAX_RXDS_PER_BLOCK) { | 105 | if (rxb_size <= MAX_RXDS_PER_BLOCK) { |
92 | level = PANIC; | 106 | level = PANIC; |
93 | } | 107 | } |
94 | } | 108 | } |
@@ -145,6 +159,9 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
145 | {"rmac_pause_cnt"}, | 159 | {"rmac_pause_cnt"}, |
146 | {"rmac_accepted_ip"}, | 160 | {"rmac_accepted_ip"}, |
147 | {"rmac_err_tcp"}, | 161 | {"rmac_err_tcp"}, |
162 | {"\n DRIVER STATISTICS"}, | ||
163 | {"single_bit_ecc_errs"}, | ||
164 | {"double_bit_ecc_errs"}, | ||
148 | }; | 165 | }; |
149 | 166 | ||
150 | #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN | 167 | #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN |
@@ -153,8 +170,37 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
153 | #define S2IO_TEST_LEN sizeof(s2io_gstrings) / ETH_GSTRING_LEN | 170 | #define S2IO_TEST_LEN sizeof(s2io_gstrings) / ETH_GSTRING_LEN |
154 | #define S2IO_STRINGS_LEN S2IO_TEST_LEN * ETH_GSTRING_LEN | 171 | #define S2IO_STRINGS_LEN S2IO_TEST_LEN * ETH_GSTRING_LEN |
155 | 172 | ||
173 | #define S2IO_TIMER_CONF(timer, handle, arg, exp) \ | ||
174 | init_timer(&timer); \ | ||
175 | timer.function = handle; \ | ||
176 | timer.data = (unsigned long) arg; \ | ||
177 | mod_timer(&timer, (jiffies + exp)) \ | ||
178 | |||
179 | /* Add the vlan */ | ||
180 | static void s2io_vlan_rx_register(struct net_device *dev, | ||
181 | struct vlan_group *grp) | ||
182 | { | ||
183 | nic_t *nic = dev->priv; | ||
184 | unsigned long flags; | ||
185 | |||
186 | spin_lock_irqsave(&nic->tx_lock, flags); | ||
187 | nic->vlgrp = grp; | ||
188 | spin_unlock_irqrestore(&nic->tx_lock, flags); | ||
189 | } | ||
190 | |||
191 | /* Unregister the vlan */ | ||
192 | static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) | ||
193 | { | ||
194 | nic_t *nic = dev->priv; | ||
195 | unsigned long flags; | ||
196 | |||
197 | spin_lock_irqsave(&nic->tx_lock, flags); | ||
198 | if (nic->vlgrp) | ||
199 | nic->vlgrp->vlan_devices[vid] = NULL; | ||
200 | spin_unlock_irqrestore(&nic->tx_lock, flags); | ||
201 | } | ||
156 | 202 | ||
157 | /* | 203 | /* |
158 | * Constants to be programmed into the Xena's registers, to configure | 204 | * Constants to be programmed into the Xena's registers, to configure |
159 | * the XAUI. | 205 | * the XAUI. |
160 | */ | 206 | */ |
@@ -162,7 +208,28 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
162 | #define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL | 208 | #define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL |
163 | #define END_SIGN 0x0 | 209 | #define END_SIGN 0x0 |
164 | 210 | ||
165 | static u64 default_mdio_cfg[] = { | 211 | static u64 herc_act_dtx_cfg[] = { |
212 | /* Set address */ | ||
213 | 0x8000051536750000ULL, 0x80000515367500E0ULL, | ||
214 | /* Write data */ | ||
215 | 0x8000051536750004ULL, 0x80000515367500E4ULL, | ||
216 | /* Set address */ | ||
217 | 0x80010515003F0000ULL, 0x80010515003F00E0ULL, | ||
218 | /* Write data */ | ||
219 | 0x80010515003F0004ULL, 0x80010515003F00E4ULL, | ||
220 | /* Set address */ | ||
221 | 0x801205150D440000ULL, 0x801205150D4400E0ULL, | ||
222 | /* Write data */ | ||
223 | 0x801205150D440004ULL, 0x801205150D4400E4ULL, | ||
224 | /* Set address */ | ||
225 | 0x80020515F2100000ULL, 0x80020515F21000E0ULL, | ||
226 | /* Write data */ | ||
227 | 0x80020515F2100004ULL, 0x80020515F21000E4ULL, | ||
228 | /* Done */ | ||
229 | END_SIGN | ||
230 | }; | ||
231 | |||
232 | static u64 xena_mdio_cfg[] = { | ||
166 | /* Reset PMA PLL */ | 233 | /* Reset PMA PLL */ |
167 | 0xC001010000000000ULL, 0xC0010100000000E0ULL, | 234 | 0xC001010000000000ULL, 0xC0010100000000E0ULL, |
168 | 0xC0010100008000E4ULL, | 235 | 0xC0010100008000E4ULL, |
@@ -172,7 +239,7 @@ static u64 default_mdio_cfg[] = { | |||
172 | END_SIGN | 239 | END_SIGN |
173 | }; | 240 | }; |
174 | 241 | ||
175 | static u64 default_dtx_cfg[] = { | 242 | static u64 xena_dtx_cfg[] = { |
176 | 0x8000051500000000ULL, 0x80000515000000E0ULL, | 243 | 0x8000051500000000ULL, 0x80000515000000E0ULL, |
177 | 0x80000515D93500E4ULL, 0x8001051500000000ULL, | 244 | 0x80000515D93500E4ULL, 0x8001051500000000ULL, |
178 | 0x80010515000000E0ULL, 0x80010515001E00E4ULL, | 245 | 0x80010515000000E0ULL, 0x80010515001E00E4ULL, |
@@ -196,8 +263,7 @@ static u64 default_dtx_cfg[] = { | |||
196 | END_SIGN | 263 | END_SIGN |
197 | }; | 264 | }; |
198 | 265 | ||
199 | 266 | /* | |
200 | /* | ||
201 | * Constants for Fixing the MacAddress problem seen mostly on | 267 | * Constants for Fixing the MacAddress problem seen mostly on |
202 | * Alpha machines. | 268 | * Alpha machines. |
203 | */ | 269 | */ |
@@ -226,20 +292,25 @@ static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | |||
226 | static unsigned int rx_ring_num = 1; | 292 | static unsigned int rx_ring_num = 1; |
227 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 293 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = |
228 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 294 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; |
229 | static unsigned int Stats_refresh_time = 4; | 295 | static unsigned int rts_frm_len[MAX_RX_RINGS] = |
296 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | ||
297 | static unsigned int use_continuous_tx_intrs = 1; | ||
230 | static unsigned int rmac_pause_time = 65535; | 298 | static unsigned int rmac_pause_time = 65535; |
231 | static unsigned int mc_pause_threshold_q0q3 = 187; | 299 | static unsigned int mc_pause_threshold_q0q3 = 187; |
232 | static unsigned int mc_pause_threshold_q4q7 = 187; | 300 | static unsigned int mc_pause_threshold_q4q7 = 187; |
233 | static unsigned int shared_splits; | 301 | static unsigned int shared_splits; |
234 | static unsigned int tmac_util_period = 5; | 302 | static unsigned int tmac_util_period = 5; |
235 | static unsigned int rmac_util_period = 5; | 303 | static unsigned int rmac_util_period = 5; |
304 | static unsigned int bimodal = 0; | ||
236 | #ifndef CONFIG_S2IO_NAPI | 305 | #ifndef CONFIG_S2IO_NAPI |
237 | static unsigned int indicate_max_pkts; | 306 | static unsigned int indicate_max_pkts; |
238 | #endif | 307 | #endif |
308 | /* Frequency of Rx desc syncs expressed as power of 2 */ | ||
309 | static unsigned int rxsync_frequency = 3; | ||
239 | 310 | ||
240 | /* | 311 | /* |
241 | * S2IO device table. | 312 | * S2IO device table. |
242 | * This table lists all the devices that this driver supports. | 313 | * This table lists all the devices that this driver supports. |
243 | */ | 314 | */ |
244 | static struct pci_device_id s2io_tbl[] __devinitdata = { | 315 | static struct pci_device_id s2io_tbl[] __devinitdata = { |
245 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN, | 316 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN, |
@@ -247,9 +318,9 @@ static struct pci_device_id s2io_tbl[] __devinitdata = { | |||
247 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI, | 318 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI, |
248 | PCI_ANY_ID, PCI_ANY_ID}, | 319 | PCI_ANY_ID, PCI_ANY_ID}, |
249 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN, | 320 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN, |
250 | PCI_ANY_ID, PCI_ANY_ID}, | 321 | PCI_ANY_ID, PCI_ANY_ID}, |
251 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI, | 322 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI, |
252 | PCI_ANY_ID, PCI_ANY_ID}, | 323 | PCI_ANY_ID, PCI_ANY_ID}, |
253 | {0,} | 324 | {0,} |
254 | }; | 325 | }; |
255 | 326 | ||
@@ -268,8 +339,8 @@ static struct pci_driver s2io_driver = { | |||
268 | /** | 339 | /** |
269 | * init_shared_mem - Allocation and Initialization of Memory | 340 | * init_shared_mem - Allocation and Initialization of Memory |
270 | * @nic: Device private variable. | 341 | * @nic: Device private variable. |
271 | * Description: The function allocates all the memory areas shared | 342 | * Description: The function allocates all the memory areas shared |
272 | * between the NIC and the driver. This includes Tx descriptors, | 343 | * between the NIC and the driver. This includes Tx descriptors, |
273 | * Rx descriptors and the statistics block. | 344 | * Rx descriptors and the statistics block. |
274 | */ | 345 | */ |
275 | 346 | ||
@@ -279,11 +350,11 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
279 | void *tmp_v_addr, *tmp_v_addr_next; | 350 | void *tmp_v_addr, *tmp_v_addr_next; |
280 | dma_addr_t tmp_p_addr, tmp_p_addr_next; | 351 | dma_addr_t tmp_p_addr, tmp_p_addr_next; |
281 | RxD_block_t *pre_rxd_blk = NULL; | 352 | RxD_block_t *pre_rxd_blk = NULL; |
282 | int i, j, blk_cnt; | 353 | int i, j, blk_cnt, rx_sz, tx_sz; |
283 | int lst_size, lst_per_page; | 354 | int lst_size, lst_per_page; |
284 | struct net_device *dev = nic->dev; | 355 | struct net_device *dev = nic->dev; |
285 | #ifdef CONFIG_2BUFF_MODE | 356 | #ifdef CONFIG_2BUFF_MODE |
286 | unsigned long tmp; | 357 | u64 tmp; |
287 | buffAdd_t *ba; | 358 | buffAdd_t *ba; |
288 | #endif | 359 | #endif |
289 | 360 | ||
@@ -300,36 +371,41 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
300 | size += config->tx_cfg[i].fifo_len; | 371 | size += config->tx_cfg[i].fifo_len; |
301 | } | 372 | } |
302 | if (size > MAX_AVAILABLE_TXDS) { | 373 | if (size > MAX_AVAILABLE_TXDS) { |
303 | DBG_PRINT(ERR_DBG, "%s: Total number of Tx FIFOs ", | 374 | DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ", |
304 | dev->name); | 375 | __FUNCTION__); |
305 | DBG_PRINT(ERR_DBG, "exceeds the maximum value "); | 376 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); |
306 | DBG_PRINT(ERR_DBG, "that can be used\n"); | ||
307 | return FAILURE; | 377 | return FAILURE; |
308 | } | 378 | } |
309 | 379 | ||
310 | lst_size = (sizeof(TxD_t) * config->max_txds); | 380 | lst_size = (sizeof(TxD_t) * config->max_txds); |
381 | tx_sz = lst_size * size; | ||
311 | lst_per_page = PAGE_SIZE / lst_size; | 382 | lst_per_page = PAGE_SIZE / lst_size; |
312 | 383 | ||
313 | for (i = 0; i < config->tx_fifo_num; i++) { | 384 | for (i = 0; i < config->tx_fifo_num; i++) { |
314 | int fifo_len = config->tx_cfg[i].fifo_len; | 385 | int fifo_len = config->tx_cfg[i].fifo_len; |
315 | int list_holder_size = fifo_len * sizeof(list_info_hold_t); | 386 | int list_holder_size = fifo_len * sizeof(list_info_hold_t); |
316 | nic->list_info[i] = kmalloc(list_holder_size, GFP_KERNEL); | 387 | mac_control->fifos[i].list_info = kmalloc(list_holder_size, |
317 | if (!nic->list_info[i]) { | 388 | GFP_KERNEL); |
389 | if (!mac_control->fifos[i].list_info) { | ||
318 | DBG_PRINT(ERR_DBG, | 390 | DBG_PRINT(ERR_DBG, |
319 | "Malloc failed for list_info\n"); | 391 | "Malloc failed for list_info\n"); |
320 | return -ENOMEM; | 392 | return -ENOMEM; |
321 | } | 393 | } |
322 | memset(nic->list_info[i], 0, list_holder_size); | 394 | memset(mac_control->fifos[i].list_info, 0, list_holder_size); |
323 | } | 395 | } |
324 | for (i = 0; i < config->tx_fifo_num; i++) { | 396 | for (i = 0; i < config->tx_fifo_num; i++) { |
325 | int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, | 397 | int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, |
326 | lst_per_page); | 398 | lst_per_page); |
327 | mac_control->tx_curr_put_info[i].offset = 0; | 399 | mac_control->fifos[i].tx_curr_put_info.offset = 0; |
328 | mac_control->tx_curr_put_info[i].fifo_len = | 400 | mac_control->fifos[i].tx_curr_put_info.fifo_len = |
329 | config->tx_cfg[i].fifo_len - 1; | 401 | config->tx_cfg[i].fifo_len - 1; |
330 | mac_control->tx_curr_get_info[i].offset = 0; | 402 | mac_control->fifos[i].tx_curr_get_info.offset = 0; |
331 | mac_control->tx_curr_get_info[i].fifo_len = | 403 | mac_control->fifos[i].tx_curr_get_info.fifo_len = |
332 | config->tx_cfg[i].fifo_len - 1; | 404 | config->tx_cfg[i].fifo_len - 1; |
405 | mac_control->fifos[i].fifo_no = i; | ||
406 | mac_control->fifos[i].nic = nic; | ||
407 | mac_control->fifos[i].max_txds = MAX_SKB_FRAGS; | ||
408 | |||
333 | for (j = 0; j < page_num; j++) { | 409 | for (j = 0; j < page_num; j++) { |
334 | int k = 0; | 410 | int k = 0; |
335 | dma_addr_t tmp_p; | 411 | dma_addr_t tmp_p; |
@@ -345,16 +421,15 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
345 | while (k < lst_per_page) { | 421 | while (k < lst_per_page) { |
346 | int l = (j * lst_per_page) + k; | 422 | int l = (j * lst_per_page) + k; |
347 | if (l == config->tx_cfg[i].fifo_len) | 423 | if (l == config->tx_cfg[i].fifo_len) |
348 | goto end_txd_alloc; | 424 | break; |
349 | nic->list_info[i][l].list_virt_addr = | 425 | mac_control->fifos[i].list_info[l].list_virt_addr = |
350 | tmp_v + (k * lst_size); | 426 | tmp_v + (k * lst_size); |
351 | nic->list_info[i][l].list_phy_addr = | 427 | mac_control->fifos[i].list_info[l].list_phy_addr = |
352 | tmp_p + (k * lst_size); | 428 | tmp_p + (k * lst_size); |
353 | k++; | 429 | k++; |
354 | } | 430 | } |
355 | } | 431 | } |
356 | } | 432 | } |
357 | end_txd_alloc: | ||
358 | 433 | ||
359 | /* Allocation and initialization of RXDs in Rings */ | 434 | /* Allocation and initialization of RXDs in Rings */ |
360 | size = 0; | 435 | size = 0; |
@@ -367,21 +442,26 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
367 | return FAILURE; | 442 | return FAILURE; |
368 | } | 443 | } |
369 | size += config->rx_cfg[i].num_rxd; | 444 | size += config->rx_cfg[i].num_rxd; |
370 | nic->block_count[i] = | 445 | mac_control->rings[i].block_count = |
371 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 446 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
372 | nic->pkt_cnt[i] = | 447 | mac_control->rings[i].pkt_cnt = |
373 | config->rx_cfg[i].num_rxd - nic->block_count[i]; | 448 | config->rx_cfg[i].num_rxd - mac_control->rings[i].block_count; |
374 | } | 449 | } |
450 | size = (size * (sizeof(RxD_t))); | ||
451 | rx_sz = size; | ||
375 | 452 | ||
376 | for (i = 0; i < config->rx_ring_num; i++) { | 453 | for (i = 0; i < config->rx_ring_num; i++) { |
377 | mac_control->rx_curr_get_info[i].block_index = 0; | 454 | mac_control->rings[i].rx_curr_get_info.block_index = 0; |
378 | mac_control->rx_curr_get_info[i].offset = 0; | 455 | mac_control->rings[i].rx_curr_get_info.offset = 0; |
379 | mac_control->rx_curr_get_info[i].ring_len = | 456 | mac_control->rings[i].rx_curr_get_info.ring_len = |
380 | config->rx_cfg[i].num_rxd - 1; | 457 | config->rx_cfg[i].num_rxd - 1; |
381 | mac_control->rx_curr_put_info[i].block_index = 0; | 458 | mac_control->rings[i].rx_curr_put_info.block_index = 0; |
382 | mac_control->rx_curr_put_info[i].offset = 0; | 459 | mac_control->rings[i].rx_curr_put_info.offset = 0; |
383 | mac_control->rx_curr_put_info[i].ring_len = | 460 | mac_control->rings[i].rx_curr_put_info.ring_len = |
384 | config->rx_cfg[i].num_rxd - 1; | 461 | config->rx_cfg[i].num_rxd - 1; |
462 | mac_control->rings[i].nic = nic; | ||
463 | mac_control->rings[i].ring_no = i; | ||
464 | |||
385 | blk_cnt = | 465 | blk_cnt = |
386 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 466 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
387 | /* Allocating all the Rx blocks */ | 467 | /* Allocating all the Rx blocks */ |
@@ -395,32 +475,36 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
395 | &tmp_p_addr); | 475 | &tmp_p_addr); |
396 | if (tmp_v_addr == NULL) { | 476 | if (tmp_v_addr == NULL) { |
397 | /* | 477 | /* |
398 | * In case of failure, free_shared_mem() | 478 | * In case of failure, free_shared_mem() |
399 | * is called, which should free any | 479 | * is called, which should free any |
400 | * memory that was alloced till the | 480 | * memory that was alloced till the |
401 | * failure happened. | 481 | * failure happened. |
402 | */ | 482 | */ |
403 | nic->rx_blocks[i][j].block_virt_addr = | 483 | mac_control->rings[i].rx_blocks[j].block_virt_addr = |
404 | tmp_v_addr; | 484 | tmp_v_addr; |
405 | return -ENOMEM; | 485 | return -ENOMEM; |
406 | } | 486 | } |
407 | memset(tmp_v_addr, 0, size); | 487 | memset(tmp_v_addr, 0, size); |
408 | nic->rx_blocks[i][j].block_virt_addr = tmp_v_addr; | 488 | mac_control->rings[i].rx_blocks[j].block_virt_addr = |
409 | nic->rx_blocks[i][j].block_dma_addr = tmp_p_addr; | 489 | tmp_v_addr; |
490 | mac_control->rings[i].rx_blocks[j].block_dma_addr = | ||
491 | tmp_p_addr; | ||
410 | } | 492 | } |
411 | /* Interlinking all Rx Blocks */ | 493 | /* Interlinking all Rx Blocks */ |
412 | for (j = 0; j < blk_cnt; j++) { | 494 | for (j = 0; j < blk_cnt; j++) { |
413 | tmp_v_addr = nic->rx_blocks[i][j].block_virt_addr; | 495 | tmp_v_addr = |
496 | mac_control->rings[i].rx_blocks[j].block_virt_addr; | ||
414 | tmp_v_addr_next = | 497 | tmp_v_addr_next = |
415 | nic->rx_blocks[i][(j + 1) % | 498 | mac_control->rings[i].rx_blocks[(j + 1) % |
416 | blk_cnt].block_virt_addr; | 499 | blk_cnt].block_virt_addr; |
417 | tmp_p_addr = nic->rx_blocks[i][j].block_dma_addr; | 500 | tmp_p_addr = |
501 | mac_control->rings[i].rx_blocks[j].block_dma_addr; | ||
418 | tmp_p_addr_next = | 502 | tmp_p_addr_next = |
419 | nic->rx_blocks[i][(j + 1) % | 503 | mac_control->rings[i].rx_blocks[(j + 1) % |
420 | blk_cnt].block_dma_addr; | 504 | blk_cnt].block_dma_addr; |
421 | 505 | ||
422 | pre_rxd_blk = (RxD_block_t *) tmp_v_addr; | 506 | pre_rxd_blk = (RxD_block_t *) tmp_v_addr; |
423 | pre_rxd_blk->reserved_1 = END_OF_BLOCK; /* last RxD | 507 | pre_rxd_blk->reserved_1 = END_OF_BLOCK; /* last RxD |
424 | * marker. | 508 | * marker. |
425 | */ | 509 | */ |
426 | #ifndef CONFIG_2BUFF_MODE | 510 | #ifndef CONFIG_2BUFF_MODE |
@@ -433,43 +517,43 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
433 | } | 517 | } |
434 | 518 | ||
435 | #ifdef CONFIG_2BUFF_MODE | 519 | #ifdef CONFIG_2BUFF_MODE |
436 | /* | 520 | /* |
437 | * Allocation of Storages for buffer addresses in 2BUFF mode | 521 | * Allocation of Storages for buffer addresses in 2BUFF mode |
438 | * and the buffers as well. | 522 | * and the buffers as well. |
439 | */ | 523 | */ |
440 | for (i = 0; i < config->rx_ring_num; i++) { | 524 | for (i = 0; i < config->rx_ring_num; i++) { |
441 | blk_cnt = | 525 | blk_cnt = |
442 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 526 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
443 | nic->ba[i] = kmalloc((sizeof(buffAdd_t *) * blk_cnt), | 527 | mac_control->rings[i].ba = kmalloc((sizeof(buffAdd_t *) * blk_cnt), |
444 | GFP_KERNEL); | 528 | GFP_KERNEL); |
445 | if (!nic->ba[i]) | 529 | if (!mac_control->rings[i].ba) |
446 | return -ENOMEM; | 530 | return -ENOMEM; |
447 | for (j = 0; j < blk_cnt; j++) { | 531 | for (j = 0; j < blk_cnt; j++) { |
448 | int k = 0; | 532 | int k = 0; |
449 | nic->ba[i][j] = kmalloc((sizeof(buffAdd_t) * | 533 | mac_control->rings[i].ba[j] = kmalloc((sizeof(buffAdd_t) * |
450 | (MAX_RXDS_PER_BLOCK + 1)), | 534 | (MAX_RXDS_PER_BLOCK + 1)), |
451 | GFP_KERNEL); | 535 | GFP_KERNEL); |
452 | if (!nic->ba[i][j]) | 536 | if (!mac_control->rings[i].ba[j]) |
453 | return -ENOMEM; | 537 | return -ENOMEM; |
454 | while (k != MAX_RXDS_PER_BLOCK) { | 538 | while (k != MAX_RXDS_PER_BLOCK) { |
455 | ba = &nic->ba[i][j][k]; | 539 | ba = &mac_control->rings[i].ba[j][k]; |
456 | 540 | ||
457 | ba->ba_0_org = kmalloc | 541 | ba->ba_0_org = (void *) kmalloc |
458 | (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); | 542 | (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); |
459 | if (!ba->ba_0_org) | 543 | if (!ba->ba_0_org) |
460 | return -ENOMEM; | 544 | return -ENOMEM; |
461 | tmp = (unsigned long) ba->ba_0_org; | 545 | tmp = (u64) ba->ba_0_org; |
462 | tmp += ALIGN_SIZE; | 546 | tmp += ALIGN_SIZE; |
463 | tmp &= ~((unsigned long) ALIGN_SIZE); | 547 | tmp &= ~((u64) ALIGN_SIZE); |
464 | ba->ba_0 = (void *) tmp; | 548 | ba->ba_0 = (void *) tmp; |
465 | 549 | ||
466 | ba->ba_1_org = kmalloc | 550 | ba->ba_1_org = (void *) kmalloc |
467 | (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); | 551 | (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); |
468 | if (!ba->ba_1_org) | 552 | if (!ba->ba_1_org) |
469 | return -ENOMEM; | 553 | return -ENOMEM; |
470 | tmp = (unsigned long) ba->ba_1_org; | 554 | tmp = (u64) ba->ba_1_org; |
471 | tmp += ALIGN_SIZE; | 555 | tmp += ALIGN_SIZE; |
472 | tmp &= ~((unsigned long) ALIGN_SIZE); | 556 | tmp &= ~((u64) ALIGN_SIZE); |
473 | ba->ba_1 = (void *) tmp; | 557 | ba->ba_1 = (void *) tmp; |
474 | k++; | 558 | k++; |
475 | } | 559 | } |
@@ -483,9 +567,9 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
483 | (nic->pdev, size, &mac_control->stats_mem_phy); | 567 | (nic->pdev, size, &mac_control->stats_mem_phy); |
484 | 568 | ||
485 | if (!mac_control->stats_mem) { | 569 | if (!mac_control->stats_mem) { |
486 | /* | 570 | /* |
487 | * In case of failure, free_shared_mem() is called, which | 571 | * In case of failure, free_shared_mem() is called, which |
488 | * should free any memory that was alloced till the | 572 | * should free any memory that was alloced till the |
489 | * failure happened. | 573 | * failure happened. |
490 | */ | 574 | */ |
491 | return -ENOMEM; | 575 | return -ENOMEM; |
@@ -495,15 +579,14 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
495 | tmp_v_addr = mac_control->stats_mem; | 579 | tmp_v_addr = mac_control->stats_mem; |
496 | mac_control->stats_info = (StatInfo_t *) tmp_v_addr; | 580 | mac_control->stats_info = (StatInfo_t *) tmp_v_addr; |
497 | memset(tmp_v_addr, 0, size); | 581 | memset(tmp_v_addr, 0, size); |
498 | |||
499 | DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, | 582 | DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, |
500 | (unsigned long long) tmp_p_addr); | 583 | (unsigned long long) tmp_p_addr); |
501 | 584 | ||
502 | return SUCCESS; | 585 | return SUCCESS; |
503 | } | 586 | } |
504 | 587 | ||
505 | /** | 588 | /** |
506 | * free_shared_mem - Free the allocated Memory | 589 | * free_shared_mem - Free the allocated Memory |
507 | * @nic: Device private variable. | 590 | * @nic: Device private variable. |
508 | * Description: This function is to free all memory locations allocated by | 591 | * Description: This function is to free all memory locations allocated by |
509 | * the init_shared_mem() function and return it to the kernel. | 592 | * the init_shared_mem() function and return it to the kernel. |
@@ -533,15 +616,19 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
533 | lst_per_page); | 616 | lst_per_page); |
534 | for (j = 0; j < page_num; j++) { | 617 | for (j = 0; j < page_num; j++) { |
535 | int mem_blks = (j * lst_per_page); | 618 | int mem_blks = (j * lst_per_page); |
536 | if (!nic->list_info[i][mem_blks].list_virt_addr) | 619 | if ((!mac_control->fifos[i].list_info) || |
620 | (!mac_control->fifos[i].list_info[mem_blks]. | ||
621 | list_virt_addr)) | ||
537 | break; | 622 | break; |
538 | pci_free_consistent(nic->pdev, PAGE_SIZE, | 623 | pci_free_consistent(nic->pdev, PAGE_SIZE, |
539 | nic->list_info[i][mem_blks]. | 624 | mac_control->fifos[i]. |
625 | list_info[mem_blks]. | ||
540 | list_virt_addr, | 626 | list_virt_addr, |
541 | nic->list_info[i][mem_blks]. | 627 | mac_control->fifos[i]. |
628 | list_info[mem_blks]. | ||
542 | list_phy_addr); | 629 | list_phy_addr); |
543 | } | 630 | } |
544 | kfree(nic->list_info[i]); | 631 | kfree(mac_control->fifos[i].list_info); |
545 | } | 632 | } |
546 | 633 | ||
547 | #ifndef CONFIG_2BUFF_MODE | 634 | #ifndef CONFIG_2BUFF_MODE |
@@ -550,10 +637,12 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
550 | size = SIZE_OF_BLOCK; | 637 | size = SIZE_OF_BLOCK; |
551 | #endif | 638 | #endif |
552 | for (i = 0; i < config->rx_ring_num; i++) { | 639 | for (i = 0; i < config->rx_ring_num; i++) { |
553 | blk_cnt = nic->block_count[i]; | 640 | blk_cnt = mac_control->rings[i].block_count; |
554 | for (j = 0; j < blk_cnt; j++) { | 641 | for (j = 0; j < blk_cnt; j++) { |
555 | tmp_v_addr = nic->rx_blocks[i][j].block_virt_addr; | 642 | tmp_v_addr = mac_control->rings[i].rx_blocks[j]. |
556 | tmp_p_addr = nic->rx_blocks[i][j].block_dma_addr; | 643 | block_virt_addr; |
644 | tmp_p_addr = mac_control->rings[i].rx_blocks[j]. | ||
645 | block_dma_addr; | ||
557 | if (tmp_v_addr == NULL) | 646 | if (tmp_v_addr == NULL) |
558 | break; | 647 | break; |
559 | pci_free_consistent(nic->pdev, size, | 648 | pci_free_consistent(nic->pdev, size, |
@@ -566,35 +655,21 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
566 | for (i = 0; i < config->rx_ring_num; i++) { | 655 | for (i = 0; i < config->rx_ring_num; i++) { |
567 | blk_cnt = | 656 | blk_cnt = |
568 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 657 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
569 | if (!nic->ba[i]) | ||
570 | goto end_free; | ||
571 | for (j = 0; j < blk_cnt; j++) { | 658 | for (j = 0; j < blk_cnt; j++) { |
572 | int k = 0; | 659 | int k = 0; |
573 | if (!nic->ba[i][j]) { | 660 | if (!mac_control->rings[i].ba[j]) |
574 | kfree(nic->ba[i]); | 661 | continue; |
575 | goto end_free; | ||
576 | } | ||
577 | while (k != MAX_RXDS_PER_BLOCK) { | 662 | while (k != MAX_RXDS_PER_BLOCK) { |
578 | buffAdd_t *ba = &nic->ba[i][j][k]; | 663 | buffAdd_t *ba = &mac_control->rings[i].ba[j][k]; |
579 | if (!ba || !ba->ba_0_org || !ba->ba_1_org) | ||
580 | { | ||
581 | kfree(nic->ba[i]); | ||
582 | kfree(nic->ba[i][j]); | ||
583 | if(ba->ba_0_org) | ||
584 | kfree(ba->ba_0_org); | ||
585 | if(ba->ba_1_org) | ||
586 | kfree(ba->ba_1_org); | ||
587 | goto end_free; | ||
588 | } | ||
589 | kfree(ba->ba_0_org); | 664 | kfree(ba->ba_0_org); |
590 | kfree(ba->ba_1_org); | 665 | kfree(ba->ba_1_org); |
591 | k++; | 666 | k++; |
592 | } | 667 | } |
593 | kfree(nic->ba[i][j]); | 668 | kfree(mac_control->rings[i].ba[j]); |
594 | } | 669 | } |
595 | kfree(nic->ba[i]); | 670 | if (mac_control->rings[i].ba) |
671 | kfree(mac_control->rings[i].ba); | ||
596 | } | 672 | } |
597 | end_free: | ||
598 | #endif | 673 | #endif |
599 | 674 | ||
600 | if (mac_control->stats_mem) { | 675 | if (mac_control->stats_mem) { |
@@ -605,12 +680,93 @@ end_free: | |||
605 | } | 680 | } |
606 | } | 681 | } |
607 | 682 | ||
608 | /** | 683 | /** |
609 | * init_nic - Initialization of hardware | 684 | * s2io_verify_pci_mode - |
685 | */ | ||
686 | |||
687 | static int s2io_verify_pci_mode(nic_t *nic) | ||
688 | { | ||
689 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
690 | register u64 val64 = 0; | ||
691 | int mode; | ||
692 | |||
693 | val64 = readq(&bar0->pci_mode); | ||
694 | mode = (u8)GET_PCI_MODE(val64); | ||
695 | |||
696 | if ( val64 & PCI_MODE_UNKNOWN_MODE) | ||
697 | return -1; /* Unknown PCI mode */ | ||
698 | return mode; | ||
699 | } | ||
700 | |||
701 | |||
702 | /** | ||
703 | * s2io_print_pci_mode - | ||
704 | */ | ||
705 | static int s2io_print_pci_mode(nic_t *nic) | ||
706 | { | ||
707 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
708 | register u64 val64 = 0; | ||
709 | int mode; | ||
710 | struct config_param *config = &nic->config; | ||
711 | |||
712 | val64 = readq(&bar0->pci_mode); | ||
713 | mode = (u8)GET_PCI_MODE(val64); | ||
714 | |||
715 | if ( val64 & PCI_MODE_UNKNOWN_MODE) | ||
716 | return -1; /* Unknown PCI mode */ | ||
717 | |||
718 | if (val64 & PCI_MODE_32_BITS) { | ||
719 | DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name); | ||
720 | } else { | ||
721 | DBG_PRINT(ERR_DBG, "%s: Device is on 64 bit ", nic->dev->name); | ||
722 | } | ||
723 | |||
724 | switch(mode) { | ||
725 | case PCI_MODE_PCI_33: | ||
726 | DBG_PRINT(ERR_DBG, "33MHz PCI bus\n"); | ||
727 | config->bus_speed = 33; | ||
728 | break; | ||
729 | case PCI_MODE_PCI_66: | ||
730 | DBG_PRINT(ERR_DBG, "66MHz PCI bus\n"); | ||
731 | config->bus_speed = 133; | ||
732 | break; | ||
733 | case PCI_MODE_PCIX_M1_66: | ||
734 | DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n"); | ||
735 | config->bus_speed = 133; /* Herc doubles the clock rate */ | ||
736 | break; | ||
737 | case PCI_MODE_PCIX_M1_100: | ||
738 | DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n"); | ||
739 | config->bus_speed = 200; | ||
740 | break; | ||
741 | case PCI_MODE_PCIX_M1_133: | ||
742 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n"); | ||
743 | config->bus_speed = 266; | ||
744 | break; | ||
745 | case PCI_MODE_PCIX_M2_66: | ||
746 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n"); | ||
747 | config->bus_speed = 133; | ||
748 | break; | ||
749 | case PCI_MODE_PCIX_M2_100: | ||
750 | DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n"); | ||
751 | config->bus_speed = 200; | ||
752 | break; | ||
753 | case PCI_MODE_PCIX_M2_133: | ||
754 | DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n"); | ||
755 | config->bus_speed = 266; | ||
756 | break; | ||
757 | default: | ||
758 | return -1; /* Unsupported bus speed */ | ||
759 | } | ||
760 | |||
761 | return mode; | ||
762 | } | ||
763 | |||
764 | /** | ||
765 | * init_nic - Initialization of hardware | ||
610 | * @nic: device peivate variable | 766 | * @nic: device peivate variable |
611 | * Description: The function sequentially configures every block | 767 | * Description: The function sequentially configures every block |
612 | * of the H/W from their reset values. | 768 | * of the H/W from their reset values. |
613 | * Return Value: SUCCESS on success and | 769 | * Return Value: SUCCESS on success and |
614 | * '-1' on failure (endian settings incorrect). | 770 | * '-1' on failure (endian settings incorrect). |
615 | */ | 771 | */ |
616 | 772 | ||
@@ -626,21 +782,32 @@ static int init_nic(struct s2io_nic *nic) | |||
626 | struct config_param *config; | 782 | struct config_param *config; |
627 | int mdio_cnt = 0, dtx_cnt = 0; | 783 | int mdio_cnt = 0, dtx_cnt = 0; |
628 | unsigned long long mem_share; | 784 | unsigned long long mem_share; |
785 | int mem_size; | ||
629 | 786 | ||
630 | mac_control = &nic->mac_control; | 787 | mac_control = &nic->mac_control; |
631 | config = &nic->config; | 788 | config = &nic->config; |
632 | 789 | ||
633 | /* Initialize swapper control register */ | 790 | /* to set the swapper controle on the card */ |
634 | if (s2io_set_swapper(nic)) { | 791 | if(s2io_set_swapper(nic)) { |
635 | DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n"); | 792 | DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n"); |
636 | return -1; | 793 | return -1; |
637 | } | 794 | } |
638 | 795 | ||
796 | /* | ||
797 | * Herc requires EOI to be removed from reset before XGXS, so.. | ||
798 | */ | ||
799 | if (nic->device_type & XFRAME_II_DEVICE) { | ||
800 | val64 = 0xA500000000ULL; | ||
801 | writeq(val64, &bar0->sw_reset); | ||
802 | msleep(500); | ||
803 | val64 = readq(&bar0->sw_reset); | ||
804 | } | ||
805 | |||
639 | /* Remove XGXS from reset state */ | 806 | /* Remove XGXS from reset state */ |
640 | val64 = 0; | 807 | val64 = 0; |
641 | writeq(val64, &bar0->sw_reset); | 808 | writeq(val64, &bar0->sw_reset); |
642 | val64 = readq(&bar0->sw_reset); | ||
643 | msleep(500); | 809 | msleep(500); |
810 | val64 = readq(&bar0->sw_reset); | ||
644 | 811 | ||
645 | /* Enable Receiving broadcasts */ | 812 | /* Enable Receiving broadcasts */ |
646 | add = &bar0->mac_cfg; | 813 | add = &bar0->mac_cfg; |
@@ -660,48 +827,58 @@ static int init_nic(struct s2io_nic *nic) | |||
660 | val64 = dev->mtu; | 827 | val64 = dev->mtu; |
661 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | 828 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); |
662 | 829 | ||
663 | /* | 830 | /* |
664 | * Configuring the XAUI Interface of Xena. | 831 | * Configuring the XAUI Interface of Xena. |
665 | * *************************************** | 832 | * *************************************** |
666 | * To Configure the Xena's XAUI, one has to write a series | 833 | * To Configure the Xena's XAUI, one has to write a series |
667 | * of 64 bit values into two registers in a particular | 834 | * of 64 bit values into two registers in a particular |
668 | * sequence. Hence a macro 'SWITCH_SIGN' has been defined | 835 | * sequence. Hence a macro 'SWITCH_SIGN' has been defined |
669 | * which will be defined in the array of configuration values | 836 | * which will be defined in the array of configuration values |
670 | * (default_dtx_cfg & default_mdio_cfg) at appropriate places | 837 | * (xena_dtx_cfg & xena_mdio_cfg) at appropriate places |
671 | * to switch writing from one regsiter to another. We continue | 838 | * to switch writing from one regsiter to another. We continue |
672 | * writing these values until we encounter the 'END_SIGN' macro. | 839 | * writing these values until we encounter the 'END_SIGN' macro. |
673 | * For example, After making a series of 21 writes into | 840 | * For example, After making a series of 21 writes into |
674 | * dtx_control register the 'SWITCH_SIGN' appears and hence we | 841 | * dtx_control register the 'SWITCH_SIGN' appears and hence we |
675 | * start writing into mdio_control until we encounter END_SIGN. | 842 | * start writing into mdio_control until we encounter END_SIGN. |
676 | */ | 843 | */ |
677 | while (1) { | 844 | if (nic->device_type & XFRAME_II_DEVICE) { |
678 | dtx_cfg: | 845 | while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) { |
679 | while (default_dtx_cfg[dtx_cnt] != END_SIGN) { | 846 | SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt], |
680 | if (default_dtx_cfg[dtx_cnt] == SWITCH_SIGN) { | ||
681 | dtx_cnt++; | ||
682 | goto mdio_cfg; | ||
683 | } | ||
684 | SPECIAL_REG_WRITE(default_dtx_cfg[dtx_cnt], | ||
685 | &bar0->dtx_control, UF); | 847 | &bar0->dtx_control, UF); |
686 | val64 = readq(&bar0->dtx_control); | 848 | if (dtx_cnt & 0x1) |
849 | msleep(1); /* Necessary!! */ | ||
687 | dtx_cnt++; | 850 | dtx_cnt++; |
688 | } | 851 | } |
689 | mdio_cfg: | 852 | } else { |
690 | while (default_mdio_cfg[mdio_cnt] != END_SIGN) { | 853 | while (1) { |
691 | if (default_mdio_cfg[mdio_cnt] == SWITCH_SIGN) { | 854 | dtx_cfg: |
855 | while (xena_dtx_cfg[dtx_cnt] != END_SIGN) { | ||
856 | if (xena_dtx_cfg[dtx_cnt] == SWITCH_SIGN) { | ||
857 | dtx_cnt++; | ||
858 | goto mdio_cfg; | ||
859 | } | ||
860 | SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt], | ||
861 | &bar0->dtx_control, UF); | ||
862 | val64 = readq(&bar0->dtx_control); | ||
863 | dtx_cnt++; | ||
864 | } | ||
865 | mdio_cfg: | ||
866 | while (xena_mdio_cfg[mdio_cnt] != END_SIGN) { | ||
867 | if (xena_mdio_cfg[mdio_cnt] == SWITCH_SIGN) { | ||
868 | mdio_cnt++; | ||
869 | goto dtx_cfg; | ||
870 | } | ||
871 | SPECIAL_REG_WRITE(xena_mdio_cfg[mdio_cnt], | ||
872 | &bar0->mdio_control, UF); | ||
873 | val64 = readq(&bar0->mdio_control); | ||
692 | mdio_cnt++; | 874 | mdio_cnt++; |
875 | } | ||
876 | if ((xena_dtx_cfg[dtx_cnt] == END_SIGN) && | ||
877 | (xena_mdio_cfg[mdio_cnt] == END_SIGN)) { | ||
878 | break; | ||
879 | } else { | ||
693 | goto dtx_cfg; | 880 | goto dtx_cfg; |
694 | } | 881 | } |
695 | SPECIAL_REG_WRITE(default_mdio_cfg[mdio_cnt], | ||
696 | &bar0->mdio_control, UF); | ||
697 | val64 = readq(&bar0->mdio_control); | ||
698 | mdio_cnt++; | ||
699 | } | ||
700 | if ((default_dtx_cfg[dtx_cnt] == END_SIGN) && | ||
701 | (default_mdio_cfg[mdio_cnt] == END_SIGN)) { | ||
702 | break; | ||
703 | } else { | ||
704 | goto dtx_cfg; | ||
705 | } | 882 | } |
706 | } | 883 | } |
707 | 884 | ||
@@ -748,12 +925,20 @@ static int init_nic(struct s2io_nic *nic) | |||
748 | val64 |= BIT(0); /* To enable the FIFO partition. */ | 925 | val64 |= BIT(0); /* To enable the FIFO partition. */ |
749 | writeq(val64, &bar0->tx_fifo_partition_0); | 926 | writeq(val64, &bar0->tx_fifo_partition_0); |
750 | 927 | ||
928 | /* | ||
929 | * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug | ||
930 | * SXE-008 TRANSMIT DMA ARBITRATION ISSUE. | ||
931 | */ | ||
932 | if ((nic->device_type == XFRAME_I_DEVICE) && | ||
933 | (get_xena_rev_id(nic->pdev) < 4)) | ||
934 | writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable); | ||
935 | |||
751 | val64 = readq(&bar0->tx_fifo_partition_0); | 936 | val64 = readq(&bar0->tx_fifo_partition_0); |
752 | DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n", | 937 | DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n", |
753 | &bar0->tx_fifo_partition_0, (unsigned long long) val64); | 938 | &bar0->tx_fifo_partition_0, (unsigned long long) val64); |
754 | 939 | ||
755 | /* | 940 | /* |
756 | * Initialization of Tx_PA_CONFIG register to ignore packet | 941 | * Initialization of Tx_PA_CONFIG register to ignore packet |
757 | * integrity checking. | 942 | * integrity checking. |
758 | */ | 943 | */ |
759 | val64 = readq(&bar0->tx_pa_cfg); | 944 | val64 = readq(&bar0->tx_pa_cfg); |
@@ -770,85 +955,304 @@ static int init_nic(struct s2io_nic *nic) | |||
770 | } | 955 | } |
771 | writeq(val64, &bar0->rx_queue_priority); | 956 | writeq(val64, &bar0->rx_queue_priority); |
772 | 957 | ||
773 | /* | 958 | /* |
774 | * Allocating equal share of memory to all the | 959 | * Allocating equal share of memory to all the |
775 | * configured Rings. | 960 | * configured Rings. |
776 | */ | 961 | */ |
777 | val64 = 0; | 962 | val64 = 0; |
963 | if (nic->device_type & XFRAME_II_DEVICE) | ||
964 | mem_size = 32; | ||
965 | else | ||
966 | mem_size = 64; | ||
967 | |||
778 | for (i = 0; i < config->rx_ring_num; i++) { | 968 | for (i = 0; i < config->rx_ring_num; i++) { |
779 | switch (i) { | 969 | switch (i) { |
780 | case 0: | 970 | case 0: |
781 | mem_share = (64 / config->rx_ring_num + | 971 | mem_share = (mem_size / config->rx_ring_num + |
782 | 64 % config->rx_ring_num); | 972 | mem_size % config->rx_ring_num); |
783 | val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share); | 973 | val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share); |
784 | continue; | 974 | continue; |
785 | case 1: | 975 | case 1: |
786 | mem_share = (64 / config->rx_ring_num); | 976 | mem_share = (mem_size / config->rx_ring_num); |
787 | val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share); | 977 | val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share); |
788 | continue; | 978 | continue; |
789 | case 2: | 979 | case 2: |
790 | mem_share = (64 / config->rx_ring_num); | 980 | mem_share = (mem_size / config->rx_ring_num); |
791 | val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share); | 981 | val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share); |
792 | continue; | 982 | continue; |
793 | case 3: | 983 | case 3: |
794 | mem_share = (64 / config->rx_ring_num); | 984 | mem_share = (mem_size / config->rx_ring_num); |
795 | val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share); | 985 | val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share); |
796 | continue; | 986 | continue; |
797 | case 4: | 987 | case 4: |
798 | mem_share = (64 / config->rx_ring_num); | 988 | mem_share = (mem_size / config->rx_ring_num); |
799 | val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share); | 989 | val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share); |
800 | continue; | 990 | continue; |
801 | case 5: | 991 | case 5: |
802 | mem_share = (64 / config->rx_ring_num); | 992 | mem_share = (mem_size / config->rx_ring_num); |
803 | val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share); | 993 | val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share); |
804 | continue; | 994 | continue; |
805 | case 6: | 995 | case 6: |
806 | mem_share = (64 / config->rx_ring_num); | 996 | mem_share = (mem_size / config->rx_ring_num); |
807 | val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share); | 997 | val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share); |
808 | continue; | 998 | continue; |
809 | case 7: | 999 | case 7: |
810 | mem_share = (64 / config->rx_ring_num); | 1000 | mem_share = (mem_size / config->rx_ring_num); |
811 | val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share); | 1001 | val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share); |
812 | continue; | 1002 | continue; |
813 | } | 1003 | } |
814 | } | 1004 | } |
815 | writeq(val64, &bar0->rx_queue_cfg); | 1005 | writeq(val64, &bar0->rx_queue_cfg); |
816 | 1006 | ||
817 | /* | 1007 | /* |
818 | * Initializing the Tx round robin registers to 0. | 1008 | * Filling Tx round robin registers |
819 | * Filling Tx and Rx round robin registers as per the | 1009 | * as per the number of FIFOs |
820 | * number of FIFOs and Rings is still TODO. | ||
821 | */ | ||
822 | writeq(0, &bar0->tx_w_round_robin_0); | ||
823 | writeq(0, &bar0->tx_w_round_robin_1); | ||
824 | writeq(0, &bar0->tx_w_round_robin_2); | ||
825 | writeq(0, &bar0->tx_w_round_robin_3); | ||
826 | writeq(0, &bar0->tx_w_round_robin_4); | ||
827 | |||
828 | /* | ||
829 | * TODO | ||
830 | * Disable Rx steering. Hard coding all packets be steered to | ||
831 | * Queue 0 for now. | ||
832 | */ | 1010 | */ |
833 | val64 = 0x8080808080808080ULL; | 1011 | switch (config->tx_fifo_num) { |
834 | writeq(val64, &bar0->rts_qos_steering); | 1012 | case 1: |
1013 | val64 = 0x0000000000000000ULL; | ||
1014 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1015 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1016 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1017 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1018 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1019 | break; | ||
1020 | case 2: | ||
1021 | val64 = 0x0000010000010000ULL; | ||
1022 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1023 | val64 = 0x0100000100000100ULL; | ||
1024 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1025 | val64 = 0x0001000001000001ULL; | ||
1026 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1027 | val64 = 0x0000010000010000ULL; | ||
1028 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1029 | val64 = 0x0100000000000000ULL; | ||
1030 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1031 | break; | ||
1032 | case 3: | ||
1033 | val64 = 0x0001000102000001ULL; | ||
1034 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1035 | val64 = 0x0001020000010001ULL; | ||
1036 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1037 | val64 = 0x0200000100010200ULL; | ||
1038 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1039 | val64 = 0x0001000102000001ULL; | ||
1040 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1041 | val64 = 0x0001020000000000ULL; | ||
1042 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1043 | break; | ||
1044 | case 4: | ||
1045 | val64 = 0x0001020300010200ULL; | ||
1046 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1047 | val64 = 0x0100000102030001ULL; | ||
1048 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1049 | val64 = 0x0200010000010203ULL; | ||
1050 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1051 | val64 = 0x0001020001000001ULL; | ||
1052 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1053 | val64 = 0x0203000100000000ULL; | ||
1054 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1055 | break; | ||
1056 | case 5: | ||
1057 | val64 = 0x0001000203000102ULL; | ||
1058 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1059 | val64 = 0x0001020001030004ULL; | ||
1060 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1061 | val64 = 0x0001000203000102ULL; | ||
1062 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1063 | val64 = 0x0001020001030004ULL; | ||
1064 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1065 | val64 = 0x0001000000000000ULL; | ||
1066 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1067 | break; | ||
1068 | case 6: | ||
1069 | val64 = 0x0001020304000102ULL; | ||
1070 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1071 | val64 = 0x0304050001020001ULL; | ||
1072 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1073 | val64 = 0x0203000100000102ULL; | ||
1074 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1075 | val64 = 0x0304000102030405ULL; | ||
1076 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1077 | val64 = 0x0001000200000000ULL; | ||
1078 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1079 | break; | ||
1080 | case 7: | ||
1081 | val64 = 0x0001020001020300ULL; | ||
1082 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1083 | val64 = 0x0102030400010203ULL; | ||
1084 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1085 | val64 = 0x0405060001020001ULL; | ||
1086 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1087 | val64 = 0x0304050000010200ULL; | ||
1088 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1089 | val64 = 0x0102030000000000ULL; | ||
1090 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1091 | break; | ||
1092 | case 8: | ||
1093 | val64 = 0x0001020300040105ULL; | ||
1094 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1095 | val64 = 0x0200030106000204ULL; | ||
1096 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1097 | val64 = 0x0103000502010007ULL; | ||
1098 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1099 | val64 = 0x0304010002060500ULL; | ||
1100 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1101 | val64 = 0x0103020400000000ULL; | ||
1102 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1103 | break; | ||
1104 | } | ||
1105 | |||
1106 | /* Filling the Rx round robin registers as per the | ||
1107 | * number of Rings and steering based on QoS. | ||
1108 | */ | ||
1109 | switch (config->rx_ring_num) { | ||
1110 | case 1: | ||
1111 | val64 = 0x8080808080808080ULL; | ||
1112 | writeq(val64, &bar0->rts_qos_steering); | ||
1113 | break; | ||
1114 | case 2: | ||
1115 | val64 = 0x0000010000010000ULL; | ||
1116 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1117 | val64 = 0x0100000100000100ULL; | ||
1118 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1119 | val64 = 0x0001000001000001ULL; | ||
1120 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1121 | val64 = 0x0000010000010000ULL; | ||
1122 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1123 | val64 = 0x0100000000000000ULL; | ||
1124 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1125 | |||
1126 | val64 = 0x8080808040404040ULL; | ||
1127 | writeq(val64, &bar0->rts_qos_steering); | ||
1128 | break; | ||
1129 | case 3: | ||
1130 | val64 = 0x0001000102000001ULL; | ||
1131 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1132 | val64 = 0x0001020000010001ULL; | ||
1133 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1134 | val64 = 0x0200000100010200ULL; | ||
1135 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1136 | val64 = 0x0001000102000001ULL; | ||
1137 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1138 | val64 = 0x0001020000000000ULL; | ||
1139 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1140 | |||
1141 | val64 = 0x8080804040402020ULL; | ||
1142 | writeq(val64, &bar0->rts_qos_steering); | ||
1143 | break; | ||
1144 | case 4: | ||
1145 | val64 = 0x0001020300010200ULL; | ||
1146 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1147 | val64 = 0x0100000102030001ULL; | ||
1148 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1149 | val64 = 0x0200010000010203ULL; | ||
1150 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1151 | val64 = 0x0001020001000001ULL; | ||
1152 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1153 | val64 = 0x0203000100000000ULL; | ||
1154 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1155 | |||
1156 | val64 = 0x8080404020201010ULL; | ||
1157 | writeq(val64, &bar0->rts_qos_steering); | ||
1158 | break; | ||
1159 | case 5: | ||
1160 | val64 = 0x0001000203000102ULL; | ||
1161 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1162 | val64 = 0x0001020001030004ULL; | ||
1163 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1164 | val64 = 0x0001000203000102ULL; | ||
1165 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1166 | val64 = 0x0001020001030004ULL; | ||
1167 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1168 | val64 = 0x0001000000000000ULL; | ||
1169 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1170 | |||
1171 | val64 = 0x8080404020201008ULL; | ||
1172 | writeq(val64, &bar0->rts_qos_steering); | ||
1173 | break; | ||
1174 | case 6: | ||
1175 | val64 = 0x0001020304000102ULL; | ||
1176 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1177 | val64 = 0x0304050001020001ULL; | ||
1178 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1179 | val64 = 0x0203000100000102ULL; | ||
1180 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1181 | val64 = 0x0304000102030405ULL; | ||
1182 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1183 | val64 = 0x0001000200000000ULL; | ||
1184 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1185 | |||
1186 | val64 = 0x8080404020100804ULL; | ||
1187 | writeq(val64, &bar0->rts_qos_steering); | ||
1188 | break; | ||
1189 | case 7: | ||
1190 | val64 = 0x0001020001020300ULL; | ||
1191 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1192 | val64 = 0x0102030400010203ULL; | ||
1193 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1194 | val64 = 0x0405060001020001ULL; | ||
1195 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1196 | val64 = 0x0304050000010200ULL; | ||
1197 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1198 | val64 = 0x0102030000000000ULL; | ||
1199 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1200 | |||
1201 | val64 = 0x8080402010080402ULL; | ||
1202 | writeq(val64, &bar0->rts_qos_steering); | ||
1203 | break; | ||
1204 | case 8: | ||
1205 | val64 = 0x0001020300040105ULL; | ||
1206 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1207 | val64 = 0x0200030106000204ULL; | ||
1208 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1209 | val64 = 0x0103000502010007ULL; | ||
1210 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1211 | val64 = 0x0304010002060500ULL; | ||
1212 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1213 | val64 = 0x0103020400000000ULL; | ||
1214 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1215 | |||
1216 | val64 = 0x8040201008040201ULL; | ||
1217 | writeq(val64, &bar0->rts_qos_steering); | ||
1218 | break; | ||
1219 | } | ||
835 | 1220 | ||
836 | /* UDP Fix */ | 1221 | /* UDP Fix */ |
837 | val64 = 0; | 1222 | val64 = 0; |
838 | for (i = 1; i < 8; i++) | 1223 | for (i = 0; i < 8; i++) |
1224 | writeq(val64, &bar0->rts_frm_len_n[i]); | ||
1225 | |||
1226 | /* Set the default rts frame length for the rings configured */ | ||
1227 | val64 = MAC_RTS_FRM_LEN_SET(dev->mtu+22); | ||
1228 | for (i = 0 ; i < config->rx_ring_num ; i++) | ||
839 | writeq(val64, &bar0->rts_frm_len_n[i]); | 1229 | writeq(val64, &bar0->rts_frm_len_n[i]); |
840 | 1230 | ||
841 | /* Set rts_frm_len register for fifo 0 */ | 1231 | /* Set the frame length for the configured rings |
842 | writeq(MAC_RTS_FRM_LEN_SET(dev->mtu + 22), | 1232 | * desired by the user |
843 | &bar0->rts_frm_len_n[0]); | 1233 | */ |
1234 | for (i = 0; i < config->rx_ring_num; i++) { | ||
1235 | /* If rts_frm_len[i] == 0 then it is assumed that user not | ||
1236 | * specified frame length steering. | ||
1237 | * If the user provides the frame length then program | ||
1238 | * the rts_frm_len register for those values or else | ||
1239 | * leave it as it is. | ||
1240 | */ | ||
1241 | if (rts_frm_len[i] != 0) { | ||
1242 | writeq(MAC_RTS_FRM_LEN_SET(rts_frm_len[i]), | ||
1243 | &bar0->rts_frm_len_n[i]); | ||
1244 | } | ||
1245 | } | ||
844 | 1246 | ||
845 | /* Enable statistics */ | 1247 | /* Program statistics memory */ |
846 | writeq(mac_control->stats_mem_phy, &bar0->stat_addr); | 1248 | writeq(mac_control->stats_mem_phy, &bar0->stat_addr); |
847 | val64 = SET_UPDT_PERIOD(Stats_refresh_time) | | ||
848 | STAT_CFG_STAT_RO | STAT_CFG_STAT_EN; | ||
849 | writeq(val64, &bar0->stat_cfg); | ||
850 | 1249 | ||
851 | /* | 1250 | if (nic->device_type == XFRAME_II_DEVICE) { |
1251 | val64 = STAT_BC(0x320); | ||
1252 | writeq(val64, &bar0->stat_byte_cnt); | ||
1253 | } | ||
1254 | |||
1255 | /* | ||
852 | * Initializing the sampling rate for the device to calculate the | 1256 | * Initializing the sampling rate for the device to calculate the |
853 | * bandwidth utilization. | 1257 | * bandwidth utilization. |
854 | */ | 1258 | */ |
@@ -857,30 +1261,38 @@ static int init_nic(struct s2io_nic *nic) | |||
857 | writeq(val64, &bar0->mac_link_util); | 1261 | writeq(val64, &bar0->mac_link_util); |
858 | 1262 | ||
859 | 1263 | ||
860 | /* | 1264 | /* |
861 | * Initializing the Transmit and Receive Traffic Interrupt | 1265 | * Initializing the Transmit and Receive Traffic Interrupt |
862 | * Scheme. | 1266 | * Scheme. |
863 | */ | 1267 | */ |
864 | /* TTI Initialization. Default Tx timer gets us about | 1268 | /* |
1269 | * TTI Initialization. Default Tx timer gets us about | ||
865 | * 250 interrupts per sec. Continuous interrupts are enabled | 1270 | * 250 interrupts per sec. Continuous interrupts are enabled |
866 | * by default. | 1271 | * by default. |
867 | */ | 1272 | */ |
868 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078) | | 1273 | if (nic->device_type == XFRAME_II_DEVICE) { |
869 | TTI_DATA1_MEM_TX_URNG_A(0xA) | | 1274 | int count = (nic->config.bus_speed * 125)/2; |
1275 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count); | ||
1276 | } else { | ||
1277 | |||
1278 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078); | ||
1279 | } | ||
1280 | val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) | | ||
870 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | 1281 | TTI_DATA1_MEM_TX_URNG_B(0x10) | |
871 | TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN | | 1282 | TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN; |
872 | TTI_DATA1_MEM_TX_TIMER_CI_EN; | 1283 | if (use_continuous_tx_intrs) |
1284 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | ||
873 | writeq(val64, &bar0->tti_data1_mem); | 1285 | writeq(val64, &bar0->tti_data1_mem); |
874 | 1286 | ||
875 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | 1287 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | |
876 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | 1288 | TTI_DATA2_MEM_TX_UFC_B(0x20) | |
877 | TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80); | 1289 | TTI_DATA2_MEM_TX_UFC_C(0x70) | TTI_DATA2_MEM_TX_UFC_D(0x80); |
878 | writeq(val64, &bar0->tti_data2_mem); | 1290 | writeq(val64, &bar0->tti_data2_mem); |
879 | 1291 | ||
880 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; | 1292 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; |
881 | writeq(val64, &bar0->tti_command_mem); | 1293 | writeq(val64, &bar0->tti_command_mem); |
882 | 1294 | ||
883 | /* | 1295 | /* |
884 | * Once the operation completes, the Strobe bit of the command | 1296 | * Once the operation completes, the Strobe bit of the command |
885 | * register will be reset. We poll for this particular condition | 1297 | * register will be reset. We poll for this particular condition |
886 | * We wait for a maximum of 500ms for the operation to complete, | 1298 | * We wait for a maximum of 500ms for the operation to complete, |
@@ -901,52 +1313,97 @@ static int init_nic(struct s2io_nic *nic) | |||
901 | time++; | 1313 | time++; |
902 | } | 1314 | } |
903 | 1315 | ||
904 | /* RTI Initialization */ | 1316 | if (nic->config.bimodal) { |
905 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF) | | 1317 | int k = 0; |
906 | RTI_DATA1_MEM_RX_URNG_A(0xA) | | 1318 | for (k = 0; k < config->rx_ring_num; k++) { |
907 | RTI_DATA1_MEM_RX_URNG_B(0x10) | | 1319 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; |
908 | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; | 1320 | val64 |= TTI_CMD_MEM_OFFSET(0x38+k); |
1321 | writeq(val64, &bar0->tti_command_mem); | ||
1322 | |||
1323 | /* | ||
1324 | * Once the operation completes, the Strobe bit of the command | ||
1325 | * register will be reset. We poll for this particular condition | ||
1326 | * We wait for a maximum of 500ms for the operation to complete, | ||
1327 | * if it's not complete by then we return error. | ||
1328 | */ | ||
1329 | time = 0; | ||
1330 | while (TRUE) { | ||
1331 | val64 = readq(&bar0->tti_command_mem); | ||
1332 | if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { | ||
1333 | break; | ||
1334 | } | ||
1335 | if (time > 10) { | ||
1336 | DBG_PRINT(ERR_DBG, | ||
1337 | "%s: TTI init Failed\n", | ||
1338 | dev->name); | ||
1339 | return -1; | ||
1340 | } | ||
1341 | time++; | ||
1342 | msleep(50); | ||
1343 | } | ||
1344 | } | ||
1345 | } else { | ||
909 | 1346 | ||
910 | writeq(val64, &bar0->rti_data1_mem); | 1347 | /* RTI Initialization */ |
1348 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1349 | /* | ||
1350 | * Programmed to generate Apprx 500 Intrs per | ||
1351 | * second | ||
1352 | */ | ||
1353 | int count = (nic->config.bus_speed * 125)/4; | ||
1354 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count); | ||
1355 | } else { | ||
1356 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF); | ||
1357 | } | ||
1358 | val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) | | ||
1359 | RTI_DATA1_MEM_RX_URNG_B(0x10) | | ||
1360 | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; | ||
911 | 1361 | ||
912 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | | 1362 | writeq(val64, &bar0->rti_data1_mem); |
913 | RTI_DATA2_MEM_RX_UFC_B(0x2) | | ||
914 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | ||
915 | writeq(val64, &bar0->rti_data2_mem); | ||
916 | 1363 | ||
917 | val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD; | 1364 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | |
918 | writeq(val64, &bar0->rti_command_mem); | 1365 | RTI_DATA2_MEM_RX_UFC_B(0x2) | |
1366 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | ||
1367 | writeq(val64, &bar0->rti_data2_mem); | ||
919 | 1368 | ||
920 | /* | 1369 | for (i = 0; i < config->rx_ring_num; i++) { |
921 | * Once the operation completes, the Strobe bit of the command | 1370 | val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD |
922 | * register will be reset. We poll for this particular condition | 1371 | | RTI_CMD_MEM_OFFSET(i); |
923 | * We wait for a maximum of 500ms for the operation to complete, | 1372 | writeq(val64, &bar0->rti_command_mem); |
924 | * if it's not complete by then we return error. | 1373 | |
925 | */ | 1374 | /* |
926 | time = 0; | 1375 | * Once the operation completes, the Strobe bit of the |
927 | while (TRUE) { | 1376 | * command register will be reset. We poll for this |
928 | val64 = readq(&bar0->rti_command_mem); | 1377 | * particular condition. We wait for a maximum of 500ms |
929 | if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { | 1378 | * for the operation to complete, if it's not complete |
930 | break; | 1379 | * by then we return error. |
931 | } | 1380 | */ |
932 | if (time > 10) { | 1381 | time = 0; |
933 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | 1382 | while (TRUE) { |
934 | dev->name); | 1383 | val64 = readq(&bar0->rti_command_mem); |
935 | return -1; | 1384 | if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) { |
1385 | break; | ||
1386 | } | ||
1387 | if (time > 10) { | ||
1388 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | ||
1389 | dev->name); | ||
1390 | return -1; | ||
1391 | } | ||
1392 | time++; | ||
1393 | msleep(50); | ||
1394 | } | ||
936 | } | 1395 | } |
937 | time++; | ||
938 | msleep(50); | ||
939 | } | 1396 | } |
940 | 1397 | ||
941 | /* | 1398 | /* |
942 | * Initializing proper values as Pause threshold into all | 1399 | * Initializing proper values as Pause threshold into all |
943 | * the 8 Queues on Rx side. | 1400 | * the 8 Queues on Rx side. |
944 | */ | 1401 | */ |
945 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3); | 1402 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3); |
946 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7); | 1403 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7); |
947 | 1404 | ||
948 | /* Disable RMAC PAD STRIPPING */ | 1405 | /* Disable RMAC PAD STRIPPING */ |
949 | add = &bar0->mac_cfg; | 1406 | add = (void *) &bar0->mac_cfg; |
950 | val64 = readq(&bar0->mac_cfg); | 1407 | val64 = readq(&bar0->mac_cfg); |
951 | val64 &= ~(MAC_CFG_RMAC_STRIP_PAD); | 1408 | val64 &= ~(MAC_CFG_RMAC_STRIP_PAD); |
952 | writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); | 1409 | writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); |
@@ -955,8 +1412,8 @@ static int init_nic(struct s2io_nic *nic) | |||
955 | writel((u32) (val64 >> 32), (add + 4)); | 1412 | writel((u32) (val64 >> 32), (add + 4)); |
956 | val64 = readq(&bar0->mac_cfg); | 1413 | val64 = readq(&bar0->mac_cfg); |
957 | 1414 | ||
958 | /* | 1415 | /* |
959 | * Set the time value to be inserted in the pause frame | 1416 | * Set the time value to be inserted in the pause frame |
960 | * generated by xena. | 1417 | * generated by xena. |
961 | */ | 1418 | */ |
962 | val64 = readq(&bar0->rmac_pause_cfg); | 1419 | val64 = readq(&bar0->rmac_pause_cfg); |
@@ -964,7 +1421,7 @@ static int init_nic(struct s2io_nic *nic) | |||
964 | val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time); | 1421 | val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time); |
965 | writeq(val64, &bar0->rmac_pause_cfg); | 1422 | writeq(val64, &bar0->rmac_pause_cfg); |
966 | 1423 | ||
967 | /* | 1424 | /* |
968 | * Set the Threshold Limit for Generating the pause frame | 1425 | * Set the Threshold Limit for Generating the pause frame |
969 | * If the amount of data in any Queue exceeds ratio of | 1426 | * If the amount of data in any Queue exceeds ratio of |
970 | * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256 | 1427 | * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256 |
@@ -988,25 +1445,54 @@ static int init_nic(struct s2io_nic *nic) | |||
988 | } | 1445 | } |
989 | writeq(val64, &bar0->mc_pause_thresh_q4q7); | 1446 | writeq(val64, &bar0->mc_pause_thresh_q4q7); |
990 | 1447 | ||
991 | /* | 1448 | /* |
992 | * TxDMA will stop Read request if the number of read split has | 1449 | * TxDMA will stop Read request if the number of read split has |
993 | * exceeded the limit pointed by shared_splits | 1450 | * exceeded the limit pointed by shared_splits |
994 | */ | 1451 | */ |
995 | val64 = readq(&bar0->pic_control); | 1452 | val64 = readq(&bar0->pic_control); |
996 | val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); | 1453 | val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); |
997 | writeq(val64, &bar0->pic_control); | 1454 | writeq(val64, &bar0->pic_control); |
998 | 1455 | ||
1456 | /* | ||
1457 | * Programming the Herc to split every write transaction | ||
1458 | * that does not start on an ADB to reduce disconnects. | ||
1459 | */ | ||
1460 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1461 | val64 = WREQ_SPLIT_MASK_SET_MASK(255); | ||
1462 | writeq(val64, &bar0->wreq_split_mask); | ||
1463 | } | ||
1464 | |||
1465 | /* Setting Link stability period to 64 ms */ | ||
1466 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1467 | val64 = MISC_LINK_STABILITY_PRD(3); | ||
1468 | writeq(val64, &bar0->misc_control); | ||
1469 | } | ||
1470 | |||
999 | return SUCCESS; | 1471 | return SUCCESS; |
1000 | } | 1472 | } |
1473 | #define LINK_UP_DOWN_INTERRUPT 1 | ||
1474 | #define MAC_RMAC_ERR_TIMER 2 | ||
1001 | 1475 | ||
1002 | /** | 1476 | #if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE) |
1003 | * en_dis_able_nic_intrs - Enable or Disable the interrupts | 1477 | #define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER |
1478 | #else | ||
1479 | int s2io_link_fault_indication(nic_t *nic) | ||
1480 | { | ||
1481 | if (nic->device_type == XFRAME_II_DEVICE) | ||
1482 | return LINK_UP_DOWN_INTERRUPT; | ||
1483 | else | ||
1484 | return MAC_RMAC_ERR_TIMER; | ||
1485 | } | ||
1486 | #endif | ||
1487 | |||
1488 | /** | ||
1489 | * en_dis_able_nic_intrs - Enable or Disable the interrupts | ||
1004 | * @nic: device private variable, | 1490 | * @nic: device private variable, |
1005 | * @mask: A mask indicating which Intr block must be modified and, | 1491 | * @mask: A mask indicating which Intr block must be modified and, |
1006 | * @flag: A flag indicating whether to enable or disable the Intrs. | 1492 | * @flag: A flag indicating whether to enable or disable the Intrs. |
1007 | * Description: This function will either disable or enable the interrupts | 1493 | * Description: This function will either disable or enable the interrupts |
1008 | * depending on the flag argument. The mask argument can be used to | 1494 | * depending on the flag argument. The mask argument can be used to |
1009 | * enable/disable any Intr block. | 1495 | * enable/disable any Intr block. |
1010 | * Return Value: NONE. | 1496 | * Return Value: NONE. |
1011 | */ | 1497 | */ |
1012 | 1498 | ||
@@ -1024,20 +1510,31 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1024 | temp64 = readq(&bar0->general_int_mask); | 1510 | temp64 = readq(&bar0->general_int_mask); |
1025 | temp64 &= ~((u64) val64); | 1511 | temp64 &= ~((u64) val64); |
1026 | writeq(temp64, &bar0->general_int_mask); | 1512 | writeq(temp64, &bar0->general_int_mask); |
1027 | /* | 1513 | /* |
1028 | * Disabled all PCIX, Flash, MDIO, IIC and GPIO | 1514 | * If Hercules adapter enable GPIO otherwise |
1029 | * interrupts for now. | 1515 | * disabled all PCIX, Flash, MDIO, IIC and GPIO |
1030 | * TODO | 1516 | * interrupts for now. |
1517 | * TODO | ||
1031 | */ | 1518 | */ |
1032 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | 1519 | if (s2io_link_fault_indication(nic) == |
1033 | /* | 1520 | LINK_UP_DOWN_INTERRUPT ) { |
1521 | temp64 = readq(&bar0->pic_int_mask); | ||
1522 | temp64 &= ~((u64) PIC_INT_GPIO); | ||
1523 | writeq(temp64, &bar0->pic_int_mask); | ||
1524 | temp64 = readq(&bar0->gpio_int_mask); | ||
1525 | temp64 &= ~((u64) GPIO_INT_MASK_LINK_UP); | ||
1526 | writeq(temp64, &bar0->gpio_int_mask); | ||
1527 | } else { | ||
1528 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | ||
1529 | } | ||
1530 | /* | ||
1034 | * No MSI Support is available presently, so TTI and | 1531 | * No MSI Support is available presently, so TTI and |
1035 | * RTI interrupts are also disabled. | 1532 | * RTI interrupts are also disabled. |
1036 | */ | 1533 | */ |
1037 | } else if (flag == DISABLE_INTRS) { | 1534 | } else if (flag == DISABLE_INTRS) { |
1038 | /* | 1535 | /* |
1039 | * Disable PIC Intrs in the general | 1536 | * Disable PIC Intrs in the general |
1040 | * intr mask register | 1537 | * intr mask register |
1041 | */ | 1538 | */ |
1042 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | 1539 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); |
1043 | temp64 = readq(&bar0->general_int_mask); | 1540 | temp64 = readq(&bar0->general_int_mask); |
@@ -1055,27 +1552,27 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1055 | temp64 = readq(&bar0->general_int_mask); | 1552 | temp64 = readq(&bar0->general_int_mask); |
1056 | temp64 &= ~((u64) val64); | 1553 | temp64 &= ~((u64) val64); |
1057 | writeq(temp64, &bar0->general_int_mask); | 1554 | writeq(temp64, &bar0->general_int_mask); |
1058 | /* | 1555 | /* |
1059 | * Keep all interrupts other than PFC interrupt | 1556 | * Keep all interrupts other than PFC interrupt |
1060 | * and PCC interrupt disabled in DMA level. | 1557 | * and PCC interrupt disabled in DMA level. |
1061 | */ | 1558 | */ |
1062 | val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M | | 1559 | val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M | |
1063 | TXDMA_PCC_INT_M); | 1560 | TXDMA_PCC_INT_M); |
1064 | writeq(val64, &bar0->txdma_int_mask); | 1561 | writeq(val64, &bar0->txdma_int_mask); |
1065 | /* | 1562 | /* |
1066 | * Enable only the MISC error 1 interrupt in PFC block | 1563 | * Enable only the MISC error 1 interrupt in PFC block |
1067 | */ | 1564 | */ |
1068 | val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1); | 1565 | val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1); |
1069 | writeq(val64, &bar0->pfc_err_mask); | 1566 | writeq(val64, &bar0->pfc_err_mask); |
1070 | /* | 1567 | /* |
1071 | * Enable only the FB_ECC error interrupt in PCC block | 1568 | * Enable only the FB_ECC error interrupt in PCC block |
1072 | */ | 1569 | */ |
1073 | val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR); | 1570 | val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR); |
1074 | writeq(val64, &bar0->pcc_err_mask); | 1571 | writeq(val64, &bar0->pcc_err_mask); |
1075 | } else if (flag == DISABLE_INTRS) { | 1572 | } else if (flag == DISABLE_INTRS) { |
1076 | /* | 1573 | /* |
1077 | * Disable TxDMA Intrs in the general intr mask | 1574 | * Disable TxDMA Intrs in the general intr mask |
1078 | * register | 1575 | * register |
1079 | */ | 1576 | */ |
1080 | writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask); | 1577 | writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask); |
1081 | writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask); | 1578 | writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask); |
@@ -1093,15 +1590,15 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1093 | temp64 = readq(&bar0->general_int_mask); | 1590 | temp64 = readq(&bar0->general_int_mask); |
1094 | temp64 &= ~((u64) val64); | 1591 | temp64 &= ~((u64) val64); |
1095 | writeq(temp64, &bar0->general_int_mask); | 1592 | writeq(temp64, &bar0->general_int_mask); |
1096 | /* | 1593 | /* |
1097 | * All RxDMA block interrupts are disabled for now | 1594 | * All RxDMA block interrupts are disabled for now |
1098 | * TODO | 1595 | * TODO |
1099 | */ | 1596 | */ |
1100 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); | 1597 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); |
1101 | } else if (flag == DISABLE_INTRS) { | 1598 | } else if (flag == DISABLE_INTRS) { |
1102 | /* | 1599 | /* |
1103 | * Disable RxDMA Intrs in the general intr mask | 1600 | * Disable RxDMA Intrs in the general intr mask |
1104 | * register | 1601 | * register |
1105 | */ | 1602 | */ |
1106 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); | 1603 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); |
1107 | temp64 = readq(&bar0->general_int_mask); | 1604 | temp64 = readq(&bar0->general_int_mask); |
@@ -1118,22 +1615,13 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1118 | temp64 = readq(&bar0->general_int_mask); | 1615 | temp64 = readq(&bar0->general_int_mask); |
1119 | temp64 &= ~((u64) val64); | 1616 | temp64 &= ~((u64) val64); |
1120 | writeq(temp64, &bar0->general_int_mask); | 1617 | writeq(temp64, &bar0->general_int_mask); |
1121 | /* | 1618 | /* |
1122 | * All MAC block error interrupts are disabled for now | 1619 | * All MAC block error interrupts are disabled for now |
1123 | * except the link status change interrupt. | ||
1124 | * TODO | 1620 | * TODO |
1125 | */ | 1621 | */ |
1126 | val64 = MAC_INT_STATUS_RMAC_INT; | ||
1127 | temp64 = readq(&bar0->mac_int_mask); | ||
1128 | temp64 &= ~((u64) val64); | ||
1129 | writeq(temp64, &bar0->mac_int_mask); | ||
1130 | |||
1131 | val64 = readq(&bar0->mac_rmac_err_mask); | ||
1132 | val64 &= ~((u64) RMAC_LINK_STATE_CHANGE_INT); | ||
1133 | writeq(val64, &bar0->mac_rmac_err_mask); | ||
1134 | } else if (flag == DISABLE_INTRS) { | 1622 | } else if (flag == DISABLE_INTRS) { |
1135 | /* | 1623 | /* |
1136 | * Disable MAC Intrs in the general intr mask register | 1624 | * Disable MAC Intrs in the general intr mask register |
1137 | */ | 1625 | */ |
1138 | writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask); | 1626 | writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask); |
1139 | writeq(DISABLE_ALL_INTRS, | 1627 | writeq(DISABLE_ALL_INTRS, |
@@ -1152,14 +1640,14 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1152 | temp64 = readq(&bar0->general_int_mask); | 1640 | temp64 = readq(&bar0->general_int_mask); |
1153 | temp64 &= ~((u64) val64); | 1641 | temp64 &= ~((u64) val64); |
1154 | writeq(temp64, &bar0->general_int_mask); | 1642 | writeq(temp64, &bar0->general_int_mask); |
1155 | /* | 1643 | /* |
1156 | * All XGXS block error interrupts are disabled for now | 1644 | * All XGXS block error interrupts are disabled for now |
1157 | * TODO | 1645 | * TODO |
1158 | */ | 1646 | */ |
1159 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); | 1647 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); |
1160 | } else if (flag == DISABLE_INTRS) { | 1648 | } else if (flag == DISABLE_INTRS) { |
1161 | /* | 1649 | /* |
1162 | * Disable MC Intrs in the general intr mask register | 1650 | * Disable MC Intrs in the general intr mask register |
1163 | */ | 1651 | */ |
1164 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); | 1652 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); |
1165 | temp64 = readq(&bar0->general_int_mask); | 1653 | temp64 = readq(&bar0->general_int_mask); |
@@ -1175,11 +1663,11 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1175 | temp64 = readq(&bar0->general_int_mask); | 1663 | temp64 = readq(&bar0->general_int_mask); |
1176 | temp64 &= ~((u64) val64); | 1664 | temp64 &= ~((u64) val64); |
1177 | writeq(temp64, &bar0->general_int_mask); | 1665 | writeq(temp64, &bar0->general_int_mask); |
1178 | /* | 1666 | /* |
1179 | * All MC block error interrupts are disabled for now | 1667 | * Enable all MC Intrs. |
1180 | * TODO | ||
1181 | */ | 1668 | */ |
1182 | writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask); | 1669 | writeq(0x0, &bar0->mc_int_mask); |
1670 | writeq(0x0, &bar0->mc_err_mask); | ||
1183 | } else if (flag == DISABLE_INTRS) { | 1671 | } else if (flag == DISABLE_INTRS) { |
1184 | /* | 1672 | /* |
1185 | * Disable MC Intrs in the general intr mask register | 1673 | * Disable MC Intrs in the general intr mask register |
@@ -1199,14 +1687,14 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1199 | temp64 = readq(&bar0->general_int_mask); | 1687 | temp64 = readq(&bar0->general_int_mask); |
1200 | temp64 &= ~((u64) val64); | 1688 | temp64 &= ~((u64) val64); |
1201 | writeq(temp64, &bar0->general_int_mask); | 1689 | writeq(temp64, &bar0->general_int_mask); |
1202 | /* | 1690 | /* |
1203 | * Enable all the Tx side interrupts | 1691 | * Enable all the Tx side interrupts |
1204 | * writing 0 Enables all 64 TX interrupt levels | 1692 | * writing 0 Enables all 64 TX interrupt levels |
1205 | */ | 1693 | */ |
1206 | writeq(0x0, &bar0->tx_traffic_mask); | 1694 | writeq(0x0, &bar0->tx_traffic_mask); |
1207 | } else if (flag == DISABLE_INTRS) { | 1695 | } else if (flag == DISABLE_INTRS) { |
1208 | /* | 1696 | /* |
1209 | * Disable Tx Traffic Intrs in the general intr mask | 1697 | * Disable Tx Traffic Intrs in the general intr mask |
1210 | * register. | 1698 | * register. |
1211 | */ | 1699 | */ |
1212 | writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask); | 1700 | writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask); |
@@ -1226,8 +1714,8 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1226 | /* writing 0 Enables all 8 RX interrupt levels */ | 1714 | /* writing 0 Enables all 8 RX interrupt levels */ |
1227 | writeq(0x0, &bar0->rx_traffic_mask); | 1715 | writeq(0x0, &bar0->rx_traffic_mask); |
1228 | } else if (flag == DISABLE_INTRS) { | 1716 | } else if (flag == DISABLE_INTRS) { |
1229 | /* | 1717 | /* |
1230 | * Disable Rx Traffic Intrs in the general intr mask | 1718 | * Disable Rx Traffic Intrs in the general intr mask |
1231 | * register. | 1719 | * register. |
1232 | */ | 1720 | */ |
1233 | writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask); | 1721 | writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask); |
@@ -1238,24 +1726,66 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1238 | } | 1726 | } |
1239 | } | 1727 | } |
1240 | 1728 | ||
1241 | /** | 1729 | static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc) |
1242 | * verify_xena_quiescence - Checks whether the H/W is ready | 1730 | { |
1731 | int ret = 0; | ||
1732 | |||
1733 | if (flag == FALSE) { | ||
1734 | if ((!herc && (rev_id >= 4)) || herc) { | ||
1735 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1736 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1737 | ADAPTER_STATUS_RC_PRC_QUIESCENT)) { | ||
1738 | ret = 1; | ||
1739 | } | ||
1740 | }else { | ||
1741 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && | ||
1742 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1743 | ADAPTER_STATUS_RC_PRC_QUIESCENT)) { | ||
1744 | ret = 1; | ||
1745 | } | ||
1746 | } | ||
1747 | } else { | ||
1748 | if ((!herc && (rev_id >= 4)) || herc) { | ||
1749 | if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) == | ||
1750 | ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1751 | (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || | ||
1752 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1753 | ADAPTER_STATUS_RC_PRC_QUIESCENT))) { | ||
1754 | ret = 1; | ||
1755 | } | ||
1756 | } else { | ||
1757 | if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) == | ||
1758 | ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && | ||
1759 | (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || | ||
1760 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1761 | ADAPTER_STATUS_RC_PRC_QUIESCENT))) { | ||
1762 | ret = 1; | ||
1763 | } | ||
1764 | } | ||
1765 | } | ||
1766 | |||
1767 | return ret; | ||
1768 | } | ||
1769 | /** | ||
1770 | * verify_xena_quiescence - Checks whether the H/W is ready | ||
1243 | * @val64 : Value read from adapter status register. | 1771 | * @val64 : Value read from adapter status register. |
1244 | * @flag : indicates if the adapter enable bit was ever written once | 1772 | * @flag : indicates if the adapter enable bit was ever written once |
1245 | * before. | 1773 | * before. |
1246 | * Description: Returns whether the H/W is ready to go or not. Depending | 1774 | * Description: Returns whether the H/W is ready to go or not. Depending |
1247 | * on whether adapter enable bit was written or not the comparison | 1775 | * on whether adapter enable bit was written or not the comparison |
1248 | * differs and the calling function passes the input argument flag to | 1776 | * differs and the calling function passes the input argument flag to |
1249 | * indicate this. | 1777 | * indicate this. |
1250 | * Return: 1 If xena is quiescence | 1778 | * Return: 1 If xena is quiescence |
1251 | * 0 If Xena is not quiescence | 1779 | * 0 If Xena is not quiescence |
1252 | */ | 1780 | */ |
1253 | 1781 | ||
1254 | static int verify_xena_quiescence(u64 val64, int flag) | 1782 | static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag) |
1255 | { | 1783 | { |
1256 | int ret = 0; | 1784 | int ret = 0, herc; |
1257 | u64 tmp64 = ~((u64) val64); | 1785 | u64 tmp64 = ~((u64) val64); |
1786 | int rev_id = get_xena_rev_id(sp->pdev); | ||
1258 | 1787 | ||
1788 | herc = (sp->device_type == XFRAME_II_DEVICE); | ||
1259 | if (! | 1789 | if (! |
1260 | (tmp64 & | 1790 | (tmp64 & |
1261 | (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY | | 1791 | (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY | |
@@ -1263,25 +1793,7 @@ static int verify_xena_quiescence(u64 val64, int flag) | |||
1263 | ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY | | 1793 | ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY | |
1264 | ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK | | 1794 | ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK | |
1265 | ADAPTER_STATUS_P_PLL_LOCK))) { | 1795 | ADAPTER_STATUS_P_PLL_LOCK))) { |
1266 | if (flag == FALSE) { | 1796 | ret = check_prc_pcc_state(val64, flag, rev_id, herc); |
1267 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1268 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1269 | ADAPTER_STATUS_RC_PRC_QUIESCENT)) { | ||
1270 | |||
1271 | ret = 1; | ||
1272 | |||
1273 | } | ||
1274 | } else { | ||
1275 | if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) == | ||
1276 | ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1277 | (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || | ||
1278 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1279 | ADAPTER_STATUS_RC_PRC_QUIESCENT))) { | ||
1280 | |||
1281 | ret = 1; | ||
1282 | |||
1283 | } | ||
1284 | } | ||
1285 | } | 1797 | } |
1286 | 1798 | ||
1287 | return ret; | 1799 | return ret; |
@@ -1290,12 +1802,12 @@ static int verify_xena_quiescence(u64 val64, int flag) | |||
1290 | /** | 1802 | /** |
1291 | * fix_mac_address - Fix for Mac addr problem on Alpha platforms | 1803 | * fix_mac_address - Fix for Mac addr problem on Alpha platforms |
1292 | * @sp: Pointer to device specifc structure | 1804 | * @sp: Pointer to device specifc structure |
1293 | * Description : | 1805 | * Description : |
1294 | * New procedure to clear mac address reading problems on Alpha platforms | 1806 | * New procedure to clear mac address reading problems on Alpha platforms |
1295 | * | 1807 | * |
1296 | */ | 1808 | */ |
1297 | 1809 | ||
1298 | static void fix_mac_address(nic_t * sp) | 1810 | void fix_mac_address(nic_t * sp) |
1299 | { | 1811 | { |
1300 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 1812 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
1301 | u64 val64; | 1813 | u64 val64; |
@@ -1303,20 +1815,21 @@ static void fix_mac_address(nic_t * sp) | |||
1303 | 1815 | ||
1304 | while (fix_mac[i] != END_SIGN) { | 1816 | while (fix_mac[i] != END_SIGN) { |
1305 | writeq(fix_mac[i++], &bar0->gpio_control); | 1817 | writeq(fix_mac[i++], &bar0->gpio_control); |
1818 | udelay(10); | ||
1306 | val64 = readq(&bar0->gpio_control); | 1819 | val64 = readq(&bar0->gpio_control); |
1307 | } | 1820 | } |
1308 | } | 1821 | } |
1309 | 1822 | ||
1310 | /** | 1823 | /** |
1311 | * start_nic - Turns the device on | 1824 | * start_nic - Turns the device on |
1312 | * @nic : device private variable. | 1825 | * @nic : device private variable. |
1313 | * Description: | 1826 | * Description: |
1314 | * This function actually turns the device on. Before this function is | 1827 | * This function actually turns the device on. Before this function is |
1315 | * called,all Registers are configured from their reset states | 1828 | * called,all Registers are configured from their reset states |
1316 | * and shared memory is allocated but the NIC is still quiescent. On | 1829 | * and shared memory is allocated but the NIC is still quiescent. On |
1317 | * calling this function, the device interrupts are cleared and the NIC is | 1830 | * calling this function, the device interrupts are cleared and the NIC is |
1318 | * literally switched on by writing into the adapter control register. | 1831 | * literally switched on by writing into the adapter control register. |
1319 | * Return Value: | 1832 | * Return Value: |
1320 | * SUCCESS on success and -1 on failure. | 1833 | * SUCCESS on success and -1 on failure. |
1321 | */ | 1834 | */ |
1322 | 1835 | ||
@@ -1325,8 +1838,8 @@ static int start_nic(struct s2io_nic *nic) | |||
1325 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 1838 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
1326 | struct net_device *dev = nic->dev; | 1839 | struct net_device *dev = nic->dev; |
1327 | register u64 val64 = 0; | 1840 | register u64 val64 = 0; |
1328 | u16 interruptible, i; | 1841 | u16 interruptible; |
1329 | u16 subid; | 1842 | u16 subid, i; |
1330 | mac_info_t *mac_control; | 1843 | mac_info_t *mac_control; |
1331 | struct config_param *config; | 1844 | struct config_param *config; |
1332 | 1845 | ||
@@ -1335,10 +1848,12 @@ static int start_nic(struct s2io_nic *nic) | |||
1335 | 1848 | ||
1336 | /* PRC Initialization and configuration */ | 1849 | /* PRC Initialization and configuration */ |
1337 | for (i = 0; i < config->rx_ring_num; i++) { | 1850 | for (i = 0; i < config->rx_ring_num; i++) { |
1338 | writeq((u64) nic->rx_blocks[i][0].block_dma_addr, | 1851 | writeq((u64) mac_control->rings[i].rx_blocks[0].block_dma_addr, |
1339 | &bar0->prc_rxd0_n[i]); | 1852 | &bar0->prc_rxd0_n[i]); |
1340 | 1853 | ||
1341 | val64 = readq(&bar0->prc_ctrl_n[i]); | 1854 | val64 = readq(&bar0->prc_ctrl_n[i]); |
1855 | if (nic->config.bimodal) | ||
1856 | val64 |= PRC_CTRL_BIMODAL_INTERRUPT; | ||
1342 | #ifndef CONFIG_2BUFF_MODE | 1857 | #ifndef CONFIG_2BUFF_MODE |
1343 | val64 |= PRC_CTRL_RC_ENABLED; | 1858 | val64 |= PRC_CTRL_RC_ENABLED; |
1344 | #else | 1859 | #else |
@@ -1354,7 +1869,7 @@ static int start_nic(struct s2io_nic *nic) | |||
1354 | writeq(val64, &bar0->rx_pa_cfg); | 1869 | writeq(val64, &bar0->rx_pa_cfg); |
1355 | #endif | 1870 | #endif |
1356 | 1871 | ||
1357 | /* | 1872 | /* |
1358 | * Enabling MC-RLDRAM. After enabling the device, we timeout | 1873 | * Enabling MC-RLDRAM. After enabling the device, we timeout |
1359 | * for around 100ms, which is approximately the time required | 1874 | * for around 100ms, which is approximately the time required |
1360 | * for the device to be ready for operation. | 1875 | * for the device to be ready for operation. |
@@ -1364,27 +1879,27 @@ static int start_nic(struct s2io_nic *nic) | |||
1364 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF); | 1879 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF); |
1365 | val64 = readq(&bar0->mc_rldram_mrs); | 1880 | val64 = readq(&bar0->mc_rldram_mrs); |
1366 | 1881 | ||
1367 | msleep(100); /* Delay by around 100 ms. */ | 1882 | msleep(100); /* Delay by around 100 ms. */ |
1368 | 1883 | ||
1369 | /* Enabling ECC Protection. */ | 1884 | /* Enabling ECC Protection. */ |
1370 | val64 = readq(&bar0->adapter_control); | 1885 | val64 = readq(&bar0->adapter_control); |
1371 | val64 &= ~ADAPTER_ECC_EN; | 1886 | val64 &= ~ADAPTER_ECC_EN; |
1372 | writeq(val64, &bar0->adapter_control); | 1887 | writeq(val64, &bar0->adapter_control); |
1373 | 1888 | ||
1374 | /* | 1889 | /* |
1375 | * Clearing any possible Link state change interrupts that | 1890 | * Clearing any possible Link state change interrupts that |
1376 | * could have popped up just before Enabling the card. | 1891 | * could have popped up just before Enabling the card. |
1377 | */ | 1892 | */ |
1378 | val64 = readq(&bar0->mac_rmac_err_reg); | 1893 | val64 = readq(&bar0->mac_rmac_err_reg); |
1379 | if (val64) | 1894 | if (val64) |
1380 | writeq(val64, &bar0->mac_rmac_err_reg); | 1895 | writeq(val64, &bar0->mac_rmac_err_reg); |
1381 | 1896 | ||
1382 | /* | 1897 | /* |
1383 | * Verify if the device is ready to be enabled, if so enable | 1898 | * Verify if the device is ready to be enabled, if so enable |
1384 | * it. | 1899 | * it. |
1385 | */ | 1900 | */ |
1386 | val64 = readq(&bar0->adapter_status); | 1901 | val64 = readq(&bar0->adapter_status); |
1387 | if (!verify_xena_quiescence(val64, nic->device_enabled_once)) { | 1902 | if (!verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { |
1388 | DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name); | 1903 | DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name); |
1389 | DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n", | 1904 | DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n", |
1390 | (unsigned long long) val64); | 1905 | (unsigned long long) val64); |
@@ -1392,16 +1907,18 @@ static int start_nic(struct s2io_nic *nic) | |||
1392 | } | 1907 | } |
1393 | 1908 | ||
1394 | /* Enable select interrupts */ | 1909 | /* Enable select interrupts */ |
1395 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | | 1910 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
1396 | RX_MAC_INTR; | 1911 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
1912 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
1913 | |||
1397 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); | 1914 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); |
1398 | 1915 | ||
1399 | /* | 1916 | /* |
1400 | * With some switches, link might be already up at this point. | 1917 | * With some switches, link might be already up at this point. |
1401 | * Because of this weird behavior, when we enable laser, | 1918 | * Because of this weird behavior, when we enable laser, |
1402 | * we may not get link. We need to handle this. We cannot | 1919 | * we may not get link. We need to handle this. We cannot |
1403 | * figure out which switch is misbehaving. So we are forced to | 1920 | * figure out which switch is misbehaving. So we are forced to |
1404 | * make a global change. | 1921 | * make a global change. |
1405 | */ | 1922 | */ |
1406 | 1923 | ||
1407 | /* Enabling Laser. */ | 1924 | /* Enabling Laser. */ |
@@ -1411,44 +1928,30 @@ static int start_nic(struct s2io_nic *nic) | |||
1411 | 1928 | ||
1412 | /* SXE-002: Initialize link and activity LED */ | 1929 | /* SXE-002: Initialize link and activity LED */ |
1413 | subid = nic->pdev->subsystem_device; | 1930 | subid = nic->pdev->subsystem_device; |
1414 | if ((subid & 0xFF) >= 0x07) { | 1931 | if (((subid & 0xFF) >= 0x07) && |
1932 | (nic->device_type == XFRAME_I_DEVICE)) { | ||
1415 | val64 = readq(&bar0->gpio_control); | 1933 | val64 = readq(&bar0->gpio_control); |
1416 | val64 |= 0x0000800000000000ULL; | 1934 | val64 |= 0x0000800000000000ULL; |
1417 | writeq(val64, &bar0->gpio_control); | 1935 | writeq(val64, &bar0->gpio_control); |
1418 | val64 = 0x0411040400000000ULL; | 1936 | val64 = 0x0411040400000000ULL; |
1419 | writeq(val64, (void __iomem *) bar0 + 0x2700); | 1937 | writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700)); |
1420 | } | 1938 | } |
1421 | 1939 | ||
1422 | /* | 1940 | /* |
1423 | * Don't see link state interrupts on certain switches, so | 1941 | * Don't see link state interrupts on certain switches, so |
1424 | * directly scheduling a link state task from here. | 1942 | * directly scheduling a link state task from here. |
1425 | */ | 1943 | */ |
1426 | schedule_work(&nic->set_link_task); | 1944 | schedule_work(&nic->set_link_task); |
1427 | 1945 | ||
1428 | /* | ||
1429 | * Here we are performing soft reset on XGXS to | ||
1430 | * force link down. Since link is already up, we will get | ||
1431 | * link state change interrupt after this reset | ||
1432 | */ | ||
1433 | SPECIAL_REG_WRITE(0x80010515001E0000ULL, &bar0->dtx_control, UF); | ||
1434 | val64 = readq(&bar0->dtx_control); | ||
1435 | udelay(50); | ||
1436 | SPECIAL_REG_WRITE(0x80010515001E00E0ULL, &bar0->dtx_control, UF); | ||
1437 | val64 = readq(&bar0->dtx_control); | ||
1438 | udelay(50); | ||
1439 | SPECIAL_REG_WRITE(0x80070515001F00E4ULL, &bar0->dtx_control, UF); | ||
1440 | val64 = readq(&bar0->dtx_control); | ||
1441 | udelay(50); | ||
1442 | |||
1443 | return SUCCESS; | 1946 | return SUCCESS; |
1444 | } | 1947 | } |
1445 | 1948 | ||
1446 | /** | 1949 | /** |
1447 | * free_tx_buffers - Free all queued Tx buffers | 1950 | * free_tx_buffers - Free all queued Tx buffers |
1448 | * @nic : device private variable. | 1951 | * @nic : device private variable. |
1449 | * Description: | 1952 | * Description: |
1450 | * Free all queued Tx buffers. | 1953 | * Free all queued Tx buffers. |
1451 | * Return Value: void | 1954 | * Return Value: void |
1452 | */ | 1955 | */ |
1453 | 1956 | ||
1454 | static void free_tx_buffers(struct s2io_nic *nic) | 1957 | static void free_tx_buffers(struct s2io_nic *nic) |
@@ -1459,39 +1962,61 @@ static void free_tx_buffers(struct s2io_nic *nic) | |||
1459 | int i, j; | 1962 | int i, j; |
1460 | mac_info_t *mac_control; | 1963 | mac_info_t *mac_control; |
1461 | struct config_param *config; | 1964 | struct config_param *config; |
1462 | int cnt = 0; | 1965 | int cnt = 0, frg_cnt; |
1463 | 1966 | ||
1464 | mac_control = &nic->mac_control; | 1967 | mac_control = &nic->mac_control; |
1465 | config = &nic->config; | 1968 | config = &nic->config; |
1466 | 1969 | ||
1467 | for (i = 0; i < config->tx_fifo_num; i++) { | 1970 | for (i = 0; i < config->tx_fifo_num; i++) { |
1468 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { | 1971 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { |
1469 | txdp = (TxD_t *) nic->list_info[i][j]. | 1972 | txdp = (TxD_t *) mac_control->fifos[i].list_info[j]. |
1470 | list_virt_addr; | 1973 | list_virt_addr; |
1471 | skb = | 1974 | skb = |
1472 | (struct sk_buff *) ((unsigned long) txdp-> | 1975 | (struct sk_buff *) ((unsigned long) txdp-> |
1473 | Host_Control); | 1976 | Host_Control); |
1474 | if (skb == NULL) { | 1977 | if (skb == NULL) { |
1475 | memset(txdp, 0, sizeof(TxD_t)); | 1978 | memset(txdp, 0, sizeof(TxD_t) * |
1979 | config->max_txds); | ||
1476 | continue; | 1980 | continue; |
1477 | } | 1981 | } |
1982 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
1983 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1984 | txdp->Buffer_Pointer, | ||
1985 | skb->len - skb->data_len, | ||
1986 | PCI_DMA_TODEVICE); | ||
1987 | if (frg_cnt) { | ||
1988 | TxD_t *temp; | ||
1989 | temp = txdp; | ||
1990 | txdp++; | ||
1991 | for (j = 0; j < frg_cnt; j++, txdp++) { | ||
1992 | skb_frag_t *frag = | ||
1993 | &skb_shinfo(skb)->frags[j]; | ||
1994 | pci_unmap_page(nic->pdev, | ||
1995 | (dma_addr_t) | ||
1996 | txdp-> | ||
1997 | Buffer_Pointer, | ||
1998 | frag->size, | ||
1999 | PCI_DMA_TODEVICE); | ||
2000 | } | ||
2001 | txdp = temp; | ||
2002 | } | ||
1478 | dev_kfree_skb(skb); | 2003 | dev_kfree_skb(skb); |
1479 | memset(txdp, 0, sizeof(TxD_t)); | 2004 | memset(txdp, 0, sizeof(TxD_t) * config->max_txds); |
1480 | cnt++; | 2005 | cnt++; |
1481 | } | 2006 | } |
1482 | DBG_PRINT(INTR_DBG, | 2007 | DBG_PRINT(INTR_DBG, |
1483 | "%s:forcibly freeing %d skbs on FIFO%d\n", | 2008 | "%s:forcibly freeing %d skbs on FIFO%d\n", |
1484 | dev->name, cnt, i); | 2009 | dev->name, cnt, i); |
1485 | mac_control->tx_curr_get_info[i].offset = 0; | 2010 | mac_control->fifos[i].tx_curr_get_info.offset = 0; |
1486 | mac_control->tx_curr_put_info[i].offset = 0; | 2011 | mac_control->fifos[i].tx_curr_put_info.offset = 0; |
1487 | } | 2012 | } |
1488 | } | 2013 | } |
1489 | 2014 | ||
1490 | /** | 2015 | /** |
1491 | * stop_nic - To stop the nic | 2016 | * stop_nic - To stop the nic |
1492 | * @nic ; device private variable. | 2017 | * @nic ; device private variable. |
1493 | * Description: | 2018 | * Description: |
1494 | * This function does exactly the opposite of what the start_nic() | 2019 | * This function does exactly the opposite of what the start_nic() |
1495 | * function does. This function is called to stop the device. | 2020 | * function does. This function is called to stop the device. |
1496 | * Return Value: | 2021 | * Return Value: |
1497 | * void. | 2022 | * void. |
@@ -1509,8 +2034,9 @@ static void stop_nic(struct s2io_nic *nic) | |||
1509 | config = &nic->config; | 2034 | config = &nic->config; |
1510 | 2035 | ||
1511 | /* Disable all interrupts */ | 2036 | /* Disable all interrupts */ |
1512 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | | 2037 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
1513 | RX_MAC_INTR; | 2038 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
2039 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
1514 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); | 2040 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); |
1515 | 2041 | ||
1516 | /* Disable PRCs */ | 2042 | /* Disable PRCs */ |
@@ -1521,11 +2047,11 @@ static void stop_nic(struct s2io_nic *nic) | |||
1521 | } | 2047 | } |
1522 | } | 2048 | } |
1523 | 2049 | ||
1524 | /** | 2050 | /** |
1525 | * fill_rx_buffers - Allocates the Rx side skbs | 2051 | * fill_rx_buffers - Allocates the Rx side skbs |
1526 | * @nic: device private variable | 2052 | * @nic: device private variable |
1527 | * @ring_no: ring number | 2053 | * @ring_no: ring number |
1528 | * Description: | 2054 | * Description: |
1529 | * The function allocates Rx side skbs and puts the physical | 2055 | * The function allocates Rx side skbs and puts the physical |
1530 | * address of these buffers into the RxD buffer pointers, so that the NIC | 2056 | * address of these buffers into the RxD buffer pointers, so that the NIC |
1531 | * can DMA the received frame into these locations. | 2057 | * can DMA the received frame into these locations. |
@@ -1533,8 +2059,8 @@ static void stop_nic(struct s2io_nic *nic) | |||
1533 | * 1. single buffer, | 2059 | * 1. single buffer, |
1534 | * 2. three buffer and | 2060 | * 2. three buffer and |
1535 | * 3. Five buffer modes. | 2061 | * 3. Five buffer modes. |
1536 | * Each mode defines how many fragments the received frame will be split | 2062 | * Each mode defines how many fragments the received frame will be split |
1537 | * up into by the NIC. The frame is split into L3 header, L4 Header, | 2063 | * up into by the NIC. The frame is split into L3 header, L4 Header, |
1538 | * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself | 2064 | * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself |
1539 | * is split into 3 fragments. As of now only single buffer mode is | 2065 | * is split into 3 fragments. As of now only single buffer mode is |
1540 | * supported. | 2066 | * supported. |
@@ -1542,7 +2068,7 @@ static void stop_nic(struct s2io_nic *nic) | |||
1542 | * SUCCESS on success or an appropriate -ve value on failure. | 2068 | * SUCCESS on success or an appropriate -ve value on failure. |
1543 | */ | 2069 | */ |
1544 | 2070 | ||
1545 | static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | 2071 | int fill_rx_buffers(struct s2io_nic *nic, int ring_no) |
1546 | { | 2072 | { |
1547 | struct net_device *dev = nic->dev; | 2073 | struct net_device *dev = nic->dev; |
1548 | struct sk_buff *skb; | 2074 | struct sk_buff *skb; |
@@ -1550,34 +2076,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1550 | int off, off1, size, block_no, block_no1; | 2076 | int off, off1, size, block_no, block_no1; |
1551 | int offset, offset1; | 2077 | int offset, offset1; |
1552 | u32 alloc_tab = 0; | 2078 | u32 alloc_tab = 0; |
1553 | u32 alloc_cnt = nic->pkt_cnt[ring_no] - | 2079 | u32 alloc_cnt; |
1554 | atomic_read(&nic->rx_bufs_left[ring_no]); | ||
1555 | mac_info_t *mac_control; | 2080 | mac_info_t *mac_control; |
1556 | struct config_param *config; | 2081 | struct config_param *config; |
1557 | #ifdef CONFIG_2BUFF_MODE | 2082 | #ifdef CONFIG_2BUFF_MODE |
1558 | RxD_t *rxdpnext; | 2083 | RxD_t *rxdpnext; |
1559 | int nextblk; | 2084 | int nextblk; |
1560 | unsigned long tmp; | 2085 | u64 tmp; |
1561 | buffAdd_t *ba; | 2086 | buffAdd_t *ba; |
1562 | dma_addr_t rxdpphys; | 2087 | dma_addr_t rxdpphys; |
1563 | #endif | 2088 | #endif |
1564 | #ifndef CONFIG_S2IO_NAPI | 2089 | #ifndef CONFIG_S2IO_NAPI |
1565 | unsigned long flags; | 2090 | unsigned long flags; |
1566 | #endif | 2091 | #endif |
2092 | RxD_t *first_rxdp = NULL; | ||
1567 | 2093 | ||
1568 | mac_control = &nic->mac_control; | 2094 | mac_control = &nic->mac_control; |
1569 | config = &nic->config; | 2095 | config = &nic->config; |
1570 | 2096 | alloc_cnt = mac_control->rings[ring_no].pkt_cnt - | |
2097 | atomic_read(&nic->rx_bufs_left[ring_no]); | ||
1571 | size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + | 2098 | size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + |
1572 | HEADER_802_2_SIZE + HEADER_SNAP_SIZE; | 2099 | HEADER_802_2_SIZE + HEADER_SNAP_SIZE; |
1573 | 2100 | ||
1574 | while (alloc_tab < alloc_cnt) { | 2101 | while (alloc_tab < alloc_cnt) { |
1575 | block_no = mac_control->rx_curr_put_info[ring_no]. | 2102 | block_no = mac_control->rings[ring_no].rx_curr_put_info. |
1576 | block_index; | 2103 | block_index; |
1577 | block_no1 = mac_control->rx_curr_get_info[ring_no]. | 2104 | block_no1 = mac_control->rings[ring_no].rx_curr_get_info. |
1578 | block_index; | 2105 | block_index; |
1579 | off = mac_control->rx_curr_put_info[ring_no].offset; | 2106 | off = mac_control->rings[ring_no].rx_curr_put_info.offset; |
1580 | off1 = mac_control->rx_curr_get_info[ring_no].offset; | 2107 | off1 = mac_control->rings[ring_no].rx_curr_get_info.offset; |
1581 | #ifndef CONFIG_2BUFF_MODE | 2108 | #ifndef CONFIG_2BUFF_MODE |
1582 | offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off; | 2109 | offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off; |
1583 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1; | 2110 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1; |
@@ -1586,7 +2113,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1586 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1; | 2113 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1; |
1587 | #endif | 2114 | #endif |
1588 | 2115 | ||
1589 | rxdp = nic->rx_blocks[ring_no][block_no]. | 2116 | rxdp = mac_control->rings[ring_no].rx_blocks[block_no]. |
1590 | block_virt_addr + off; | 2117 | block_virt_addr + off; |
1591 | if ((offset == offset1) && (rxdp->Host_Control)) { | 2118 | if ((offset == offset1) && (rxdp->Host_Control)) { |
1592 | DBG_PRINT(INTR_DBG, "%s: Get and Put", dev->name); | 2119 | DBG_PRINT(INTR_DBG, "%s: Get and Put", dev->name); |
@@ -1595,15 +2122,15 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1595 | } | 2122 | } |
1596 | #ifndef CONFIG_2BUFF_MODE | 2123 | #ifndef CONFIG_2BUFF_MODE |
1597 | if (rxdp->Control_1 == END_OF_BLOCK) { | 2124 | if (rxdp->Control_1 == END_OF_BLOCK) { |
1598 | mac_control->rx_curr_put_info[ring_no]. | 2125 | mac_control->rings[ring_no].rx_curr_put_info. |
1599 | block_index++; | 2126 | block_index++; |
1600 | mac_control->rx_curr_put_info[ring_no]. | 2127 | mac_control->rings[ring_no].rx_curr_put_info. |
1601 | block_index %= nic->block_count[ring_no]; | 2128 | block_index %= mac_control->rings[ring_no].block_count; |
1602 | block_no = mac_control->rx_curr_put_info | 2129 | block_no = mac_control->rings[ring_no].rx_curr_put_info. |
1603 | [ring_no].block_index; | 2130 | block_index; |
1604 | off++; | 2131 | off++; |
1605 | off %= (MAX_RXDS_PER_BLOCK + 1); | 2132 | off %= (MAX_RXDS_PER_BLOCK + 1); |
1606 | mac_control->rx_curr_put_info[ring_no].offset = | 2133 | mac_control->rings[ring_no].rx_curr_put_info.offset = |
1607 | off; | 2134 | off; |
1608 | rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2); | 2135 | rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2); |
1609 | DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", | 2136 | DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", |
@@ -1611,30 +2138,30 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1611 | } | 2138 | } |
1612 | #ifndef CONFIG_S2IO_NAPI | 2139 | #ifndef CONFIG_S2IO_NAPI |
1613 | spin_lock_irqsave(&nic->put_lock, flags); | 2140 | spin_lock_irqsave(&nic->put_lock, flags); |
1614 | nic->put_pos[ring_no] = | 2141 | mac_control->rings[ring_no].put_pos = |
1615 | (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off; | 2142 | (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off; |
1616 | spin_unlock_irqrestore(&nic->put_lock, flags); | 2143 | spin_unlock_irqrestore(&nic->put_lock, flags); |
1617 | #endif | 2144 | #endif |
1618 | #else | 2145 | #else |
1619 | if (rxdp->Host_Control == END_OF_BLOCK) { | 2146 | if (rxdp->Host_Control == END_OF_BLOCK) { |
1620 | mac_control->rx_curr_put_info[ring_no]. | 2147 | mac_control->rings[ring_no].rx_curr_put_info. |
1621 | block_index++; | 2148 | block_index++; |
1622 | mac_control->rx_curr_put_info[ring_no]. | 2149 | mac_control->rings[ring_no].rx_curr_put_info.block_index |
1623 | block_index %= nic->block_count[ring_no]; | 2150 | %= mac_control->rings[ring_no].block_count; |
1624 | block_no = mac_control->rx_curr_put_info | 2151 | block_no = mac_control->rings[ring_no].rx_curr_put_info |
1625 | [ring_no].block_index; | 2152 | .block_index; |
1626 | off = 0; | 2153 | off = 0; |
1627 | DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n", | 2154 | DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n", |
1628 | dev->name, block_no, | 2155 | dev->name, block_no, |
1629 | (unsigned long long) rxdp->Control_1); | 2156 | (unsigned long long) rxdp->Control_1); |
1630 | mac_control->rx_curr_put_info[ring_no].offset = | 2157 | mac_control->rings[ring_no].rx_curr_put_info.offset = |
1631 | off; | 2158 | off; |
1632 | rxdp = nic->rx_blocks[ring_no][block_no]. | 2159 | rxdp = mac_control->rings[ring_no].rx_blocks[block_no]. |
1633 | block_virt_addr; | 2160 | block_virt_addr; |
1634 | } | 2161 | } |
1635 | #ifndef CONFIG_S2IO_NAPI | 2162 | #ifndef CONFIG_S2IO_NAPI |
1636 | spin_lock_irqsave(&nic->put_lock, flags); | 2163 | spin_lock_irqsave(&nic->put_lock, flags); |
1637 | nic->put_pos[ring_no] = (block_no * | 2164 | mac_control->rings[ring_no].put_pos = (block_no * |
1638 | (MAX_RXDS_PER_BLOCK + 1)) + off; | 2165 | (MAX_RXDS_PER_BLOCK + 1)) + off; |
1639 | spin_unlock_irqrestore(&nic->put_lock, flags); | 2166 | spin_unlock_irqrestore(&nic->put_lock, flags); |
1640 | #endif | 2167 | #endif |
@@ -1646,27 +2173,27 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1646 | if (rxdp->Control_2 & BIT(0)) | 2173 | if (rxdp->Control_2 & BIT(0)) |
1647 | #endif | 2174 | #endif |
1648 | { | 2175 | { |
1649 | mac_control->rx_curr_put_info[ring_no]. | 2176 | mac_control->rings[ring_no].rx_curr_put_info. |
1650 | offset = off; | 2177 | offset = off; |
1651 | goto end; | 2178 | goto end; |
1652 | } | 2179 | } |
1653 | #ifdef CONFIG_2BUFF_MODE | 2180 | #ifdef CONFIG_2BUFF_MODE |
1654 | /* | 2181 | /* |
1655 | * RxDs Spanning cache lines will be replenished only | 2182 | * RxDs Spanning cache lines will be replenished only |
1656 | * if the succeeding RxD is also owned by Host. It | 2183 | * if the succeeding RxD is also owned by Host. It |
1657 | * will always be the ((8*i)+3) and ((8*i)+6) | 2184 | * will always be the ((8*i)+3) and ((8*i)+6) |
1658 | * descriptors for the 48 byte descriptor. The offending | 2185 | * descriptors for the 48 byte descriptor. The offending |
1659 | * decsriptor is of-course the 3rd descriptor. | 2186 | * decsriptor is of-course the 3rd descriptor. |
1660 | */ | 2187 | */ |
1661 | rxdpphys = nic->rx_blocks[ring_no][block_no]. | 2188 | rxdpphys = mac_control->rings[ring_no].rx_blocks[block_no]. |
1662 | block_dma_addr + (off * sizeof(RxD_t)); | 2189 | block_dma_addr + (off * sizeof(RxD_t)); |
1663 | if (((u64) (rxdpphys)) % 128 > 80) { | 2190 | if (((u64) (rxdpphys)) % 128 > 80) { |
1664 | rxdpnext = nic->rx_blocks[ring_no][block_no]. | 2191 | rxdpnext = mac_control->rings[ring_no].rx_blocks[block_no]. |
1665 | block_virt_addr + (off + 1); | 2192 | block_virt_addr + (off + 1); |
1666 | if (rxdpnext->Host_Control == END_OF_BLOCK) { | 2193 | if (rxdpnext->Host_Control == END_OF_BLOCK) { |
1667 | nextblk = (block_no + 1) % | 2194 | nextblk = (block_no + 1) % |
1668 | (nic->block_count[ring_no]); | 2195 | (mac_control->rings[ring_no].block_count); |
1669 | rxdpnext = nic->rx_blocks[ring_no] | 2196 | rxdpnext = mac_control->rings[ring_no].rx_blocks |
1670 | [nextblk].block_virt_addr; | 2197 | [nextblk].block_virt_addr; |
1671 | } | 2198 | } |
1672 | if (rxdpnext->Control_2 & BIT(0)) | 2199 | if (rxdpnext->Control_2 & BIT(0)) |
@@ -1682,6 +2209,10 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1682 | if (!skb) { | 2209 | if (!skb) { |
1683 | DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); | 2210 | DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); |
1684 | DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); | 2211 | DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); |
2212 | if (first_rxdp) { | ||
2213 | wmb(); | ||
2214 | first_rxdp->Control_1 |= RXD_OWN_XENA; | ||
2215 | } | ||
1685 | return -ENOMEM; | 2216 | return -ENOMEM; |
1686 | } | 2217 | } |
1687 | #ifndef CONFIG_2BUFF_MODE | 2218 | #ifndef CONFIG_2BUFF_MODE |
@@ -1692,12 +2223,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1692 | rxdp->Control_2 &= (~MASK_BUFFER0_SIZE); | 2223 | rxdp->Control_2 &= (~MASK_BUFFER0_SIZE); |
1693 | rxdp->Control_2 |= SET_BUFFER0_SIZE(size); | 2224 | rxdp->Control_2 |= SET_BUFFER0_SIZE(size); |
1694 | rxdp->Host_Control = (unsigned long) (skb); | 2225 | rxdp->Host_Control = (unsigned long) (skb); |
1695 | rxdp->Control_1 |= RXD_OWN_XENA; | 2226 | if (alloc_tab & ((1 << rxsync_frequency) - 1)) |
2227 | rxdp->Control_1 |= RXD_OWN_XENA; | ||
1696 | off++; | 2228 | off++; |
1697 | off %= (MAX_RXDS_PER_BLOCK + 1); | 2229 | off %= (MAX_RXDS_PER_BLOCK + 1); |
1698 | mac_control->rx_curr_put_info[ring_no].offset = off; | 2230 | mac_control->rings[ring_no].rx_curr_put_info.offset = off; |
1699 | #else | 2231 | #else |
1700 | ba = &nic->ba[ring_no][block_no][off]; | 2232 | ba = &mac_control->rings[ring_no].ba[block_no][off]; |
1701 | skb_reserve(skb, BUF0_LEN); | 2233 | skb_reserve(skb, BUF0_LEN); |
1702 | tmp = ((unsigned long) skb->data & ALIGN_SIZE); | 2234 | tmp = ((unsigned long) skb->data & ALIGN_SIZE); |
1703 | if (tmp) | 2235 | if (tmp) |
@@ -1719,22 +2251,41 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1719 | rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */ | 2251 | rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */ |
1720 | rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */ | 2252 | rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */ |
1721 | rxdp->Host_Control = (u64) ((unsigned long) (skb)); | 2253 | rxdp->Host_Control = (u64) ((unsigned long) (skb)); |
1722 | rxdp->Control_1 |= RXD_OWN_XENA; | 2254 | if (alloc_tab & ((1 << rxsync_frequency) - 1)) |
2255 | rxdp->Control_1 |= RXD_OWN_XENA; | ||
1723 | off++; | 2256 | off++; |
1724 | mac_control->rx_curr_put_info[ring_no].offset = off; | 2257 | mac_control->rings[ring_no].rx_curr_put_info.offset = off; |
1725 | #endif | 2258 | #endif |
2259 | rxdp->Control_2 |= SET_RXD_MARKER; | ||
2260 | |||
2261 | if (!(alloc_tab & ((1 << rxsync_frequency) - 1))) { | ||
2262 | if (first_rxdp) { | ||
2263 | wmb(); | ||
2264 | first_rxdp->Control_1 |= RXD_OWN_XENA; | ||
2265 | } | ||
2266 | first_rxdp = rxdp; | ||
2267 | } | ||
1726 | atomic_inc(&nic->rx_bufs_left[ring_no]); | 2268 | atomic_inc(&nic->rx_bufs_left[ring_no]); |
1727 | alloc_tab++; | 2269 | alloc_tab++; |
1728 | } | 2270 | } |
1729 | 2271 | ||
1730 | end: | 2272 | end: |
2273 | /* Transfer ownership of first descriptor to adapter just before | ||
2274 | * exiting. Before that, use memory barrier so that ownership | ||
2275 | * and other fields are seen by adapter correctly. | ||
2276 | */ | ||
2277 | if (first_rxdp) { | ||
2278 | wmb(); | ||
2279 | first_rxdp->Control_1 |= RXD_OWN_XENA; | ||
2280 | } | ||
2281 | |||
1731 | return SUCCESS; | 2282 | return SUCCESS; |
1732 | } | 2283 | } |
1733 | 2284 | ||
1734 | /** | 2285 | /** |
1735 | * free_rx_buffers - Frees all Rx buffers | 2286 | * free_rx_buffers - Frees all Rx buffers |
1736 | * @sp: device private variable. | 2287 | * @sp: device private variable. |
1737 | * Description: | 2288 | * Description: |
1738 | * This function will free all Rx buffers allocated by host. | 2289 | * This function will free all Rx buffers allocated by host. |
1739 | * Return Value: | 2290 | * Return Value: |
1740 | * NONE. | 2291 | * NONE. |
@@ -1758,7 +2309,8 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1758 | for (i = 0; i < config->rx_ring_num; i++) { | 2309 | for (i = 0; i < config->rx_ring_num; i++) { |
1759 | for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) { | 2310 | for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) { |
1760 | off = j % (MAX_RXDS_PER_BLOCK + 1); | 2311 | off = j % (MAX_RXDS_PER_BLOCK + 1); |
1761 | rxdp = sp->rx_blocks[i][blk].block_virt_addr + off; | 2312 | rxdp = mac_control->rings[i].rx_blocks[blk]. |
2313 | block_virt_addr + off; | ||
1762 | 2314 | ||
1763 | #ifndef CONFIG_2BUFF_MODE | 2315 | #ifndef CONFIG_2BUFF_MODE |
1764 | if (rxdp->Control_1 == END_OF_BLOCK) { | 2316 | if (rxdp->Control_1 == END_OF_BLOCK) { |
@@ -1793,7 +2345,7 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1793 | HEADER_SNAP_SIZE, | 2345 | HEADER_SNAP_SIZE, |
1794 | PCI_DMA_FROMDEVICE); | 2346 | PCI_DMA_FROMDEVICE); |
1795 | #else | 2347 | #else |
1796 | ba = &sp->ba[i][blk][off]; | 2348 | ba = &mac_control->rings[i].ba[blk][off]; |
1797 | pci_unmap_single(sp->pdev, (dma_addr_t) | 2349 | pci_unmap_single(sp->pdev, (dma_addr_t) |
1798 | rxdp->Buffer0_ptr, | 2350 | rxdp->Buffer0_ptr, |
1799 | BUF0_LEN, | 2351 | BUF0_LEN, |
@@ -1813,10 +2365,10 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1813 | } | 2365 | } |
1814 | memset(rxdp, 0, sizeof(RxD_t)); | 2366 | memset(rxdp, 0, sizeof(RxD_t)); |
1815 | } | 2367 | } |
1816 | mac_control->rx_curr_put_info[i].block_index = 0; | 2368 | mac_control->rings[i].rx_curr_put_info.block_index = 0; |
1817 | mac_control->rx_curr_get_info[i].block_index = 0; | 2369 | mac_control->rings[i].rx_curr_get_info.block_index = 0; |
1818 | mac_control->rx_curr_put_info[i].offset = 0; | 2370 | mac_control->rings[i].rx_curr_put_info.offset = 0; |
1819 | mac_control->rx_curr_get_info[i].offset = 0; | 2371 | mac_control->rings[i].rx_curr_get_info.offset = 0; |
1820 | atomic_set(&sp->rx_bufs_left[i], 0); | 2372 | atomic_set(&sp->rx_bufs_left[i], 0); |
1821 | DBG_PRINT(INIT_DBG, "%s:Freed 0x%x Rx Buffers on ring%d\n", | 2373 | DBG_PRINT(INIT_DBG, "%s:Freed 0x%x Rx Buffers on ring%d\n", |
1822 | dev->name, buf_cnt, i); | 2374 | dev->name, buf_cnt, i); |
@@ -1826,7 +2378,7 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1826 | /** | 2378 | /** |
1827 | * s2io_poll - Rx interrupt handler for NAPI support | 2379 | * s2io_poll - Rx interrupt handler for NAPI support |
1828 | * @dev : pointer to the device structure. | 2380 | * @dev : pointer to the device structure. |
1829 | * @budget : The number of packets that were budgeted to be processed | 2381 | * @budget : The number of packets that were budgeted to be processed |
1830 | * during one pass through the 'Poll" function. | 2382 | * during one pass through the 'Poll" function. |
1831 | * Description: | 2383 | * Description: |
1832 | * Comes into picture only if NAPI support has been incorporated. It does | 2384 | * Comes into picture only if NAPI support has been incorporated. It does |
@@ -1836,160 +2388,36 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1836 | * 0 on success and 1 if there are No Rx packets to be processed. | 2388 | * 0 on success and 1 if there are No Rx packets to be processed. |
1837 | */ | 2389 | */ |
1838 | 2390 | ||
1839 | #ifdef CONFIG_S2IO_NAPI | 2391 | #if defined(CONFIG_S2IO_NAPI) |
1840 | static int s2io_poll(struct net_device *dev, int *budget) | 2392 | static int s2io_poll(struct net_device *dev, int *budget) |
1841 | { | 2393 | { |
1842 | nic_t *nic = dev->priv; | 2394 | nic_t *nic = dev->priv; |
1843 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2395 | int pkt_cnt = 0, org_pkts_to_process; |
1844 | int pkts_to_process = *budget, pkt_cnt = 0; | ||
1845 | register u64 val64 = 0; | ||
1846 | rx_curr_get_info_t get_info, put_info; | ||
1847 | int i, get_block, put_block, get_offset, put_offset, ring_bufs; | ||
1848 | #ifndef CONFIG_2BUFF_MODE | ||
1849 | u16 val16, cksum; | ||
1850 | #endif | ||
1851 | struct sk_buff *skb; | ||
1852 | RxD_t *rxdp; | ||
1853 | mac_info_t *mac_control; | 2396 | mac_info_t *mac_control; |
1854 | struct config_param *config; | 2397 | struct config_param *config; |
1855 | #ifdef CONFIG_2BUFF_MODE | 2398 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; |
1856 | buffAdd_t *ba; | 2399 | u64 val64; |
1857 | #endif | 2400 | int i; |
1858 | 2401 | ||
2402 | atomic_inc(&nic->isr_cnt); | ||
1859 | mac_control = &nic->mac_control; | 2403 | mac_control = &nic->mac_control; |
1860 | config = &nic->config; | 2404 | config = &nic->config; |
1861 | 2405 | ||
1862 | if (pkts_to_process > dev->quota) | 2406 | nic->pkts_to_process = *budget; |
1863 | pkts_to_process = dev->quota; | 2407 | if (nic->pkts_to_process > dev->quota) |
2408 | nic->pkts_to_process = dev->quota; | ||
2409 | org_pkts_to_process = nic->pkts_to_process; | ||
1864 | 2410 | ||
1865 | val64 = readq(&bar0->rx_traffic_int); | 2411 | val64 = readq(&bar0->rx_traffic_int); |
1866 | writeq(val64, &bar0->rx_traffic_int); | 2412 | writeq(val64, &bar0->rx_traffic_int); |
1867 | 2413 | ||
1868 | for (i = 0; i < config->rx_ring_num; i++) { | 2414 | for (i = 0; i < config->rx_ring_num; i++) { |
1869 | get_info = mac_control->rx_curr_get_info[i]; | 2415 | rx_intr_handler(&mac_control->rings[i]); |
1870 | get_block = get_info.block_index; | 2416 | pkt_cnt = org_pkts_to_process - nic->pkts_to_process; |
1871 | put_info = mac_control->rx_curr_put_info[i]; | 2417 | if (!nic->pkts_to_process) { |
1872 | put_block = put_info.block_index; | 2418 | /* Quota for the current iteration has been met */ |
1873 | ring_bufs = config->rx_cfg[i].num_rxd; | 2419 | goto no_rx; |
1874 | rxdp = nic->rx_blocks[i][get_block].block_virt_addr + | ||
1875 | get_info.offset; | ||
1876 | #ifndef CONFIG_2BUFF_MODE | ||
1877 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1878 | get_info.offset; | ||
1879 | put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1880 | put_info.offset; | ||
1881 | while ((!(rxdp->Control_1 & RXD_OWN_XENA)) && | ||
1882 | (((get_offset + 1) % ring_bufs) != put_offset)) { | ||
1883 | if (--pkts_to_process < 0) { | ||
1884 | goto no_rx; | ||
1885 | } | ||
1886 | if (rxdp->Control_1 == END_OF_BLOCK) { | ||
1887 | rxdp = | ||
1888 | (RxD_t *) ((unsigned long) rxdp-> | ||
1889 | Control_2); | ||
1890 | get_info.offset++; | ||
1891 | get_info.offset %= | ||
1892 | (MAX_RXDS_PER_BLOCK + 1); | ||
1893 | get_block++; | ||
1894 | get_block %= nic->block_count[i]; | ||
1895 | mac_control->rx_curr_get_info[i]. | ||
1896 | offset = get_info.offset; | ||
1897 | mac_control->rx_curr_get_info[i]. | ||
1898 | block_index = get_block; | ||
1899 | continue; | ||
1900 | } | ||
1901 | get_offset = | ||
1902 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1903 | get_info.offset; | ||
1904 | skb = | ||
1905 | (struct sk_buff *) ((unsigned long) rxdp-> | ||
1906 | Host_Control); | ||
1907 | if (skb == NULL) { | ||
1908 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | ||
1909 | dev->name); | ||
1910 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | ||
1911 | goto no_rx; | ||
1912 | } | ||
1913 | val64 = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); | ||
1914 | val16 = (u16) (val64 >> 48); | ||
1915 | cksum = RXD_GET_L4_CKSUM(rxdp->Control_1); | ||
1916 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1917 | rxdp->Buffer0_ptr, | ||
1918 | dev->mtu + | ||
1919 | HEADER_ETHERNET_II_802_3_SIZE + | ||
1920 | HEADER_802_2_SIZE + | ||
1921 | HEADER_SNAP_SIZE, | ||
1922 | PCI_DMA_FROMDEVICE); | ||
1923 | rx_osm_handler(nic, val16, rxdp, i); | ||
1924 | pkt_cnt++; | ||
1925 | get_info.offset++; | ||
1926 | get_info.offset %= (MAX_RXDS_PER_BLOCK + 1); | ||
1927 | rxdp = | ||
1928 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
1929 | get_info.offset; | ||
1930 | mac_control->rx_curr_get_info[i].offset = | ||
1931 | get_info.offset; | ||
1932 | } | 2420 | } |
1933 | #else | ||
1934 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1935 | get_info.offset; | ||
1936 | put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1937 | put_info.offset; | ||
1938 | while (((!(rxdp->Control_1 & RXD_OWN_XENA)) && | ||
1939 | !(rxdp->Control_2 & BIT(0))) && | ||
1940 | (((get_offset + 1) % ring_bufs) != put_offset)) { | ||
1941 | if (--pkts_to_process < 0) { | ||
1942 | goto no_rx; | ||
1943 | } | ||
1944 | skb = (struct sk_buff *) ((unsigned long) | ||
1945 | rxdp->Host_Control); | ||
1946 | if (skb == NULL) { | ||
1947 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | ||
1948 | dev->name); | ||
1949 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | ||
1950 | goto no_rx; | ||
1951 | } | ||
1952 | |||
1953 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1954 | rxdp->Buffer0_ptr, | ||
1955 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
1956 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1957 | rxdp->Buffer1_ptr, | ||
1958 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
1959 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1960 | rxdp->Buffer2_ptr, | ||
1961 | dev->mtu + BUF0_LEN + 4, | ||
1962 | PCI_DMA_FROMDEVICE); | ||
1963 | ba = &nic->ba[i][get_block][get_info.offset]; | ||
1964 | |||
1965 | rx_osm_handler(nic, rxdp, i, ba); | ||
1966 | |||
1967 | get_info.offset++; | ||
1968 | mac_control->rx_curr_get_info[i].offset = | ||
1969 | get_info.offset; | ||
1970 | rxdp = | ||
1971 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
1972 | get_info.offset; | ||
1973 | |||
1974 | if (get_info.offset && | ||
1975 | (!(get_info.offset % MAX_RXDS_PER_BLOCK))) { | ||
1976 | get_info.offset = 0; | ||
1977 | mac_control->rx_curr_get_info[i]. | ||
1978 | offset = get_info.offset; | ||
1979 | get_block++; | ||
1980 | get_block %= nic->block_count[i]; | ||
1981 | mac_control->rx_curr_get_info[i]. | ||
1982 | block_index = get_block; | ||
1983 | rxdp = | ||
1984 | nic->rx_blocks[i][get_block]. | ||
1985 | block_virt_addr; | ||
1986 | } | ||
1987 | get_offset = | ||
1988 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1989 | get_info.offset; | ||
1990 | pkt_cnt++; | ||
1991 | } | ||
1992 | #endif | ||
1993 | } | 2421 | } |
1994 | if (!pkt_cnt) | 2422 | if (!pkt_cnt) |
1995 | pkt_cnt = 1; | 2423 | pkt_cnt = 1; |
@@ -2007,9 +2435,10 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
2007 | } | 2435 | } |
2008 | /* Re enable the Rx interrupts. */ | 2436 | /* Re enable the Rx interrupts. */ |
2009 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); | 2437 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); |
2438 | atomic_dec(&nic->isr_cnt); | ||
2010 | return 0; | 2439 | return 0; |
2011 | 2440 | ||
2012 | no_rx: | 2441 | no_rx: |
2013 | dev->quota -= pkt_cnt; | 2442 | dev->quota -= pkt_cnt; |
2014 | *budget -= pkt_cnt; | 2443 | *budget -= pkt_cnt; |
2015 | 2444 | ||
@@ -2020,279 +2449,204 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
2020 | break; | 2449 | break; |
2021 | } | 2450 | } |
2022 | } | 2451 | } |
2452 | atomic_dec(&nic->isr_cnt); | ||
2023 | return 1; | 2453 | return 1; |
2024 | } | 2454 | } |
2025 | #else | 2455 | #endif |
2026 | /** | 2456 | |
2457 | /** | ||
2027 | * rx_intr_handler - Rx interrupt handler | 2458 | * rx_intr_handler - Rx interrupt handler |
2028 | * @nic: device private variable. | 2459 | * @nic: device private variable. |
2029 | * Description: | 2460 | * Description: |
2030 | * If the interrupt is because of a received frame or if the | 2461 | * If the interrupt is because of a received frame or if the |
2031 | * receive ring contains fresh as yet un-processed frames,this function is | 2462 | * receive ring contains fresh as yet un-processed frames,this function is |
2032 | * called. It picks out the RxD at which place the last Rx processing had | 2463 | * called. It picks out the RxD at which place the last Rx processing had |
2033 | * stopped and sends the skb to the OSM's Rx handler and then increments | 2464 | * stopped and sends the skb to the OSM's Rx handler and then increments |
2034 | * the offset. | 2465 | * the offset. |
2035 | * Return Value: | 2466 | * Return Value: |
2036 | * NONE. | 2467 | * NONE. |
2037 | */ | 2468 | */ |
2038 | 2469 | static void rx_intr_handler(ring_info_t *ring_data) | |
2039 | static void rx_intr_handler(struct s2io_nic *nic) | ||
2040 | { | 2470 | { |
2471 | nic_t *nic = ring_data->nic; | ||
2041 | struct net_device *dev = (struct net_device *) nic->dev; | 2472 | struct net_device *dev = (struct net_device *) nic->dev; |
2042 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | 2473 | int get_block, get_offset, put_block, put_offset, ring_bufs; |
2043 | rx_curr_get_info_t get_info, put_info; | 2474 | rx_curr_get_info_t get_info, put_info; |
2044 | RxD_t *rxdp; | 2475 | RxD_t *rxdp; |
2045 | struct sk_buff *skb; | 2476 | struct sk_buff *skb; |
2046 | #ifndef CONFIG_2BUFF_MODE | 2477 | #ifndef CONFIG_S2IO_NAPI |
2047 | u16 val16, cksum; | 2478 | int pkt_cnt = 0; |
2048 | #endif | ||
2049 | register u64 val64 = 0; | ||
2050 | int get_block, get_offset, put_block, put_offset, ring_bufs; | ||
2051 | int i, pkt_cnt = 0; | ||
2052 | mac_info_t *mac_control; | ||
2053 | struct config_param *config; | ||
2054 | #ifdef CONFIG_2BUFF_MODE | ||
2055 | buffAdd_t *ba; | ||
2056 | #endif | 2479 | #endif |
2480 | spin_lock(&nic->rx_lock); | ||
2481 | if (atomic_read(&nic->card_state) == CARD_DOWN) { | ||
2482 | DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n", | ||
2483 | __FUNCTION__, dev->name); | ||
2484 | spin_unlock(&nic->rx_lock); | ||
2485 | } | ||
2057 | 2486 | ||
2058 | mac_control = &nic->mac_control; | 2487 | get_info = ring_data->rx_curr_get_info; |
2059 | config = &nic->config; | 2488 | get_block = get_info.block_index; |
2060 | 2489 | put_info = ring_data->rx_curr_put_info; | |
2061 | /* | 2490 | put_block = put_info.block_index; |
2062 | * rx_traffic_int reg is an R1 register, hence we read and write back | 2491 | ring_bufs = get_info.ring_len+1; |
2063 | * the samevalue in the register to clear it. | 2492 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr + |
2064 | */ | ||
2065 | val64 = readq(&bar0->rx_traffic_int); | ||
2066 | writeq(val64, &bar0->rx_traffic_int); | ||
2067 | |||
2068 | for (i = 0; i < config->rx_ring_num; i++) { | ||
2069 | get_info = mac_control->rx_curr_get_info[i]; | ||
2070 | get_block = get_info.block_index; | ||
2071 | put_info = mac_control->rx_curr_put_info[i]; | ||
2072 | put_block = put_info.block_index; | ||
2073 | ring_bufs = config->rx_cfg[i].num_rxd; | ||
2074 | rxdp = nic->rx_blocks[i][get_block].block_virt_addr + | ||
2075 | get_info.offset; | ||
2076 | #ifndef CONFIG_2BUFF_MODE | ||
2077 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
2078 | get_info.offset; | 2493 | get_info.offset; |
2079 | spin_lock(&nic->put_lock); | 2494 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + |
2080 | put_offset = nic->put_pos[i]; | 2495 | get_info.offset; |
2081 | spin_unlock(&nic->put_lock); | 2496 | #ifndef CONFIG_S2IO_NAPI |
2082 | while ((!(rxdp->Control_1 & RXD_OWN_XENA)) && | 2497 | spin_lock(&nic->put_lock); |
2083 | (((get_offset + 1) % ring_bufs) != put_offset)) { | 2498 | put_offset = ring_data->put_pos; |
2084 | if (rxdp->Control_1 == END_OF_BLOCK) { | 2499 | spin_unlock(&nic->put_lock); |
2085 | rxdp = (RxD_t *) ((unsigned long) | 2500 | #else |
2086 | rxdp->Control_2); | 2501 | put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) + |
2087 | get_info.offset++; | 2502 | put_info.offset; |
2088 | get_info.offset %= | 2503 | #endif |
2089 | (MAX_RXDS_PER_BLOCK + 1); | 2504 | while (RXD_IS_UP2DT(rxdp) && |
2090 | get_block++; | 2505 | (((get_offset + 1) % ring_bufs) != put_offset)) { |
2091 | get_block %= nic->block_count[i]; | 2506 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); |
2092 | mac_control->rx_curr_get_info[i]. | 2507 | if (skb == NULL) { |
2093 | offset = get_info.offset; | 2508 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
2094 | mac_control->rx_curr_get_info[i]. | 2509 | dev->name); |
2095 | block_index = get_block; | 2510 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
2096 | continue; | 2511 | spin_unlock(&nic->rx_lock); |
2097 | } | 2512 | return; |
2098 | get_offset = | ||
2099 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
2100 | get_info.offset; | ||
2101 | skb = (struct sk_buff *) ((unsigned long) | ||
2102 | rxdp->Host_Control); | ||
2103 | if (skb == NULL) { | ||
2104 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | ||
2105 | dev->name); | ||
2106 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | ||
2107 | return; | ||
2108 | } | ||
2109 | val64 = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); | ||
2110 | val16 = (u16) (val64 >> 48); | ||
2111 | cksum = RXD_GET_L4_CKSUM(rxdp->Control_1); | ||
2112 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2113 | rxdp->Buffer0_ptr, | ||
2114 | dev->mtu + | ||
2115 | HEADER_ETHERNET_II_802_3_SIZE + | ||
2116 | HEADER_802_2_SIZE + | ||
2117 | HEADER_SNAP_SIZE, | ||
2118 | PCI_DMA_FROMDEVICE); | ||
2119 | rx_osm_handler(nic, val16, rxdp, i); | ||
2120 | get_info.offset++; | ||
2121 | get_info.offset %= (MAX_RXDS_PER_BLOCK + 1); | ||
2122 | rxdp = | ||
2123 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
2124 | get_info.offset; | ||
2125 | mac_control->rx_curr_get_info[i].offset = | ||
2126 | get_info.offset; | ||
2127 | pkt_cnt++; | ||
2128 | if ((indicate_max_pkts) | ||
2129 | && (pkt_cnt > indicate_max_pkts)) | ||
2130 | break; | ||
2131 | } | 2513 | } |
2514 | #ifndef CONFIG_2BUFF_MODE | ||
2515 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2516 | rxdp->Buffer0_ptr, | ||
2517 | dev->mtu + | ||
2518 | HEADER_ETHERNET_II_802_3_SIZE + | ||
2519 | HEADER_802_2_SIZE + | ||
2520 | HEADER_SNAP_SIZE, | ||
2521 | PCI_DMA_FROMDEVICE); | ||
2132 | #else | 2522 | #else |
2133 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | 2523 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2524 | rxdp->Buffer0_ptr, | ||
2525 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2526 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2527 | rxdp->Buffer1_ptr, | ||
2528 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2529 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2530 | rxdp->Buffer2_ptr, | ||
2531 | dev->mtu + BUF0_LEN + 4, | ||
2532 | PCI_DMA_FROMDEVICE); | ||
2533 | #endif | ||
2534 | rx_osm_handler(ring_data, rxdp); | ||
2535 | get_info.offset++; | ||
2536 | ring_data->rx_curr_get_info.offset = | ||
2134 | get_info.offset; | 2537 | get_info.offset; |
2135 | spin_lock(&nic->put_lock); | 2538 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr + |
2136 | put_offset = nic->put_pos[i]; | 2539 | get_info.offset; |
2137 | spin_unlock(&nic->put_lock); | 2540 | if (get_info.offset && |
2138 | while (((!(rxdp->Control_1 & RXD_OWN_XENA)) && | 2541 | (!(get_info.offset % MAX_RXDS_PER_BLOCK))) { |
2139 | !(rxdp->Control_2 & BIT(0))) && | 2542 | get_info.offset = 0; |
2140 | (((get_offset + 1) % ring_bufs) != put_offset)) { | 2543 | ring_data->rx_curr_get_info.offset |
2141 | skb = (struct sk_buff *) ((unsigned long) | 2544 | = get_info.offset; |
2142 | rxdp->Host_Control); | 2545 | get_block++; |
2143 | if (skb == NULL) { | 2546 | get_block %= ring_data->block_count; |
2144 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 2547 | ring_data->rx_curr_get_info.block_index |
2145 | dev->name); | 2548 | = get_block; |
2146 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 2549 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; |
2147 | return; | 2550 | } |
2148 | } | ||
2149 | |||
2150 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2151 | rxdp->Buffer0_ptr, | ||
2152 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2153 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2154 | rxdp->Buffer1_ptr, | ||
2155 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2156 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2157 | rxdp->Buffer2_ptr, | ||
2158 | dev->mtu + BUF0_LEN + 4, | ||
2159 | PCI_DMA_FROMDEVICE); | ||
2160 | ba = &nic->ba[i][get_block][get_info.offset]; | ||
2161 | |||
2162 | rx_osm_handler(nic, rxdp, i, ba); | ||
2163 | |||
2164 | get_info.offset++; | ||
2165 | mac_control->rx_curr_get_info[i].offset = | ||
2166 | get_info.offset; | ||
2167 | rxdp = | ||
2168 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
2169 | get_info.offset; | ||
2170 | 2551 | ||
2171 | if (get_info.offset && | 2552 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + |
2172 | (!(get_info.offset % MAX_RXDS_PER_BLOCK))) { | ||
2173 | get_info.offset = 0; | ||
2174 | mac_control->rx_curr_get_info[i]. | ||
2175 | offset = get_info.offset; | ||
2176 | get_block++; | ||
2177 | get_block %= nic->block_count[i]; | ||
2178 | mac_control->rx_curr_get_info[i]. | ||
2179 | block_index = get_block; | ||
2180 | rxdp = | ||
2181 | nic->rx_blocks[i][get_block]. | ||
2182 | block_virt_addr; | ||
2183 | } | ||
2184 | get_offset = | ||
2185 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
2186 | get_info.offset; | 2553 | get_info.offset; |
2187 | pkt_cnt++; | 2554 | #ifdef CONFIG_S2IO_NAPI |
2188 | if ((indicate_max_pkts) | 2555 | nic->pkts_to_process -= 1; |
2189 | && (pkt_cnt > indicate_max_pkts)) | 2556 | if (!nic->pkts_to_process) |
2190 | break; | 2557 | break; |
2191 | } | 2558 | #else |
2192 | #endif | 2559 | pkt_cnt++; |
2193 | if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) | 2560 | if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) |
2194 | break; | 2561 | break; |
2562 | #endif | ||
2195 | } | 2563 | } |
2564 | spin_unlock(&nic->rx_lock); | ||
2196 | } | 2565 | } |
2197 | #endif | 2566 | |
2198 | /** | 2567 | /** |
2199 | * tx_intr_handler - Transmit interrupt handler | 2568 | * tx_intr_handler - Transmit interrupt handler |
2200 | * @nic : device private variable | 2569 | * @nic : device private variable |
2201 | * Description: | 2570 | * Description: |
2202 | * If an interrupt was raised to indicate DMA complete of the | 2571 | * If an interrupt was raised to indicate DMA complete of the |
2203 | * Tx packet, this function is called. It identifies the last TxD | 2572 | * Tx packet, this function is called. It identifies the last TxD |
2204 | * whose buffer was freed and frees all skbs whose data have already | 2573 | * whose buffer was freed and frees all skbs whose data have already |
2205 | * DMA'ed into the NICs internal memory. | 2574 | * DMA'ed into the NICs internal memory. |
2206 | * Return Value: | 2575 | * Return Value: |
2207 | * NONE | 2576 | * NONE |
2208 | */ | 2577 | */ |
2209 | 2578 | ||
2210 | static void tx_intr_handler(struct s2io_nic *nic) | 2579 | static void tx_intr_handler(fifo_info_t *fifo_data) |
2211 | { | 2580 | { |
2212 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2581 | nic_t *nic = fifo_data->nic; |
2213 | struct net_device *dev = (struct net_device *) nic->dev; | 2582 | struct net_device *dev = (struct net_device *) nic->dev; |
2214 | tx_curr_get_info_t get_info, put_info; | 2583 | tx_curr_get_info_t get_info, put_info; |
2215 | struct sk_buff *skb; | 2584 | struct sk_buff *skb; |
2216 | TxD_t *txdlp; | 2585 | TxD_t *txdlp; |
2217 | register u64 val64 = 0; | ||
2218 | int i; | ||
2219 | u16 j, frg_cnt; | 2586 | u16 j, frg_cnt; |
2220 | mac_info_t *mac_control; | ||
2221 | struct config_param *config; | ||
2222 | 2587 | ||
2223 | mac_control = &nic->mac_control; | 2588 | get_info = fifo_data->tx_curr_get_info; |
2224 | config = &nic->config; | 2589 | put_info = fifo_data->tx_curr_put_info; |
2225 | 2590 | txdlp = (TxD_t *) fifo_data->list_info[get_info.offset]. | |
2226 | /* | 2591 | list_virt_addr; |
2227 | * tx_traffic_int reg is an R1 register, hence we read and write | 2592 | while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && |
2228 | * back the samevalue in the register to clear it. | 2593 | (get_info.offset != put_info.offset) && |
2229 | */ | 2594 | (txdlp->Host_Control)) { |
2230 | val64 = readq(&bar0->tx_traffic_int); | 2595 | /* Check for TxD errors */ |
2231 | writeq(val64, &bar0->tx_traffic_int); | 2596 | if (txdlp->Control_1 & TXD_T_CODE) { |
2597 | unsigned long long err; | ||
2598 | err = txdlp->Control_1 & TXD_T_CODE; | ||
2599 | DBG_PRINT(ERR_DBG, "***TxD error %llx\n", | ||
2600 | err); | ||
2601 | } | ||
2232 | 2602 | ||
2233 | for (i = 0; i < config->tx_fifo_num; i++) { | 2603 | skb = (struct sk_buff *) ((unsigned long) |
2234 | get_info = mac_control->tx_curr_get_info[i]; | 2604 | txdlp->Host_Control); |
2235 | put_info = mac_control->tx_curr_put_info[i]; | 2605 | if (skb == NULL) { |
2236 | txdlp = (TxD_t *) nic->list_info[i][get_info.offset]. | 2606 | DBG_PRINT(ERR_DBG, "%s: Null skb ", |
2237 | list_virt_addr; | 2607 | __FUNCTION__); |
2238 | while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && | 2608 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); |
2239 | (get_info.offset != put_info.offset) && | 2609 | return; |
2240 | (txdlp->Host_Control)) { | 2610 | } |
2241 | /* Check for TxD errors */ | ||
2242 | if (txdlp->Control_1 & TXD_T_CODE) { | ||
2243 | unsigned long long err; | ||
2244 | err = txdlp->Control_1 & TXD_T_CODE; | ||
2245 | DBG_PRINT(ERR_DBG, "***TxD error %llx\n", | ||
2246 | err); | ||
2247 | } | ||
2248 | 2611 | ||
2249 | skb = (struct sk_buff *) ((unsigned long) | 2612 | frg_cnt = skb_shinfo(skb)->nr_frags; |
2250 | txdlp->Host_Control); | 2613 | nic->tx_pkt_count++; |
2251 | if (skb == NULL) { | 2614 | |
2252 | DBG_PRINT(ERR_DBG, "%s: Null skb ", | 2615 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2253 | dev->name); | 2616 | txdlp->Buffer_Pointer, |
2254 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); | 2617 | skb->len - skb->data_len, |
2255 | return; | 2618 | PCI_DMA_TODEVICE); |
2619 | if (frg_cnt) { | ||
2620 | TxD_t *temp; | ||
2621 | temp = txdlp; | ||
2622 | txdlp++; | ||
2623 | for (j = 0; j < frg_cnt; j++, txdlp++) { | ||
2624 | skb_frag_t *frag = | ||
2625 | &skb_shinfo(skb)->frags[j]; | ||
2626 | if (!txdlp->Buffer_Pointer) | ||
2627 | break; | ||
2628 | pci_unmap_page(nic->pdev, | ||
2629 | (dma_addr_t) | ||
2630 | txdlp-> | ||
2631 | Buffer_Pointer, | ||
2632 | frag->size, | ||
2633 | PCI_DMA_TODEVICE); | ||
2256 | } | 2634 | } |
2257 | nic->tx_pkt_count++; | 2635 | txdlp = temp; |
2258 | |||
2259 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
2260 | |||
2261 | /* For unfragmented skb */ | ||
2262 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2263 | txdlp->Buffer_Pointer, | ||
2264 | skb->len - skb->data_len, | ||
2265 | PCI_DMA_TODEVICE); | ||
2266 | if (frg_cnt) { | ||
2267 | TxD_t *temp = txdlp; | ||
2268 | txdlp++; | ||
2269 | for (j = 0; j < frg_cnt; j++, txdlp++) { | ||
2270 | skb_frag_t *frag = | ||
2271 | &skb_shinfo(skb)->frags[j]; | ||
2272 | pci_unmap_page(nic->pdev, | ||
2273 | (dma_addr_t) | ||
2274 | txdlp-> | ||
2275 | Buffer_Pointer, | ||
2276 | frag->size, | ||
2277 | PCI_DMA_TODEVICE); | ||
2278 | } | ||
2279 | txdlp = temp; | ||
2280 | } | ||
2281 | memset(txdlp, 0, | ||
2282 | (sizeof(TxD_t) * config->max_txds)); | ||
2283 | |||
2284 | /* Updating the statistics block */ | ||
2285 | nic->stats.tx_packets++; | ||
2286 | nic->stats.tx_bytes += skb->len; | ||
2287 | dev_kfree_skb_irq(skb); | ||
2288 | |||
2289 | get_info.offset++; | ||
2290 | get_info.offset %= get_info.fifo_len + 1; | ||
2291 | txdlp = (TxD_t *) nic->list_info[i] | ||
2292 | [get_info.offset].list_virt_addr; | ||
2293 | mac_control->tx_curr_get_info[i].offset = | ||
2294 | get_info.offset; | ||
2295 | } | 2636 | } |
2637 | memset(txdlp, 0, | ||
2638 | (sizeof(TxD_t) * fifo_data->max_txds)); | ||
2639 | |||
2640 | /* Updating the statistics block */ | ||
2641 | nic->stats.tx_bytes += skb->len; | ||
2642 | dev_kfree_skb_irq(skb); | ||
2643 | |||
2644 | get_info.offset++; | ||
2645 | get_info.offset %= get_info.fifo_len + 1; | ||
2646 | txdlp = (TxD_t *) fifo_data->list_info | ||
2647 | [get_info.offset].list_virt_addr; | ||
2648 | fifo_data->tx_curr_get_info.offset = | ||
2649 | get_info.offset; | ||
2296 | } | 2650 | } |
2297 | 2651 | ||
2298 | spin_lock(&nic->tx_lock); | 2652 | spin_lock(&nic->tx_lock); |
@@ -2301,13 +2655,13 @@ static void tx_intr_handler(struct s2io_nic *nic) | |||
2301 | spin_unlock(&nic->tx_lock); | 2655 | spin_unlock(&nic->tx_lock); |
2302 | } | 2656 | } |
2303 | 2657 | ||
2304 | /** | 2658 | /** |
2305 | * alarm_intr_handler - Alarm Interrrupt handler | 2659 | * alarm_intr_handler - Alarm Interrrupt handler |
2306 | * @nic: device private variable | 2660 | * @nic: device private variable |
2307 | * Description: If the interrupt was neither because of Rx packet or Tx | 2661 | * Description: If the interrupt was neither because of Rx packet or Tx |
2308 | * complete, this function is called. If the interrupt was to indicate | 2662 | * complete, this function is called. If the interrupt was to indicate |
2309 | * a loss of link, the OSM link status handler is invoked for any other | 2663 | * a loss of link, the OSM link status handler is invoked for any other |
2310 | * alarm interrupt the block that raised the interrupt is displayed | 2664 | * alarm interrupt the block that raised the interrupt is displayed |
2311 | * and a H/W reset is issued. | 2665 | * and a H/W reset is issued. |
2312 | * Return Value: | 2666 | * Return Value: |
2313 | * NONE | 2667 | * NONE |
@@ -2320,10 +2674,32 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2320 | register u64 val64 = 0, err_reg = 0; | 2674 | register u64 val64 = 0, err_reg = 0; |
2321 | 2675 | ||
2322 | /* Handling link status change error Intr */ | 2676 | /* Handling link status change error Intr */ |
2323 | err_reg = readq(&bar0->mac_rmac_err_reg); | 2677 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
2324 | writeq(err_reg, &bar0->mac_rmac_err_reg); | 2678 | err_reg = readq(&bar0->mac_rmac_err_reg); |
2325 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { | 2679 | writeq(err_reg, &bar0->mac_rmac_err_reg); |
2326 | schedule_work(&nic->set_link_task); | 2680 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { |
2681 | schedule_work(&nic->set_link_task); | ||
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | /* Handling Ecc errors */ | ||
2686 | val64 = readq(&bar0->mc_err_reg); | ||
2687 | writeq(val64, &bar0->mc_err_reg); | ||
2688 | if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) { | ||
2689 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { | ||
2690 | nic->mac_control.stats_info->sw_stat. | ||
2691 | double_ecc_errs++; | ||
2692 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", | ||
2693 | dev->name); | ||
2694 | DBG_PRINT(ERR_DBG, "double ECC error!!\n"); | ||
2695 | if (nic->device_type != XFRAME_II_DEVICE) { | ||
2696 | netif_stop_queue(dev); | ||
2697 | schedule_work(&nic->rst_timer_task); | ||
2698 | } | ||
2699 | } else { | ||
2700 | nic->mac_control.stats_info->sw_stat. | ||
2701 | single_ecc_errs++; | ||
2702 | } | ||
2327 | } | 2703 | } |
2328 | 2704 | ||
2329 | /* In case of a serious error, the device will be Reset. */ | 2705 | /* In case of a serious error, the device will be Reset. */ |
@@ -2338,7 +2714,7 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2338 | /* | 2714 | /* |
2339 | * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC | 2715 | * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC |
2340 | * Error occurs, the adapter will be recycled by disabling the | 2716 | * Error occurs, the adapter will be recycled by disabling the |
2341 | * adapter enable bit and enabling it again after the device | 2717 | * adapter enable bit and enabling it again after the device |
2342 | * becomes Quiescent. | 2718 | * becomes Quiescent. |
2343 | */ | 2719 | */ |
2344 | val64 = readq(&bar0->pcc_err_reg); | 2720 | val64 = readq(&bar0->pcc_err_reg); |
@@ -2354,18 +2730,18 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2354 | /* Other type of interrupts are not being handled now, TODO */ | 2730 | /* Other type of interrupts are not being handled now, TODO */ |
2355 | } | 2731 | } |
2356 | 2732 | ||
2357 | /** | 2733 | /** |
2358 | * wait_for_cmd_complete - waits for a command to complete. | 2734 | * wait_for_cmd_complete - waits for a command to complete. |
2359 | * @sp : private member of the device structure, which is a pointer to the | 2735 | * @sp : private member of the device structure, which is a pointer to the |
2360 | * s2io_nic structure. | 2736 | * s2io_nic structure. |
2361 | * Description: Function that waits for a command to Write into RMAC | 2737 | * Description: Function that waits for a command to Write into RMAC |
2362 | * ADDR DATA registers to be completed and returns either success or | 2738 | * ADDR DATA registers to be completed and returns either success or |
2363 | * error depending on whether the command was complete or not. | 2739 | * error depending on whether the command was complete or not. |
2364 | * Return value: | 2740 | * Return value: |
2365 | * SUCCESS on success and FAILURE on failure. | 2741 | * SUCCESS on success and FAILURE on failure. |
2366 | */ | 2742 | */ |
2367 | 2743 | ||
2368 | static int wait_for_cmd_complete(nic_t * sp) | 2744 | int wait_for_cmd_complete(nic_t * sp) |
2369 | { | 2745 | { |
2370 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2746 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2371 | int ret = FAILURE, cnt = 0; | 2747 | int ret = FAILURE, cnt = 0; |
@@ -2385,29 +2761,32 @@ static int wait_for_cmd_complete(nic_t * sp) | |||
2385 | return ret; | 2761 | return ret; |
2386 | } | 2762 | } |
2387 | 2763 | ||
2388 | /** | 2764 | /** |
2389 | * s2io_reset - Resets the card. | 2765 | * s2io_reset - Resets the card. |
2390 | * @sp : private member of the device structure. | 2766 | * @sp : private member of the device structure. |
2391 | * Description: Function to Reset the card. This function then also | 2767 | * Description: Function to Reset the card. This function then also |
2392 | * restores the previously saved PCI configuration space registers as | 2768 | * restores the previously saved PCI configuration space registers as |
2393 | * the card reset also resets the configuration space. | 2769 | * the card reset also resets the configuration space. |
2394 | * Return value: | 2770 | * Return value: |
2395 | * void. | 2771 | * void. |
2396 | */ | 2772 | */ |
2397 | 2773 | ||
2398 | static void s2io_reset(nic_t * sp) | 2774 | void s2io_reset(nic_t * sp) |
2399 | { | 2775 | { |
2400 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2776 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2401 | u64 val64; | 2777 | u64 val64; |
2402 | u16 subid; | 2778 | u16 subid, pci_cmd; |
2779 | |||
2780 | /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ | ||
2781 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); | ||
2403 | 2782 | ||
2404 | val64 = SW_RESET_ALL; | 2783 | val64 = SW_RESET_ALL; |
2405 | writeq(val64, &bar0->sw_reset); | 2784 | writeq(val64, &bar0->sw_reset); |
2406 | 2785 | ||
2407 | /* | 2786 | /* |
2408 | * At this stage, if the PCI write is indeed completed, the | 2787 | * At this stage, if the PCI write is indeed completed, the |
2409 | * card is reset and so is the PCI Config space of the device. | 2788 | * card is reset and so is the PCI Config space of the device. |
2410 | * So a read cannot be issued at this stage on any of the | 2789 | * So a read cannot be issued at this stage on any of the |
2411 | * registers to ensure the write into "sw_reset" register | 2790 | * registers to ensure the write into "sw_reset" register |
2412 | * has gone through. | 2791 | * has gone through. |
2413 | * Question: Is there any system call that will explicitly force | 2792 | * Question: Is there any system call that will explicitly force |
@@ -2418,42 +2797,72 @@ static void s2io_reset(nic_t * sp) | |||
2418 | */ | 2797 | */ |
2419 | msleep(250); | 2798 | msleep(250); |
2420 | 2799 | ||
2421 | /* Restore the PCI state saved during initializarion. */ | 2800 | /* Restore the PCI state saved during initialization. */ |
2422 | pci_restore_state(sp->pdev); | 2801 | pci_restore_state(sp->pdev); |
2802 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
2803 | pci_cmd); | ||
2423 | s2io_init_pci(sp); | 2804 | s2io_init_pci(sp); |
2424 | 2805 | ||
2425 | msleep(250); | 2806 | msleep(250); |
2426 | 2807 | ||
2808 | /* Set swapper to enable I/O register access */ | ||
2809 | s2io_set_swapper(sp); | ||
2810 | |||
2811 | /* Clear certain PCI/PCI-X fields after reset */ | ||
2812 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
2813 | /* Clear parity err detect bit */ | ||
2814 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); | ||
2815 | |||
2816 | /* Clearing PCIX Ecc status register */ | ||
2817 | pci_write_config_dword(sp->pdev, 0x68, 0x7C); | ||
2818 | |||
2819 | /* Clearing PCI_STATUS error reflected here */ | ||
2820 | writeq(BIT(62), &bar0->txpic_int_reg); | ||
2821 | } | ||
2822 | |||
2823 | /* Reset device statistics maintained by OS */ | ||
2824 | memset(&sp->stats, 0, sizeof (struct net_device_stats)); | ||
2825 | |||
2427 | /* SXE-002: Configure link and activity LED to turn it off */ | 2826 | /* SXE-002: Configure link and activity LED to turn it off */ |
2428 | subid = sp->pdev->subsystem_device; | 2827 | subid = sp->pdev->subsystem_device; |
2429 | if ((subid & 0xFF) >= 0x07) { | 2828 | if (((subid & 0xFF) >= 0x07) && |
2829 | (sp->device_type == XFRAME_I_DEVICE)) { | ||
2430 | val64 = readq(&bar0->gpio_control); | 2830 | val64 = readq(&bar0->gpio_control); |
2431 | val64 |= 0x0000800000000000ULL; | 2831 | val64 |= 0x0000800000000000ULL; |
2432 | writeq(val64, &bar0->gpio_control); | 2832 | writeq(val64, &bar0->gpio_control); |
2433 | val64 = 0x0411040400000000ULL; | 2833 | val64 = 0x0411040400000000ULL; |
2434 | writeq(val64, (void __iomem *) bar0 + 0x2700); | 2834 | writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700)); |
2835 | } | ||
2836 | |||
2837 | /* | ||
2838 | * Clear spurious ECC interrupts that would have occured on | ||
2839 | * XFRAME II cards after reset. | ||
2840 | */ | ||
2841 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
2842 | val64 = readq(&bar0->pcc_err_reg); | ||
2843 | writeq(val64, &bar0->pcc_err_reg); | ||
2435 | } | 2844 | } |
2436 | 2845 | ||
2437 | sp->device_enabled_once = FALSE; | 2846 | sp->device_enabled_once = FALSE; |
2438 | } | 2847 | } |
2439 | 2848 | ||
2440 | /** | 2849 | /** |
2441 | * s2io_set_swapper - to set the swapper controle on the card | 2850 | * s2io_set_swapper - to set the swapper controle on the card |
2442 | * @sp : private member of the device structure, | 2851 | * @sp : private member of the device structure, |
2443 | * pointer to the s2io_nic structure. | 2852 | * pointer to the s2io_nic structure. |
2444 | * Description: Function to set the swapper control on the card | 2853 | * Description: Function to set the swapper control on the card |
2445 | * correctly depending on the 'endianness' of the system. | 2854 | * correctly depending on the 'endianness' of the system. |
2446 | * Return value: | 2855 | * Return value: |
2447 | * SUCCESS on success and FAILURE on failure. | 2856 | * SUCCESS on success and FAILURE on failure. |
2448 | */ | 2857 | */ |
2449 | 2858 | ||
2450 | static int s2io_set_swapper(nic_t * sp) | 2859 | int s2io_set_swapper(nic_t * sp) |
2451 | { | 2860 | { |
2452 | struct net_device *dev = sp->dev; | 2861 | struct net_device *dev = sp->dev; |
2453 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2862 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2454 | u64 val64, valt, valr; | 2863 | u64 val64, valt, valr; |
2455 | 2864 | ||
2456 | /* | 2865 | /* |
2457 | * Set proper endian settings and verify the same by reading | 2866 | * Set proper endian settings and verify the same by reading |
2458 | * the PIF Feed-back register. | 2867 | * the PIF Feed-back register. |
2459 | */ | 2868 | */ |
@@ -2505,8 +2914,9 @@ static int s2io_set_swapper(nic_t * sp) | |||
2505 | i++; | 2914 | i++; |
2506 | } | 2915 | } |
2507 | if(i == 4) { | 2916 | if(i == 4) { |
2917 | unsigned long long x = val64; | ||
2508 | DBG_PRINT(ERR_DBG, "Write failed, Xmsi_addr "); | 2918 | DBG_PRINT(ERR_DBG, "Write failed, Xmsi_addr "); |
2509 | DBG_PRINT(ERR_DBG, "reads:0x%llx\n",val64); | 2919 | DBG_PRINT(ERR_DBG, "reads:0x%llx\n", x); |
2510 | return FAILURE; | 2920 | return FAILURE; |
2511 | } | 2921 | } |
2512 | } | 2922 | } |
@@ -2514,8 +2924,8 @@ static int s2io_set_swapper(nic_t * sp) | |||
2514 | val64 &= 0xFFFF000000000000ULL; | 2924 | val64 &= 0xFFFF000000000000ULL; |
2515 | 2925 | ||
2516 | #ifdef __BIG_ENDIAN | 2926 | #ifdef __BIG_ENDIAN |
2517 | /* | 2927 | /* |
2518 | * The device by default set to a big endian format, so a | 2928 | * The device by default set to a big endian format, so a |
2519 | * big endian driver need not set anything. | 2929 | * big endian driver need not set anything. |
2520 | */ | 2930 | */ |
2521 | val64 |= (SWAPPER_CTRL_TXP_FE | | 2931 | val64 |= (SWAPPER_CTRL_TXP_FE | |
@@ -2531,9 +2941,9 @@ static int s2io_set_swapper(nic_t * sp) | |||
2531 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); | 2941 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); |
2532 | writeq(val64, &bar0->swapper_ctrl); | 2942 | writeq(val64, &bar0->swapper_ctrl); |
2533 | #else | 2943 | #else |
2534 | /* | 2944 | /* |
2535 | * Initially we enable all bits to make it accessible by the | 2945 | * Initially we enable all bits to make it accessible by the |
2536 | * driver, then we selectively enable only those bits that | 2946 | * driver, then we selectively enable only those bits that |
2537 | * we want to set. | 2947 | * we want to set. |
2538 | */ | 2948 | */ |
2539 | val64 |= (SWAPPER_CTRL_TXP_FE | | 2949 | val64 |= (SWAPPER_CTRL_TXP_FE | |
@@ -2555,8 +2965,8 @@ static int s2io_set_swapper(nic_t * sp) | |||
2555 | #endif | 2965 | #endif |
2556 | val64 = readq(&bar0->swapper_ctrl); | 2966 | val64 = readq(&bar0->swapper_ctrl); |
2557 | 2967 | ||
2558 | /* | 2968 | /* |
2559 | * Verifying if endian settings are accurate by reading a | 2969 | * Verifying if endian settings are accurate by reading a |
2560 | * feedback register. | 2970 | * feedback register. |
2561 | */ | 2971 | */ |
2562 | val64 = readq(&bar0->pif_rd_swapper_fb); | 2972 | val64 = readq(&bar0->pif_rd_swapper_fb); |
@@ -2576,55 +2986,63 @@ static int s2io_set_swapper(nic_t * sp) | |||
2576 | * Functions defined below concern the OS part of the driver * | 2986 | * Functions defined below concern the OS part of the driver * |
2577 | * ********************************************************* */ | 2987 | * ********************************************************* */ |
2578 | 2988 | ||
2579 | /** | 2989 | /** |
2580 | * s2io_open - open entry point of the driver | 2990 | * s2io_open - open entry point of the driver |
2581 | * @dev : pointer to the device structure. | 2991 | * @dev : pointer to the device structure. |
2582 | * Description: | 2992 | * Description: |
2583 | * This function is the open entry point of the driver. It mainly calls a | 2993 | * This function is the open entry point of the driver. It mainly calls a |
2584 | * function to allocate Rx buffers and inserts them into the buffer | 2994 | * function to allocate Rx buffers and inserts them into the buffer |
2585 | * descriptors and then enables the Rx part of the NIC. | 2995 | * descriptors and then enables the Rx part of the NIC. |
2586 | * Return value: | 2996 | * Return value: |
2587 | * 0 on success and an appropriate (-)ve integer as defined in errno.h | 2997 | * 0 on success and an appropriate (-)ve integer as defined in errno.h |
2588 | * file on failure. | 2998 | * file on failure. |
2589 | */ | 2999 | */ |
2590 | 3000 | ||
2591 | static int s2io_open(struct net_device *dev) | 3001 | int s2io_open(struct net_device *dev) |
2592 | { | 3002 | { |
2593 | nic_t *sp = dev->priv; | 3003 | nic_t *sp = dev->priv; |
2594 | int err = 0; | 3004 | int err = 0; |
2595 | 3005 | ||
2596 | /* | 3006 | /* |
2597 | * Make sure you have link off by default every time | 3007 | * Make sure you have link off by default every time |
2598 | * Nic is initialized | 3008 | * Nic is initialized |
2599 | */ | 3009 | */ |
2600 | netif_carrier_off(dev); | 3010 | netif_carrier_off(dev); |
2601 | sp->last_link_state = LINK_DOWN; | 3011 | sp->last_link_state = 0; |
2602 | 3012 | ||
2603 | /* Initialize H/W and enable interrupts */ | 3013 | /* Initialize H/W and enable interrupts */ |
2604 | if (s2io_card_up(sp)) { | 3014 | if (s2io_card_up(sp)) { |
2605 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", | 3015 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", |
2606 | dev->name); | 3016 | dev->name); |
2607 | return -ENODEV; | 3017 | err = -ENODEV; |
3018 | goto hw_init_failed; | ||
2608 | } | 3019 | } |
2609 | 3020 | ||
2610 | /* After proper initialization of H/W, register ISR */ | 3021 | /* After proper initialization of H/W, register ISR */ |
2611 | err = request_irq((int) sp->irq, s2io_isr, SA_SHIRQ, | 3022 | err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ, |
2612 | sp->name, dev); | 3023 | sp->name, dev); |
2613 | if (err) { | 3024 | if (err) { |
2614 | s2io_reset(sp); | ||
2615 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", | 3025 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", |
2616 | dev->name); | 3026 | dev->name); |
2617 | return err; | 3027 | goto isr_registration_failed; |
2618 | } | 3028 | } |
2619 | 3029 | ||
2620 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { | 3030 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { |
2621 | DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n"); | 3031 | DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n"); |
2622 | s2io_reset(sp); | 3032 | err = -ENODEV; |
2623 | return -ENODEV; | 3033 | goto setting_mac_address_failed; |
2624 | } | 3034 | } |
2625 | 3035 | ||
2626 | netif_start_queue(dev); | 3036 | netif_start_queue(dev); |
2627 | return 0; | 3037 | return 0; |
3038 | |||
3039 | setting_mac_address_failed: | ||
3040 | free_irq(sp->pdev->irq, dev); | ||
3041 | isr_registration_failed: | ||
3042 | del_timer_sync(&sp->alarm_timer); | ||
3043 | s2io_reset(sp); | ||
3044 | hw_init_failed: | ||
3045 | return err; | ||
2628 | } | 3046 | } |
2629 | 3047 | ||
2630 | /** | 3048 | /** |
@@ -2640,16 +3058,15 @@ static int s2io_open(struct net_device *dev) | |||
2640 | * file on failure. | 3058 | * file on failure. |
2641 | */ | 3059 | */ |
2642 | 3060 | ||
2643 | static int s2io_close(struct net_device *dev) | 3061 | int s2io_close(struct net_device *dev) |
2644 | { | 3062 | { |
2645 | nic_t *sp = dev->priv; | 3063 | nic_t *sp = dev->priv; |
2646 | |||
2647 | flush_scheduled_work(); | 3064 | flush_scheduled_work(); |
2648 | netif_stop_queue(dev); | 3065 | netif_stop_queue(dev); |
2649 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3066 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
2650 | s2io_card_down(sp); | 3067 | s2io_card_down(sp); |
2651 | 3068 | ||
2652 | free_irq(dev->irq, dev); | 3069 | free_irq(sp->pdev->irq, dev); |
2653 | sp->device_close_flag = TRUE; /* Device is shut down. */ | 3070 | sp->device_close_flag = TRUE; /* Device is shut down. */ |
2654 | return 0; | 3071 | return 0; |
2655 | } | 3072 | } |
@@ -2667,7 +3084,7 @@ static int s2io_close(struct net_device *dev) | |||
2667 | * 0 on success & 1 on failure. | 3084 | * 0 on success & 1 on failure. |
2668 | */ | 3085 | */ |
2669 | 3086 | ||
2670 | static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | 3087 | int s2io_xmit(struct sk_buff *skb, struct net_device *dev) |
2671 | { | 3088 | { |
2672 | nic_t *sp = dev->priv; | 3089 | nic_t *sp = dev->priv; |
2673 | u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; | 3090 | u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; |
@@ -2678,29 +3095,39 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2678 | #ifdef NETIF_F_TSO | 3095 | #ifdef NETIF_F_TSO |
2679 | int mss; | 3096 | int mss; |
2680 | #endif | 3097 | #endif |
3098 | u16 vlan_tag = 0; | ||
3099 | int vlan_priority = 0; | ||
2681 | mac_info_t *mac_control; | 3100 | mac_info_t *mac_control; |
2682 | struct config_param *config; | 3101 | struct config_param *config; |
2683 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
2684 | 3102 | ||
2685 | mac_control = &sp->mac_control; | 3103 | mac_control = &sp->mac_control; |
2686 | config = &sp->config; | 3104 | config = &sp->config; |
2687 | 3105 | ||
2688 | DBG_PRINT(TX_DBG, "%s: In S2IO Tx routine\n", dev->name); | 3106 | DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name); |
2689 | spin_lock_irqsave(&sp->tx_lock, flags); | 3107 | spin_lock_irqsave(&sp->tx_lock, flags); |
2690 | |||
2691 | if (atomic_read(&sp->card_state) == CARD_DOWN) { | 3108 | if (atomic_read(&sp->card_state) == CARD_DOWN) { |
2692 | DBG_PRINT(ERR_DBG, "%s: Card going down for reset\n", | 3109 | DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", |
2693 | dev->name); | 3110 | dev->name); |
2694 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 3111 | spin_unlock_irqrestore(&sp->tx_lock, flags); |
2695 | return 1; | 3112 | dev_kfree_skb(skb); |
3113 | return 0; | ||
2696 | } | 3114 | } |
2697 | 3115 | ||
2698 | queue = 0; | 3116 | queue = 0; |
2699 | put_off = (u16) mac_control->tx_curr_put_info[queue].offset; | ||
2700 | get_off = (u16) mac_control->tx_curr_get_info[queue].offset; | ||
2701 | txdp = (TxD_t *) sp->list_info[queue][put_off].list_virt_addr; | ||
2702 | 3117 | ||
2703 | queue_len = mac_control->tx_curr_put_info[queue].fifo_len + 1; | 3118 | /* Get Fifo number to Transmit based on vlan priority */ |
3119 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | ||
3120 | vlan_tag = vlan_tx_tag_get(skb); | ||
3121 | vlan_priority = vlan_tag >> 13; | ||
3122 | queue = config->fifo_mapping[vlan_priority]; | ||
3123 | } | ||
3124 | |||
3125 | put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset; | ||
3126 | get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset; | ||
3127 | txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off]. | ||
3128 | list_virt_addr; | ||
3129 | |||
3130 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | ||
2704 | /* Avoid "put" pointer going beyond "get" pointer */ | 3131 | /* Avoid "put" pointer going beyond "get" pointer */ |
2705 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { | 3132 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { |
2706 | DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n"); | 3133 | DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n"); |
@@ -2709,6 +3136,15 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2709 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 3136 | spin_unlock_irqrestore(&sp->tx_lock, flags); |
2710 | return 0; | 3137 | return 0; |
2711 | } | 3138 | } |
3139 | |||
3140 | /* A buffer with no data will be dropped */ | ||
3141 | if (!skb->len) { | ||
3142 | DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); | ||
3143 | dev_kfree_skb(skb); | ||
3144 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
3145 | return 0; | ||
3146 | } | ||
3147 | |||
2712 | #ifdef NETIF_F_TSO | 3148 | #ifdef NETIF_F_TSO |
2713 | mss = skb_shinfo(skb)->tso_size; | 3149 | mss = skb_shinfo(skb)->tso_size; |
2714 | if (mss) { | 3150 | if (mss) { |
@@ -2720,9 +3156,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2720 | frg_cnt = skb_shinfo(skb)->nr_frags; | 3156 | frg_cnt = skb_shinfo(skb)->nr_frags; |
2721 | frg_len = skb->len - skb->data_len; | 3157 | frg_len = skb->len - skb->data_len; |
2722 | 3158 | ||
2723 | txdp->Host_Control = (unsigned long) skb; | ||
2724 | txdp->Buffer_Pointer = pci_map_single | 3159 | txdp->Buffer_Pointer = pci_map_single |
2725 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 3160 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
3161 | txdp->Host_Control = (unsigned long) skb; | ||
2726 | if (skb->ip_summed == CHECKSUM_HW) { | 3162 | if (skb->ip_summed == CHECKSUM_HW) { |
2727 | txdp->Control_2 |= | 3163 | txdp->Control_2 |= |
2728 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | | 3164 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | |
@@ -2731,6 +3167,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2731 | 3167 | ||
2732 | txdp->Control_2 |= config->tx_intr_type; | 3168 | txdp->Control_2 |= config->tx_intr_type; |
2733 | 3169 | ||
3170 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | ||
3171 | txdp->Control_2 |= TXD_VLAN_ENABLE; | ||
3172 | txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag); | ||
3173 | } | ||
3174 | |||
2734 | txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | | 3175 | txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | |
2735 | TXD_GATHER_CODE_FIRST); | 3176 | TXD_GATHER_CODE_FIRST); |
2736 | txdp->Control_1 |= TXD_LIST_OWN_XENA; | 3177 | txdp->Control_1 |= TXD_LIST_OWN_XENA; |
@@ -2738,6 +3179,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2738 | /* For fragmented SKB. */ | 3179 | /* For fragmented SKB. */ |
2739 | for (i = 0; i < frg_cnt; i++) { | 3180 | for (i = 0; i < frg_cnt; i++) { |
2740 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 3181 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
3182 | /* A '0' length fragment will be ignored */ | ||
3183 | if (!frag->size) | ||
3184 | continue; | ||
2741 | txdp++; | 3185 | txdp++; |
2742 | txdp->Buffer_Pointer = (u64) pci_map_page | 3186 | txdp->Buffer_Pointer = (u64) pci_map_page |
2743 | (sp->pdev, frag->page, frag->page_offset, | 3187 | (sp->pdev, frag->page, frag->page_offset, |
@@ -2747,23 +3191,23 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2747 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; | 3191 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; |
2748 | 3192 | ||
2749 | tx_fifo = mac_control->tx_FIFO_start[queue]; | 3193 | tx_fifo = mac_control->tx_FIFO_start[queue]; |
2750 | val64 = sp->list_info[queue][put_off].list_phy_addr; | 3194 | val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr; |
2751 | writeq(val64, &tx_fifo->TxDL_Pointer); | 3195 | writeq(val64, &tx_fifo->TxDL_Pointer); |
2752 | 3196 | ||
2753 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 3197 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
2754 | TX_FIFO_LAST_LIST); | 3198 | TX_FIFO_LAST_LIST); |
3199 | |||
2755 | #ifdef NETIF_F_TSO | 3200 | #ifdef NETIF_F_TSO |
2756 | if (mss) | 3201 | if (mss) |
2757 | val64 |= TX_FIFO_SPECIAL_FUNC; | 3202 | val64 |= TX_FIFO_SPECIAL_FUNC; |
2758 | #endif | 3203 | #endif |
2759 | writeq(val64, &tx_fifo->List_Control); | 3204 | writeq(val64, &tx_fifo->List_Control); |
2760 | 3205 | ||
2761 | /* Perform a PCI read to flush previous writes */ | 3206 | mmiowb(); |
2762 | val64 = readq(&bar0->general_int_status); | ||
2763 | 3207 | ||
2764 | put_off++; | 3208 | put_off++; |
2765 | put_off %= mac_control->tx_curr_put_info[queue].fifo_len + 1; | 3209 | put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; |
2766 | mac_control->tx_curr_put_info[queue].offset = put_off; | 3210 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; |
2767 | 3211 | ||
2768 | /* Avoid "put" pointer going beyond "get" pointer */ | 3212 | /* Avoid "put" pointer going beyond "get" pointer */ |
2769 | if (((put_off + 1) % queue_len) == get_off) { | 3213 | if (((put_off + 1) % queue_len) == get_off) { |
@@ -2779,18 +3223,74 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2779 | return 0; | 3223 | return 0; |
2780 | } | 3224 | } |
2781 | 3225 | ||
3226 | static void | ||
3227 | s2io_alarm_handle(unsigned long data) | ||
3228 | { | ||
3229 | nic_t *sp = (nic_t *)data; | ||
3230 | |||
3231 | alarm_intr_handler(sp); | ||
3232 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | ||
3233 | } | ||
3234 | |||
3235 | static void s2io_txpic_intr_handle(nic_t *sp) | ||
3236 | { | ||
3237 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; | ||
3238 | u64 val64; | ||
3239 | |||
3240 | val64 = readq(&bar0->pic_int_status); | ||
3241 | if (val64 & PIC_INT_GPIO) { | ||
3242 | val64 = readq(&bar0->gpio_int_reg); | ||
3243 | if ((val64 & GPIO_INT_REG_LINK_DOWN) && | ||
3244 | (val64 & GPIO_INT_REG_LINK_UP)) { | ||
3245 | val64 |= GPIO_INT_REG_LINK_DOWN; | ||
3246 | val64 |= GPIO_INT_REG_LINK_UP; | ||
3247 | writeq(val64, &bar0->gpio_int_reg); | ||
3248 | goto masking; | ||
3249 | } | ||
3250 | |||
3251 | if (((sp->last_link_state == LINK_UP) && | ||
3252 | (val64 & GPIO_INT_REG_LINK_DOWN)) || | ||
3253 | ((sp->last_link_state == LINK_DOWN) && | ||
3254 | (val64 & GPIO_INT_REG_LINK_UP))) { | ||
3255 | val64 = readq(&bar0->gpio_int_mask); | ||
3256 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
3257 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
3258 | writeq(val64, &bar0->gpio_int_mask); | ||
3259 | s2io_set_link((unsigned long)sp); | ||
3260 | } | ||
3261 | masking: | ||
3262 | if (sp->last_link_state == LINK_UP) { | ||
3263 | /*enable down interrupt */ | ||
3264 | val64 = readq(&bar0->gpio_int_mask); | ||
3265 | /* unmasks link down intr */ | ||
3266 | val64 &= ~GPIO_INT_MASK_LINK_DOWN; | ||
3267 | /* masks link up intr */ | ||
3268 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
3269 | writeq(val64, &bar0->gpio_int_mask); | ||
3270 | } else { | ||
3271 | /*enable UP Interrupt */ | ||
3272 | val64 = readq(&bar0->gpio_int_mask); | ||
3273 | /* unmasks link up interrupt */ | ||
3274 | val64 &= ~GPIO_INT_MASK_LINK_UP; | ||
3275 | /* masks link down interrupt */ | ||
3276 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
3277 | writeq(val64, &bar0->gpio_int_mask); | ||
3278 | } | ||
3279 | } | ||
3280 | } | ||
3281 | |||
2782 | /** | 3282 | /** |
2783 | * s2io_isr - ISR handler of the device . | 3283 | * s2io_isr - ISR handler of the device . |
2784 | * @irq: the irq of the device. | 3284 | * @irq: the irq of the device. |
2785 | * @dev_id: a void pointer to the dev structure of the NIC. | 3285 | * @dev_id: a void pointer to the dev structure of the NIC. |
2786 | * @pt_regs: pointer to the registers pushed on the stack. | 3286 | * @pt_regs: pointer to the registers pushed on the stack. |
2787 | * Description: This function is the ISR handler of the device. It | 3287 | * Description: This function is the ISR handler of the device. It |
2788 | * identifies the reason for the interrupt and calls the relevant | 3288 | * identifies the reason for the interrupt and calls the relevant |
2789 | * service routines. As a contongency measure, this ISR allocates the | 3289 | * service routines. As a contongency measure, this ISR allocates the |
2790 | * recv buffers, if their numbers are below the panic value which is | 3290 | * recv buffers, if their numbers are below the panic value which is |
2791 | * presently set to 25% of the original number of rcv buffers allocated. | 3291 | * presently set to 25% of the original number of rcv buffers allocated. |
2792 | * Return value: | 3292 | * Return value: |
2793 | * IRQ_HANDLED: will be returned if IRQ was handled by this routine | 3293 | * IRQ_HANDLED: will be returned if IRQ was handled by this routine |
2794 | * IRQ_NONE: will be returned if interrupt is not from our device | 3294 | * IRQ_NONE: will be returned if interrupt is not from our device |
2795 | */ | 3295 | */ |
2796 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | 3296 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) |
@@ -2798,40 +3298,31 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2798 | struct net_device *dev = (struct net_device *) dev_id; | 3298 | struct net_device *dev = (struct net_device *) dev_id; |
2799 | nic_t *sp = dev->priv; | 3299 | nic_t *sp = dev->priv; |
2800 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 3300 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2801 | #ifndef CONFIG_S2IO_NAPI | 3301 | int i; |
2802 | int i, ret; | 3302 | u64 reason = 0, val64; |
2803 | #endif | ||
2804 | u64 reason = 0; | ||
2805 | mac_info_t *mac_control; | 3303 | mac_info_t *mac_control; |
2806 | struct config_param *config; | 3304 | struct config_param *config; |
2807 | 3305 | ||
3306 | atomic_inc(&sp->isr_cnt); | ||
2808 | mac_control = &sp->mac_control; | 3307 | mac_control = &sp->mac_control; |
2809 | config = &sp->config; | 3308 | config = &sp->config; |
2810 | 3309 | ||
2811 | /* | 3310 | /* |
2812 | * Identify the cause for interrupt and call the appropriate | 3311 | * Identify the cause for interrupt and call the appropriate |
2813 | * interrupt handler. Causes for the interrupt could be; | 3312 | * interrupt handler. Causes for the interrupt could be; |
2814 | * 1. Rx of packet. | 3313 | * 1. Rx of packet. |
2815 | * 2. Tx complete. | 3314 | * 2. Tx complete. |
2816 | * 3. Link down. | 3315 | * 3. Link down. |
2817 | * 4. Error in any functional blocks of the NIC. | 3316 | * 4. Error in any functional blocks of the NIC. |
2818 | */ | 3317 | */ |
2819 | reason = readq(&bar0->general_int_status); | 3318 | reason = readq(&bar0->general_int_status); |
2820 | 3319 | ||
2821 | if (!reason) { | 3320 | if (!reason) { |
2822 | /* The interrupt was not raised by Xena. */ | 3321 | /* The interrupt was not raised by Xena. */ |
3322 | atomic_dec(&sp->isr_cnt); | ||
2823 | return IRQ_NONE; | 3323 | return IRQ_NONE; |
2824 | } | 3324 | } |
2825 | 3325 | ||
2826 | /* If Intr is because of Tx Traffic */ | ||
2827 | if (reason & GEN_INTR_TXTRAFFIC) { | ||
2828 | tx_intr_handler(sp); | ||
2829 | } | ||
2830 | |||
2831 | /* If Intr is because of an error */ | ||
2832 | if (reason & (GEN_ERROR_INTR)) | ||
2833 | alarm_intr_handler(sp); | ||
2834 | |||
2835 | #ifdef CONFIG_S2IO_NAPI | 3326 | #ifdef CONFIG_S2IO_NAPI |
2836 | if (reason & GEN_INTR_RXTRAFFIC) { | 3327 | if (reason & GEN_INTR_RXTRAFFIC) { |
2837 | if (netif_rx_schedule_prep(dev)) { | 3328 | if (netif_rx_schedule_prep(dev)) { |
@@ -2843,17 +3334,43 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2843 | #else | 3334 | #else |
2844 | /* If Intr is because of Rx Traffic */ | 3335 | /* If Intr is because of Rx Traffic */ |
2845 | if (reason & GEN_INTR_RXTRAFFIC) { | 3336 | if (reason & GEN_INTR_RXTRAFFIC) { |
2846 | rx_intr_handler(sp); | 3337 | /* |
3338 | * rx_traffic_int reg is an R1 register, writing all 1's | ||
3339 | * will ensure that the actual interrupt causing bit get's | ||
3340 | * cleared and hence a read can be avoided. | ||
3341 | */ | ||
3342 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
3343 | writeq(val64, &bar0->rx_traffic_int); | ||
3344 | for (i = 0; i < config->rx_ring_num; i++) { | ||
3345 | rx_intr_handler(&mac_control->rings[i]); | ||
3346 | } | ||
2847 | } | 3347 | } |
2848 | #endif | 3348 | #endif |
2849 | 3349 | ||
2850 | /* | 3350 | /* If Intr is because of Tx Traffic */ |
2851 | * If the Rx buffer count is below the panic threshold then | 3351 | if (reason & GEN_INTR_TXTRAFFIC) { |
2852 | * reallocate the buffers from the interrupt handler itself, | 3352 | /* |
3353 | * tx_traffic_int reg is an R1 register, writing all 1's | ||
3354 | * will ensure that the actual interrupt causing bit get's | ||
3355 | * cleared and hence a read can be avoided. | ||
3356 | */ | ||
3357 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
3358 | writeq(val64, &bar0->tx_traffic_int); | ||
3359 | |||
3360 | for (i = 0; i < config->tx_fifo_num; i++) | ||
3361 | tx_intr_handler(&mac_control->fifos[i]); | ||
3362 | } | ||
3363 | |||
3364 | if (reason & GEN_INTR_TXPIC) | ||
3365 | s2io_txpic_intr_handle(sp); | ||
3366 | /* | ||
3367 | * If the Rx buffer count is below the panic threshold then | ||
3368 | * reallocate the buffers from the interrupt handler itself, | ||
2853 | * else schedule a tasklet to reallocate the buffers. | 3369 | * else schedule a tasklet to reallocate the buffers. |
2854 | */ | 3370 | */ |
2855 | #ifndef CONFIG_S2IO_NAPI | 3371 | #ifndef CONFIG_S2IO_NAPI |
2856 | for (i = 0; i < config->rx_ring_num; i++) { | 3372 | for (i = 0; i < config->rx_ring_num; i++) { |
3373 | int ret; | ||
2857 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | 3374 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); |
2858 | int level = rx_buffer_level(sp, rxb_size, i); | 3375 | int level = rx_buffer_level(sp, rxb_size, i); |
2859 | 3376 | ||
@@ -2865,6 +3382,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2865 | dev->name); | 3382 | dev->name); |
2866 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | 3383 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); |
2867 | clear_bit(0, (&sp->tasklet_status)); | 3384 | clear_bit(0, (&sp->tasklet_status)); |
3385 | atomic_dec(&sp->isr_cnt); | ||
2868 | return IRQ_HANDLED; | 3386 | return IRQ_HANDLED; |
2869 | } | 3387 | } |
2870 | clear_bit(0, (&sp->tasklet_status)); | 3388 | clear_bit(0, (&sp->tasklet_status)); |
@@ -2874,33 +3392,69 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2874 | } | 3392 | } |
2875 | #endif | 3393 | #endif |
2876 | 3394 | ||
3395 | atomic_dec(&sp->isr_cnt); | ||
2877 | return IRQ_HANDLED; | 3396 | return IRQ_HANDLED; |
2878 | } | 3397 | } |
2879 | 3398 | ||
2880 | /** | 3399 | /** |
2881 | * s2io_get_stats - Updates the device statistics structure. | 3400 | * s2io_updt_stats - |
3401 | */ | ||
3402 | static void s2io_updt_stats(nic_t *sp) | ||
3403 | { | ||
3404 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
3405 | u64 val64; | ||
3406 | int cnt = 0; | ||
3407 | |||
3408 | if (atomic_read(&sp->card_state) == CARD_UP) { | ||
3409 | /* Apprx 30us on a 133 MHz bus */ | ||
3410 | val64 = SET_UPDT_CLICKS(10) | | ||
3411 | STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN; | ||
3412 | writeq(val64, &bar0->stat_cfg); | ||
3413 | do { | ||
3414 | udelay(100); | ||
3415 | val64 = readq(&bar0->stat_cfg); | ||
3416 | if (!(val64 & BIT(0))) | ||
3417 | break; | ||
3418 | cnt++; | ||
3419 | if (cnt == 5) | ||
3420 | break; /* Updt failed */ | ||
3421 | } while(1); | ||
3422 | } | ||
3423 | } | ||
3424 | |||
3425 | /** | ||
3426 | * s2io_get_stats - Updates the device statistics structure. | ||
2882 | * @dev : pointer to the device structure. | 3427 | * @dev : pointer to the device structure. |
2883 | * Description: | 3428 | * Description: |
2884 | * This function updates the device statistics structure in the s2io_nic | 3429 | * This function updates the device statistics structure in the s2io_nic |
2885 | * structure and returns a pointer to the same. | 3430 | * structure and returns a pointer to the same. |
2886 | * Return value: | 3431 | * Return value: |
2887 | * pointer to the updated net_device_stats structure. | 3432 | * pointer to the updated net_device_stats structure. |
2888 | */ | 3433 | */ |
2889 | 3434 | ||
2890 | static struct net_device_stats *s2io_get_stats(struct net_device *dev) | 3435 | struct net_device_stats *s2io_get_stats(struct net_device *dev) |
2891 | { | 3436 | { |
2892 | nic_t *sp = dev->priv; | 3437 | nic_t *sp = dev->priv; |
2893 | mac_info_t *mac_control; | 3438 | mac_info_t *mac_control; |
2894 | struct config_param *config; | 3439 | struct config_param *config; |
2895 | 3440 | ||
3441 | |||
2896 | mac_control = &sp->mac_control; | 3442 | mac_control = &sp->mac_control; |
2897 | config = &sp->config; | 3443 | config = &sp->config; |
2898 | 3444 | ||
2899 | sp->stats.tx_errors = mac_control->stats_info->tmac_any_err_frms; | 3445 | /* Configure Stats for immediate updt */ |
2900 | sp->stats.rx_errors = mac_control->stats_info->rmac_drop_frms; | 3446 | s2io_updt_stats(sp); |
2901 | sp->stats.multicast = mac_control->stats_info->rmac_vld_mcst_frms; | 3447 | |
3448 | sp->stats.tx_packets = | ||
3449 | le32_to_cpu(mac_control->stats_info->tmac_frms); | ||
3450 | sp->stats.tx_errors = | ||
3451 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); | ||
3452 | sp->stats.rx_errors = | ||
3453 | le32_to_cpu(mac_control->stats_info->rmac_drop_frms); | ||
3454 | sp->stats.multicast = | ||
3455 | le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); | ||
2902 | sp->stats.rx_length_errors = | 3456 | sp->stats.rx_length_errors = |
2903 | mac_control->stats_info->rmac_long_frms; | 3457 | le32_to_cpu(mac_control->stats_info->rmac_long_frms); |
2904 | 3458 | ||
2905 | return (&sp->stats); | 3459 | return (&sp->stats); |
2906 | } | 3460 | } |
@@ -2909,8 +3463,8 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev) | |||
2909 | * s2io_set_multicast - entry point for multicast address enable/disable. | 3463 | * s2io_set_multicast - entry point for multicast address enable/disable. |
2910 | * @dev : pointer to the device structure | 3464 | * @dev : pointer to the device structure |
2911 | * Description: | 3465 | * Description: |
2912 | * This function is a driver entry point which gets called by the kernel | 3466 | * This function is a driver entry point which gets called by the kernel |
2913 | * whenever multicast addresses must be enabled/disabled. This also gets | 3467 | * whenever multicast addresses must be enabled/disabled. This also gets |
2914 | * called to set/reset promiscuous mode. Depending on the deivce flag, we | 3468 | * called to set/reset promiscuous mode. Depending on the deivce flag, we |
2915 | * determine, if multicast address must be enabled or if promiscuous mode | 3469 | * determine, if multicast address must be enabled or if promiscuous mode |
2916 | * is to be disabled etc. | 3470 | * is to be disabled etc. |
@@ -2948,6 +3502,8 @@ static void s2io_set_multicast(struct net_device *dev) | |||
2948 | /* Disable all Multicast addresses */ | 3502 | /* Disable all Multicast addresses */ |
2949 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), | 3503 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), |
2950 | &bar0->rmac_addr_data0_mem); | 3504 | &bar0->rmac_addr_data0_mem); |
3505 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0x0), | ||
3506 | &bar0->rmac_addr_data1_mem); | ||
2951 | val64 = RMAC_ADDR_CMD_MEM_WE | | 3507 | val64 = RMAC_ADDR_CMD_MEM_WE | |
2952 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 3508 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
2953 | RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); | 3509 | RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); |
@@ -3010,7 +3566,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
3010 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), | 3566 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), |
3011 | &bar0->rmac_addr_data0_mem); | 3567 | &bar0->rmac_addr_data0_mem); |
3012 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), | 3568 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), |
3013 | &bar0->rmac_addr_data1_mem); | 3569 | &bar0->rmac_addr_data1_mem); |
3014 | val64 = RMAC_ADDR_CMD_MEM_WE | | 3570 | val64 = RMAC_ADDR_CMD_MEM_WE | |
3015 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 3571 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
3016 | RMAC_ADDR_CMD_MEM_OFFSET | 3572 | RMAC_ADDR_CMD_MEM_OFFSET |
@@ -3039,8 +3595,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
3039 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr), | 3595 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr), |
3040 | &bar0->rmac_addr_data0_mem); | 3596 | &bar0->rmac_addr_data0_mem); |
3041 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), | 3597 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), |
3042 | &bar0->rmac_addr_data1_mem); | 3598 | &bar0->rmac_addr_data1_mem); |
3043 | |||
3044 | val64 = RMAC_ADDR_CMD_MEM_WE | | 3599 | val64 = RMAC_ADDR_CMD_MEM_WE | |
3045 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 3600 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
3046 | RMAC_ADDR_CMD_MEM_OFFSET | 3601 | RMAC_ADDR_CMD_MEM_OFFSET |
@@ -3059,12 +3614,12 @@ static void s2io_set_multicast(struct net_device *dev) | |||
3059 | } | 3614 | } |
3060 | 3615 | ||
3061 | /** | 3616 | /** |
3062 | * s2io_set_mac_addr - Programs the Xframe mac address | 3617 | * s2io_set_mac_addr - Programs the Xframe mac address |
3063 | * @dev : pointer to the device structure. | 3618 | * @dev : pointer to the device structure. |
3064 | * @addr: a uchar pointer to the new mac address which is to be set. | 3619 | * @addr: a uchar pointer to the new mac address which is to be set. |
3065 | * Description : This procedure will program the Xframe to receive | 3620 | * Description : This procedure will program the Xframe to receive |
3066 | * frames with new Mac Address | 3621 | * frames with new Mac Address |
3067 | * Return value: SUCCESS on success and an appropriate (-)ve integer | 3622 | * Return value: SUCCESS on success and an appropriate (-)ve integer |
3068 | * as defined in errno.h file on failure. | 3623 | * as defined in errno.h file on failure. |
3069 | */ | 3624 | */ |
3070 | 3625 | ||
@@ -3075,10 +3630,10 @@ int s2io_set_mac_addr(struct net_device *dev, u8 * addr) | |||
3075 | register u64 val64, mac_addr = 0; | 3630 | register u64 val64, mac_addr = 0; |
3076 | int i; | 3631 | int i; |
3077 | 3632 | ||
3078 | /* | 3633 | /* |
3079 | * Set the new MAC address as the new unicast filter and reflect this | 3634 | * Set the new MAC address as the new unicast filter and reflect this |
3080 | * change on the device address registered with the OS. It will be | 3635 | * change on the device address registered with the OS. It will be |
3081 | * at offset 0. | 3636 | * at offset 0. |
3082 | */ | 3637 | */ |
3083 | for (i = 0; i < ETH_ALEN; i++) { | 3638 | for (i = 0; i < ETH_ALEN; i++) { |
3084 | mac_addr <<= 8; | 3639 | mac_addr <<= 8; |
@@ -3102,12 +3657,12 @@ int s2io_set_mac_addr(struct net_device *dev, u8 * addr) | |||
3102 | } | 3657 | } |
3103 | 3658 | ||
3104 | /** | 3659 | /** |
3105 | * s2io_ethtool_sset - Sets different link parameters. | 3660 | * s2io_ethtool_sset - Sets different link parameters. |
3106 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. | 3661 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. |
3107 | * @info: pointer to the structure with parameters given by ethtool to set | 3662 | * @info: pointer to the structure with parameters given by ethtool to set |
3108 | * link information. | 3663 | * link information. |
3109 | * Description: | 3664 | * Description: |
3110 | * The function sets different link parameters provided by the user onto | 3665 | * The function sets different link parameters provided by the user onto |
3111 | * the NIC. | 3666 | * the NIC. |
3112 | * Return value: | 3667 | * Return value: |
3113 | * 0 on success. | 3668 | * 0 on success. |
@@ -3129,7 +3684,7 @@ static int s2io_ethtool_sset(struct net_device *dev, | |||
3129 | } | 3684 | } |
3130 | 3685 | ||
3131 | /** | 3686 | /** |
3132 | * s2io_ethtol_gset - Return link specific information. | 3687 | * s2io_ethtol_gset - Return link specific information. |
3133 | * @sp : private member of the device structure, pointer to the | 3688 | * @sp : private member of the device structure, pointer to the |
3134 | * s2io_nic structure. | 3689 | * s2io_nic structure. |
3135 | * @info : pointer to the structure with parameters given by ethtool | 3690 | * @info : pointer to the structure with parameters given by ethtool |
@@ -3161,8 +3716,8 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) | |||
3161 | } | 3716 | } |
3162 | 3717 | ||
3163 | /** | 3718 | /** |
3164 | * s2io_ethtool_gdrvinfo - Returns driver specific information. | 3719 | * s2io_ethtool_gdrvinfo - Returns driver specific information. |
3165 | * @sp : private member of the device structure, which is a pointer to the | 3720 | * @sp : private member of the device structure, which is a pointer to the |
3166 | * s2io_nic structure. | 3721 | * s2io_nic structure. |
3167 | * @info : pointer to the structure with parameters given by ethtool to | 3722 | * @info : pointer to the structure with parameters given by ethtool to |
3168 | * return driver information. | 3723 | * return driver information. |
@@ -3190,9 +3745,9 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev, | |||
3190 | 3745 | ||
3191 | /** | 3746 | /** |
3192 | * s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer. | 3747 | * s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer. |
3193 | * @sp: private member of the device structure, which is a pointer to the | 3748 | * @sp: private member of the device structure, which is a pointer to the |
3194 | * s2io_nic structure. | 3749 | * s2io_nic structure. |
3195 | * @regs : pointer to the structure with parameters given by ethtool for | 3750 | * @regs : pointer to the structure with parameters given by ethtool for |
3196 | * dumping the registers. | 3751 | * dumping the registers. |
3197 | * @reg_space: The input argumnet into which all the registers are dumped. | 3752 | * @reg_space: The input argumnet into which all the registers are dumped. |
3198 | * Description: | 3753 | * Description: |
@@ -3221,11 +3776,11 @@ static void s2io_ethtool_gregs(struct net_device *dev, | |||
3221 | 3776 | ||
3222 | /** | 3777 | /** |
3223 | * s2io_phy_id - timer function that alternates adapter LED. | 3778 | * s2io_phy_id - timer function that alternates adapter LED. |
3224 | * @data : address of the private member of the device structure, which | 3779 | * @data : address of the private member of the device structure, which |
3225 | * is a pointer to the s2io_nic structure, provided as an u32. | 3780 | * is a pointer to the s2io_nic structure, provided as an u32. |
3226 | * Description: This is actually the timer function that alternates the | 3781 | * Description: This is actually the timer function that alternates the |
3227 | * adapter LED bit of the adapter control bit to set/reset every time on | 3782 | * adapter LED bit of the adapter control bit to set/reset every time on |
3228 | * invocation. The timer is set for 1/2 a second, hence tha NIC blinks | 3783 | * invocation. The timer is set for 1/2 a second, hence tha NIC blinks |
3229 | * once every second. | 3784 | * once every second. |
3230 | */ | 3785 | */ |
3231 | static void s2io_phy_id(unsigned long data) | 3786 | static void s2io_phy_id(unsigned long data) |
@@ -3236,7 +3791,8 @@ static void s2io_phy_id(unsigned long data) | |||
3236 | u16 subid; | 3791 | u16 subid; |
3237 | 3792 | ||
3238 | subid = sp->pdev->subsystem_device; | 3793 | subid = sp->pdev->subsystem_device; |
3239 | if ((subid & 0xFF) >= 0x07) { | 3794 | if ((sp->device_type == XFRAME_II_DEVICE) || |
3795 | ((subid & 0xFF) >= 0x07)) { | ||
3240 | val64 = readq(&bar0->gpio_control); | 3796 | val64 = readq(&bar0->gpio_control); |
3241 | val64 ^= GPIO_CTRL_GPIO_0; | 3797 | val64 ^= GPIO_CTRL_GPIO_0; |
3242 | writeq(val64, &bar0->gpio_control); | 3798 | writeq(val64, &bar0->gpio_control); |
@@ -3253,12 +3809,12 @@ static void s2io_phy_id(unsigned long data) | |||
3253 | * s2io_ethtool_idnic - To physically identify the nic on the system. | 3809 | * s2io_ethtool_idnic - To physically identify the nic on the system. |
3254 | * @sp : private member of the device structure, which is a pointer to the | 3810 | * @sp : private member of the device structure, which is a pointer to the |
3255 | * s2io_nic structure. | 3811 | * s2io_nic structure. |
3256 | * @id : pointer to the structure with identification parameters given by | 3812 | * @id : pointer to the structure with identification parameters given by |
3257 | * ethtool. | 3813 | * ethtool. |
3258 | * Description: Used to physically identify the NIC on the system. | 3814 | * Description: Used to physically identify the NIC on the system. |
3259 | * The Link LED will blink for a time specified by the user for | 3815 | * The Link LED will blink for a time specified by the user for |
3260 | * identification. | 3816 | * identification. |
3261 | * NOTE: The Link has to be Up to be able to blink the LED. Hence | 3817 | * NOTE: The Link has to be Up to be able to blink the LED. Hence |
3262 | * identification is possible only if it's link is up. | 3818 | * identification is possible only if it's link is up. |
3263 | * Return value: | 3819 | * Return value: |
3264 | * int , returns 0 on success | 3820 | * int , returns 0 on success |
@@ -3273,7 +3829,8 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) | |||
3273 | 3829 | ||
3274 | subid = sp->pdev->subsystem_device; | 3830 | subid = sp->pdev->subsystem_device; |
3275 | last_gpio_ctrl_val = readq(&bar0->gpio_control); | 3831 | last_gpio_ctrl_val = readq(&bar0->gpio_control); |
3276 | if ((subid & 0xFF) < 0x07) { | 3832 | if ((sp->device_type == XFRAME_I_DEVICE) && |
3833 | ((subid & 0xFF) < 0x07)) { | ||
3277 | val64 = readq(&bar0->adapter_control); | 3834 | val64 = readq(&bar0->adapter_control); |
3278 | if (!(val64 & ADAPTER_CNTL_EN)) { | 3835 | if (!(val64 & ADAPTER_CNTL_EN)) { |
3279 | printk(KERN_ERR | 3836 | printk(KERN_ERR |
@@ -3288,12 +3845,12 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) | |||
3288 | } | 3845 | } |
3289 | mod_timer(&sp->id_timer, jiffies); | 3846 | mod_timer(&sp->id_timer, jiffies); |
3290 | if (data) | 3847 | if (data) |
3291 | msleep(data * 1000); | 3848 | msleep_interruptible(data * HZ); |
3292 | else | 3849 | else |
3293 | msleep(0xFFFFFFFF); | 3850 | msleep_interruptible(MAX_FLICKER_TIME); |
3294 | del_timer_sync(&sp->id_timer); | 3851 | del_timer_sync(&sp->id_timer); |
3295 | 3852 | ||
3296 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { | 3853 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) { |
3297 | writeq(last_gpio_ctrl_val, &bar0->gpio_control); | 3854 | writeq(last_gpio_ctrl_val, &bar0->gpio_control); |
3298 | last_gpio_ctrl_val = readq(&bar0->gpio_control); | 3855 | last_gpio_ctrl_val = readq(&bar0->gpio_control); |
3299 | } | 3856 | } |
@@ -3303,7 +3860,8 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) | |||
3303 | 3860 | ||
3304 | /** | 3861 | /** |
3305 | * s2io_ethtool_getpause_data -Pause frame frame generation and reception. | 3862 | * s2io_ethtool_getpause_data -Pause frame frame generation and reception. |
3306 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. | 3863 | * @sp : private member of the device structure, which is a pointer to the |
3864 | * s2io_nic structure. | ||
3307 | * @ep : pointer to the structure with pause parameters given by ethtool. | 3865 | * @ep : pointer to the structure with pause parameters given by ethtool. |
3308 | * Description: | 3866 | * Description: |
3309 | * Returns the Pause frame generation and reception capability of the NIC. | 3867 | * Returns the Pause frame generation and reception capability of the NIC. |
@@ -3327,7 +3885,7 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, | |||
3327 | 3885 | ||
3328 | /** | 3886 | /** |
3329 | * s2io_ethtool_setpause_data - set/reset pause frame generation. | 3887 | * s2io_ethtool_setpause_data - set/reset pause frame generation. |
3330 | * @sp : private member of the device structure, which is a pointer to the | 3888 | * @sp : private member of the device structure, which is a pointer to the |
3331 | * s2io_nic structure. | 3889 | * s2io_nic structure. |
3332 | * @ep : pointer to the structure with pause parameters given by ethtool. | 3890 | * @ep : pointer to the structure with pause parameters given by ethtool. |
3333 | * Description: | 3891 | * Description: |
@@ -3338,7 +3896,7 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, | |||
3338 | */ | 3896 | */ |
3339 | 3897 | ||
3340 | static int s2io_ethtool_setpause_data(struct net_device *dev, | 3898 | static int s2io_ethtool_setpause_data(struct net_device *dev, |
3341 | struct ethtool_pauseparam *ep) | 3899 | struct ethtool_pauseparam *ep) |
3342 | { | 3900 | { |
3343 | u64 val64; | 3901 | u64 val64; |
3344 | nic_t *sp = dev->priv; | 3902 | nic_t *sp = dev->priv; |
@@ -3359,13 +3917,13 @@ static int s2io_ethtool_setpause_data(struct net_device *dev, | |||
3359 | 3917 | ||
3360 | /** | 3918 | /** |
3361 | * read_eeprom - reads 4 bytes of data from user given offset. | 3919 | * read_eeprom - reads 4 bytes of data from user given offset. |
3362 | * @sp : private member of the device structure, which is a pointer to the | 3920 | * @sp : private member of the device structure, which is a pointer to the |
3363 | * s2io_nic structure. | 3921 | * s2io_nic structure. |
3364 | * @off : offset at which the data must be written | 3922 | * @off : offset at which the data must be written |
3365 | * @data : Its an output parameter where the data read at the given | 3923 | * @data : Its an output parameter where the data read at the given |
3366 | * offset is stored. | 3924 | * offset is stored. |
3367 | * Description: | 3925 | * Description: |
3368 | * Will read 4 bytes of data from the user given offset and return the | 3926 | * Will read 4 bytes of data from the user given offset and return the |
3369 | * read data. | 3927 | * read data. |
3370 | * NOTE: Will allow to read only part of the EEPROM visible through the | 3928 | * NOTE: Will allow to read only part of the EEPROM visible through the |
3371 | * I2C bus. | 3929 | * I2C bus. |
@@ -3406,7 +3964,7 @@ static int read_eeprom(nic_t * sp, int off, u32 * data) | |||
3406 | * s2io_nic structure. | 3964 | * s2io_nic structure. |
3407 | * @off : offset at which the data must be written | 3965 | * @off : offset at which the data must be written |
3408 | * @data : The data that is to be written | 3966 | * @data : The data that is to be written |
3409 | * @cnt : Number of bytes of the data that are actually to be written into | 3967 | * @cnt : Number of bytes of the data that are actually to be written into |
3410 | * the Eeprom. (max of 3) | 3968 | * the Eeprom. (max of 3) |
3411 | * Description: | 3969 | * Description: |
3412 | * Actually writes the relevant part of the data value into the Eeprom | 3970 | * Actually writes the relevant part of the data value into the Eeprom |
@@ -3443,7 +4001,7 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) | |||
3443 | /** | 4001 | /** |
3444 | * s2io_ethtool_geeprom - reads the value stored in the Eeprom. | 4002 | * s2io_ethtool_geeprom - reads the value stored in the Eeprom. |
3445 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. | 4003 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. |
3446 | * @eeprom : pointer to the user level structure provided by ethtool, | 4004 | * @eeprom : pointer to the user level structure provided by ethtool, |
3447 | * containing all relevant information. | 4005 | * containing all relevant information. |
3448 | * @data_buf : user defined value to be written into Eeprom. | 4006 | * @data_buf : user defined value to be written into Eeprom. |
3449 | * Description: Reads the values stored in the Eeprom at given offset | 4007 | * Description: Reads the values stored in the Eeprom at given offset |
@@ -3454,7 +4012,7 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) | |||
3454 | */ | 4012 | */ |
3455 | 4013 | ||
3456 | static int s2io_ethtool_geeprom(struct net_device *dev, | 4014 | static int s2io_ethtool_geeprom(struct net_device *dev, |
3457 | struct ethtool_eeprom *eeprom, u8 * data_buf) | 4015 | struct ethtool_eeprom *eeprom, u8 * data_buf) |
3458 | { | 4016 | { |
3459 | u32 data, i, valid; | 4017 | u32 data, i, valid; |
3460 | nic_t *sp = dev->priv; | 4018 | nic_t *sp = dev->priv; |
@@ -3479,7 +4037,7 @@ static int s2io_ethtool_geeprom(struct net_device *dev, | |||
3479 | * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom | 4037 | * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom |
3480 | * @sp : private member of the device structure, which is a pointer to the | 4038 | * @sp : private member of the device structure, which is a pointer to the |
3481 | * s2io_nic structure. | 4039 | * s2io_nic structure. |
3482 | * @eeprom : pointer to the user level structure provided by ethtool, | 4040 | * @eeprom : pointer to the user level structure provided by ethtool, |
3483 | * containing all relevant information. | 4041 | * containing all relevant information. |
3484 | * @data_buf ; user defined value to be written into Eeprom. | 4042 | * @data_buf ; user defined value to be written into Eeprom. |
3485 | * Description: | 4043 | * Description: |
@@ -3527,8 +4085,8 @@ static int s2io_ethtool_seeprom(struct net_device *dev, | |||
3527 | } | 4085 | } |
3528 | 4086 | ||
3529 | /** | 4087 | /** |
3530 | * s2io_register_test - reads and writes into all clock domains. | 4088 | * s2io_register_test - reads and writes into all clock domains. |
3531 | * @sp : private member of the device structure, which is a pointer to the | 4089 | * @sp : private member of the device structure, which is a pointer to the |
3532 | * s2io_nic structure. | 4090 | * s2io_nic structure. |
3533 | * @data : variable that returns the result of each of the test conducted b | 4091 | * @data : variable that returns the result of each of the test conducted b |
3534 | * by the driver. | 4092 | * by the driver. |
@@ -3545,8 +4103,8 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
3545 | u64 val64 = 0; | 4103 | u64 val64 = 0; |
3546 | int fail = 0; | 4104 | int fail = 0; |
3547 | 4105 | ||
3548 | val64 = readq(&bar0->pcc_enable); | 4106 | val64 = readq(&bar0->pif_rd_swapper_fb); |
3549 | if (val64 != 0xff00000000000000ULL) { | 4107 | if (val64 != 0x123456789abcdefULL) { |
3550 | fail = 1; | 4108 | fail = 1; |
3551 | DBG_PRINT(INFO_DBG, "Read Test level 1 fails\n"); | 4109 | DBG_PRINT(INFO_DBG, "Read Test level 1 fails\n"); |
3552 | } | 4110 | } |
@@ -3590,13 +4148,13 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
3590 | } | 4148 | } |
3591 | 4149 | ||
3592 | /** | 4150 | /** |
3593 | * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. | 4151 | * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. |
3594 | * @sp : private member of the device structure, which is a pointer to the | 4152 | * @sp : private member of the device structure, which is a pointer to the |
3595 | * s2io_nic structure. | 4153 | * s2io_nic structure. |
3596 | * @data:variable that returns the result of each of the test conducted by | 4154 | * @data:variable that returns the result of each of the test conducted by |
3597 | * the driver. | 4155 | * the driver. |
3598 | * Description: | 4156 | * Description: |
3599 | * Verify that EEPROM in the xena can be programmed using I2C_CONTROL | 4157 | * Verify that EEPROM in the xena can be programmed using I2C_CONTROL |
3600 | * register. | 4158 | * register. |
3601 | * Return value: | 4159 | * Return value: |
3602 | * 0 on success. | 4160 | * 0 on success. |
@@ -3661,14 +4219,14 @@ static int s2io_eeprom_test(nic_t * sp, uint64_t * data) | |||
3661 | 4219 | ||
3662 | /** | 4220 | /** |
3663 | * s2io_bist_test - invokes the MemBist test of the card . | 4221 | * s2io_bist_test - invokes the MemBist test of the card . |
3664 | * @sp : private member of the device structure, which is a pointer to the | 4222 | * @sp : private member of the device structure, which is a pointer to the |
3665 | * s2io_nic structure. | 4223 | * s2io_nic structure. |
3666 | * @data:variable that returns the result of each of the test conducted by | 4224 | * @data:variable that returns the result of each of the test conducted by |
3667 | * the driver. | 4225 | * the driver. |
3668 | * Description: | 4226 | * Description: |
3669 | * This invokes the MemBist test of the card. We give around | 4227 | * This invokes the MemBist test of the card. We give around |
3670 | * 2 secs time for the Test to complete. If it's still not complete | 4228 | * 2 secs time for the Test to complete. If it's still not complete |
3671 | * within this peiod, we consider that the test failed. | 4229 | * within this peiod, we consider that the test failed. |
3672 | * Return value: | 4230 | * Return value: |
3673 | * 0 on success and -1 on failure. | 4231 | * 0 on success and -1 on failure. |
3674 | */ | 4232 | */ |
@@ -3697,13 +4255,13 @@ static int s2io_bist_test(nic_t * sp, uint64_t * data) | |||
3697 | } | 4255 | } |
3698 | 4256 | ||
3699 | /** | 4257 | /** |
3700 | * s2io-link_test - verifies the link state of the nic | 4258 | * s2io-link_test - verifies the link state of the nic |
3701 | * @sp ; private member of the device structure, which is a pointer to the | 4259 | * @sp ; private member of the device structure, which is a pointer to the |
3702 | * s2io_nic structure. | 4260 | * s2io_nic structure. |
3703 | * @data: variable that returns the result of each of the test conducted by | 4261 | * @data: variable that returns the result of each of the test conducted by |
3704 | * the driver. | 4262 | * the driver. |
3705 | * Description: | 4263 | * Description: |
3706 | * The function verifies the link state of the NIC and updates the input | 4264 | * The function verifies the link state of the NIC and updates the input |
3707 | * argument 'data' appropriately. | 4265 | * argument 'data' appropriately. |
3708 | * Return value: | 4266 | * Return value: |
3709 | * 0 on success. | 4267 | * 0 on success. |
@@ -3722,13 +4280,13 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) | |||
3722 | } | 4280 | } |
3723 | 4281 | ||
3724 | /** | 4282 | /** |
3725 | * s2io_rldram_test - offline test for access to the RldRam chip on the NIC | 4283 | * s2io_rldram_test - offline test for access to the RldRam chip on the NIC |
3726 | * @sp - private member of the device structure, which is a pointer to the | 4284 | * @sp - private member of the device structure, which is a pointer to the |
3727 | * s2io_nic structure. | 4285 | * s2io_nic structure. |
3728 | * @data - variable that returns the result of each of the test | 4286 | * @data - variable that returns the result of each of the test |
3729 | * conducted by the driver. | 4287 | * conducted by the driver. |
3730 | * Description: | 4288 | * Description: |
3731 | * This is one of the offline test that tests the read and write | 4289 | * This is one of the offline test that tests the read and write |
3732 | * access to the RldRam chip on the NIC. | 4290 | * access to the RldRam chip on the NIC. |
3733 | * Return value: | 4291 | * Return value: |
3734 | * 0 on success. | 4292 | * 0 on success. |
@@ -3833,7 +4391,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
3833 | * s2io_nic structure. | 4391 | * s2io_nic structure. |
3834 | * @ethtest : pointer to a ethtool command specific structure that will be | 4392 | * @ethtest : pointer to a ethtool command specific structure that will be |
3835 | * returned to the user. | 4393 | * returned to the user. |
3836 | * @data : variable that returns the result of each of the test | 4394 | * @data : variable that returns the result of each of the test |
3837 | * conducted by the driver. | 4395 | * conducted by the driver. |
3838 | * Description: | 4396 | * Description: |
3839 | * This function conducts 6 tests ( 4 offline and 2 online) to determine | 4397 | * This function conducts 6 tests ( 4 offline and 2 online) to determine |
@@ -3851,23 +4409,18 @@ static void s2io_ethtool_test(struct net_device *dev, | |||
3851 | 4409 | ||
3852 | if (ethtest->flags == ETH_TEST_FL_OFFLINE) { | 4410 | if (ethtest->flags == ETH_TEST_FL_OFFLINE) { |
3853 | /* Offline Tests. */ | 4411 | /* Offline Tests. */ |
3854 | if (orig_state) { | 4412 | if (orig_state) |
3855 | s2io_close(sp->dev); | 4413 | s2io_close(sp->dev); |
3856 | s2io_set_swapper(sp); | ||
3857 | } else | ||
3858 | s2io_set_swapper(sp); | ||
3859 | 4414 | ||
3860 | if (s2io_register_test(sp, &data[0])) | 4415 | if (s2io_register_test(sp, &data[0])) |
3861 | ethtest->flags |= ETH_TEST_FL_FAILED; | 4416 | ethtest->flags |= ETH_TEST_FL_FAILED; |
3862 | 4417 | ||
3863 | s2io_reset(sp); | 4418 | s2io_reset(sp); |
3864 | s2io_set_swapper(sp); | ||
3865 | 4419 | ||
3866 | if (s2io_rldram_test(sp, &data[3])) | 4420 | if (s2io_rldram_test(sp, &data[3])) |
3867 | ethtest->flags |= ETH_TEST_FL_FAILED; | 4421 | ethtest->flags |= ETH_TEST_FL_FAILED; |
3868 | 4422 | ||
3869 | s2io_reset(sp); | 4423 | s2io_reset(sp); |
3870 | s2io_set_swapper(sp); | ||
3871 | 4424 | ||
3872 | if (s2io_eeprom_test(sp, &data[1])) | 4425 | if (s2io_eeprom_test(sp, &data[1])) |
3873 | ethtest->flags |= ETH_TEST_FL_FAILED; | 4426 | ethtest->flags |= ETH_TEST_FL_FAILED; |
@@ -3910,61 +4463,111 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
3910 | nic_t *sp = dev->priv; | 4463 | nic_t *sp = dev->priv; |
3911 | StatInfo_t *stat_info = sp->mac_control.stats_info; | 4464 | StatInfo_t *stat_info = sp->mac_control.stats_info; |
3912 | 4465 | ||
3913 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_frms); | 4466 | s2io_updt_stats(sp); |
3914 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_data_octets); | 4467 | tmp_stats[i++] = |
4468 | (u64)le32_to_cpu(stat_info->tmac_frms_oflow) << 32 | | ||
4469 | le32_to_cpu(stat_info->tmac_frms); | ||
4470 | tmp_stats[i++] = | ||
4471 | (u64)le32_to_cpu(stat_info->tmac_data_octets_oflow) << 32 | | ||
4472 | le32_to_cpu(stat_info->tmac_data_octets); | ||
3915 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms); | 4473 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms); |
3916 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_mcst_frms); | 4474 | tmp_stats[i++] = |
3917 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_bcst_frms); | 4475 | (u64)le32_to_cpu(stat_info->tmac_mcst_frms_oflow) << 32 | |
4476 | le32_to_cpu(stat_info->tmac_mcst_frms); | ||
4477 | tmp_stats[i++] = | ||
4478 | (u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 | | ||
4479 | le32_to_cpu(stat_info->tmac_bcst_frms); | ||
3918 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); | 4480 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); |
3919 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_any_err_frms); | 4481 | tmp_stats[i++] = |
4482 | (u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 | | ||
4483 | le32_to_cpu(stat_info->tmac_any_err_frms); | ||
3920 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); | 4484 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); |
3921 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_vld_ip); | 4485 | tmp_stats[i++] = |
3922 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_drop_ip); | 4486 | (u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 | |
3923 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_icmp); | 4487 | le32_to_cpu(stat_info->tmac_vld_ip); |
3924 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_rst_tcp); | 4488 | tmp_stats[i++] = |
4489 | (u64)le32_to_cpu(stat_info->tmac_drop_ip_oflow) << 32 | | ||
4490 | le32_to_cpu(stat_info->tmac_drop_ip); | ||
4491 | tmp_stats[i++] = | ||
4492 | (u64)le32_to_cpu(stat_info->tmac_icmp_oflow) << 32 | | ||
4493 | le32_to_cpu(stat_info->tmac_icmp); | ||
4494 | tmp_stats[i++] = | ||
4495 | (u64)le32_to_cpu(stat_info->tmac_rst_tcp_oflow) << 32 | | ||
4496 | le32_to_cpu(stat_info->tmac_rst_tcp); | ||
3925 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_tcp); | 4497 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_tcp); |
3926 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_udp); | 4498 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->tmac_udp_oflow) << 32 | |
3927 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_frms); | 4499 | le32_to_cpu(stat_info->tmac_udp); |
3928 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_data_octets); | 4500 | tmp_stats[i++] = |
4501 | (u64)le32_to_cpu(stat_info->rmac_vld_frms_oflow) << 32 | | ||
4502 | le32_to_cpu(stat_info->rmac_vld_frms); | ||
4503 | tmp_stats[i++] = | ||
4504 | (u64)le32_to_cpu(stat_info->rmac_data_octets_oflow) << 32 | | ||
4505 | le32_to_cpu(stat_info->rmac_data_octets); | ||
3929 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_fcs_err_frms); | 4506 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_fcs_err_frms); |
3930 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_drop_frms); | 4507 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_drop_frms); |
3931 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_mcst_frms); | 4508 | tmp_stats[i++] = |
3932 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_bcst_frms); | 4509 | (u64)le32_to_cpu(stat_info->rmac_vld_mcst_frms_oflow) << 32 | |
4510 | le32_to_cpu(stat_info->rmac_vld_mcst_frms); | ||
4511 | tmp_stats[i++] = | ||
4512 | (u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 | | ||
4513 | le32_to_cpu(stat_info->rmac_vld_bcst_frms); | ||
3933 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); | 4514 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); |
3934 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); | 4515 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); |
3935 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); | 4516 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); |
3936 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_discarded_frms); | 4517 | tmp_stats[i++] = |
3937 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_usized_frms); | 4518 | (u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 | |
3938 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_osized_frms); | 4519 | le32_to_cpu(stat_info->rmac_discarded_frms); |
3939 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_frag_frms); | 4520 | tmp_stats[i++] = |
3940 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_jabber_frms); | 4521 | (u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 | |
3941 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ip); | 4522 | le32_to_cpu(stat_info->rmac_usized_frms); |
4523 | tmp_stats[i++] = | ||
4524 | (u64)le32_to_cpu(stat_info->rmac_osized_frms_oflow) << 32 | | ||
4525 | le32_to_cpu(stat_info->rmac_osized_frms); | ||
4526 | tmp_stats[i++] = | ||
4527 | (u64)le32_to_cpu(stat_info->rmac_frag_frms_oflow) << 32 | | ||
4528 | le32_to_cpu(stat_info->rmac_frag_frms); | ||
4529 | tmp_stats[i++] = | ||
4530 | (u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 | | ||
4531 | le32_to_cpu(stat_info->rmac_jabber_frms); | ||
4532 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 | | ||
4533 | le32_to_cpu(stat_info->rmac_ip); | ||
3942 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); | 4534 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); |
3943 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); | 4535 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); |
3944 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_drop_ip); | 4536 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 | |
3945 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_icmp); | 4537 | le32_to_cpu(stat_info->rmac_drop_ip); |
4538 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 | | ||
4539 | le32_to_cpu(stat_info->rmac_icmp); | ||
3946 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); | 4540 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); |
3947 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_udp); | 4541 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 | |
3948 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_drp_udp); | 4542 | le32_to_cpu(stat_info->rmac_udp); |
3949 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pause_cnt); | 4543 | tmp_stats[i++] = |
3950 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_accepted_ip); | 4544 | (u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 | |
4545 | le32_to_cpu(stat_info->rmac_err_drp_udp); | ||
4546 | tmp_stats[i++] = | ||
4547 | (u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 | | ||
4548 | le32_to_cpu(stat_info->rmac_pause_cnt); | ||
4549 | tmp_stats[i++] = | ||
4550 | (u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 | | ||
4551 | le32_to_cpu(stat_info->rmac_accepted_ip); | ||
3951 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); | 4552 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); |
4553 | tmp_stats[i++] = 0; | ||
4554 | tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; | ||
4555 | tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; | ||
3952 | } | 4556 | } |
3953 | 4557 | ||
3954 | static int s2io_ethtool_get_regs_len(struct net_device *dev) | 4558 | int s2io_ethtool_get_regs_len(struct net_device *dev) |
3955 | { | 4559 | { |
3956 | return (XENA_REG_SPACE); | 4560 | return (XENA_REG_SPACE); |
3957 | } | 4561 | } |
3958 | 4562 | ||
3959 | 4563 | ||
3960 | static u32 s2io_ethtool_get_rx_csum(struct net_device * dev) | 4564 | u32 s2io_ethtool_get_rx_csum(struct net_device * dev) |
3961 | { | 4565 | { |
3962 | nic_t *sp = dev->priv; | 4566 | nic_t *sp = dev->priv; |
3963 | 4567 | ||
3964 | return (sp->rx_csum); | 4568 | return (sp->rx_csum); |
3965 | } | 4569 | } |
3966 | 4570 | int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) | |
3967 | static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) | ||
3968 | { | 4571 | { |
3969 | nic_t *sp = dev->priv; | 4572 | nic_t *sp = dev->priv; |
3970 | 4573 | ||
@@ -3975,19 +4578,17 @@ static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) | |||
3975 | 4578 | ||
3976 | return 0; | 4579 | return 0; |
3977 | } | 4580 | } |
3978 | 4581 | int s2io_get_eeprom_len(struct net_device *dev) | |
3979 | static int s2io_get_eeprom_len(struct net_device *dev) | ||
3980 | { | 4582 | { |
3981 | return (XENA_EEPROM_SPACE); | 4583 | return (XENA_EEPROM_SPACE); |
3982 | } | 4584 | } |
3983 | 4585 | ||
3984 | static int s2io_ethtool_self_test_count(struct net_device *dev) | 4586 | int s2io_ethtool_self_test_count(struct net_device *dev) |
3985 | { | 4587 | { |
3986 | return (S2IO_TEST_LEN); | 4588 | return (S2IO_TEST_LEN); |
3987 | } | 4589 | } |
3988 | 4590 | void s2io_ethtool_get_strings(struct net_device *dev, | |
3989 | static void s2io_ethtool_get_strings(struct net_device *dev, | 4591 | u32 stringset, u8 * data) |
3990 | u32 stringset, u8 * data) | ||
3991 | { | 4592 | { |
3992 | switch (stringset) { | 4593 | switch (stringset) { |
3993 | case ETH_SS_TEST: | 4594 | case ETH_SS_TEST: |
@@ -3998,13 +4599,12 @@ static void s2io_ethtool_get_strings(struct net_device *dev, | |||
3998 | sizeof(ethtool_stats_keys)); | 4599 | sizeof(ethtool_stats_keys)); |
3999 | } | 4600 | } |
4000 | } | 4601 | } |
4001 | |||
4002 | static int s2io_ethtool_get_stats_count(struct net_device *dev) | 4602 | static int s2io_ethtool_get_stats_count(struct net_device *dev) |
4003 | { | 4603 | { |
4004 | return (S2IO_STAT_LEN); | 4604 | return (S2IO_STAT_LEN); |
4005 | } | 4605 | } |
4006 | 4606 | ||
4007 | static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | 4607 | int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) |
4008 | { | 4608 | { |
4009 | if (data) | 4609 | if (data) |
4010 | dev->features |= NETIF_F_IP_CSUM; | 4610 | dev->features |= NETIF_F_IP_CSUM; |
@@ -4046,21 +4646,18 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
4046 | }; | 4646 | }; |
4047 | 4647 | ||
4048 | /** | 4648 | /** |
4049 | * s2io_ioctl - Entry point for the Ioctl | 4649 | * s2io_ioctl - Entry point for the Ioctl |
4050 | * @dev : Device pointer. | 4650 | * @dev : Device pointer. |
4051 | * @ifr : An IOCTL specefic structure, that can contain a pointer to | 4651 | * @ifr : An IOCTL specefic structure, that can contain a pointer to |
4052 | * a proprietary structure used to pass information to the driver. | 4652 | * a proprietary structure used to pass information to the driver. |
4053 | * @cmd : This is used to distinguish between the different commands that | 4653 | * @cmd : This is used to distinguish between the different commands that |
4054 | * can be passed to the IOCTL functions. | 4654 | * can be passed to the IOCTL functions. |
4055 | * Description: | 4655 | * Description: |
4056 | * This function has support for ethtool, adding multiple MAC addresses on | 4656 | * Currently there are no special functionality supported in IOCTL, hence |
4057 | * the NIC and some DBG commands for the util tool. | 4657 | * function always return EOPNOTSUPPORTED |
4058 | * Return value: | ||
4059 | * Currently the IOCTL supports no operations, hence by default this | ||
4060 | * function returns OP NOT SUPPORTED value. | ||
4061 | */ | 4658 | */ |
4062 | 4659 | ||
4063 | static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 4660 | int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
4064 | { | 4661 | { |
4065 | return -EOPNOTSUPP; | 4662 | return -EOPNOTSUPP; |
4066 | } | 4663 | } |
@@ -4076,17 +4673,9 @@ static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
4076 | * file on failure. | 4673 | * file on failure. |
4077 | */ | 4674 | */ |
4078 | 4675 | ||
4079 | static int s2io_change_mtu(struct net_device *dev, int new_mtu) | 4676 | int s2io_change_mtu(struct net_device *dev, int new_mtu) |
4080 | { | 4677 | { |
4081 | nic_t *sp = dev->priv; | 4678 | nic_t *sp = dev->priv; |
4082 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
4083 | register u64 val64; | ||
4084 | |||
4085 | if (netif_running(dev)) { | ||
4086 | DBG_PRINT(ERR_DBG, "%s: Must be stopped to ", dev->name); | ||
4087 | DBG_PRINT(ERR_DBG, "change its MTU \n"); | ||
4088 | return -EBUSY; | ||
4089 | } | ||
4090 | 4679 | ||
4091 | if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { | 4680 | if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { |
4092 | DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", | 4681 | DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", |
@@ -4094,11 +4683,22 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
4094 | return -EPERM; | 4683 | return -EPERM; |
4095 | } | 4684 | } |
4096 | 4685 | ||
4097 | /* Set the new MTU into the PYLD register of the NIC */ | ||
4098 | val64 = new_mtu; | ||
4099 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | ||
4100 | |||
4101 | dev->mtu = new_mtu; | 4686 | dev->mtu = new_mtu; |
4687 | if (netif_running(dev)) { | ||
4688 | s2io_card_down(sp); | ||
4689 | netif_stop_queue(dev); | ||
4690 | if (s2io_card_up(sp)) { | ||
4691 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | ||
4692 | __FUNCTION__); | ||
4693 | } | ||
4694 | if (netif_queue_stopped(dev)) | ||
4695 | netif_wake_queue(dev); | ||
4696 | } else { /* Device is down */ | ||
4697 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
4698 | u64 val64 = new_mtu; | ||
4699 | |||
4700 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | ||
4701 | } | ||
4102 | 4702 | ||
4103 | return 0; | 4703 | return 0; |
4104 | } | 4704 | } |
@@ -4108,9 +4708,9 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
4108 | * @dev_adr : address of the device structure in dma_addr_t format. | 4708 | * @dev_adr : address of the device structure in dma_addr_t format. |
4109 | * Description: | 4709 | * Description: |
4110 | * This is the tasklet or the bottom half of the ISR. This is | 4710 | * This is the tasklet or the bottom half of the ISR. This is |
4111 | * an extension of the ISR which is scheduled by the scheduler to be run | 4711 | * an extension of the ISR which is scheduled by the scheduler to be run |
4112 | * when the load on the CPU is low. All low priority tasks of the ISR can | 4712 | * when the load on the CPU is low. All low priority tasks of the ISR can |
4113 | * be pushed into the tasklet. For now the tasklet is used only to | 4713 | * be pushed into the tasklet. For now the tasklet is used only to |
4114 | * replenish the Rx buffers in the Rx buffer descriptors. | 4714 | * replenish the Rx buffers in the Rx buffer descriptors. |
4115 | * Return value: | 4715 | * Return value: |
4116 | * void. | 4716 | * void. |
@@ -4166,19 +4766,22 @@ static void s2io_set_link(unsigned long data) | |||
4166 | } | 4766 | } |
4167 | 4767 | ||
4168 | subid = nic->pdev->subsystem_device; | 4768 | subid = nic->pdev->subsystem_device; |
4169 | /* | 4769 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
4170 | * Allow a small delay for the NICs self initiated | 4770 | /* |
4171 | * cleanup to complete. | 4771 | * Allow a small delay for the NICs self initiated |
4172 | */ | 4772 | * cleanup to complete. |
4173 | msleep(100); | 4773 | */ |
4774 | msleep(100); | ||
4775 | } | ||
4174 | 4776 | ||
4175 | val64 = readq(&bar0->adapter_status); | 4777 | val64 = readq(&bar0->adapter_status); |
4176 | if (verify_xena_quiescence(val64, nic->device_enabled_once)) { | 4778 | if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { |
4177 | if (LINK_IS_UP(val64)) { | 4779 | if (LINK_IS_UP(val64)) { |
4178 | val64 = readq(&bar0->adapter_control); | 4780 | val64 = readq(&bar0->adapter_control); |
4179 | val64 |= ADAPTER_CNTL_EN; | 4781 | val64 |= ADAPTER_CNTL_EN; |
4180 | writeq(val64, &bar0->adapter_control); | 4782 | writeq(val64, &bar0->adapter_control); |
4181 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { | 4783 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, |
4784 | subid)) { | ||
4182 | val64 = readq(&bar0->gpio_control); | 4785 | val64 = readq(&bar0->gpio_control); |
4183 | val64 |= GPIO_CTRL_GPIO_0; | 4786 | val64 |= GPIO_CTRL_GPIO_0; |
4184 | writeq(val64, &bar0->gpio_control); | 4787 | writeq(val64, &bar0->gpio_control); |
@@ -4187,20 +4790,24 @@ static void s2io_set_link(unsigned long data) | |||
4187 | val64 |= ADAPTER_LED_ON; | 4790 | val64 |= ADAPTER_LED_ON; |
4188 | writeq(val64, &bar0->adapter_control); | 4791 | writeq(val64, &bar0->adapter_control); |
4189 | } | 4792 | } |
4190 | val64 = readq(&bar0->adapter_status); | 4793 | if (s2io_link_fault_indication(nic) == |
4191 | if (!LINK_IS_UP(val64)) { | 4794 | MAC_RMAC_ERR_TIMER) { |
4192 | DBG_PRINT(ERR_DBG, "%s:", dev->name); | 4795 | val64 = readq(&bar0->adapter_status); |
4193 | DBG_PRINT(ERR_DBG, " Link down"); | 4796 | if (!LINK_IS_UP(val64)) { |
4194 | DBG_PRINT(ERR_DBG, "after "); | 4797 | DBG_PRINT(ERR_DBG, "%s:", dev->name); |
4195 | DBG_PRINT(ERR_DBG, "enabling "); | 4798 | DBG_PRINT(ERR_DBG, " Link down"); |
4196 | DBG_PRINT(ERR_DBG, "device \n"); | 4799 | DBG_PRINT(ERR_DBG, "after "); |
4800 | DBG_PRINT(ERR_DBG, "enabling "); | ||
4801 | DBG_PRINT(ERR_DBG, "device \n"); | ||
4802 | } | ||
4197 | } | 4803 | } |
4198 | if (nic->device_enabled_once == FALSE) { | 4804 | if (nic->device_enabled_once == FALSE) { |
4199 | nic->device_enabled_once = TRUE; | 4805 | nic->device_enabled_once = TRUE; |
4200 | } | 4806 | } |
4201 | s2io_link(nic, LINK_UP); | 4807 | s2io_link(nic, LINK_UP); |
4202 | } else { | 4808 | } else { |
4203 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { | 4809 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, |
4810 | subid)) { | ||
4204 | val64 = readq(&bar0->gpio_control); | 4811 | val64 = readq(&bar0->gpio_control); |
4205 | val64 &= ~GPIO_CTRL_GPIO_0; | 4812 | val64 &= ~GPIO_CTRL_GPIO_0; |
4206 | writeq(val64, &bar0->gpio_control); | 4813 | writeq(val64, &bar0->gpio_control); |
@@ -4223,9 +4830,11 @@ static void s2io_card_down(nic_t * sp) | |||
4223 | unsigned long flags; | 4830 | unsigned long flags; |
4224 | register u64 val64 = 0; | 4831 | register u64 val64 = 0; |
4225 | 4832 | ||
4833 | del_timer_sync(&sp->alarm_timer); | ||
4226 | /* If s2io_set_link task is executing, wait till it completes. */ | 4834 | /* If s2io_set_link task is executing, wait till it completes. */ |
4227 | while (test_and_set_bit(0, &(sp->link_state))) | 4835 | while (test_and_set_bit(0, &(sp->link_state))) { |
4228 | msleep(50); | 4836 | msleep(50); |
4837 | } | ||
4229 | atomic_set(&sp->card_state, CARD_DOWN); | 4838 | atomic_set(&sp->card_state, CARD_DOWN); |
4230 | 4839 | ||
4231 | /* disable Tx and Rx traffic on the NIC */ | 4840 | /* disable Tx and Rx traffic on the NIC */ |
@@ -4237,7 +4846,7 @@ static void s2io_card_down(nic_t * sp) | |||
4237 | /* Check if the device is Quiescent and then Reset the NIC */ | 4846 | /* Check if the device is Quiescent and then Reset the NIC */ |
4238 | do { | 4847 | do { |
4239 | val64 = readq(&bar0->adapter_status); | 4848 | val64 = readq(&bar0->adapter_status); |
4240 | if (verify_xena_quiescence(val64, sp->device_enabled_once)) { | 4849 | if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { |
4241 | break; | 4850 | break; |
4242 | } | 4851 | } |
4243 | 4852 | ||
@@ -4251,14 +4860,27 @@ static void s2io_card_down(nic_t * sp) | |||
4251 | break; | 4860 | break; |
4252 | } | 4861 | } |
4253 | } while (1); | 4862 | } while (1); |
4254 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
4255 | s2io_reset(sp); | 4863 | s2io_reset(sp); |
4256 | 4864 | ||
4257 | /* Free all unused Tx and Rx buffers */ | 4865 | /* Waiting till all Interrupt handlers are complete */ |
4866 | cnt = 0; | ||
4867 | do { | ||
4868 | msleep(10); | ||
4869 | if (!atomic_read(&sp->isr_cnt)) | ||
4870 | break; | ||
4871 | cnt++; | ||
4872 | } while(cnt < 5); | ||
4873 | |||
4874 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
4875 | /* Free all Tx buffers */ | ||
4258 | free_tx_buffers(sp); | 4876 | free_tx_buffers(sp); |
4877 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
4878 | |||
4879 | /* Free all Rx buffers */ | ||
4880 | spin_lock_irqsave(&sp->rx_lock, flags); | ||
4259 | free_rx_buffers(sp); | 4881 | free_rx_buffers(sp); |
4882 | spin_unlock_irqrestore(&sp->rx_lock, flags); | ||
4260 | 4883 | ||
4261 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
4262 | clear_bit(0, &(sp->link_state)); | 4884 | clear_bit(0, &(sp->link_state)); |
4263 | } | 4885 | } |
4264 | 4886 | ||
@@ -4276,8 +4898,8 @@ static int s2io_card_up(nic_t * sp) | |||
4276 | return -ENODEV; | 4898 | return -ENODEV; |
4277 | } | 4899 | } |
4278 | 4900 | ||
4279 | /* | 4901 | /* |
4280 | * Initializing the Rx buffers. For now we are considering only 1 | 4902 | * Initializing the Rx buffers. For now we are considering only 1 |
4281 | * Rx ring and initializing buffers into 30 Rx blocks | 4903 | * Rx ring and initializing buffers into 30 Rx blocks |
4282 | */ | 4904 | */ |
4283 | mac_control = &sp->mac_control; | 4905 | mac_control = &sp->mac_control; |
@@ -4311,16 +4933,18 @@ static int s2io_card_up(nic_t * sp) | |||
4311 | return -ENODEV; | 4933 | return -ENODEV; |
4312 | } | 4934 | } |
4313 | 4935 | ||
4936 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); | ||
4937 | |||
4314 | atomic_set(&sp->card_state, CARD_UP); | 4938 | atomic_set(&sp->card_state, CARD_UP); |
4315 | return 0; | 4939 | return 0; |
4316 | } | 4940 | } |
4317 | 4941 | ||
4318 | /** | 4942 | /** |
4319 | * s2io_restart_nic - Resets the NIC. | 4943 | * s2io_restart_nic - Resets the NIC. |
4320 | * @data : long pointer to the device private structure | 4944 | * @data : long pointer to the device private structure |
4321 | * Description: | 4945 | * Description: |
4322 | * This function is scheduled to be run by the s2io_tx_watchdog | 4946 | * This function is scheduled to be run by the s2io_tx_watchdog |
4323 | * function after 0.5 secs to reset the NIC. The idea is to reduce | 4947 | * function after 0.5 secs to reset the NIC. The idea is to reduce |
4324 | * the run time of the watch dog routine which is run holding a | 4948 | * the run time of the watch dog routine which is run holding a |
4325 | * spin lock. | 4949 | * spin lock. |
4326 | */ | 4950 | */ |
@@ -4338,10 +4962,11 @@ static void s2io_restart_nic(unsigned long data) | |||
4338 | netif_wake_queue(dev); | 4962 | netif_wake_queue(dev); |
4339 | DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", | 4963 | DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", |
4340 | dev->name); | 4964 | dev->name); |
4965 | |||
4341 | } | 4966 | } |
4342 | 4967 | ||
4343 | /** | 4968 | /** |
4344 | * s2io_tx_watchdog - Watchdog for transmit side. | 4969 | * s2io_tx_watchdog - Watchdog for transmit side. |
4345 | * @dev : Pointer to net device structure | 4970 | * @dev : Pointer to net device structure |
4346 | * Description: | 4971 | * Description: |
4347 | * This function is triggered if the Tx Queue is stopped | 4972 | * This function is triggered if the Tx Queue is stopped |
@@ -4369,7 +4994,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
4369 | * @len : length of the packet | 4994 | * @len : length of the packet |
4370 | * @cksum : FCS checksum of the frame. | 4995 | * @cksum : FCS checksum of the frame. |
4371 | * @ring_no : the ring from which this RxD was extracted. | 4996 | * @ring_no : the ring from which this RxD was extracted. |
4372 | * Description: | 4997 | * Description: |
4373 | * This function is called by the Tx interrupt serivce routine to perform | 4998 | * This function is called by the Tx interrupt serivce routine to perform |
4374 | * some OS related operations on the SKB before passing it to the upper | 4999 | * some OS related operations on the SKB before passing it to the upper |
4375 | * layers. It mainly checks if the checksum is OK, if so adds it to the | 5000 | * layers. It mainly checks if the checksum is OK, if so adds it to the |
@@ -4379,35 +5004,68 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
4379 | * Return value: | 5004 | * Return value: |
4380 | * SUCCESS on success and -1 on failure. | 5005 | * SUCCESS on success and -1 on failure. |
4381 | */ | 5006 | */ |
4382 | #ifndef CONFIG_2BUFF_MODE | 5007 | static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) |
4383 | static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no) | ||
4384 | #else | ||
4385 | static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | ||
4386 | buffAdd_t * ba) | ||
4387 | #endif | ||
4388 | { | 5008 | { |
5009 | nic_t *sp = ring_data->nic; | ||
4389 | struct net_device *dev = (struct net_device *) sp->dev; | 5010 | struct net_device *dev = (struct net_device *) sp->dev; |
4390 | struct sk_buff *skb = | 5011 | struct sk_buff *skb = (struct sk_buff *) |
4391 | (struct sk_buff *) ((unsigned long) rxdp->Host_Control); | 5012 | ((unsigned long) rxdp->Host_Control); |
5013 | int ring_no = ring_data->ring_no; | ||
4392 | u16 l3_csum, l4_csum; | 5014 | u16 l3_csum, l4_csum; |
4393 | #ifdef CONFIG_2BUFF_MODE | 5015 | #ifdef CONFIG_2BUFF_MODE |
4394 | int buf0_len, buf2_len; | 5016 | int buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); |
5017 | int buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2); | ||
5018 | int get_block = ring_data->rx_curr_get_info.block_index; | ||
5019 | int get_off = ring_data->rx_curr_get_info.offset; | ||
5020 | buffAdd_t *ba = &ring_data->ba[get_block][get_off]; | ||
4395 | unsigned char *buff; | 5021 | unsigned char *buff; |
5022 | #else | ||
5023 | u16 len = (u16) ((RXD_GET_BUFFER0_SIZE(rxdp->Control_2)) >> 48);; | ||
4396 | #endif | 5024 | #endif |
5025 | skb->dev = dev; | ||
5026 | if (rxdp->Control_1 & RXD_T_CODE) { | ||
5027 | unsigned long long err = rxdp->Control_1 & RXD_T_CODE; | ||
5028 | DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", | ||
5029 | dev->name, err); | ||
5030 | dev_kfree_skb(skb); | ||
5031 | sp->stats.rx_crc_errors++; | ||
5032 | atomic_dec(&sp->rx_bufs_left[ring_no]); | ||
5033 | rxdp->Host_Control = 0; | ||
5034 | return 0; | ||
5035 | } | ||
4397 | 5036 | ||
4398 | l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); | 5037 | /* Updating statistics */ |
4399 | if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && (sp->rx_csum)) { | 5038 | rxdp->Host_Control = 0; |
5039 | sp->rx_pkt_count++; | ||
5040 | sp->stats.rx_packets++; | ||
5041 | #ifndef CONFIG_2BUFF_MODE | ||
5042 | sp->stats.rx_bytes += len; | ||
5043 | #else | ||
5044 | sp->stats.rx_bytes += buf0_len + buf2_len; | ||
5045 | #endif | ||
5046 | |||
5047 | #ifndef CONFIG_2BUFF_MODE | ||
5048 | skb_put(skb, len); | ||
5049 | #else | ||
5050 | buff = skb_push(skb, buf0_len); | ||
5051 | memcpy(buff, ba->ba_0, buf0_len); | ||
5052 | skb_put(skb, buf2_len); | ||
5053 | #endif | ||
5054 | |||
5055 | if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && | ||
5056 | (sp->rx_csum)) { | ||
5057 | l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); | ||
4400 | l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1); | 5058 | l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1); |
4401 | if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) { | 5059 | if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) { |
4402 | /* | 5060 | /* |
4403 | * NIC verifies if the Checksum of the received | 5061 | * NIC verifies if the Checksum of the received |
4404 | * frame is Ok or not and accordingly returns | 5062 | * frame is Ok or not and accordingly returns |
4405 | * a flag in the RxD. | 5063 | * a flag in the RxD. |
4406 | */ | 5064 | */ |
4407 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 5065 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
4408 | } else { | 5066 | } else { |
4409 | /* | 5067 | /* |
4410 | * Packet with erroneous checksum, let the | 5068 | * Packet with erroneous checksum, let the |
4411 | * upper layers deal with it. | 5069 | * upper layers deal with it. |
4412 | */ | 5070 | */ |
4413 | skb->ip_summed = CHECKSUM_NONE; | 5071 | skb->ip_summed = CHECKSUM_NONE; |
@@ -4416,44 +5074,26 @@ static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | |||
4416 | skb->ip_summed = CHECKSUM_NONE; | 5074 | skb->ip_summed = CHECKSUM_NONE; |
4417 | } | 5075 | } |
4418 | 5076 | ||
4419 | if (rxdp->Control_1 & RXD_T_CODE) { | ||
4420 | unsigned long long err = rxdp->Control_1 & RXD_T_CODE; | ||
4421 | DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", | ||
4422 | dev->name, err); | ||
4423 | } | ||
4424 | #ifdef CONFIG_2BUFF_MODE | ||
4425 | buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); | ||
4426 | buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2); | ||
4427 | #endif | ||
4428 | |||
4429 | skb->dev = dev; | ||
4430 | #ifndef CONFIG_2BUFF_MODE | ||
4431 | skb_put(skb, len); | ||
4432 | skb->protocol = eth_type_trans(skb, dev); | ||
4433 | #else | ||
4434 | buff = skb_push(skb, buf0_len); | ||
4435 | memcpy(buff, ba->ba_0, buf0_len); | ||
4436 | skb_put(skb, buf2_len); | ||
4437 | skb->protocol = eth_type_trans(skb, dev); | 5077 | skb->protocol = eth_type_trans(skb, dev); |
4438 | #endif | ||
4439 | |||
4440 | #ifdef CONFIG_S2IO_NAPI | 5078 | #ifdef CONFIG_S2IO_NAPI |
4441 | netif_receive_skb(skb); | 5079 | if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { |
5080 | /* Queueing the vlan frame to the upper layer */ | ||
5081 | vlan_hwaccel_receive_skb(skb, sp->vlgrp, | ||
5082 | RXD_GET_VLAN_TAG(rxdp->Control_2)); | ||
5083 | } else { | ||
5084 | netif_receive_skb(skb); | ||
5085 | } | ||
4442 | #else | 5086 | #else |
4443 | netif_rx(skb); | 5087 | if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { |
5088 | /* Queueing the vlan frame to the upper layer */ | ||
5089 | vlan_hwaccel_rx(skb, sp->vlgrp, | ||
5090 | RXD_GET_VLAN_TAG(rxdp->Control_2)); | ||
5091 | } else { | ||
5092 | netif_rx(skb); | ||
5093 | } | ||
4444 | #endif | 5094 | #endif |
4445 | |||
4446 | dev->last_rx = jiffies; | 5095 | dev->last_rx = jiffies; |
4447 | sp->rx_pkt_count++; | ||
4448 | sp->stats.rx_packets++; | ||
4449 | #ifndef CONFIG_2BUFF_MODE | ||
4450 | sp->stats.rx_bytes += len; | ||
4451 | #else | ||
4452 | sp->stats.rx_bytes += buf0_len + buf2_len; | ||
4453 | #endif | ||
4454 | |||
4455 | atomic_dec(&sp->rx_bufs_left[ring_no]); | 5096 | atomic_dec(&sp->rx_bufs_left[ring_no]); |
4456 | rxdp->Host_Control = 0; | ||
4457 | return SUCCESS; | 5097 | return SUCCESS; |
4458 | } | 5098 | } |
4459 | 5099 | ||
@@ -4464,13 +5104,13 @@ static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | |||
4464 | * @link : inidicates whether link is UP/DOWN. | 5104 | * @link : inidicates whether link is UP/DOWN. |
4465 | * Description: | 5105 | * Description: |
4466 | * This function stops/starts the Tx queue depending on whether the link | 5106 | * This function stops/starts the Tx queue depending on whether the link |
4467 | * status of the NIC is is down or up. This is called by the Alarm | 5107 | * status of the NIC is is down or up. This is called by the Alarm |
4468 | * interrupt handler whenever a link change interrupt comes up. | 5108 | * interrupt handler whenever a link change interrupt comes up. |
4469 | * Return value: | 5109 | * Return value: |
4470 | * void. | 5110 | * void. |
4471 | */ | 5111 | */ |
4472 | 5112 | ||
4473 | static void s2io_link(nic_t * sp, int link) | 5113 | void s2io_link(nic_t * sp, int link) |
4474 | { | 5114 | { |
4475 | struct net_device *dev = (struct net_device *) sp->dev; | 5115 | struct net_device *dev = (struct net_device *) sp->dev; |
4476 | 5116 | ||
@@ -4487,8 +5127,25 @@ static void s2io_link(nic_t * sp, int link) | |||
4487 | } | 5127 | } |
4488 | 5128 | ||
4489 | /** | 5129 | /** |
4490 | * s2io_init_pci -Initialization of PCI and PCI-X configuration registers . | 5130 | * get_xena_rev_id - to identify revision ID of xena. |
4491 | * @sp : private member of the device structure, which is a pointer to the | 5131 | * @pdev : PCI Dev structure |
5132 | * Description: | ||
5133 | * Function to identify the Revision ID of xena. | ||
5134 | * Return value: | ||
5135 | * returns the revision ID of the device. | ||
5136 | */ | ||
5137 | |||
5138 | int get_xena_rev_id(struct pci_dev *pdev) | ||
5139 | { | ||
5140 | u8 id = 0; | ||
5141 | int ret; | ||
5142 | ret = pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) & id); | ||
5143 | return id; | ||
5144 | } | ||
5145 | |||
5146 | /** | ||
5147 | * s2io_init_pci -Initialization of PCI and PCI-X configuration registers . | ||
5148 | * @sp : private member of the device structure, which is a pointer to the | ||
4492 | * s2io_nic structure. | 5149 | * s2io_nic structure. |
4493 | * Description: | 5150 | * Description: |
4494 | * This function initializes a few of the PCI and PCI-X configuration registers | 5151 | * This function initializes a few of the PCI and PCI-X configuration registers |
@@ -4499,15 +5156,15 @@ static void s2io_link(nic_t * sp, int link) | |||
4499 | 5156 | ||
4500 | static void s2io_init_pci(nic_t * sp) | 5157 | static void s2io_init_pci(nic_t * sp) |
4501 | { | 5158 | { |
4502 | u16 pci_cmd = 0; | 5159 | u16 pci_cmd = 0, pcix_cmd = 0; |
4503 | 5160 | ||
4504 | /* Enable Data Parity Error Recovery in PCI-X command register. */ | 5161 | /* Enable Data Parity Error Recovery in PCI-X command register. */ |
4505 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5162 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4506 | &(sp->pcix_cmd)); | 5163 | &(pcix_cmd)); |
4507 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5164 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4508 | (sp->pcix_cmd | 1)); | 5165 | (pcix_cmd | 1)); |
4509 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5166 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4510 | &(sp->pcix_cmd)); | 5167 | &(pcix_cmd)); |
4511 | 5168 | ||
4512 | /* Set the PErr Response bit in PCI command register. */ | 5169 | /* Set the PErr Response bit in PCI command register. */ |
4513 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 5170 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
@@ -4515,53 +5172,43 @@ static void s2io_init_pci(nic_t * sp) | |||
4515 | (pci_cmd | PCI_COMMAND_PARITY)); | 5172 | (pci_cmd | PCI_COMMAND_PARITY)); |
4516 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 5173 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
4517 | 5174 | ||
4518 | /* Set MMRB count to 1024 in PCI-X Command register. */ | ||
4519 | sp->pcix_cmd &= 0xFFF3; | ||
4520 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, (sp->pcix_cmd | (0x1 << 2))); /* MMRBC 1K */ | ||
4521 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
4522 | &(sp->pcix_cmd)); | ||
4523 | |||
4524 | /* Setting Maximum outstanding splits based on system type. */ | ||
4525 | sp->pcix_cmd &= 0xFF8F; | ||
4526 | |||
4527 | sp->pcix_cmd |= XENA_MAX_OUTSTANDING_SPLITS(0x1); /* 2 splits. */ | ||
4528 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
4529 | sp->pcix_cmd); | ||
4530 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
4531 | &(sp->pcix_cmd)); | ||
4532 | /* Forcibly disabling relaxed ordering capability of the card. */ | 5175 | /* Forcibly disabling relaxed ordering capability of the card. */ |
4533 | sp->pcix_cmd &= 0xfffd; | 5176 | pcix_cmd &= 0xfffd; |
4534 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5177 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4535 | sp->pcix_cmd); | 5178 | pcix_cmd); |
4536 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5179 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4537 | &(sp->pcix_cmd)); | 5180 | &(pcix_cmd)); |
4538 | } | 5181 | } |
4539 | 5182 | ||
4540 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | 5183 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); |
4541 | MODULE_LICENSE("GPL"); | 5184 | MODULE_LICENSE("GPL"); |
4542 | module_param(tx_fifo_num, int, 0); | 5185 | module_param(tx_fifo_num, int, 0); |
4543 | module_param_array(tx_fifo_len, int, NULL, 0); | ||
4544 | module_param(rx_ring_num, int, 0); | 5186 | module_param(rx_ring_num, int, 0); |
4545 | module_param_array(rx_ring_sz, int, NULL, 0); | 5187 | module_param_array(tx_fifo_len, uint, NULL, 0); |
4546 | module_param(Stats_refresh_time, int, 0); | 5188 | module_param_array(rx_ring_sz, uint, NULL, 0); |
5189 | module_param_array(rts_frm_len, uint, NULL, 0); | ||
5190 | module_param(use_continuous_tx_intrs, int, 1); | ||
4547 | module_param(rmac_pause_time, int, 0); | 5191 | module_param(rmac_pause_time, int, 0); |
4548 | module_param(mc_pause_threshold_q0q3, int, 0); | 5192 | module_param(mc_pause_threshold_q0q3, int, 0); |
4549 | module_param(mc_pause_threshold_q4q7, int, 0); | 5193 | module_param(mc_pause_threshold_q4q7, int, 0); |
4550 | module_param(shared_splits, int, 0); | 5194 | module_param(shared_splits, int, 0); |
4551 | module_param(tmac_util_period, int, 0); | 5195 | module_param(tmac_util_period, int, 0); |
4552 | module_param(rmac_util_period, int, 0); | 5196 | module_param(rmac_util_period, int, 0); |
5197 | module_param(bimodal, bool, 0); | ||
4553 | #ifndef CONFIG_S2IO_NAPI | 5198 | #ifndef CONFIG_S2IO_NAPI |
4554 | module_param(indicate_max_pkts, int, 0); | 5199 | module_param(indicate_max_pkts, int, 0); |
4555 | #endif | 5200 | #endif |
5201 | module_param(rxsync_frequency, int, 0); | ||
5202 | |||
4556 | /** | 5203 | /** |
4557 | * s2io_init_nic - Initialization of the adapter . | 5204 | * s2io_init_nic - Initialization of the adapter . |
4558 | * @pdev : structure containing the PCI related information of the device. | 5205 | * @pdev : structure containing the PCI related information of the device. |
4559 | * @pre: List of PCI devices supported by the driver listed in s2io_tbl. | 5206 | * @pre: List of PCI devices supported by the driver listed in s2io_tbl. |
4560 | * Description: | 5207 | * Description: |
4561 | * The function initializes an adapter identified by the pci_dec structure. | 5208 | * The function initializes an adapter identified by the pci_dec structure. |
4562 | * All OS related initialization including memory and device structure and | 5209 | * All OS related initialization including memory and device structure and |
4563 | * initlaization of the device private variable is done. Also the swapper | 5210 | * initlaization of the device private variable is done. Also the swapper |
4564 | * control register is initialized to enable read and write into the I/O | 5211 | * control register is initialized to enable read and write into the I/O |
4565 | * registers of the device. | 5212 | * registers of the device. |
4566 | * Return value: | 5213 | * Return value: |
4567 | * returns 0 on success and negative on failure. | 5214 | * returns 0 on success and negative on failure. |
@@ -4572,7 +5219,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4572 | { | 5219 | { |
4573 | nic_t *sp; | 5220 | nic_t *sp; |
4574 | struct net_device *dev; | 5221 | struct net_device *dev; |
4575 | char *dev_name = "S2IO 10GE NIC"; | ||
4576 | int i, j, ret; | 5222 | int i, j, ret; |
4577 | int dma_flag = FALSE; | 5223 | int dma_flag = FALSE; |
4578 | u32 mac_up, mac_down; | 5224 | u32 mac_up, mac_down; |
@@ -4581,10 +5227,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4581 | u16 subid; | 5227 | u16 subid; |
4582 | mac_info_t *mac_control; | 5228 | mac_info_t *mac_control; |
4583 | struct config_param *config; | 5229 | struct config_param *config; |
5230 | int mode; | ||
4584 | 5231 | ||
4585 | 5232 | #ifdef CONFIG_S2IO_NAPI | |
4586 | DBG_PRINT(ERR_DBG, "Loading S2IO driver with %s\n", | 5233 | DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n"); |
4587 | s2io_driver_version); | 5234 | #endif |
4588 | 5235 | ||
4589 | if ((ret = pci_enable_device(pdev))) { | 5236 | if ((ret = pci_enable_device(pdev))) { |
4590 | DBG_PRINT(ERR_DBG, | 5237 | DBG_PRINT(ERR_DBG, |
@@ -4595,7 +5242,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4595 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | 5242 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
4596 | DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); | 5243 | DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); |
4597 | dma_flag = TRUE; | 5244 | dma_flag = TRUE; |
4598 | |||
4599 | if (pci_set_consistent_dma_mask | 5245 | if (pci_set_consistent_dma_mask |
4600 | (pdev, DMA_64BIT_MASK)) { | 5246 | (pdev, DMA_64BIT_MASK)) { |
4601 | DBG_PRINT(ERR_DBG, | 5247 | DBG_PRINT(ERR_DBG, |
@@ -4635,34 +5281,41 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4635 | memset(sp, 0, sizeof(nic_t)); | 5281 | memset(sp, 0, sizeof(nic_t)); |
4636 | sp->dev = dev; | 5282 | sp->dev = dev; |
4637 | sp->pdev = pdev; | 5283 | sp->pdev = pdev; |
4638 | sp->vendor_id = pdev->vendor; | ||
4639 | sp->device_id = pdev->device; | ||
4640 | sp->high_dma_flag = dma_flag; | 5284 | sp->high_dma_flag = dma_flag; |
4641 | sp->irq = pdev->irq; | ||
4642 | sp->device_enabled_once = FALSE; | 5285 | sp->device_enabled_once = FALSE; |
4643 | strcpy(sp->name, dev_name); | 5286 | |
5287 | if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) || | ||
5288 | (pdev->device == PCI_DEVICE_ID_HERC_UNI)) | ||
5289 | sp->device_type = XFRAME_II_DEVICE; | ||
5290 | else | ||
5291 | sp->device_type = XFRAME_I_DEVICE; | ||
4644 | 5292 | ||
4645 | /* Initialize some PCI/PCI-X fields of the NIC. */ | 5293 | /* Initialize some PCI/PCI-X fields of the NIC. */ |
4646 | s2io_init_pci(sp); | 5294 | s2io_init_pci(sp); |
4647 | 5295 | ||
4648 | /* | 5296 | /* |
4649 | * Setting the device configuration parameters. | 5297 | * Setting the device configuration parameters. |
4650 | * Most of these parameters can be specified by the user during | 5298 | * Most of these parameters can be specified by the user during |
4651 | * module insertion as they are module loadable parameters. If | 5299 | * module insertion as they are module loadable parameters. If |
4652 | * these parameters are not not specified during load time, they | 5300 | * these parameters are not not specified during load time, they |
4653 | * are initialized with default values. | 5301 | * are initialized with default values. |
4654 | */ | 5302 | */ |
4655 | mac_control = &sp->mac_control; | 5303 | mac_control = &sp->mac_control; |
4656 | config = &sp->config; | 5304 | config = &sp->config; |
4657 | 5305 | ||
4658 | /* Tx side parameters. */ | 5306 | /* Tx side parameters. */ |
4659 | tx_fifo_len[0] = DEFAULT_FIFO_LEN; /* Default value. */ | 5307 | if (tx_fifo_len[0] == 0) |
5308 | tx_fifo_len[0] = DEFAULT_FIFO_LEN; /* Default value. */ | ||
4660 | config->tx_fifo_num = tx_fifo_num; | 5309 | config->tx_fifo_num = tx_fifo_num; |
4661 | for (i = 0; i < MAX_TX_FIFOS; i++) { | 5310 | for (i = 0; i < MAX_TX_FIFOS; i++) { |
4662 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; | 5311 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; |
4663 | config->tx_cfg[i].fifo_priority = i; | 5312 | config->tx_cfg[i].fifo_priority = i; |
4664 | } | 5313 | } |
4665 | 5314 | ||
5315 | /* mapping the QoS priority to the configured fifos */ | ||
5316 | for (i = 0; i < MAX_TX_FIFOS; i++) | ||
5317 | config->fifo_mapping[i] = fifo_map[config->tx_fifo_num][i]; | ||
5318 | |||
4666 | config->tx_intr_type = TXD_INT_TYPE_UTILZ; | 5319 | config->tx_intr_type = TXD_INT_TYPE_UTILZ; |
4667 | for (i = 0; i < config->tx_fifo_num; i++) { | 5320 | for (i = 0; i < config->tx_fifo_num; i++) { |
4668 | config->tx_cfg[i].f_no_snoop = | 5321 | config->tx_cfg[i].f_no_snoop = |
@@ -4675,7 +5328,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4675 | config->max_txds = MAX_SKB_FRAGS; | 5328 | config->max_txds = MAX_SKB_FRAGS; |
4676 | 5329 | ||
4677 | /* Rx side parameters. */ | 5330 | /* Rx side parameters. */ |
4678 | rx_ring_sz[0] = SMALL_BLK_CNT; /* Default value. */ | 5331 | if (rx_ring_sz[0] == 0) |
5332 | rx_ring_sz[0] = SMALL_BLK_CNT; /* Default value. */ | ||
4679 | config->rx_ring_num = rx_ring_num; | 5333 | config->rx_ring_num = rx_ring_num; |
4680 | for (i = 0; i < MAX_RX_RINGS; i++) { | 5334 | for (i = 0; i < MAX_RX_RINGS; i++) { |
4681 | config->rx_cfg[i].num_rxd = rx_ring_sz[i] * | 5335 | config->rx_cfg[i].num_rxd = rx_ring_sz[i] * |
@@ -4699,10 +5353,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4699 | for (i = 0; i < config->rx_ring_num; i++) | 5353 | for (i = 0; i < config->rx_ring_num; i++) |
4700 | atomic_set(&sp->rx_bufs_left[i], 0); | 5354 | atomic_set(&sp->rx_bufs_left[i], 0); |
4701 | 5355 | ||
5356 | /* Initialize the number of ISRs currently running */ | ||
5357 | atomic_set(&sp->isr_cnt, 0); | ||
5358 | |||
4702 | /* initialize the shared memory used by the NIC and the host */ | 5359 | /* initialize the shared memory used by the NIC and the host */ |
4703 | if (init_shared_mem(sp)) { | 5360 | if (init_shared_mem(sp)) { |
4704 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 5361 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |
4705 | dev->name); | 5362 | __FUNCTION__); |
4706 | ret = -ENOMEM; | 5363 | ret = -ENOMEM; |
4707 | goto mem_alloc_failed; | 5364 | goto mem_alloc_failed; |
4708 | } | 5365 | } |
@@ -4743,13 +5400,17 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4743 | dev->do_ioctl = &s2io_ioctl; | 5400 | dev->do_ioctl = &s2io_ioctl; |
4744 | dev->change_mtu = &s2io_change_mtu; | 5401 | dev->change_mtu = &s2io_change_mtu; |
4745 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 5402 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
5403 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
5404 | dev->vlan_rx_register = s2io_vlan_rx_register; | ||
5405 | dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid; | ||
5406 | |||
4746 | /* | 5407 | /* |
4747 | * will use eth_mac_addr() for dev->set_mac_address | 5408 | * will use eth_mac_addr() for dev->set_mac_address |
4748 | * mac address will be set every time dev->open() is called | 5409 | * mac address will be set every time dev->open() is called |
4749 | */ | 5410 | */ |
4750 | #ifdef CONFIG_S2IO_NAPI | 5411 | #if defined(CONFIG_S2IO_NAPI) |
4751 | dev->poll = s2io_poll; | 5412 | dev->poll = s2io_poll; |
4752 | dev->weight = 90; | 5413 | dev->weight = 32; |
4753 | #endif | 5414 | #endif |
4754 | 5415 | ||
4755 | dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | 5416 | dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; |
@@ -4776,22 +5437,28 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4776 | goto set_swap_failed; | 5437 | goto set_swap_failed; |
4777 | } | 5438 | } |
4778 | 5439 | ||
4779 | /* Fix for all "FFs" MAC address problems observed on Alpha platforms */ | 5440 | /* Verify if the Herc works on the slot its placed into */ |
4780 | fix_mac_address(sp); | 5441 | if (sp->device_type & XFRAME_II_DEVICE) { |
4781 | s2io_reset(sp); | 5442 | mode = s2io_verify_pci_mode(sp); |
5443 | if (mode < 0) { | ||
5444 | DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__); | ||
5445 | DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n"); | ||
5446 | ret = -EBADSLT; | ||
5447 | goto set_swap_failed; | ||
5448 | } | ||
5449 | } | ||
4782 | 5450 | ||
4783 | /* | 5451 | /* Not needed for Herc */ |
4784 | * Setting swapper control on the NIC, so the MAC address can be read. | 5452 | if (sp->device_type & XFRAME_I_DEVICE) { |
4785 | */ | 5453 | /* |
4786 | if (s2io_set_swapper(sp)) { | 5454 | * Fix for all "FFs" MAC address problems observed on |
4787 | DBG_PRINT(ERR_DBG, | 5455 | * Alpha platforms |
4788 | "%s: S2IO: swapper settings are wrong\n", | 5456 | */ |
4789 | dev->name); | 5457 | fix_mac_address(sp); |
4790 | ret = -EAGAIN; | 5458 | s2io_reset(sp); |
4791 | goto set_swap_failed; | ||
4792 | } | 5459 | } |
4793 | 5460 | ||
4794 | /* | 5461 | /* |
4795 | * MAC address initialization. | 5462 | * MAC address initialization. |
4796 | * For now only one mac address will be read and used. | 5463 | * For now only one mac address will be read and used. |
4797 | */ | 5464 | */ |
@@ -4814,37 +5481,28 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4814 | sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16); | 5481 | sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16); |
4815 | sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24); | 5482 | sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24); |
4816 | 5483 | ||
4817 | DBG_PRINT(INIT_DBG, | ||
4818 | "DEFAULT MAC ADDR:0x%02x-%02x-%02x-%02x-%02x-%02x\n", | ||
4819 | sp->def_mac_addr[0].mac_addr[0], | ||
4820 | sp->def_mac_addr[0].mac_addr[1], | ||
4821 | sp->def_mac_addr[0].mac_addr[2], | ||
4822 | sp->def_mac_addr[0].mac_addr[3], | ||
4823 | sp->def_mac_addr[0].mac_addr[4], | ||
4824 | sp->def_mac_addr[0].mac_addr[5]); | ||
4825 | |||
4826 | /* Set the factory defined MAC address initially */ | 5484 | /* Set the factory defined MAC address initially */ |
4827 | dev->addr_len = ETH_ALEN; | 5485 | dev->addr_len = ETH_ALEN; |
4828 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); | 5486 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); |
4829 | 5487 | ||
4830 | /* | 5488 | /* |
4831 | * Initialize the tasklet status and link state flags | 5489 | * Initialize the tasklet status and link state flags |
4832 | * and the card statte parameter | 5490 | * and the card state parameter |
4833 | */ | 5491 | */ |
4834 | atomic_set(&(sp->card_state), 0); | 5492 | atomic_set(&(sp->card_state), 0); |
4835 | sp->tasklet_status = 0; | 5493 | sp->tasklet_status = 0; |
4836 | sp->link_state = 0; | 5494 | sp->link_state = 0; |
4837 | 5495 | ||
4838 | |||
4839 | /* Initialize spinlocks */ | 5496 | /* Initialize spinlocks */ |
4840 | spin_lock_init(&sp->tx_lock); | 5497 | spin_lock_init(&sp->tx_lock); |
4841 | #ifndef CONFIG_S2IO_NAPI | 5498 | #ifndef CONFIG_S2IO_NAPI |
4842 | spin_lock_init(&sp->put_lock); | 5499 | spin_lock_init(&sp->put_lock); |
4843 | #endif | 5500 | #endif |
5501 | spin_lock_init(&sp->rx_lock); | ||
4844 | 5502 | ||
4845 | /* | 5503 | /* |
4846 | * SXE-002: Configure link and activity LED to init state | 5504 | * SXE-002: Configure link and activity LED to init state |
4847 | * on driver load. | 5505 | * on driver load. |
4848 | */ | 5506 | */ |
4849 | subid = sp->pdev->subsystem_device; | 5507 | subid = sp->pdev->subsystem_device; |
4850 | if ((subid & 0xFF) >= 0x07) { | 5508 | if ((subid & 0xFF) >= 0x07) { |
@@ -4864,13 +5522,61 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4864 | goto register_failed; | 5522 | goto register_failed; |
4865 | } | 5523 | } |
4866 | 5524 | ||
4867 | /* | 5525 | if (sp->device_type & XFRAME_II_DEVICE) { |
4868 | * Make Link state as off at this point, when the Link change | 5526 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", |
4869 | * interrupt comes the state will be automatically changed to | 5527 | dev->name); |
5528 | DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n", | ||
5529 | get_xena_rev_id(sp->pdev), | ||
5530 | s2io_driver_version); | ||
5531 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
5532 | sp->def_mac_addr[0].mac_addr[0], | ||
5533 | sp->def_mac_addr[0].mac_addr[1], | ||
5534 | sp->def_mac_addr[0].mac_addr[2], | ||
5535 | sp->def_mac_addr[0].mac_addr[3], | ||
5536 | sp->def_mac_addr[0].mac_addr[4], | ||
5537 | sp->def_mac_addr[0].mac_addr[5]); | ||
5538 | mode = s2io_print_pci_mode(sp); | ||
5539 | if (mode < 0) { | ||
5540 | DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode "); | ||
5541 | ret = -EBADSLT; | ||
5542 | goto set_swap_failed; | ||
5543 | } | ||
5544 | } else { | ||
5545 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", | ||
5546 | dev->name); | ||
5547 | DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n", | ||
5548 | get_xena_rev_id(sp->pdev), | ||
5549 | s2io_driver_version); | ||
5550 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
5551 | sp->def_mac_addr[0].mac_addr[0], | ||
5552 | sp->def_mac_addr[0].mac_addr[1], | ||
5553 | sp->def_mac_addr[0].mac_addr[2], | ||
5554 | sp->def_mac_addr[0].mac_addr[3], | ||
5555 | sp->def_mac_addr[0].mac_addr[4], | ||
5556 | sp->def_mac_addr[0].mac_addr[5]); | ||
5557 | } | ||
5558 | |||
5559 | /* Initialize device name */ | ||
5560 | strcpy(sp->name, dev->name); | ||
5561 | if (sp->device_type & XFRAME_II_DEVICE) | ||
5562 | strcat(sp->name, ": Neterion Xframe II 10GbE adapter"); | ||
5563 | else | ||
5564 | strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); | ||
5565 | |||
5566 | /* Initialize bimodal Interrupts */ | ||
5567 | sp->config.bimodal = bimodal; | ||
5568 | if (!(sp->device_type & XFRAME_II_DEVICE) && bimodal) { | ||
5569 | sp->config.bimodal = 0; | ||
5570 | DBG_PRINT(ERR_DBG,"%s:Bimodal intr not supported by Xframe I\n", | ||
5571 | dev->name); | ||
5572 | } | ||
5573 | |||
5574 | /* | ||
5575 | * Make Link state as off at this point, when the Link change | ||
5576 | * interrupt comes the state will be automatically changed to | ||
4870 | * the right state. | 5577 | * the right state. |
4871 | */ | 5578 | */ |
4872 | netif_carrier_off(dev); | 5579 | netif_carrier_off(dev); |
4873 | sp->last_link_state = LINK_DOWN; | ||
4874 | 5580 | ||
4875 | return 0; | 5581 | return 0; |
4876 | 5582 | ||
@@ -4891,11 +5597,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4891 | } | 5597 | } |
4892 | 5598 | ||
4893 | /** | 5599 | /** |
4894 | * s2io_rem_nic - Free the PCI device | 5600 | * s2io_rem_nic - Free the PCI device |
4895 | * @pdev: structure containing the PCI related information of the device. | 5601 | * @pdev: structure containing the PCI related information of the device. |
4896 | * Description: This function is called by the Pci subsystem to release a | 5602 | * Description: This function is called by the Pci subsystem to release a |
4897 | * PCI device and free up all resource held up by the device. This could | 5603 | * PCI device and free up all resource held up by the device. This could |
4898 | * be in response to a Hot plug event or when the driver is to be removed | 5604 | * be in response to a Hot plug event or when the driver is to be removed |
4899 | * from memory. | 5605 | * from memory. |
4900 | */ | 5606 | */ |
4901 | 5607 | ||
@@ -4919,7 +5625,6 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) | |||
4919 | pci_disable_device(pdev); | 5625 | pci_disable_device(pdev); |
4920 | pci_release_regions(pdev); | 5626 | pci_release_regions(pdev); |
4921 | pci_set_drvdata(pdev, NULL); | 5627 | pci_set_drvdata(pdev, NULL); |
4922 | |||
4923 | free_netdev(dev); | 5628 | free_netdev(dev); |
4924 | } | 5629 | } |
4925 | 5630 | ||
@@ -4935,11 +5640,11 @@ int __init s2io_starter(void) | |||
4935 | } | 5640 | } |
4936 | 5641 | ||
4937 | /** | 5642 | /** |
4938 | * s2io_closer - Cleanup routine for the driver | 5643 | * s2io_closer - Cleanup routine for the driver |
4939 | * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. | 5644 | * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. |
4940 | */ | 5645 | */ |
4941 | 5646 | ||
4942 | static void s2io_closer(void) | 5647 | void s2io_closer(void) |
4943 | { | 5648 | { |
4944 | pci_unregister_driver(&s2io_driver); | 5649 | pci_unregister_driver(&s2io_driver); |
4945 | DBG_PRINT(INIT_DBG, "cleanup done\n"); | 5650 | DBG_PRINT(INIT_DBG, "cleanup done\n"); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 1711c8c3dc99..bc64d967f080 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -31,6 +31,9 @@ | |||
31 | #define SUCCESS 0 | 31 | #define SUCCESS 0 |
32 | #define FAILURE -1 | 32 | #define FAILURE -1 |
33 | 33 | ||
34 | /* Maximum time to flicker LED when asked to identify NIC using ethtool */ | ||
35 | #define MAX_FLICKER_TIME 60000 /* 60 Secs */ | ||
36 | |||
34 | /* Maximum outstanding splits to be configured into xena. */ | 37 | /* Maximum outstanding splits to be configured into xena. */ |
35 | typedef enum xena_max_outstanding_splits { | 38 | typedef enum xena_max_outstanding_splits { |
36 | XENA_ONE_SPLIT_TRANSACTION = 0, | 39 | XENA_ONE_SPLIT_TRANSACTION = 0, |
@@ -45,10 +48,10 @@ typedef enum xena_max_outstanding_splits { | |||
45 | #define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4) | 48 | #define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4) |
46 | 49 | ||
47 | /* OS concerned variables and constants */ | 50 | /* OS concerned variables and constants */ |
48 | #define WATCH_DOG_TIMEOUT 5*HZ | 51 | #define WATCH_DOG_TIMEOUT 15*HZ |
49 | #define EFILL 0x1234 | 52 | #define EFILL 0x1234 |
50 | #define ALIGN_SIZE 127 | 53 | #define ALIGN_SIZE 127 |
51 | #define PCIX_COMMAND_REGISTER 0x62 | 54 | #define PCIX_COMMAND_REGISTER 0x62 |
52 | 55 | ||
53 | /* | 56 | /* |
54 | * Debug related variables. | 57 | * Debug related variables. |
@@ -61,7 +64,7 @@ typedef enum xena_max_outstanding_splits { | |||
61 | #define INTR_DBG 4 | 64 | #define INTR_DBG 4 |
62 | 65 | ||
63 | /* Global variable that defines the present debug level of the driver. */ | 66 | /* Global variable that defines the present debug level of the driver. */ |
64 | static int debug_level = ERR_DBG; /* Default level. */ | 67 | int debug_level = ERR_DBG; /* Default level. */ |
65 | 68 | ||
66 | /* DEBUG message print. */ | 69 | /* DEBUG message print. */ |
67 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) | 70 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) |
@@ -71,6 +74,12 @@ static int debug_level = ERR_DBG; /* Default level. */ | |||
71 | #define L4_CKSUM_OK 0xFFFF | 74 | #define L4_CKSUM_OK 0xFFFF |
72 | #define S2IO_JUMBO_SIZE 9600 | 75 | #define S2IO_JUMBO_SIZE 9600 |
73 | 76 | ||
77 | /* Driver statistics maintained by driver */ | ||
78 | typedef struct { | ||
79 | unsigned long long single_ecc_errs; | ||
80 | unsigned long long double_ecc_errs; | ||
81 | } swStat_t; | ||
82 | |||
74 | /* The statistics block of Xena */ | 83 | /* The statistics block of Xena */ |
75 | typedef struct stat_block { | 84 | typedef struct stat_block { |
76 | /* Tx MAC statistics counters. */ | 85 | /* Tx MAC statistics counters. */ |
@@ -186,12 +195,90 @@ typedef struct stat_block { | |||
186 | u32 rxd_rd_cnt; | 195 | u32 rxd_rd_cnt; |
187 | u32 rxf_wr_cnt; | 196 | u32 rxf_wr_cnt; |
188 | u32 txf_rd_cnt; | 197 | u32 txf_rd_cnt; |
198 | |||
199 | /* Tx MAC statistics overflow counters. */ | ||
200 | u32 tmac_data_octets_oflow; | ||
201 | u32 tmac_frms_oflow; | ||
202 | u32 tmac_bcst_frms_oflow; | ||
203 | u32 tmac_mcst_frms_oflow; | ||
204 | u32 tmac_ucst_frms_oflow; | ||
205 | u32 tmac_ttl_octets_oflow; | ||
206 | u32 tmac_any_err_frms_oflow; | ||
207 | u32 tmac_nucst_frms_oflow; | ||
208 | u64 tmac_vlan_frms; | ||
209 | u32 tmac_drop_ip_oflow; | ||
210 | u32 tmac_vld_ip_oflow; | ||
211 | u32 tmac_rst_tcp_oflow; | ||
212 | u32 tmac_icmp_oflow; | ||
213 | u32 tpa_unknown_protocol; | ||
214 | u32 tmac_udp_oflow; | ||
215 | u32 reserved_10; | ||
216 | u32 tpa_parse_failure; | ||
217 | |||
218 | /* Rx MAC Statistics overflow counters. */ | ||
219 | u32 rmac_data_octets_oflow; | ||
220 | u32 rmac_vld_frms_oflow; | ||
221 | u32 rmac_vld_bcst_frms_oflow; | ||
222 | u32 rmac_vld_mcst_frms_oflow; | ||
223 | u32 rmac_accepted_ucst_frms_oflow; | ||
224 | u32 rmac_ttl_octets_oflow; | ||
225 | u32 rmac_discarded_frms_oflow; | ||
226 | u32 rmac_accepted_nucst_frms_oflow; | ||
227 | u32 rmac_usized_frms_oflow; | ||
228 | u32 rmac_drop_events_oflow; | ||
229 | u32 rmac_frag_frms_oflow; | ||
230 | u32 rmac_osized_frms_oflow; | ||
231 | u32 rmac_ip_oflow; | ||
232 | u32 rmac_jabber_frms_oflow; | ||
233 | u32 rmac_icmp_oflow; | ||
234 | u32 rmac_drop_ip_oflow; | ||
235 | u32 rmac_err_drp_udp_oflow; | ||
236 | u32 rmac_udp_oflow; | ||
237 | u32 reserved_11; | ||
238 | u32 rmac_pause_cnt_oflow; | ||
239 | u64 rmac_ttl_1519_4095_frms; | ||
240 | u64 rmac_ttl_4096_8191_frms; | ||
241 | u64 rmac_ttl_8192_max_frms; | ||
242 | u64 rmac_ttl_gt_max_frms; | ||
243 | u64 rmac_osized_alt_frms; | ||
244 | u64 rmac_jabber_alt_frms; | ||
245 | u64 rmac_gt_max_alt_frms; | ||
246 | u64 rmac_vlan_frms; | ||
247 | u32 rmac_len_discard; | ||
248 | u32 rmac_fcs_discard; | ||
249 | u32 rmac_pf_discard; | ||
250 | u32 rmac_da_discard; | ||
251 | u32 rmac_red_discard; | ||
252 | u32 rmac_rts_discard; | ||
253 | u32 reserved_12; | ||
254 | u32 rmac_ingm_full_discard; | ||
255 | u32 reserved_13; | ||
256 | u32 rmac_accepted_ip_oflow; | ||
257 | u32 reserved_14; | ||
258 | u32 link_fault_cnt; | ||
259 | swStat_t sw_stat; | ||
189 | } StatInfo_t; | 260 | } StatInfo_t; |
190 | 261 | ||
191 | /* Structures representing different init time configuration | 262 | /* |
263 | * Structures representing different init time configuration | ||
192 | * parameters of the NIC. | 264 | * parameters of the NIC. |
193 | */ | 265 | */ |
194 | 266 | ||
267 | #define MAX_TX_FIFOS 8 | ||
268 | #define MAX_RX_RINGS 8 | ||
269 | |||
270 | /* FIFO mappings for all possible number of fifos configured */ | ||
271 | int fifo_map[][MAX_TX_FIFOS] = { | ||
272 | {0, 0, 0, 0, 0, 0, 0, 0}, | ||
273 | {0, 0, 0, 0, 1, 1, 1, 1}, | ||
274 | {0, 0, 0, 1, 1, 1, 2, 2}, | ||
275 | {0, 0, 1, 1, 2, 2, 3, 3}, | ||
276 | {0, 0, 1, 1, 2, 2, 3, 4}, | ||
277 | {0, 0, 1, 1, 2, 3, 4, 5}, | ||
278 | {0, 0, 1, 2, 3, 4, 5, 6}, | ||
279 | {0, 1, 2, 3, 4, 5, 6, 7}, | ||
280 | }; | ||
281 | |||
195 | /* Maintains Per FIFO related information. */ | 282 | /* Maintains Per FIFO related information. */ |
196 | typedef struct tx_fifo_config { | 283 | typedef struct tx_fifo_config { |
197 | #define MAX_AVAILABLE_TXDS 8192 | 284 | #define MAX_AVAILABLE_TXDS 8192 |
@@ -237,14 +324,14 @@ typedef struct rx_ring_config { | |||
237 | #define NO_SNOOP_RXD_BUFFER 0x02 | 324 | #define NO_SNOOP_RXD_BUFFER 0x02 |
238 | } rx_ring_config_t; | 325 | } rx_ring_config_t; |
239 | 326 | ||
240 | /* This structure provides contains values of the tunable parameters | 327 | /* This structure provides contains values of the tunable parameters |
241 | * of the H/W | 328 | * of the H/W |
242 | */ | 329 | */ |
243 | struct config_param { | 330 | struct config_param { |
244 | /* Tx Side */ | 331 | /* Tx Side */ |
245 | u32 tx_fifo_num; /*Number of Tx FIFOs */ | 332 | u32 tx_fifo_num; /*Number of Tx FIFOs */ |
246 | #define MAX_TX_FIFOS 8 | ||
247 | 333 | ||
334 | u8 fifo_mapping[MAX_TX_FIFOS]; | ||
248 | tx_fifo_config_t tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ | 335 | tx_fifo_config_t tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ |
249 | u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ | 336 | u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ |
250 | u64 tx_intr_type; | 337 | u64 tx_intr_type; |
@@ -252,10 +339,10 @@ struct config_param { | |||
252 | 339 | ||
253 | /* Rx Side */ | 340 | /* Rx Side */ |
254 | u32 rx_ring_num; /*Number of receive rings */ | 341 | u32 rx_ring_num; /*Number of receive rings */ |
255 | #define MAX_RX_RINGS 8 | ||
256 | #define MAX_RX_BLOCKS_PER_RING 150 | 342 | #define MAX_RX_BLOCKS_PER_RING 150 |
257 | 343 | ||
258 | rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ | 344 | rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ |
345 | u8 bimodal; /*Flag for setting bimodal interrupts*/ | ||
259 | 346 | ||
260 | #define HEADER_ETHERNET_II_802_3_SIZE 14 | 347 | #define HEADER_ETHERNET_II_802_3_SIZE 14 |
261 | #define HEADER_802_2_SIZE 3 | 348 | #define HEADER_802_2_SIZE 3 |
@@ -269,6 +356,7 @@ struct config_param { | |||
269 | #define MAX_PYLD_JUMBO 9600 | 356 | #define MAX_PYLD_JUMBO 9600 |
270 | #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) | 357 | #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) |
271 | #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) | 358 | #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) |
359 | u16 bus_speed; | ||
272 | }; | 360 | }; |
273 | 361 | ||
274 | /* Structure representing MAC Addrs */ | 362 | /* Structure representing MAC Addrs */ |
@@ -277,7 +365,7 @@ typedef struct mac_addr { | |||
277 | } macaddr_t; | 365 | } macaddr_t; |
278 | 366 | ||
279 | /* Structure that represent every FIFO element in the BAR1 | 367 | /* Structure that represent every FIFO element in the BAR1 |
280 | * Address location. | 368 | * Address location. |
281 | */ | 369 | */ |
282 | typedef struct _TxFIFO_element { | 370 | typedef struct _TxFIFO_element { |
283 | u64 TxDL_Pointer; | 371 | u64 TxDL_Pointer; |
@@ -339,6 +427,7 @@ typedef struct _RxD_t { | |||
339 | #define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) | 427 | #define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) |
340 | #define RXD_FRAME_PROTO_IPV4 BIT(27) | 428 | #define RXD_FRAME_PROTO_IPV4 BIT(27) |
341 | #define RXD_FRAME_PROTO_IPV6 BIT(28) | 429 | #define RXD_FRAME_PROTO_IPV6 BIT(28) |
430 | #define RXD_FRAME_IP_FRAG BIT(29) | ||
342 | #define RXD_FRAME_PROTO_TCP BIT(30) | 431 | #define RXD_FRAME_PROTO_TCP BIT(30) |
343 | #define RXD_FRAME_PROTO_UDP BIT(31) | 432 | #define RXD_FRAME_PROTO_UDP BIT(31) |
344 | #define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP) | 433 | #define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP) |
@@ -346,11 +435,15 @@ typedef struct _RxD_t { | |||
346 | #define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF) | 435 | #define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF) |
347 | 436 | ||
348 | u64 Control_2; | 437 | u64 Control_2; |
438 | #define THE_RXD_MARK 0x3 | ||
439 | #define SET_RXD_MARKER vBIT(THE_RXD_MARK, 0, 2) | ||
440 | #define GET_RXD_MARKER(ctrl) ((ctrl & SET_RXD_MARKER) >> 62) | ||
441 | |||
349 | #ifndef CONFIG_2BUFF_MODE | 442 | #ifndef CONFIG_2BUFF_MODE |
350 | #define MASK_BUFFER0_SIZE vBIT(0xFFFF,0,16) | 443 | #define MASK_BUFFER0_SIZE vBIT(0x3FFF,2,14) |
351 | #define SET_BUFFER0_SIZE(val) vBIT(val,0,16) | 444 | #define SET_BUFFER0_SIZE(val) vBIT(val,2,14) |
352 | #else | 445 | #else |
353 | #define MASK_BUFFER0_SIZE vBIT(0xFF,0,16) | 446 | #define MASK_BUFFER0_SIZE vBIT(0xFF,2,14) |
354 | #define MASK_BUFFER1_SIZE vBIT(0xFFFF,16,16) | 447 | #define MASK_BUFFER1_SIZE vBIT(0xFFFF,16,16) |
355 | #define MASK_BUFFER2_SIZE vBIT(0xFFFF,32,16) | 448 | #define MASK_BUFFER2_SIZE vBIT(0xFFFF,32,16) |
356 | #define SET_BUFFER0_SIZE(val) vBIT(val,8,8) | 449 | #define SET_BUFFER0_SIZE(val) vBIT(val,8,8) |
@@ -363,7 +456,7 @@ typedef struct _RxD_t { | |||
363 | #define SET_NUM_TAG(val) vBIT(val,16,32) | 456 | #define SET_NUM_TAG(val) vBIT(val,16,32) |
364 | 457 | ||
365 | #ifndef CONFIG_2BUFF_MODE | 458 | #ifndef CONFIG_2BUFF_MODE |
366 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0xFFFF,0,16))) | 459 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0x3FFF,2,14))) |
367 | #else | 460 | #else |
368 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \ | 461 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \ |
369 | >> 48) | 462 | >> 48) |
@@ -382,7 +475,7 @@ typedef struct _RxD_t { | |||
382 | #endif | 475 | #endif |
383 | } RxD_t; | 476 | } RxD_t; |
384 | 477 | ||
385 | /* Structure that represents the Rx descriptor block which contains | 478 | /* Structure that represents the Rx descriptor block which contains |
386 | * 128 Rx descriptors. | 479 | * 128 Rx descriptors. |
387 | */ | 480 | */ |
388 | #ifndef CONFIG_2BUFF_MODE | 481 | #ifndef CONFIG_2BUFF_MODE |
@@ -392,11 +485,11 @@ typedef struct _RxD_block { | |||
392 | 485 | ||
393 | u64 reserved_0; | 486 | u64 reserved_0; |
394 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL | 487 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL |
395 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last | 488 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last |
396 | * Rxd in this blk */ | 489 | * Rxd in this blk */ |
397 | u64 reserved_2_pNext_RxD_block; /* Logical ptr to next */ | 490 | u64 reserved_2_pNext_RxD_block; /* Logical ptr to next */ |
398 | u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch | 491 | u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch |
399 | * the upper 32 bits should | 492 | * the upper 32 bits should |
400 | * be 0 */ | 493 | * be 0 */ |
401 | } RxD_block_t; | 494 | } RxD_block_t; |
402 | #else | 495 | #else |
@@ -405,13 +498,13 @@ typedef struct _RxD_block { | |||
405 | RxD_t rxd[MAX_RXDS_PER_BLOCK]; | 498 | RxD_t rxd[MAX_RXDS_PER_BLOCK]; |
406 | 499 | ||
407 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL | 500 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL |
408 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd | 501 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd |
409 | * in this blk */ | 502 | * in this blk */ |
410 | u64 pNext_RxD_Blk_physical; /* Phy ponter to next blk. */ | 503 | u64 pNext_RxD_Blk_physical; /* Phy ponter to next blk. */ |
411 | } RxD_block_t; | 504 | } RxD_block_t; |
412 | #define SIZE_OF_BLOCK 4096 | 505 | #define SIZE_OF_BLOCK 4096 |
413 | 506 | ||
414 | /* Structure to hold virtual addresses of Buf0 and Buf1 in | 507 | /* Structure to hold virtual addresses of Buf0 and Buf1 in |
415 | * 2buf mode. */ | 508 | * 2buf mode. */ |
416 | typedef struct bufAdd { | 509 | typedef struct bufAdd { |
417 | void *ba_0_org; | 510 | void *ba_0_org; |
@@ -423,8 +516,8 @@ typedef struct bufAdd { | |||
423 | 516 | ||
424 | /* Structure which stores all the MAC control parameters */ | 517 | /* Structure which stores all the MAC control parameters */ |
425 | 518 | ||
426 | /* This structure stores the offset of the RxD in the ring | 519 | /* This structure stores the offset of the RxD in the ring |
427 | * from which the Rx Interrupt processor can start picking | 520 | * from which the Rx Interrupt processor can start picking |
428 | * up the RxDs for processing. | 521 | * up the RxDs for processing. |
429 | */ | 522 | */ |
430 | typedef struct _rx_curr_get_info_t { | 523 | typedef struct _rx_curr_get_info_t { |
@@ -436,7 +529,7 @@ typedef struct _rx_curr_get_info_t { | |||
436 | typedef rx_curr_get_info_t rx_curr_put_info_t; | 529 | typedef rx_curr_get_info_t rx_curr_put_info_t; |
437 | 530 | ||
438 | /* This structure stores the offset of the TxDl in the FIFO | 531 | /* This structure stores the offset of the TxDl in the FIFO |
439 | * from which the Tx Interrupt processor can start picking | 532 | * from which the Tx Interrupt processor can start picking |
440 | * up the TxDLs for send complete interrupt processing. | 533 | * up the TxDLs for send complete interrupt processing. |
441 | */ | 534 | */ |
442 | typedef struct { | 535 | typedef struct { |
@@ -446,32 +539,96 @@ typedef struct { | |||
446 | 539 | ||
447 | typedef tx_curr_get_info_t tx_curr_put_info_t; | 540 | typedef tx_curr_get_info_t tx_curr_put_info_t; |
448 | 541 | ||
449 | /* Infomation related to the Tx and Rx FIFOs and Rings of Xena | 542 | /* Structure that holds the Phy and virt addresses of the Blocks */ |
450 | * is maintained in this structure. | 543 | typedef struct rx_block_info { |
451 | */ | 544 | RxD_t *block_virt_addr; |
452 | typedef struct mac_info { | 545 | dma_addr_t block_dma_addr; |
453 | /* rx side stuff */ | 546 | } rx_block_info_t; |
454 | /* Put pointer info which indictes which RxD has to be replenished | 547 | |
548 | /* pre declaration of the nic structure */ | ||
549 | typedef struct s2io_nic nic_t; | ||
550 | |||
551 | /* Ring specific structure */ | ||
552 | typedef struct ring_info { | ||
553 | /* The ring number */ | ||
554 | int ring_no; | ||
555 | |||
556 | /* | ||
557 | * Place holders for the virtual and physical addresses of | ||
558 | * all the Rx Blocks | ||
559 | */ | ||
560 | rx_block_info_t rx_blocks[MAX_RX_BLOCKS_PER_RING]; | ||
561 | int block_count; | ||
562 | int pkt_cnt; | ||
563 | |||
564 | /* | ||
565 | * Put pointer info which indictes which RxD has to be replenished | ||
455 | * with a new buffer. | 566 | * with a new buffer. |
456 | */ | 567 | */ |
457 | rx_curr_put_info_t rx_curr_put_info[MAX_RX_RINGS]; | 568 | rx_curr_put_info_t rx_curr_put_info; |
458 | 569 | ||
459 | /* Get pointer info which indictes which is the last RxD that was | 570 | /* |
571 | * Get pointer info which indictes which is the last RxD that was | ||
460 | * processed by the driver. | 572 | * processed by the driver. |
461 | */ | 573 | */ |
462 | rx_curr_get_info_t rx_curr_get_info[MAX_RX_RINGS]; | 574 | rx_curr_get_info_t rx_curr_get_info; |
463 | 575 | ||
464 | u16 rmac_pause_time; | 576 | #ifndef CONFIG_S2IO_NAPI |
465 | u16 mc_pause_threshold_q0q3; | 577 | /* Index to the absolute position of the put pointer of Rx ring */ |
466 | u16 mc_pause_threshold_q4q7; | 578 | int put_pos; |
579 | #endif | ||
580 | |||
581 | #ifdef CONFIG_2BUFF_MODE | ||
582 | /* Buffer Address store. */ | ||
583 | buffAdd_t **ba; | ||
584 | #endif | ||
585 | nic_t *nic; | ||
586 | } ring_info_t; | ||
467 | 587 | ||
588 | /* Fifo specific structure */ | ||
589 | typedef struct fifo_info { | ||
590 | /* FIFO number */ | ||
591 | int fifo_no; | ||
592 | |||
593 | /* Maximum TxDs per TxDL */ | ||
594 | int max_txds; | ||
595 | |||
596 | /* Place holder of all the TX List's Phy and Virt addresses. */ | ||
597 | list_info_hold_t *list_info; | ||
598 | |||
599 | /* | ||
600 | * Current offset within the tx FIFO where driver would write | ||
601 | * new Tx frame | ||
602 | */ | ||
603 | tx_curr_put_info_t tx_curr_put_info; | ||
604 | |||
605 | /* | ||
606 | * Current offset within tx FIFO from where the driver would start freeing | ||
607 | * the buffers | ||
608 | */ | ||
609 | tx_curr_get_info_t tx_curr_get_info; | ||
610 | |||
611 | nic_t *nic; | ||
612 | }fifo_info_t; | ||
613 | |||
614 | /* Infomation related to the Tx and Rx FIFOs and Rings of Xena | ||
615 | * is maintained in this structure. | ||
616 | */ | ||
617 | typedef struct mac_info { | ||
468 | /* tx side stuff */ | 618 | /* tx side stuff */ |
469 | /* logical pointer of start of each Tx FIFO */ | 619 | /* logical pointer of start of each Tx FIFO */ |
470 | TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS]; | 620 | TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS]; |
471 | 621 | ||
472 | /* Current offset within tx_FIFO_start, where driver would write new Tx frame*/ | 622 | /* Fifo specific structure */ |
473 | tx_curr_put_info_t tx_curr_put_info[MAX_TX_FIFOS]; | 623 | fifo_info_t fifos[MAX_TX_FIFOS]; |
474 | tx_curr_get_info_t tx_curr_get_info[MAX_TX_FIFOS]; | 624 | |
625 | /* rx side stuff */ | ||
626 | /* Ring specific structure */ | ||
627 | ring_info_t rings[MAX_RX_RINGS]; | ||
628 | |||
629 | u16 rmac_pause_time; | ||
630 | u16 mc_pause_threshold_q0q3; | ||
631 | u16 mc_pause_threshold_q4q7; | ||
475 | 632 | ||
476 | void *stats_mem; /* orignal pointer to allocated mem */ | 633 | void *stats_mem; /* orignal pointer to allocated mem */ |
477 | dma_addr_t stats_mem_phy; /* Physical address of the stat block */ | 634 | dma_addr_t stats_mem_phy; /* Physical address of the stat block */ |
@@ -485,12 +642,6 @@ typedef struct { | |||
485 | int usage_cnt; | 642 | int usage_cnt; |
486 | } usr_addr_t; | 643 | } usr_addr_t; |
487 | 644 | ||
488 | /* Structure that holds the Phy and virt addresses of the Blocks */ | ||
489 | typedef struct rx_block_info { | ||
490 | RxD_t *block_virt_addr; | ||
491 | dma_addr_t block_dma_addr; | ||
492 | } rx_block_info_t; | ||
493 | |||
494 | /* Default Tunable parameters of the NIC. */ | 645 | /* Default Tunable parameters of the NIC. */ |
495 | #define DEFAULT_FIFO_LEN 4096 | 646 | #define DEFAULT_FIFO_LEN 4096 |
496 | #define SMALL_RXD_CNT 30 * (MAX_RXDS_PER_BLOCK+1) | 647 | #define SMALL_RXD_CNT 30 * (MAX_RXDS_PER_BLOCK+1) |
@@ -499,7 +650,20 @@ typedef struct rx_block_info { | |||
499 | #define LARGE_BLK_CNT 100 | 650 | #define LARGE_BLK_CNT 100 |
500 | 651 | ||
501 | /* Structure representing one instance of the NIC */ | 652 | /* Structure representing one instance of the NIC */ |
502 | typedef struct s2io_nic { | 653 | struct s2io_nic { |
654 | #ifdef CONFIG_S2IO_NAPI | ||
655 | /* | ||
656 | * Count of packets to be processed in a given iteration, it will be indicated | ||
657 | * by the quota field of the device structure when NAPI is enabled. | ||
658 | */ | ||
659 | int pkts_to_process; | ||
660 | #endif | ||
661 | struct net_device *dev; | ||
662 | mac_info_t mac_control; | ||
663 | struct config_param config; | ||
664 | struct pci_dev *pdev; | ||
665 | void __iomem *bar0; | ||
666 | void __iomem *bar1; | ||
503 | #define MAX_MAC_SUPPORTED 16 | 667 | #define MAX_MAC_SUPPORTED 16 |
504 | #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED | 668 | #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED |
505 | 669 | ||
@@ -507,33 +671,20 @@ typedef struct s2io_nic { | |||
507 | macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED]; | 671 | macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED]; |
508 | 672 | ||
509 | struct net_device_stats stats; | 673 | struct net_device_stats stats; |
510 | void __iomem *bar0; | ||
511 | void __iomem *bar1; | ||
512 | struct config_param config; | ||
513 | mac_info_t mac_control; | ||
514 | int high_dma_flag; | 674 | int high_dma_flag; |
515 | int device_close_flag; | 675 | int device_close_flag; |
516 | int device_enabled_once; | 676 | int device_enabled_once; |
517 | 677 | ||
518 | char name[32]; | 678 | char name[50]; |
519 | struct tasklet_struct task; | 679 | struct tasklet_struct task; |
520 | volatile unsigned long tasklet_status; | 680 | volatile unsigned long tasklet_status; |
521 | struct timer_list timer; | ||
522 | struct net_device *dev; | ||
523 | struct pci_dev *pdev; | ||
524 | 681 | ||
525 | u16 vendor_id; | 682 | /* Timer that handles I/O errors/exceptions */ |
526 | u16 device_id; | 683 | struct timer_list alarm_timer; |
527 | u16 ccmd; | 684 | |
528 | u32 cbar0_1; | 685 | /* Space to back up the PCI config space */ |
529 | u32 cbar0_2; | 686 | u32 config_space[256 / sizeof(u32)]; |
530 | u32 cbar1_1; | 687 | |
531 | u32 cbar1_2; | ||
532 | u32 cirq; | ||
533 | u8 cache_line; | ||
534 | u32 rom_expansion; | ||
535 | u16 pcix_cmd; | ||
536 | u32 irq; | ||
537 | atomic_t rx_bufs_left[MAX_RX_RINGS]; | 688 | atomic_t rx_bufs_left[MAX_RX_RINGS]; |
538 | 689 | ||
539 | spinlock_t tx_lock; | 690 | spinlock_t tx_lock; |
@@ -558,27 +709,11 @@ typedef struct s2io_nic { | |||
558 | u16 tx_err_count; | 709 | u16 tx_err_count; |
559 | u16 rx_err_count; | 710 | u16 rx_err_count; |
560 | 711 | ||
561 | #ifndef CONFIG_S2IO_NAPI | ||
562 | /* Index to the absolute position of the put pointer of Rx ring. */ | ||
563 | int put_pos[MAX_RX_RINGS]; | ||
564 | #endif | ||
565 | |||
566 | /* | ||
567 | * Place holders for the virtual and physical addresses of | ||
568 | * all the Rx Blocks | ||
569 | */ | ||
570 | rx_block_info_t rx_blocks[MAX_RX_RINGS][MAX_RX_BLOCKS_PER_RING]; | ||
571 | int block_count[MAX_RX_RINGS]; | ||
572 | int pkt_cnt[MAX_RX_RINGS]; | ||
573 | |||
574 | /* Place holder of all the TX List's Phy and Virt addresses. */ | ||
575 | list_info_hold_t *list_info[MAX_TX_FIFOS]; | ||
576 | |||
577 | /* Id timer, used to blink NIC to physically identify NIC. */ | 712 | /* Id timer, used to blink NIC to physically identify NIC. */ |
578 | struct timer_list id_timer; | 713 | struct timer_list id_timer; |
579 | 714 | ||
580 | /* Restart timer, used to restart NIC if the device is stuck and | 715 | /* Restart timer, used to restart NIC if the device is stuck and |
581 | * a schedule task that will set the correct Link state once the | 716 | * a schedule task that will set the correct Link state once the |
582 | * NIC's PHY has stabilized after a state change. | 717 | * NIC's PHY has stabilized after a state change. |
583 | */ | 718 | */ |
584 | #ifdef INIT_TQUEUE | 719 | #ifdef INIT_TQUEUE |
@@ -589,12 +724,12 @@ typedef struct s2io_nic { | |||
589 | struct work_struct set_link_task; | 724 | struct work_struct set_link_task; |
590 | #endif | 725 | #endif |
591 | 726 | ||
592 | /* Flag that can be used to turn on or turn off the Rx checksum | 727 | /* Flag that can be used to turn on or turn off the Rx checksum |
593 | * offload feature. | 728 | * offload feature. |
594 | */ | 729 | */ |
595 | int rx_csum; | 730 | int rx_csum; |
596 | 731 | ||
597 | /* after blink, the adapter must be restored with original | 732 | /* after blink, the adapter must be restored with original |
598 | * values. | 733 | * values. |
599 | */ | 734 | */ |
600 | u64 adapt_ctrl_org; | 735 | u64 adapt_ctrl_org; |
@@ -604,16 +739,19 @@ typedef struct s2io_nic { | |||
604 | #define LINK_DOWN 1 | 739 | #define LINK_DOWN 1 |
605 | #define LINK_UP 2 | 740 | #define LINK_UP 2 |
606 | 741 | ||
607 | #ifdef CONFIG_2BUFF_MODE | ||
608 | /* Buffer Address store. */ | ||
609 | buffAdd_t **ba[MAX_RX_RINGS]; | ||
610 | #endif | ||
611 | int task_flag; | 742 | int task_flag; |
612 | #define CARD_DOWN 1 | 743 | #define CARD_DOWN 1 |
613 | #define CARD_UP 2 | 744 | #define CARD_UP 2 |
614 | atomic_t card_state; | 745 | atomic_t card_state; |
615 | volatile unsigned long link_state; | 746 | volatile unsigned long link_state; |
616 | } nic_t; | 747 | struct vlan_group *vlgrp; |
748 | #define XFRAME_I_DEVICE 1 | ||
749 | #define XFRAME_II_DEVICE 2 | ||
750 | u8 device_type; | ||
751 | |||
752 | spinlock_t rx_lock; | ||
753 | atomic_t isr_cnt; | ||
754 | }; | ||
617 | 755 | ||
618 | #define RESET_ERROR 1; | 756 | #define RESET_ERROR 1; |
619 | #define CMD_ERROR 2; | 757 | #define CMD_ERROR 2; |
@@ -622,7 +760,8 @@ typedef struct s2io_nic { | |||
622 | #ifndef readq | 760 | #ifndef readq |
623 | static inline u64 readq(void __iomem *addr) | 761 | static inline u64 readq(void __iomem *addr) |
624 | { | 762 | { |
625 | u64 ret = readl(addr + 4); | 763 | u64 ret = 0; |
764 | ret = readl(addr + 4); | ||
626 | ret <<= 32; | 765 | ret <<= 32; |
627 | ret |= readl(addr); | 766 | ret |= readl(addr); |
628 | 767 | ||
@@ -637,10 +776,10 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
637 | writel((u32) (val >> 32), (addr + 4)); | 776 | writel((u32) (val >> 32), (addr + 4)); |
638 | } | 777 | } |
639 | 778 | ||
640 | /* In 32 bit modes, some registers have to be written in a | 779 | /* In 32 bit modes, some registers have to be written in a |
641 | * particular order to expect correct hardware operation. The | 780 | * particular order to expect correct hardware operation. The |
642 | * macro SPECIAL_REG_WRITE is used to perform such ordered | 781 | * macro SPECIAL_REG_WRITE is used to perform such ordered |
643 | * writes. Defines UF (Upper First) and LF (Lower First) will | 782 | * writes. Defines UF (Upper First) and LF (Lower First) will |
644 | * be used to specify the required write order. | 783 | * be used to specify the required write order. |
645 | */ | 784 | */ |
646 | #define UF 1 | 785 | #define UF 1 |
@@ -716,6 +855,7 @@ static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order) | |||
716 | #define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate | 855 | #define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate |
717 | PCC_FB_ECC Error. */ | 856 | PCC_FB_ECC Error. */ |
718 | 857 | ||
858 | #define RXD_GET_VLAN_TAG(Control_2) (u16)(Control_2 & MASK_VLAN_TAG) | ||
719 | /* | 859 | /* |
720 | * Prototype declaration. | 860 | * Prototype declaration. |
721 | */ | 861 | */ |
@@ -725,36 +865,30 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev); | |||
725 | static int init_shared_mem(struct s2io_nic *sp); | 865 | static int init_shared_mem(struct s2io_nic *sp); |
726 | static void free_shared_mem(struct s2io_nic *sp); | 866 | static void free_shared_mem(struct s2io_nic *sp); |
727 | static int init_nic(struct s2io_nic *nic); | 867 | static int init_nic(struct s2io_nic *nic); |
728 | #ifndef CONFIG_S2IO_NAPI | 868 | static void rx_intr_handler(ring_info_t *ring_data); |
729 | static void rx_intr_handler(struct s2io_nic *sp); | 869 | static void tx_intr_handler(fifo_info_t *fifo_data); |
730 | #endif | ||
731 | static void tx_intr_handler(struct s2io_nic *sp); | ||
732 | static void alarm_intr_handler(struct s2io_nic *sp); | 870 | static void alarm_intr_handler(struct s2io_nic *sp); |
733 | 871 | ||
734 | static int s2io_starter(void); | 872 | static int s2io_starter(void); |
735 | static void s2io_closer(void); | 873 | void s2io_closer(void); |
736 | static void s2io_tx_watchdog(struct net_device *dev); | 874 | static void s2io_tx_watchdog(struct net_device *dev); |
737 | static void s2io_tasklet(unsigned long dev_addr); | 875 | static void s2io_tasklet(unsigned long dev_addr); |
738 | static void s2io_set_multicast(struct net_device *dev); | 876 | static void s2io_set_multicast(struct net_device *dev); |
739 | #ifndef CONFIG_2BUFF_MODE | 877 | static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp); |
740 | static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no); | 878 | void s2io_link(nic_t * sp, int link); |
741 | #else | 879 | void s2io_reset(nic_t * sp); |
742 | static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | 880 | #if defined(CONFIG_S2IO_NAPI) |
743 | buffAdd_t * ba); | ||
744 | #endif | ||
745 | static void s2io_link(nic_t * sp, int link); | ||
746 | static void s2io_reset(nic_t * sp); | ||
747 | #ifdef CONFIG_S2IO_NAPI | ||
748 | static int s2io_poll(struct net_device *dev, int *budget); | 881 | static int s2io_poll(struct net_device *dev, int *budget); |
749 | #endif | 882 | #endif |
750 | static void s2io_init_pci(nic_t * sp); | 883 | static void s2io_init_pci(nic_t * sp); |
751 | static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); | 884 | int s2io_set_mac_addr(struct net_device *dev, u8 * addr); |
885 | static void s2io_alarm_handle(unsigned long data); | ||
752 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); | 886 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); |
753 | static int verify_xena_quiescence(u64 val64, int flag); | 887 | static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); |
754 | static struct ethtool_ops netdev_ethtool_ops; | 888 | static struct ethtool_ops netdev_ethtool_ops; |
755 | static void s2io_set_link(unsigned long data); | 889 | static void s2io_set_link(unsigned long data); |
756 | static int s2io_set_swapper(nic_t * sp); | 890 | int s2io_set_swapper(nic_t * sp); |
757 | static void s2io_card_down(nic_t * nic); | 891 | static void s2io_card_down(nic_t *nic); |
758 | static int s2io_card_up(nic_t * nic); | 892 | static int s2io_card_up(nic_t *nic); |
759 | 893 | int get_xena_rev_id(struct pci_dev *pdev); | |
760 | #endif /* _S2IO_H */ | 894 | #endif /* _S2IO_H */ |
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 3ad0b6751f6f..221354eea21f 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c | |||
@@ -156,52 +156,6 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
156 | 156 | ||
157 | SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb); | 157 | SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb); |
158 | 158 | ||
159 | #ifdef SHAPER_COMPLEX /* and broken.. */ | ||
160 | |||
161 | while(ptr && ptr!=(struct sk_buff *)&shaper->sendq) | ||
162 | { | ||
163 | if(ptr->pri<skb->pri | ||
164 | && jiffies - SHAPERCB(ptr)->shapeclock < SHAPER_MAXSLIP) | ||
165 | { | ||
166 | struct sk_buff *tmp=ptr->prev; | ||
167 | |||
168 | /* | ||
169 | * It goes before us therefore we slip the length | ||
170 | * of the new frame. | ||
171 | */ | ||
172 | |||
173 | SHAPERCB(ptr)->shapeclock+=SHAPERCB(skb)->shapelen; | ||
174 | SHAPERCB(ptr)->shapelatency+=SHAPERCB(skb)->shapelen; | ||
175 | |||
176 | /* | ||
177 | * The packet may have slipped so far back it | ||
178 | * fell off. | ||
179 | */ | ||
180 | if(SHAPERCB(ptr)->shapelatency > SHAPER_LATENCY) | ||
181 | { | ||
182 | skb_unlink(ptr); | ||
183 | dev_kfree_skb(ptr); | ||
184 | } | ||
185 | ptr=tmp; | ||
186 | } | ||
187 | else | ||
188 | break; | ||
189 | } | ||
190 | if(ptr==NULL || ptr==(struct sk_buff *)&shaper->sendq) | ||
191 | skb_queue_head(&shaper->sendq,skb); | ||
192 | else | ||
193 | { | ||
194 | struct sk_buff *tmp; | ||
195 | /* | ||
196 | * Set the packet clock out time according to the | ||
197 | * frames ahead. Im sure a bit of thought could drop | ||
198 | * this loop. | ||
199 | */ | ||
200 | for(tmp=skb_peek(&shaper->sendq); tmp!=NULL && tmp!=ptr; tmp=tmp->next) | ||
201 | SHAPERCB(skb)->shapeclock+=tmp->shapelen; | ||
202 | skb_append(ptr,skb); | ||
203 | } | ||
204 | #else | ||
205 | { | 159 | { |
206 | struct sk_buff *tmp; | 160 | struct sk_buff *tmp; |
207 | /* | 161 | /* |
@@ -220,7 +174,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
220 | } else | 174 | } else |
221 | skb_queue_tail(&shaper->sendq, skb); | 175 | skb_queue_tail(&shaper->sendq, skb); |
222 | } | 176 | } |
223 | #endif | 177 | |
224 | if(sh_debug) | 178 | if(sh_debug) |
225 | printk("Frame queued.\n"); | 179 | printk("Frame queued.\n"); |
226 | if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN) | 180 | if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN) |
@@ -302,7 +256,7 @@ static void shaper_kick(struct shaper *shaper) | |||
302 | * Pull the frame and get interrupts back on. | 256 | * Pull the frame and get interrupts back on. |
303 | */ | 257 | */ |
304 | 258 | ||
305 | skb_unlink(skb); | 259 | skb_unlink(skb, &shaper->sendq); |
306 | if (shaper->recovery < | 260 | if (shaper->recovery < |
307 | SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen) | 261 | SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen) |
308 | shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen; | 262 | shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen; |
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c new file mode 100644 index 000000000000..bf3440aa6c24 --- /dev/null +++ b/drivers/net/sis190.c | |||
@@ -0,0 +1,1843 @@ | |||
1 | /* | ||
2 | sis190.c: Silicon Integrated Systems SiS190 ethernet driver | ||
3 | |||
4 | Copyright (c) 2003 K.M. Liu <kmliu@sis.com> | ||
5 | Copyright (c) 2003, 2004 Jeff Garzik <jgarzik@pobox.com> | ||
6 | Copyright (c) 2003, 2004, 2005 Francois Romieu <romieu@fr.zoreil.com> | ||
7 | |||
8 | Based on r8169.c, tg3.c, 8139cp.c, skge.c, epic100.c and SiS 190/191 | ||
9 | genuine driver. | ||
10 | |||
11 | This software may be used and distributed according to the terms of | ||
12 | the GNU General Public License (GPL), incorporated herein by reference. | ||
13 | Drivers based on or derived from this code fall under the GPL and must | ||
14 | retain the authorship, copyright and license notice. This file is not | ||
15 | a complete program and may only be used when the entire operating | ||
16 | system is licensed under the GPL. | ||
17 | |||
18 | See the file COPYING in this distribution for more information. | ||
19 | |||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/moduleparam.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/rtnetlink.h> | ||
26 | #include <linux/etherdevice.h> | ||
27 | #include <linux/ethtool.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <linux/mii.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/crc32.h> | ||
32 | #include <linux/dma-mapping.h> | ||
33 | #include <asm/irq.h> | ||
34 | |||
35 | #define net_drv(p, arg...) if (netif_msg_drv(p)) \ | ||
36 | printk(arg) | ||
37 | #define net_probe(p, arg...) if (netif_msg_probe(p)) \ | ||
38 | printk(arg) | ||
39 | #define net_link(p, arg...) if (netif_msg_link(p)) \ | ||
40 | printk(arg) | ||
41 | #define net_intr(p, arg...) if (netif_msg_intr(p)) \ | ||
42 | printk(arg) | ||
43 | #define net_tx_err(p, arg...) if (netif_msg_tx_err(p)) \ | ||
44 | printk(arg) | ||
45 | |||
46 | #define PHY_MAX_ADDR 32 | ||
47 | #define PHY_ID_ANY 0x1f | ||
48 | #define MII_REG_ANY 0x1f | ||
49 | |||
50 | #ifdef CONFIG_SIS190_NAPI | ||
51 | #define NAPI_SUFFIX "-NAPI" | ||
52 | #else | ||
53 | #define NAPI_SUFFIX "" | ||
54 | #endif | ||
55 | |||
56 | #define DRV_VERSION "1.2" NAPI_SUFFIX | ||
57 | #define DRV_NAME "sis190" | ||
58 | #define SIS190_DRIVER_NAME DRV_NAME " Gigabit Ethernet driver " DRV_VERSION | ||
59 | #define PFX DRV_NAME ": " | ||
60 | |||
61 | #ifdef CONFIG_SIS190_NAPI | ||
62 | #define sis190_rx_skb netif_receive_skb | ||
63 | #define sis190_rx_quota(count, quota) min(count, quota) | ||
64 | #else | ||
65 | #define sis190_rx_skb netif_rx | ||
66 | #define sis190_rx_quota(count, quota) count | ||
67 | #endif | ||
68 | |||
69 | #define MAC_ADDR_LEN 6 | ||
70 | |||
71 | #define NUM_TX_DESC 64 /* [8..1024] */ | ||
72 | #define NUM_RX_DESC 64 /* [8..8192] */ | ||
73 | #define TX_RING_BYTES (NUM_TX_DESC * sizeof(struct TxDesc)) | ||
74 | #define RX_RING_BYTES (NUM_RX_DESC * sizeof(struct RxDesc)) | ||
75 | #define RX_BUF_SIZE 1536 | ||
76 | #define RX_BUF_MASK 0xfff8 | ||
77 | |||
78 | #define SIS190_REGS_SIZE 0x80 | ||
79 | #define SIS190_TX_TIMEOUT (6*HZ) | ||
80 | #define SIS190_PHY_TIMEOUT (10*HZ) | ||
81 | #define SIS190_MSG_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | \ | ||
82 | NETIF_MSG_LINK | NETIF_MSG_IFUP | \ | ||
83 | NETIF_MSG_IFDOWN) | ||
84 | |||
85 | /* Enhanced PHY access register bit definitions */ | ||
86 | #define EhnMIIread 0x0000 | ||
87 | #define EhnMIIwrite 0x0020 | ||
88 | #define EhnMIIdataShift 16 | ||
89 | #define EhnMIIpmdShift 6 /* 7016 only */ | ||
90 | #define EhnMIIregShift 11 | ||
91 | #define EhnMIIreq 0x0010 | ||
92 | #define EhnMIInotDone 0x0010 | ||
93 | |||
94 | /* Write/read MMIO register */ | ||
95 | #define SIS_W8(reg, val) writeb ((val), ioaddr + (reg)) | ||
96 | #define SIS_W16(reg, val) writew ((val), ioaddr + (reg)) | ||
97 | #define SIS_W32(reg, val) writel ((val), ioaddr + (reg)) | ||
98 | #define SIS_R8(reg) readb (ioaddr + (reg)) | ||
99 | #define SIS_R16(reg) readw (ioaddr + (reg)) | ||
100 | #define SIS_R32(reg) readl (ioaddr + (reg)) | ||
101 | |||
102 | #define SIS_PCI_COMMIT() SIS_R32(IntrControl) | ||
103 | |||
104 | enum sis190_registers { | ||
105 | TxControl = 0x00, | ||
106 | TxDescStartAddr = 0x04, | ||
107 | rsv0 = 0x08, // reserved | ||
108 | TxSts = 0x0c, // unused (Control/Status) | ||
109 | RxControl = 0x10, | ||
110 | RxDescStartAddr = 0x14, | ||
111 | rsv1 = 0x18, // reserved | ||
112 | RxSts = 0x1c, // unused | ||
113 | IntrStatus = 0x20, | ||
114 | IntrMask = 0x24, | ||
115 | IntrControl = 0x28, | ||
116 | IntrTimer = 0x2c, // unused (Interupt Timer) | ||
117 | PMControl = 0x30, // unused (Power Mgmt Control/Status) | ||
118 | rsv2 = 0x34, // reserved | ||
119 | ROMControl = 0x38, | ||
120 | ROMInterface = 0x3c, | ||
121 | StationControl = 0x40, | ||
122 | GMIIControl = 0x44, | ||
123 | GIoCR = 0x48, // unused (GMAC IO Compensation) | ||
124 | GIoCtrl = 0x4c, // unused (GMAC IO Control) | ||
125 | TxMacControl = 0x50, | ||
126 | TxLimit = 0x54, // unused (Tx MAC Timer/TryLimit) | ||
127 | RGDelay = 0x58, // unused (RGMII Tx Internal Delay) | ||
128 | rsv3 = 0x5c, // reserved | ||
129 | RxMacControl = 0x60, | ||
130 | RxMacAddr = 0x62, | ||
131 | RxHashTable = 0x68, | ||
132 | // Undocumented = 0x6c, | ||
133 | RxWolCtrl = 0x70, | ||
134 | RxWolData = 0x74, // unused (Rx WOL Data Access) | ||
135 | RxMPSControl = 0x78, // unused (Rx MPS Control) | ||
136 | rsv4 = 0x7c, // reserved | ||
137 | }; | ||
138 | |||
139 | enum sis190_register_content { | ||
140 | /* IntrStatus */ | ||
141 | SoftInt = 0x40000000, // unused | ||
142 | Timeup = 0x20000000, // unused | ||
143 | PauseFrame = 0x00080000, // unused | ||
144 | MagicPacket = 0x00040000, // unused | ||
145 | WakeupFrame = 0x00020000, // unused | ||
146 | LinkChange = 0x00010000, | ||
147 | RxQEmpty = 0x00000080, | ||
148 | RxQInt = 0x00000040, | ||
149 | TxQ1Empty = 0x00000020, // unused | ||
150 | TxQ1Int = 0x00000010, | ||
151 | TxQ0Empty = 0x00000008, // unused | ||
152 | TxQ0Int = 0x00000004, | ||
153 | RxHalt = 0x00000002, | ||
154 | TxHalt = 0x00000001, | ||
155 | |||
156 | /* {Rx/Tx}CmdBits */ | ||
157 | CmdReset = 0x10, | ||
158 | CmdRxEnb = 0x08, // unused | ||
159 | CmdTxEnb = 0x01, | ||
160 | RxBufEmpty = 0x01, // unused | ||
161 | |||
162 | /* Cfg9346Bits */ | ||
163 | Cfg9346_Lock = 0x00, // unused | ||
164 | Cfg9346_Unlock = 0xc0, // unused | ||
165 | |||
166 | /* RxMacControl */ | ||
167 | AcceptErr = 0x20, // unused | ||
168 | AcceptRunt = 0x10, // unused | ||
169 | AcceptBroadcast = 0x0800, | ||
170 | AcceptMulticast = 0x0400, | ||
171 | AcceptMyPhys = 0x0200, | ||
172 | AcceptAllPhys = 0x0100, | ||
173 | |||
174 | /* RxConfigBits */ | ||
175 | RxCfgFIFOShift = 13, | ||
176 | RxCfgDMAShift = 8, // 0x1a in RxControl ? | ||
177 | |||
178 | /* TxConfigBits */ | ||
179 | TxInterFrameGapShift = 24, | ||
180 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ | ||
181 | |||
182 | /* StationControl */ | ||
183 | _1000bpsF = 0x1c00, | ||
184 | _1000bpsH = 0x0c00, | ||
185 | _100bpsF = 0x1800, | ||
186 | _100bpsH = 0x0800, | ||
187 | _10bpsF = 0x1400, | ||
188 | _10bpsH = 0x0400, | ||
189 | |||
190 | LinkStatus = 0x02, // unused | ||
191 | FullDup = 0x01, // unused | ||
192 | |||
193 | /* TBICSRBit */ | ||
194 | TBILinkOK = 0x02000000, // unused | ||
195 | }; | ||
196 | |||
197 | struct TxDesc { | ||
198 | __le32 PSize; | ||
199 | __le32 status; | ||
200 | __le32 addr; | ||
201 | __le32 size; | ||
202 | }; | ||
203 | |||
204 | struct RxDesc { | ||
205 | __le32 PSize; | ||
206 | __le32 status; | ||
207 | __le32 addr; | ||
208 | __le32 size; | ||
209 | }; | ||
210 | |||
211 | enum _DescStatusBit { | ||
212 | /* _Desc.status */ | ||
213 | OWNbit = 0x80000000, // RXOWN/TXOWN | ||
214 | INTbit = 0x40000000, // RXINT/TXINT | ||
215 | CRCbit = 0x00020000, // CRCOFF/CRCEN | ||
216 | PADbit = 0x00010000, // PREADD/PADEN | ||
217 | /* _Desc.size */ | ||
218 | RingEnd = 0x80000000, | ||
219 | /* TxDesc.status */ | ||
220 | LSEN = 0x08000000, // TSO ? -- FR | ||
221 | IPCS = 0x04000000, | ||
222 | TCPCS = 0x02000000, | ||
223 | UDPCS = 0x01000000, | ||
224 | BSTEN = 0x00800000, | ||
225 | EXTEN = 0x00400000, | ||
226 | DEFEN = 0x00200000, | ||
227 | BKFEN = 0x00100000, | ||
228 | CRSEN = 0x00080000, | ||
229 | COLEN = 0x00040000, | ||
230 | THOL3 = 0x30000000, | ||
231 | THOL2 = 0x20000000, | ||
232 | THOL1 = 0x10000000, | ||
233 | THOL0 = 0x00000000, | ||
234 | /* RxDesc.status */ | ||
235 | IPON = 0x20000000, | ||
236 | TCPON = 0x10000000, | ||
237 | UDPON = 0x08000000, | ||
238 | Wakup = 0x00400000, | ||
239 | Magic = 0x00200000, | ||
240 | Pause = 0x00100000, | ||
241 | DEFbit = 0x00200000, | ||
242 | BCAST = 0x000c0000, | ||
243 | MCAST = 0x00080000, | ||
244 | UCAST = 0x00040000, | ||
245 | /* RxDesc.PSize */ | ||
246 | TAGON = 0x80000000, | ||
247 | RxDescCountMask = 0x7f000000, // multi-desc pkt when > 1 ? -- FR | ||
248 | ABORT = 0x00800000, | ||
249 | SHORT = 0x00400000, | ||
250 | LIMIT = 0x00200000, | ||
251 | MIIER = 0x00100000, | ||
252 | OVRUN = 0x00080000, | ||
253 | NIBON = 0x00040000, | ||
254 | COLON = 0x00020000, | ||
255 | CRCOK = 0x00010000, | ||
256 | RxSizeMask = 0x0000ffff | ||
257 | /* | ||
258 | * The asic could apparently do vlan, TSO, jumbo (sis191 only) and | ||
259 | * provide two (unused with Linux) Tx queues. No publically | ||
260 | * available documentation alas. | ||
261 | */ | ||
262 | }; | ||
263 | |||
264 | enum sis190_eeprom_access_register_bits { | ||
265 | EECS = 0x00000001, // unused | ||
266 | EECLK = 0x00000002, // unused | ||
267 | EEDO = 0x00000008, // unused | ||
268 | EEDI = 0x00000004, // unused | ||
269 | EEREQ = 0x00000080, | ||
270 | EEROP = 0x00000200, | ||
271 | EEWOP = 0x00000100 // unused | ||
272 | }; | ||
273 | |||
274 | /* EEPROM Addresses */ | ||
275 | enum sis190_eeprom_address { | ||
276 | EEPROMSignature = 0x00, | ||
277 | EEPROMCLK = 0x01, // unused | ||
278 | EEPROMInfo = 0x02, | ||
279 | EEPROMMACAddr = 0x03 | ||
280 | }; | ||
281 | |||
282 | struct sis190_private { | ||
283 | void __iomem *mmio_addr; | ||
284 | struct pci_dev *pci_dev; | ||
285 | struct net_device_stats stats; | ||
286 | spinlock_t lock; | ||
287 | u32 rx_buf_sz; | ||
288 | u32 cur_rx; | ||
289 | u32 cur_tx; | ||
290 | u32 dirty_rx; | ||
291 | u32 dirty_tx; | ||
292 | dma_addr_t rx_dma; | ||
293 | dma_addr_t tx_dma; | ||
294 | struct RxDesc *RxDescRing; | ||
295 | struct TxDesc *TxDescRing; | ||
296 | struct sk_buff *Rx_skbuff[NUM_RX_DESC]; | ||
297 | struct sk_buff *Tx_skbuff[NUM_TX_DESC]; | ||
298 | struct work_struct phy_task; | ||
299 | struct timer_list timer; | ||
300 | u32 msg_enable; | ||
301 | struct mii_if_info mii_if; | ||
302 | struct list_head first_phy; | ||
303 | }; | ||
304 | |||
305 | struct sis190_phy { | ||
306 | struct list_head list; | ||
307 | int phy_id; | ||
308 | u16 id[2]; | ||
309 | u16 status; | ||
310 | u8 type; | ||
311 | }; | ||
312 | |||
313 | enum sis190_phy_type { | ||
314 | UNKNOWN = 0x00, | ||
315 | HOME = 0x01, | ||
316 | LAN = 0x02, | ||
317 | MIX = 0x03 | ||
318 | }; | ||
319 | |||
320 | static struct mii_chip_info { | ||
321 | const char *name; | ||
322 | u16 id[2]; | ||
323 | unsigned int type; | ||
324 | } mii_chip_table[] = { | ||
325 | { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN }, | ||
326 | { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN }, | ||
327 | { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN }, | ||
328 | { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN }, | ||
329 | { NULL, } | ||
330 | }; | ||
331 | |||
332 | const static struct { | ||
333 | const char *name; | ||
334 | u8 version; /* depend on docs */ | ||
335 | u32 RxConfigMask; /* clear the bits supported by this chip */ | ||
336 | } sis_chip_info[] = { | ||
337 | { DRV_NAME, 0x00, 0xff7e1880, }, | ||
338 | }; | ||
339 | |||
340 | static struct pci_device_id sis190_pci_tbl[] __devinitdata = { | ||
341 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 }, | ||
342 | { 0, }, | ||
343 | }; | ||
344 | |||
345 | MODULE_DEVICE_TABLE(pci, sis190_pci_tbl); | ||
346 | |||
347 | static int rx_copybreak = 200; | ||
348 | |||
349 | static struct { | ||
350 | u32 msg_enable; | ||
351 | } debug = { -1 }; | ||
352 | |||
353 | MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver"); | ||
354 | module_param(rx_copybreak, int, 0); | ||
355 | MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); | ||
356 | module_param_named(debug, debug.msg_enable, int, 0); | ||
357 | MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); | ||
358 | MODULE_AUTHOR("K.M. Liu <kmliu@sis.com>, Ueimor <romieu@fr.zoreil.com>"); | ||
359 | MODULE_VERSION(DRV_VERSION); | ||
360 | MODULE_LICENSE("GPL"); | ||
361 | |||
362 | static const u32 sis190_intr_mask = | ||
363 | RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt; | ||
364 | |||
365 | /* | ||
366 | * Maximum number of multicast addresses to filter (vs. Rx-all-multicast). | ||
367 | * The chips use a 64 element hash table based on the Ethernet CRC. | ||
368 | */ | ||
369 | static int multicast_filter_limit = 32; | ||
370 | |||
371 | static void __mdio_cmd(void __iomem *ioaddr, u32 ctl) | ||
372 | { | ||
373 | unsigned int i; | ||
374 | |||
375 | SIS_W32(GMIIControl, ctl); | ||
376 | |||
377 | msleep(1); | ||
378 | |||
379 | for (i = 0; i < 100; i++) { | ||
380 | if (!(SIS_R32(GMIIControl) & EhnMIInotDone)) | ||
381 | break; | ||
382 | msleep(1); | ||
383 | } | ||
384 | |||
385 | if (i > 999) | ||
386 | printk(KERN_ERR PFX "PHY command failed !\n"); | ||
387 | } | ||
388 | |||
389 | static void mdio_write(void __iomem *ioaddr, int phy_id, int reg, int val) | ||
390 | { | ||
391 | __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIwrite | | ||
392 | (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift) | | ||
393 | (((u32) val) << EhnMIIdataShift)); | ||
394 | } | ||
395 | |||
396 | static int mdio_read(void __iomem *ioaddr, int phy_id, int reg) | ||
397 | { | ||
398 | __mdio_cmd(ioaddr, EhnMIIreq | EhnMIIread | | ||
399 | (((u32) reg) << EhnMIIregShift) | (phy_id << EhnMIIpmdShift)); | ||
400 | |||
401 | return (u16) (SIS_R32(GMIIControl) >> EhnMIIdataShift); | ||
402 | } | ||
403 | |||
404 | static void __mdio_write(struct net_device *dev, int phy_id, int reg, int val) | ||
405 | { | ||
406 | struct sis190_private *tp = netdev_priv(dev); | ||
407 | |||
408 | mdio_write(tp->mmio_addr, phy_id, reg, val); | ||
409 | } | ||
410 | |||
411 | static int __mdio_read(struct net_device *dev, int phy_id, int reg) | ||
412 | { | ||
413 | struct sis190_private *tp = netdev_priv(dev); | ||
414 | |||
415 | return mdio_read(tp->mmio_addr, phy_id, reg); | ||
416 | } | ||
417 | |||
418 | static u16 mdio_read_latched(void __iomem *ioaddr, int phy_id, int reg) | ||
419 | { | ||
420 | mdio_read(ioaddr, phy_id, reg); | ||
421 | return mdio_read(ioaddr, phy_id, reg); | ||
422 | } | ||
423 | |||
424 | static u16 __devinit sis190_read_eeprom(void __iomem *ioaddr, u32 reg) | ||
425 | { | ||
426 | u16 data = 0xffff; | ||
427 | unsigned int i; | ||
428 | |||
429 | if (!(SIS_R32(ROMControl) & 0x0002)) | ||
430 | return 0; | ||
431 | |||
432 | SIS_W32(ROMInterface, EEREQ | EEROP | (reg << 10)); | ||
433 | |||
434 | for (i = 0; i < 200; i++) { | ||
435 | if (!(SIS_R32(ROMInterface) & EEREQ)) { | ||
436 | data = (SIS_R32(ROMInterface) & 0xffff0000) >> 16; | ||
437 | break; | ||
438 | } | ||
439 | msleep(1); | ||
440 | } | ||
441 | |||
442 | return data; | ||
443 | } | ||
444 | |||
445 | static void sis190_irq_mask_and_ack(void __iomem *ioaddr) | ||
446 | { | ||
447 | SIS_W32(IntrMask, 0x00); | ||
448 | SIS_W32(IntrStatus, 0xffffffff); | ||
449 | SIS_PCI_COMMIT(); | ||
450 | } | ||
451 | |||
452 | static void sis190_asic_down(void __iomem *ioaddr) | ||
453 | { | ||
454 | /* Stop the chip's Tx and Rx DMA processes. */ | ||
455 | |||
456 | SIS_W32(TxControl, 0x1a00); | ||
457 | SIS_W32(RxControl, 0x1a00); | ||
458 | |||
459 | sis190_irq_mask_and_ack(ioaddr); | ||
460 | } | ||
461 | |||
462 | static void sis190_mark_as_last_descriptor(struct RxDesc *desc) | ||
463 | { | ||
464 | desc->size |= cpu_to_le32(RingEnd); | ||
465 | } | ||
466 | |||
467 | static inline void sis190_give_to_asic(struct RxDesc *desc, u32 rx_buf_sz) | ||
468 | { | ||
469 | u32 eor = le32_to_cpu(desc->size) & RingEnd; | ||
470 | |||
471 | desc->PSize = 0x0; | ||
472 | desc->size = cpu_to_le32((rx_buf_sz & RX_BUF_MASK) | eor); | ||
473 | wmb(); | ||
474 | desc->status = cpu_to_le32(OWNbit | INTbit); | ||
475 | } | ||
476 | |||
477 | static inline void sis190_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, | ||
478 | u32 rx_buf_sz) | ||
479 | { | ||
480 | desc->addr = cpu_to_le32(mapping); | ||
481 | sis190_give_to_asic(desc, rx_buf_sz); | ||
482 | } | ||
483 | |||
484 | static inline void sis190_make_unusable_by_asic(struct RxDesc *desc) | ||
485 | { | ||
486 | desc->PSize = 0x0; | ||
487 | desc->addr = 0xdeadbeef; | ||
488 | desc->size &= cpu_to_le32(RingEnd); | ||
489 | wmb(); | ||
490 | desc->status = 0x0; | ||
491 | } | ||
492 | |||
493 | static int sis190_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, | ||
494 | struct RxDesc *desc, u32 rx_buf_sz) | ||
495 | { | ||
496 | struct sk_buff *skb; | ||
497 | dma_addr_t mapping; | ||
498 | int ret = 0; | ||
499 | |||
500 | skb = dev_alloc_skb(rx_buf_sz); | ||
501 | if (!skb) | ||
502 | goto err_out; | ||
503 | |||
504 | *sk_buff = skb; | ||
505 | |||
506 | mapping = pci_map_single(pdev, skb->data, rx_buf_sz, | ||
507 | PCI_DMA_FROMDEVICE); | ||
508 | |||
509 | sis190_map_to_asic(desc, mapping, rx_buf_sz); | ||
510 | out: | ||
511 | return ret; | ||
512 | |||
513 | err_out: | ||
514 | ret = -ENOMEM; | ||
515 | sis190_make_unusable_by_asic(desc); | ||
516 | goto out; | ||
517 | } | ||
518 | |||
519 | static u32 sis190_rx_fill(struct sis190_private *tp, struct net_device *dev, | ||
520 | u32 start, u32 end) | ||
521 | { | ||
522 | u32 cur; | ||
523 | |||
524 | for (cur = start; cur < end; cur++) { | ||
525 | int ret, i = cur % NUM_RX_DESC; | ||
526 | |||
527 | if (tp->Rx_skbuff[i]) | ||
528 | continue; | ||
529 | |||
530 | ret = sis190_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i, | ||
531 | tp->RxDescRing + i, tp->rx_buf_sz); | ||
532 | if (ret < 0) | ||
533 | break; | ||
534 | } | ||
535 | return cur - start; | ||
536 | } | ||
537 | |||
538 | static inline int sis190_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, | ||
539 | struct RxDesc *desc, int rx_buf_sz) | ||
540 | { | ||
541 | int ret = -1; | ||
542 | |||
543 | if (pkt_size < rx_copybreak) { | ||
544 | struct sk_buff *skb; | ||
545 | |||
546 | skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); | ||
547 | if (skb) { | ||
548 | skb_reserve(skb, NET_IP_ALIGN); | ||
549 | eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); | ||
550 | *sk_buff = skb; | ||
551 | sis190_give_to_asic(desc, rx_buf_sz); | ||
552 | ret = 0; | ||
553 | } | ||
554 | } | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | static inline int sis190_rx_pkt_err(u32 status, struct net_device_stats *stats) | ||
559 | { | ||
560 | #define ErrMask (OVRUN | SHORT | LIMIT | MIIER | NIBON | COLON | ABORT) | ||
561 | |||
562 | if ((status & CRCOK) && !(status & ErrMask)) | ||
563 | return 0; | ||
564 | |||
565 | if (!(status & CRCOK)) | ||
566 | stats->rx_crc_errors++; | ||
567 | else if (status & OVRUN) | ||
568 | stats->rx_over_errors++; | ||
569 | else if (status & (SHORT | LIMIT)) | ||
570 | stats->rx_length_errors++; | ||
571 | else if (status & (MIIER | NIBON | COLON)) | ||
572 | stats->rx_frame_errors++; | ||
573 | |||
574 | stats->rx_errors++; | ||
575 | return -1; | ||
576 | } | ||
577 | |||
578 | static int sis190_rx_interrupt(struct net_device *dev, | ||
579 | struct sis190_private *tp, void __iomem *ioaddr) | ||
580 | { | ||
581 | struct net_device_stats *stats = &tp->stats; | ||
582 | u32 rx_left, cur_rx = tp->cur_rx; | ||
583 | u32 delta, count; | ||
584 | |||
585 | rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx; | ||
586 | rx_left = sis190_rx_quota(rx_left, (u32) dev->quota); | ||
587 | |||
588 | for (; rx_left > 0; rx_left--, cur_rx++) { | ||
589 | unsigned int entry = cur_rx % NUM_RX_DESC; | ||
590 | struct RxDesc *desc = tp->RxDescRing + entry; | ||
591 | u32 status; | ||
592 | |||
593 | if (desc->status & OWNbit) | ||
594 | break; | ||
595 | |||
596 | status = le32_to_cpu(desc->PSize); | ||
597 | |||
598 | // net_intr(tp, KERN_INFO "%s: Rx PSize = %08x.\n", dev->name, | ||
599 | // status); | ||
600 | |||
601 | if (sis190_rx_pkt_err(status, stats) < 0) | ||
602 | sis190_give_to_asic(desc, tp->rx_buf_sz); | ||
603 | else { | ||
604 | struct sk_buff *skb = tp->Rx_skbuff[entry]; | ||
605 | int pkt_size = (status & RxSizeMask) - 4; | ||
606 | void (*pci_action)(struct pci_dev *, dma_addr_t, | ||
607 | size_t, int) = pci_dma_sync_single_for_device; | ||
608 | |||
609 | if (unlikely(pkt_size > tp->rx_buf_sz)) { | ||
610 | net_intr(tp, KERN_INFO | ||
611 | "%s: (frag) status = %08x.\n", | ||
612 | dev->name, status); | ||
613 | stats->rx_dropped++; | ||
614 | stats->rx_length_errors++; | ||
615 | sis190_give_to_asic(desc, tp->rx_buf_sz); | ||
616 | continue; | ||
617 | } | ||
618 | |||
619 | pci_dma_sync_single_for_cpu(tp->pci_dev, | ||
620 | le32_to_cpu(desc->addr), tp->rx_buf_sz, | ||
621 | PCI_DMA_FROMDEVICE); | ||
622 | |||
623 | if (sis190_try_rx_copy(&skb, pkt_size, desc, | ||
624 | tp->rx_buf_sz)) { | ||
625 | pci_action = pci_unmap_single; | ||
626 | tp->Rx_skbuff[entry] = NULL; | ||
627 | sis190_make_unusable_by_asic(desc); | ||
628 | } | ||
629 | |||
630 | pci_action(tp->pci_dev, le32_to_cpu(desc->addr), | ||
631 | tp->rx_buf_sz, PCI_DMA_FROMDEVICE); | ||
632 | |||
633 | skb->dev = dev; | ||
634 | skb_put(skb, pkt_size); | ||
635 | skb->protocol = eth_type_trans(skb, dev); | ||
636 | |||
637 | sis190_rx_skb(skb); | ||
638 | |||
639 | dev->last_rx = jiffies; | ||
640 | stats->rx_packets++; | ||
641 | stats->rx_bytes += pkt_size; | ||
642 | if ((status & BCAST) == MCAST) | ||
643 | stats->multicast++; | ||
644 | } | ||
645 | } | ||
646 | count = cur_rx - tp->cur_rx; | ||
647 | tp->cur_rx = cur_rx; | ||
648 | |||
649 | delta = sis190_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); | ||
650 | if (!delta && count && netif_msg_intr(tp)) | ||
651 | printk(KERN_INFO "%s: no Rx buffer allocated.\n", dev->name); | ||
652 | tp->dirty_rx += delta; | ||
653 | |||
654 | if (((tp->dirty_rx + NUM_RX_DESC) == tp->cur_rx) && netif_msg_intr(tp)) | ||
655 | printk(KERN_EMERG "%s: Rx buffers exhausted.\n", dev->name); | ||
656 | |||
657 | return count; | ||
658 | } | ||
659 | |||
660 | static void sis190_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff *skb, | ||
661 | struct TxDesc *desc) | ||
662 | { | ||
663 | unsigned int len; | ||
664 | |||
665 | len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; | ||
666 | |||
667 | pci_unmap_single(pdev, le32_to_cpu(desc->addr), len, PCI_DMA_TODEVICE); | ||
668 | |||
669 | memset(desc, 0x00, sizeof(*desc)); | ||
670 | } | ||
671 | |||
672 | static void sis190_tx_interrupt(struct net_device *dev, | ||
673 | struct sis190_private *tp, void __iomem *ioaddr) | ||
674 | { | ||
675 | u32 pending, dirty_tx = tp->dirty_tx; | ||
676 | /* | ||
677 | * It would not be needed if queueing was allowed to be enabled | ||
678 | * again too early (hint: think preempt and unclocked smp systems). | ||
679 | */ | ||
680 | unsigned int queue_stopped; | ||
681 | |||
682 | smp_rmb(); | ||
683 | pending = tp->cur_tx - dirty_tx; | ||
684 | queue_stopped = (pending == NUM_TX_DESC); | ||
685 | |||
686 | for (; pending; pending--, dirty_tx++) { | ||
687 | unsigned int entry = dirty_tx % NUM_TX_DESC; | ||
688 | struct TxDesc *txd = tp->TxDescRing + entry; | ||
689 | struct sk_buff *skb; | ||
690 | |||
691 | if (le32_to_cpu(txd->status) & OWNbit) | ||
692 | break; | ||
693 | |||
694 | skb = tp->Tx_skbuff[entry]; | ||
695 | |||
696 | tp->stats.tx_packets++; | ||
697 | tp->stats.tx_bytes += skb->len; | ||
698 | |||
699 | sis190_unmap_tx_skb(tp->pci_dev, skb, txd); | ||
700 | tp->Tx_skbuff[entry] = NULL; | ||
701 | dev_kfree_skb_irq(skb); | ||
702 | } | ||
703 | |||
704 | if (tp->dirty_tx != dirty_tx) { | ||
705 | tp->dirty_tx = dirty_tx; | ||
706 | smp_wmb(); | ||
707 | if (queue_stopped) | ||
708 | netif_wake_queue(dev); | ||
709 | } | ||
710 | } | ||
711 | |||
712 | /* | ||
713 | * The interrupt handler does all of the Rx thread work and cleans up after | ||
714 | * the Tx thread. | ||
715 | */ | ||
716 | static irqreturn_t sis190_interrupt(int irq, void *__dev, struct pt_regs *regs) | ||
717 | { | ||
718 | struct net_device *dev = __dev; | ||
719 | struct sis190_private *tp = netdev_priv(dev); | ||
720 | void __iomem *ioaddr = tp->mmio_addr; | ||
721 | unsigned int handled = 0; | ||
722 | u32 status; | ||
723 | |||
724 | status = SIS_R32(IntrStatus); | ||
725 | |||
726 | if ((status == 0xffffffff) || !status) | ||
727 | goto out; | ||
728 | |||
729 | handled = 1; | ||
730 | |||
731 | if (unlikely(!netif_running(dev))) { | ||
732 | sis190_asic_down(ioaddr); | ||
733 | goto out; | ||
734 | } | ||
735 | |||
736 | SIS_W32(IntrStatus, status); | ||
737 | |||
738 | // net_intr(tp, KERN_INFO "%s: status = %08x.\n", dev->name, status); | ||
739 | |||
740 | if (status & LinkChange) { | ||
741 | net_intr(tp, KERN_INFO "%s: link change.\n", dev->name); | ||
742 | schedule_work(&tp->phy_task); | ||
743 | } | ||
744 | |||
745 | if (status & RxQInt) | ||
746 | sis190_rx_interrupt(dev, tp, ioaddr); | ||
747 | |||
748 | if (status & TxQ0Int) | ||
749 | sis190_tx_interrupt(dev, tp, ioaddr); | ||
750 | out: | ||
751 | return IRQ_RETVAL(handled); | ||
752 | } | ||
753 | |||
754 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
755 | static void sis190_netpoll(struct net_device *dev) | ||
756 | { | ||
757 | struct sis190_private *tp = netdev_priv(dev); | ||
758 | struct pci_dev *pdev = tp->pci_dev; | ||
759 | |||
760 | disable_irq(pdev->irq); | ||
761 | sis190_interrupt(pdev->irq, dev, NULL); | ||
762 | enable_irq(pdev->irq); | ||
763 | } | ||
764 | #endif | ||
765 | |||
766 | static void sis190_free_rx_skb(struct sis190_private *tp, | ||
767 | struct sk_buff **sk_buff, struct RxDesc *desc) | ||
768 | { | ||
769 | struct pci_dev *pdev = tp->pci_dev; | ||
770 | |||
771 | pci_unmap_single(pdev, le32_to_cpu(desc->addr), tp->rx_buf_sz, | ||
772 | PCI_DMA_FROMDEVICE); | ||
773 | dev_kfree_skb(*sk_buff); | ||
774 | *sk_buff = NULL; | ||
775 | sis190_make_unusable_by_asic(desc); | ||
776 | } | ||
777 | |||
778 | static void sis190_rx_clear(struct sis190_private *tp) | ||
779 | { | ||
780 | unsigned int i; | ||
781 | |||
782 | for (i = 0; i < NUM_RX_DESC; i++) { | ||
783 | if (!tp->Rx_skbuff[i]) | ||
784 | continue; | ||
785 | sis190_free_rx_skb(tp, tp->Rx_skbuff + i, tp->RxDescRing + i); | ||
786 | } | ||
787 | } | ||
788 | |||
789 | static void sis190_init_ring_indexes(struct sis190_private *tp) | ||
790 | { | ||
791 | tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0; | ||
792 | } | ||
793 | |||
794 | static int sis190_init_ring(struct net_device *dev) | ||
795 | { | ||
796 | struct sis190_private *tp = netdev_priv(dev); | ||
797 | |||
798 | sis190_init_ring_indexes(tp); | ||
799 | |||
800 | memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *)); | ||
801 | memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); | ||
802 | |||
803 | if (sis190_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC) | ||
804 | goto err_rx_clear; | ||
805 | |||
806 | sis190_mark_as_last_descriptor(tp->RxDescRing + NUM_RX_DESC - 1); | ||
807 | |||
808 | return 0; | ||
809 | |||
810 | err_rx_clear: | ||
811 | sis190_rx_clear(tp); | ||
812 | return -ENOMEM; | ||
813 | } | ||
814 | |||
815 | static void sis190_set_rx_mode(struct net_device *dev) | ||
816 | { | ||
817 | struct sis190_private *tp = netdev_priv(dev); | ||
818 | void __iomem *ioaddr = tp->mmio_addr; | ||
819 | unsigned long flags; | ||
820 | u32 mc_filter[2]; /* Multicast hash filter */ | ||
821 | u16 rx_mode; | ||
822 | |||
823 | if (dev->flags & IFF_PROMISC) { | ||
824 | /* Unconditionally log net taps. */ | ||
825 | net_drv(tp, KERN_NOTICE "%s: Promiscuous mode enabled.\n", | ||
826 | dev->name); | ||
827 | rx_mode = | ||
828 | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | | ||
829 | AcceptAllPhys; | ||
830 | mc_filter[1] = mc_filter[0] = 0xffffffff; | ||
831 | } else if ((dev->mc_count > multicast_filter_limit) || | ||
832 | (dev->flags & IFF_ALLMULTI)) { | ||
833 | /* Too many to filter perfectly -- accept all multicasts. */ | ||
834 | rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; | ||
835 | mc_filter[1] = mc_filter[0] = 0xffffffff; | ||
836 | } else { | ||
837 | struct dev_mc_list *mclist; | ||
838 | unsigned int i; | ||
839 | |||
840 | rx_mode = AcceptBroadcast | AcceptMyPhys; | ||
841 | mc_filter[1] = mc_filter[0] = 0; | ||
842 | for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; | ||
843 | i++, mclist = mclist->next) { | ||
844 | int bit_nr = | ||
845 | ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; | ||
846 | mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); | ||
847 | rx_mode |= AcceptMulticast; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | spin_lock_irqsave(&tp->lock, flags); | ||
852 | |||
853 | SIS_W16(RxMacControl, rx_mode | 0x2); | ||
854 | SIS_W32(RxHashTable, mc_filter[0]); | ||
855 | SIS_W32(RxHashTable + 4, mc_filter[1]); | ||
856 | |||
857 | spin_unlock_irqrestore(&tp->lock, flags); | ||
858 | } | ||
859 | |||
860 | static void sis190_soft_reset(void __iomem *ioaddr) | ||
861 | { | ||
862 | SIS_W32(IntrControl, 0x8000); | ||
863 | SIS_PCI_COMMIT(); | ||
864 | msleep(1); | ||
865 | SIS_W32(IntrControl, 0x0); | ||
866 | sis190_asic_down(ioaddr); | ||
867 | msleep(1); | ||
868 | } | ||
869 | |||
870 | static void sis190_hw_start(struct net_device *dev) | ||
871 | { | ||
872 | struct sis190_private *tp = netdev_priv(dev); | ||
873 | void __iomem *ioaddr = tp->mmio_addr; | ||
874 | |||
875 | sis190_soft_reset(ioaddr); | ||
876 | |||
877 | SIS_W32(TxDescStartAddr, tp->tx_dma); | ||
878 | SIS_W32(RxDescStartAddr, tp->rx_dma); | ||
879 | |||
880 | SIS_W32(IntrStatus, 0xffffffff); | ||
881 | SIS_W32(IntrMask, 0x0); | ||
882 | /* | ||
883 | * Default is 100Mbps. | ||
884 | * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09 | ||
885 | */ | ||
886 | SIS_W16(StationControl, 0x1901); | ||
887 | SIS_W32(GMIIControl, 0x0); | ||
888 | SIS_W32(TxMacControl, 0x60); | ||
889 | SIS_W16(RxMacControl, 0x02); | ||
890 | SIS_W32(RxHashTable, 0x0); | ||
891 | SIS_W32(0x6c, 0x0); | ||
892 | SIS_W32(RxWolCtrl, 0x0); | ||
893 | SIS_W32(RxWolData, 0x0); | ||
894 | |||
895 | SIS_PCI_COMMIT(); | ||
896 | |||
897 | sis190_set_rx_mode(dev); | ||
898 | |||
899 | /* Enable all known interrupts by setting the interrupt mask. */ | ||
900 | SIS_W32(IntrMask, sis190_intr_mask); | ||
901 | |||
902 | SIS_W32(TxControl, 0x1a00 | CmdTxEnb); | ||
903 | SIS_W32(RxControl, 0x1a1d); | ||
904 | |||
905 | netif_start_queue(dev); | ||
906 | } | ||
907 | |||
908 | static void sis190_phy_task(void * data) | ||
909 | { | ||
910 | struct net_device *dev = data; | ||
911 | struct sis190_private *tp = netdev_priv(dev); | ||
912 | void __iomem *ioaddr = tp->mmio_addr; | ||
913 | int phy_id = tp->mii_if.phy_id; | ||
914 | u16 val; | ||
915 | |||
916 | rtnl_lock(); | ||
917 | |||
918 | val = mdio_read(ioaddr, phy_id, MII_BMCR); | ||
919 | if (val & BMCR_RESET) { | ||
920 | // FIXME: needlessly high ? -- FR 02/07/2005 | ||
921 | mod_timer(&tp->timer, jiffies + HZ/10); | ||
922 | } else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) & | ||
923 | BMSR_ANEGCOMPLETE)) { | ||
924 | net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n", | ||
925 | dev->name); | ||
926 | mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET); | ||
927 | mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT); | ||
928 | } else { | ||
929 | /* Rejoice ! */ | ||
930 | struct { | ||
931 | int val; | ||
932 | const char *msg; | ||
933 | u16 ctl; | ||
934 | } reg31[] = { | ||
935 | { LPA_1000XFULL | LPA_SLCT, | ||
936 | "1000 Mbps Full Duplex", | ||
937 | 0x01 | _1000bpsF }, | ||
938 | { LPA_1000XHALF | LPA_SLCT, | ||
939 | "1000 Mbps Half Duplex", | ||
940 | 0x01 | _1000bpsH }, | ||
941 | { LPA_100FULL, | ||
942 | "100 Mbps Full Duplex", | ||
943 | 0x01 | _100bpsF }, | ||
944 | { LPA_100HALF, | ||
945 | "100 Mbps Half Duplex", | ||
946 | 0x01 | _100bpsH }, | ||
947 | { LPA_10FULL, | ||
948 | "10 Mbps Full Duplex", | ||
949 | 0x01 | _10bpsF }, | ||
950 | { LPA_10HALF, | ||
951 | "10 Mbps Half Duplex", | ||
952 | 0x01 | _10bpsH }, | ||
953 | { 0, "unknown", 0x0000 } | ||
954 | }, *p; | ||
955 | u16 adv; | ||
956 | |||
957 | val = mdio_read(ioaddr, phy_id, 0x1f); | ||
958 | net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val); | ||
959 | |||
960 | val = mdio_read(ioaddr, phy_id, MII_LPA); | ||
961 | adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE); | ||
962 | net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n", | ||
963 | dev->name, val, adv); | ||
964 | |||
965 | val &= adv; | ||
966 | |||
967 | for (p = reg31; p->ctl; p++) { | ||
968 | if ((val & p->val) == p->val) | ||
969 | break; | ||
970 | } | ||
971 | if (p->ctl) | ||
972 | SIS_W16(StationControl, p->ctl); | ||
973 | net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name, | ||
974 | p->msg); | ||
975 | netif_carrier_on(dev); | ||
976 | } | ||
977 | |||
978 | rtnl_unlock(); | ||
979 | } | ||
980 | |||
981 | static void sis190_phy_timer(unsigned long __opaque) | ||
982 | { | ||
983 | struct net_device *dev = (struct net_device *)__opaque; | ||
984 | struct sis190_private *tp = netdev_priv(dev); | ||
985 | |||
986 | if (likely(netif_running(dev))) | ||
987 | schedule_work(&tp->phy_task); | ||
988 | } | ||
989 | |||
990 | static inline void sis190_delete_timer(struct net_device *dev) | ||
991 | { | ||
992 | struct sis190_private *tp = netdev_priv(dev); | ||
993 | |||
994 | del_timer_sync(&tp->timer); | ||
995 | } | ||
996 | |||
997 | static inline void sis190_request_timer(struct net_device *dev) | ||
998 | { | ||
999 | struct sis190_private *tp = netdev_priv(dev); | ||
1000 | struct timer_list *timer = &tp->timer; | ||
1001 | |||
1002 | init_timer(timer); | ||
1003 | timer->expires = jiffies + SIS190_PHY_TIMEOUT; | ||
1004 | timer->data = (unsigned long)dev; | ||
1005 | timer->function = sis190_phy_timer; | ||
1006 | add_timer(timer); | ||
1007 | } | ||
1008 | |||
1009 | static void sis190_set_rxbufsize(struct sis190_private *tp, | ||
1010 | struct net_device *dev) | ||
1011 | { | ||
1012 | unsigned int mtu = dev->mtu; | ||
1013 | |||
1014 | tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE; | ||
1015 | /* RxDesc->size has a licence to kill the lower bits */ | ||
1016 | if (tp->rx_buf_sz & 0x07) { | ||
1017 | tp->rx_buf_sz += 8; | ||
1018 | tp->rx_buf_sz &= RX_BUF_MASK; | ||
1019 | } | ||
1020 | } | ||
1021 | |||
1022 | static int sis190_open(struct net_device *dev) | ||
1023 | { | ||
1024 | struct sis190_private *tp = netdev_priv(dev); | ||
1025 | struct pci_dev *pdev = tp->pci_dev; | ||
1026 | int rc = -ENOMEM; | ||
1027 | |||
1028 | sis190_set_rxbufsize(tp, dev); | ||
1029 | |||
1030 | /* | ||
1031 | * Rx and Tx descriptors need 256 bytes alignment. | ||
1032 | * pci_alloc_consistent() guarantees a stronger alignment. | ||
1033 | */ | ||
1034 | tp->TxDescRing = pci_alloc_consistent(pdev, TX_RING_BYTES, &tp->tx_dma); | ||
1035 | if (!tp->TxDescRing) | ||
1036 | goto out; | ||
1037 | |||
1038 | tp->RxDescRing = pci_alloc_consistent(pdev, RX_RING_BYTES, &tp->rx_dma); | ||
1039 | if (!tp->RxDescRing) | ||
1040 | goto err_free_tx_0; | ||
1041 | |||
1042 | rc = sis190_init_ring(dev); | ||
1043 | if (rc < 0) | ||
1044 | goto err_free_rx_1; | ||
1045 | |||
1046 | INIT_WORK(&tp->phy_task, sis190_phy_task, dev); | ||
1047 | |||
1048 | sis190_request_timer(dev); | ||
1049 | |||
1050 | rc = request_irq(dev->irq, sis190_interrupt, SA_SHIRQ, dev->name, dev); | ||
1051 | if (rc < 0) | ||
1052 | goto err_release_timer_2; | ||
1053 | |||
1054 | sis190_hw_start(dev); | ||
1055 | out: | ||
1056 | return rc; | ||
1057 | |||
1058 | err_release_timer_2: | ||
1059 | sis190_delete_timer(dev); | ||
1060 | sis190_rx_clear(tp); | ||
1061 | err_free_rx_1: | ||
1062 | pci_free_consistent(tp->pci_dev, RX_RING_BYTES, tp->RxDescRing, | ||
1063 | tp->rx_dma); | ||
1064 | err_free_tx_0: | ||
1065 | pci_free_consistent(tp->pci_dev, TX_RING_BYTES, tp->TxDescRing, | ||
1066 | tp->tx_dma); | ||
1067 | goto out; | ||
1068 | } | ||
1069 | |||
1070 | static void sis190_tx_clear(struct sis190_private *tp) | ||
1071 | { | ||
1072 | unsigned int i; | ||
1073 | |||
1074 | for (i = 0; i < NUM_TX_DESC; i++) { | ||
1075 | struct sk_buff *skb = tp->Tx_skbuff[i]; | ||
1076 | |||
1077 | if (!skb) | ||
1078 | continue; | ||
1079 | |||
1080 | sis190_unmap_tx_skb(tp->pci_dev, skb, tp->TxDescRing + i); | ||
1081 | tp->Tx_skbuff[i] = NULL; | ||
1082 | dev_kfree_skb(skb); | ||
1083 | |||
1084 | tp->stats.tx_dropped++; | ||
1085 | } | ||
1086 | tp->cur_tx = tp->dirty_tx = 0; | ||
1087 | } | ||
1088 | |||
1089 | static void sis190_down(struct net_device *dev) | ||
1090 | { | ||
1091 | struct sis190_private *tp = netdev_priv(dev); | ||
1092 | void __iomem *ioaddr = tp->mmio_addr; | ||
1093 | unsigned int poll_locked = 0; | ||
1094 | |||
1095 | sis190_delete_timer(dev); | ||
1096 | |||
1097 | netif_stop_queue(dev); | ||
1098 | |||
1099 | flush_scheduled_work(); | ||
1100 | |||
1101 | do { | ||
1102 | spin_lock_irq(&tp->lock); | ||
1103 | |||
1104 | sis190_asic_down(ioaddr); | ||
1105 | |||
1106 | spin_unlock_irq(&tp->lock); | ||
1107 | |||
1108 | synchronize_irq(dev->irq); | ||
1109 | |||
1110 | if (!poll_locked) { | ||
1111 | netif_poll_disable(dev); | ||
1112 | poll_locked++; | ||
1113 | } | ||
1114 | |||
1115 | synchronize_sched(); | ||
1116 | |||
1117 | } while (SIS_R32(IntrMask)); | ||
1118 | |||
1119 | sis190_tx_clear(tp); | ||
1120 | sis190_rx_clear(tp); | ||
1121 | } | ||
1122 | |||
1123 | static int sis190_close(struct net_device *dev) | ||
1124 | { | ||
1125 | struct sis190_private *tp = netdev_priv(dev); | ||
1126 | struct pci_dev *pdev = tp->pci_dev; | ||
1127 | |||
1128 | sis190_down(dev); | ||
1129 | |||
1130 | free_irq(dev->irq, dev); | ||
1131 | |||
1132 | netif_poll_enable(dev); | ||
1133 | |||
1134 | pci_free_consistent(pdev, TX_RING_BYTES, tp->TxDescRing, tp->tx_dma); | ||
1135 | pci_free_consistent(pdev, RX_RING_BYTES, tp->RxDescRing, tp->rx_dma); | ||
1136 | |||
1137 | tp->TxDescRing = NULL; | ||
1138 | tp->RxDescRing = NULL; | ||
1139 | |||
1140 | return 0; | ||
1141 | } | ||
1142 | |||
1143 | static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1144 | { | ||
1145 | struct sis190_private *tp = netdev_priv(dev); | ||
1146 | void __iomem *ioaddr = tp->mmio_addr; | ||
1147 | u32 len, entry, dirty_tx; | ||
1148 | struct TxDesc *desc; | ||
1149 | dma_addr_t mapping; | ||
1150 | |||
1151 | if (unlikely(skb->len < ETH_ZLEN)) { | ||
1152 | skb = skb_padto(skb, ETH_ZLEN); | ||
1153 | if (!skb) { | ||
1154 | tp->stats.tx_dropped++; | ||
1155 | goto out; | ||
1156 | } | ||
1157 | len = ETH_ZLEN; | ||
1158 | } else { | ||
1159 | len = skb->len; | ||
1160 | } | ||
1161 | |||
1162 | entry = tp->cur_tx % NUM_TX_DESC; | ||
1163 | desc = tp->TxDescRing + entry; | ||
1164 | |||
1165 | if (unlikely(le32_to_cpu(desc->status) & OWNbit)) { | ||
1166 | netif_stop_queue(dev); | ||
1167 | net_tx_err(tp, KERN_ERR PFX | ||
1168 | "%s: BUG! Tx Ring full when queue awake!\n", | ||
1169 | dev->name); | ||
1170 | return NETDEV_TX_BUSY; | ||
1171 | } | ||
1172 | |||
1173 | mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE); | ||
1174 | |||
1175 | tp->Tx_skbuff[entry] = skb; | ||
1176 | |||
1177 | desc->PSize = cpu_to_le32(len); | ||
1178 | desc->addr = cpu_to_le32(mapping); | ||
1179 | |||
1180 | desc->size = cpu_to_le32(len); | ||
1181 | if (entry == (NUM_TX_DESC - 1)) | ||
1182 | desc->size |= cpu_to_le32(RingEnd); | ||
1183 | |||
1184 | wmb(); | ||
1185 | |||
1186 | desc->status = cpu_to_le32(OWNbit | INTbit | DEFbit | CRCbit | PADbit); | ||
1187 | |||
1188 | tp->cur_tx++; | ||
1189 | |||
1190 | smp_wmb(); | ||
1191 | |||
1192 | SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb); | ||
1193 | |||
1194 | dev->trans_start = jiffies; | ||
1195 | |||
1196 | dirty_tx = tp->dirty_tx; | ||
1197 | if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) { | ||
1198 | netif_stop_queue(dev); | ||
1199 | smp_rmb(); | ||
1200 | if (dirty_tx != tp->dirty_tx) | ||
1201 | netif_wake_queue(dev); | ||
1202 | } | ||
1203 | out: | ||
1204 | return NETDEV_TX_OK; | ||
1205 | } | ||
1206 | |||
1207 | static struct net_device_stats *sis190_get_stats(struct net_device *dev) | ||
1208 | { | ||
1209 | struct sis190_private *tp = netdev_priv(dev); | ||
1210 | |||
1211 | return &tp->stats; | ||
1212 | } | ||
1213 | |||
1214 | static void sis190_free_phy(struct list_head *first_phy) | ||
1215 | { | ||
1216 | struct sis190_phy *cur, *next; | ||
1217 | |||
1218 | list_for_each_entry_safe(cur, next, first_phy, list) { | ||
1219 | kfree(cur); | ||
1220 | } | ||
1221 | } | ||
1222 | |||
1223 | /** | ||
1224 | * sis190_default_phy - Select default PHY for sis190 mac. | ||
1225 | * @dev: the net device to probe for | ||
1226 | * | ||
1227 | * Select first detected PHY with link as default. | ||
1228 | * If no one is link on, select PHY whose types is HOME as default. | ||
1229 | * If HOME doesn't exist, select LAN. | ||
1230 | */ | ||
1231 | static u16 sis190_default_phy(struct net_device *dev) | ||
1232 | { | ||
1233 | struct sis190_phy *phy, *phy_home, *phy_default, *phy_lan; | ||
1234 | struct sis190_private *tp = netdev_priv(dev); | ||
1235 | struct mii_if_info *mii_if = &tp->mii_if; | ||
1236 | void __iomem *ioaddr = tp->mmio_addr; | ||
1237 | u16 status; | ||
1238 | |||
1239 | phy_home = phy_default = phy_lan = NULL; | ||
1240 | |||
1241 | list_for_each_entry(phy, &tp->first_phy, list) { | ||
1242 | status = mdio_read_latched(ioaddr, phy->phy_id, MII_BMSR); | ||
1243 | |||
1244 | // Link ON & Not select default PHY & not ghost PHY. | ||
1245 | if ((status & BMSR_LSTATUS) && | ||
1246 | !phy_default && | ||
1247 | (phy->type != UNKNOWN)) { | ||
1248 | phy_default = phy; | ||
1249 | } else { | ||
1250 | status = mdio_read(ioaddr, phy->phy_id, MII_BMCR); | ||
1251 | mdio_write(ioaddr, phy->phy_id, MII_BMCR, | ||
1252 | status | BMCR_ANENABLE | BMCR_ISOLATE); | ||
1253 | if (phy->type == HOME) | ||
1254 | phy_home = phy; | ||
1255 | else if (phy->type == LAN) | ||
1256 | phy_lan = phy; | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | if (!phy_default) { | ||
1261 | if (phy_home) | ||
1262 | phy_default = phy_home; | ||
1263 | else if (phy_lan) | ||
1264 | phy_default = phy_lan; | ||
1265 | else | ||
1266 | phy_default = list_entry(&tp->first_phy, | ||
1267 | struct sis190_phy, list); | ||
1268 | } | ||
1269 | |||
1270 | if (mii_if->phy_id != phy_default->phy_id) { | ||
1271 | mii_if->phy_id = phy_default->phy_id; | ||
1272 | net_probe(tp, KERN_INFO | ||
1273 | "%s: Using transceiver at address %d as default.\n", | ||
1274 | pci_name(tp->pci_dev), mii_if->phy_id); | ||
1275 | } | ||
1276 | |||
1277 | status = mdio_read(ioaddr, mii_if->phy_id, MII_BMCR); | ||
1278 | status &= (~BMCR_ISOLATE); | ||
1279 | |||
1280 | mdio_write(ioaddr, mii_if->phy_id, MII_BMCR, status); | ||
1281 | status = mdio_read_latched(ioaddr, mii_if->phy_id, MII_BMSR); | ||
1282 | |||
1283 | return status; | ||
1284 | } | ||
1285 | |||
1286 | static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp, | ||
1287 | struct sis190_phy *phy, unsigned int phy_id, | ||
1288 | u16 mii_status) | ||
1289 | { | ||
1290 | void __iomem *ioaddr = tp->mmio_addr; | ||
1291 | struct mii_chip_info *p; | ||
1292 | |||
1293 | INIT_LIST_HEAD(&phy->list); | ||
1294 | phy->status = mii_status; | ||
1295 | phy->phy_id = phy_id; | ||
1296 | |||
1297 | phy->id[0] = mdio_read(ioaddr, phy_id, MII_PHYSID1); | ||
1298 | phy->id[1] = mdio_read(ioaddr, phy_id, MII_PHYSID2); | ||
1299 | |||
1300 | for (p = mii_chip_table; p->type; p++) { | ||
1301 | if ((p->id[0] == phy->id[0]) && | ||
1302 | (p->id[1] == (phy->id[1] & 0xfff0))) { | ||
1303 | break; | ||
1304 | } | ||
1305 | } | ||
1306 | |||
1307 | if (p->id[1]) { | ||
1308 | phy->type = (p->type == MIX) ? | ||
1309 | ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? | ||
1310 | LAN : HOME) : p->type; | ||
1311 | } else | ||
1312 | phy->type = UNKNOWN; | ||
1313 | |||
1314 | net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n", | ||
1315 | pci_name(tp->pci_dev), | ||
1316 | (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); | ||
1317 | } | ||
1318 | |||
1319 | /** | ||
1320 | * sis190_mii_probe - Probe MII PHY for sis190 | ||
1321 | * @dev: the net device to probe for | ||
1322 | * | ||
1323 | * Search for total of 32 possible mii phy addresses. | ||
1324 | * Identify and set current phy if found one, | ||
1325 | * return error if it failed to found. | ||
1326 | */ | ||
1327 | static int __devinit sis190_mii_probe(struct net_device *dev) | ||
1328 | { | ||
1329 | struct sis190_private *tp = netdev_priv(dev); | ||
1330 | struct mii_if_info *mii_if = &tp->mii_if; | ||
1331 | void __iomem *ioaddr = tp->mmio_addr; | ||
1332 | int phy_id; | ||
1333 | int rc = 0; | ||
1334 | |||
1335 | INIT_LIST_HEAD(&tp->first_phy); | ||
1336 | |||
1337 | for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) { | ||
1338 | struct sis190_phy *phy; | ||
1339 | u16 status; | ||
1340 | |||
1341 | status = mdio_read_latched(ioaddr, phy_id, MII_BMSR); | ||
1342 | |||
1343 | // Try next mii if the current one is not accessible. | ||
1344 | if (status == 0xffff || status == 0x0000) | ||
1345 | continue; | ||
1346 | |||
1347 | phy = kmalloc(sizeof(*phy), GFP_KERNEL); | ||
1348 | if (!phy) { | ||
1349 | sis190_free_phy(&tp->first_phy); | ||
1350 | rc = -ENOMEM; | ||
1351 | goto out; | ||
1352 | } | ||
1353 | |||
1354 | sis190_init_phy(dev, tp, phy, phy_id, status); | ||
1355 | |||
1356 | list_add(&tp->first_phy, &phy->list); | ||
1357 | } | ||
1358 | |||
1359 | if (list_empty(&tp->first_phy)) { | ||
1360 | net_probe(tp, KERN_INFO "%s: No MII transceivers found!\n", | ||
1361 | pci_name(tp->pci_dev)); | ||
1362 | rc = -EIO; | ||
1363 | goto out; | ||
1364 | } | ||
1365 | |||
1366 | /* Select default PHY for mac */ | ||
1367 | sis190_default_phy(dev); | ||
1368 | |||
1369 | mii_if->dev = dev; | ||
1370 | mii_if->mdio_read = __mdio_read; | ||
1371 | mii_if->mdio_write = __mdio_write; | ||
1372 | mii_if->phy_id_mask = PHY_ID_ANY; | ||
1373 | mii_if->reg_num_mask = MII_REG_ANY; | ||
1374 | out: | ||
1375 | return rc; | ||
1376 | } | ||
1377 | |||
1378 | static void __devexit sis190_mii_remove(struct net_device *dev) | ||
1379 | { | ||
1380 | struct sis190_private *tp = netdev_priv(dev); | ||
1381 | |||
1382 | sis190_free_phy(&tp->first_phy); | ||
1383 | } | ||
1384 | |||
1385 | static void sis190_release_board(struct pci_dev *pdev) | ||
1386 | { | ||
1387 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1388 | struct sis190_private *tp = netdev_priv(dev); | ||
1389 | |||
1390 | iounmap(tp->mmio_addr); | ||
1391 | pci_release_regions(pdev); | ||
1392 | pci_disable_device(pdev); | ||
1393 | free_netdev(dev); | ||
1394 | } | ||
1395 | |||
1396 | static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) | ||
1397 | { | ||
1398 | struct sis190_private *tp; | ||
1399 | struct net_device *dev; | ||
1400 | void __iomem *ioaddr; | ||
1401 | int rc; | ||
1402 | |||
1403 | dev = alloc_etherdev(sizeof(*tp)); | ||
1404 | if (!dev) { | ||
1405 | net_drv(&debug, KERN_ERR PFX "unable to alloc new ethernet\n"); | ||
1406 | rc = -ENOMEM; | ||
1407 | goto err_out_0; | ||
1408 | } | ||
1409 | |||
1410 | SET_MODULE_OWNER(dev); | ||
1411 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
1412 | |||
1413 | tp = netdev_priv(dev); | ||
1414 | tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT); | ||
1415 | |||
1416 | rc = pci_enable_device(pdev); | ||
1417 | if (rc < 0) { | ||
1418 | net_probe(tp, KERN_ERR "%s: enable failure\n", pci_name(pdev)); | ||
1419 | goto err_free_dev_1; | ||
1420 | } | ||
1421 | |||
1422 | rc = -ENODEV; | ||
1423 | |||
1424 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | ||
1425 | net_probe(tp, KERN_ERR "%s: region #0 is no MMIO resource.\n", | ||
1426 | pci_name(pdev)); | ||
1427 | goto err_pci_disable_2; | ||
1428 | } | ||
1429 | if (pci_resource_len(pdev, 0) < SIS190_REGS_SIZE) { | ||
1430 | net_probe(tp, KERN_ERR "%s: invalid PCI region size(s).\n", | ||
1431 | pci_name(pdev)); | ||
1432 | goto err_pci_disable_2; | ||
1433 | } | ||
1434 | |||
1435 | rc = pci_request_regions(pdev, DRV_NAME); | ||
1436 | if (rc < 0) { | ||
1437 | net_probe(tp, KERN_ERR PFX "%s: could not request regions.\n", | ||
1438 | pci_name(pdev)); | ||
1439 | goto err_pci_disable_2; | ||
1440 | } | ||
1441 | |||
1442 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
1443 | if (rc < 0) { | ||
1444 | net_probe(tp, KERN_ERR "%s: DMA configuration failed.\n", | ||
1445 | pci_name(pdev)); | ||
1446 | goto err_free_res_3; | ||
1447 | } | ||
1448 | |||
1449 | pci_set_master(pdev); | ||
1450 | |||
1451 | ioaddr = ioremap(pci_resource_start(pdev, 0), SIS190_REGS_SIZE); | ||
1452 | if (!ioaddr) { | ||
1453 | net_probe(tp, KERN_ERR "%s: cannot remap MMIO, aborting\n", | ||
1454 | pci_name(pdev)); | ||
1455 | rc = -EIO; | ||
1456 | goto err_free_res_3; | ||
1457 | } | ||
1458 | |||
1459 | tp->pci_dev = pdev; | ||
1460 | tp->mmio_addr = ioaddr; | ||
1461 | |||
1462 | sis190_irq_mask_and_ack(ioaddr); | ||
1463 | |||
1464 | sis190_soft_reset(ioaddr); | ||
1465 | out: | ||
1466 | return dev; | ||
1467 | |||
1468 | err_free_res_3: | ||
1469 | pci_release_regions(pdev); | ||
1470 | err_pci_disable_2: | ||
1471 | pci_disable_device(pdev); | ||
1472 | err_free_dev_1: | ||
1473 | free_netdev(dev); | ||
1474 | err_out_0: | ||
1475 | dev = ERR_PTR(rc); | ||
1476 | goto out; | ||
1477 | } | ||
1478 | |||
1479 | static void sis190_tx_timeout(struct net_device *dev) | ||
1480 | { | ||
1481 | struct sis190_private *tp = netdev_priv(dev); | ||
1482 | void __iomem *ioaddr = tp->mmio_addr; | ||
1483 | u8 tmp8; | ||
1484 | |||
1485 | /* Disable Tx, if not already */ | ||
1486 | tmp8 = SIS_R8(TxControl); | ||
1487 | if (tmp8 & CmdTxEnb) | ||
1488 | SIS_W8(TxControl, tmp8 & ~CmdTxEnb); | ||
1489 | |||
1490 | |||
1491 | net_tx_err(tp, KERN_INFO "%s: Transmit timeout, status %08x %08x.\n", | ||
1492 | dev->name, SIS_R32(TxControl), SIS_R32(TxSts)); | ||
1493 | |||
1494 | /* Disable interrupts by clearing the interrupt mask. */ | ||
1495 | SIS_W32(IntrMask, 0x0000); | ||
1496 | |||
1497 | /* Stop a shared interrupt from scavenging while we are. */ | ||
1498 | spin_lock_irq(&tp->lock); | ||
1499 | sis190_tx_clear(tp); | ||
1500 | spin_unlock_irq(&tp->lock); | ||
1501 | |||
1502 | /* ...and finally, reset everything. */ | ||
1503 | sis190_hw_start(dev); | ||
1504 | |||
1505 | netif_wake_queue(dev); | ||
1506 | } | ||
1507 | |||
1508 | static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, | ||
1509 | struct net_device *dev) | ||
1510 | { | ||
1511 | struct sis190_private *tp = netdev_priv(dev); | ||
1512 | void __iomem *ioaddr = tp->mmio_addr; | ||
1513 | u16 sig; | ||
1514 | int i; | ||
1515 | |||
1516 | net_probe(tp, KERN_INFO "%s: Read MAC address from EEPROM\n", | ||
1517 | pci_name(pdev)); | ||
1518 | |||
1519 | /* Check to see if there is a sane EEPROM */ | ||
1520 | sig = (u16) sis190_read_eeprom(ioaddr, EEPROMSignature); | ||
1521 | |||
1522 | if ((sig == 0xffff) || (sig == 0x0000)) { | ||
1523 | net_probe(tp, KERN_INFO "%s: Error EEPROM read %x.\n", | ||
1524 | pci_name(pdev), sig); | ||
1525 | return -EIO; | ||
1526 | } | ||
1527 | |||
1528 | /* Get MAC address from EEPROM */ | ||
1529 | for (i = 0; i < MAC_ADDR_LEN / 2; i++) { | ||
1530 | __le16 w = sis190_read_eeprom(ioaddr, EEPROMMACAddr + i); | ||
1531 | |||
1532 | ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w); | ||
1533 | } | ||
1534 | |||
1535 | return 0; | ||
1536 | } | ||
1537 | |||
1538 | /** | ||
1539 | * sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model | ||
1540 | * @pdev: PCI device | ||
1541 | * @dev: network device to get address for | ||
1542 | * | ||
1543 | * SiS965 model, use APC CMOS RAM to store MAC address. | ||
1544 | * APC CMOS RAM is accessed through ISA bridge. | ||
1545 | * MAC address is read into @net_dev->dev_addr. | ||
1546 | */ | ||
1547 | static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev, | ||
1548 | struct net_device *dev) | ||
1549 | { | ||
1550 | struct sis190_private *tp = netdev_priv(dev); | ||
1551 | struct pci_dev *isa_bridge; | ||
1552 | u8 reg, tmp8; | ||
1553 | int i; | ||
1554 | |||
1555 | net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n", | ||
1556 | pci_name(pdev)); | ||
1557 | |||
1558 | isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL); | ||
1559 | if (!isa_bridge) { | ||
1560 | net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n", | ||
1561 | pci_name(pdev)); | ||
1562 | return -EIO; | ||
1563 | } | ||
1564 | |||
1565 | /* Enable port 78h & 79h to access APC Registers. */ | ||
1566 | pci_read_config_byte(isa_bridge, 0x48, &tmp8); | ||
1567 | reg = (tmp8 & ~0x02); | ||
1568 | pci_write_config_byte(isa_bridge, 0x48, reg); | ||
1569 | udelay(50); | ||
1570 | pci_read_config_byte(isa_bridge, 0x48, ®); | ||
1571 | |||
1572 | for (i = 0; i < MAC_ADDR_LEN; i++) { | ||
1573 | outb(0x9 + i, 0x78); | ||
1574 | dev->dev_addr[i] = inb(0x79); | ||
1575 | } | ||
1576 | |||
1577 | outb(0x12, 0x78); | ||
1578 | reg = inb(0x79); | ||
1579 | |||
1580 | /* Restore the value to ISA Bridge */ | ||
1581 | pci_write_config_byte(isa_bridge, 0x48, tmp8); | ||
1582 | pci_dev_put(isa_bridge); | ||
1583 | |||
1584 | return 0; | ||
1585 | } | ||
1586 | |||
1587 | /** | ||
1588 | * sis190_init_rxfilter - Initialize the Rx filter | ||
1589 | * @dev: network device to initialize | ||
1590 | * | ||
1591 | * Set receive filter address to our MAC address | ||
1592 | * and enable packet filtering. | ||
1593 | */ | ||
1594 | static inline void sis190_init_rxfilter(struct net_device *dev) | ||
1595 | { | ||
1596 | struct sis190_private *tp = netdev_priv(dev); | ||
1597 | void __iomem *ioaddr = tp->mmio_addr; | ||
1598 | u16 ctl; | ||
1599 | int i; | ||
1600 | |||
1601 | ctl = SIS_R16(RxMacControl); | ||
1602 | /* | ||
1603 | * Disable packet filtering before setting filter. | ||
1604 | * Note: SiS's driver writes 32 bits but RxMacControl is 16 bits | ||
1605 | * only and followed by RxMacAddr (6 bytes). Strange. -- FR | ||
1606 | */ | ||
1607 | SIS_W16(RxMacControl, ctl & ~0x0f00); | ||
1608 | |||
1609 | for (i = 0; i < MAC_ADDR_LEN; i++) | ||
1610 | SIS_W8(RxMacAddr + i, dev->dev_addr[i]); | ||
1611 | |||
1612 | SIS_W16(RxMacControl, ctl); | ||
1613 | SIS_PCI_COMMIT(); | ||
1614 | } | ||
1615 | |||
1616 | static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev) | ||
1617 | { | ||
1618 | u8 from; | ||
1619 | |||
1620 | pci_read_config_byte(pdev, 0x73, &from); | ||
1621 | |||
1622 | return (from & 0x00000001) ? | ||
1623 | sis190_get_mac_addr_from_apc(pdev, dev) : | ||
1624 | sis190_get_mac_addr_from_eeprom(pdev, dev); | ||
1625 | } | ||
1626 | |||
1627 | static void sis190_set_speed_auto(struct net_device *dev) | ||
1628 | { | ||
1629 | struct sis190_private *tp = netdev_priv(dev); | ||
1630 | void __iomem *ioaddr = tp->mmio_addr; | ||
1631 | int phy_id = tp->mii_if.phy_id; | ||
1632 | int val; | ||
1633 | |||
1634 | net_link(tp, KERN_INFO "%s: Enabling Auto-negotiation.\n", dev->name); | ||
1635 | |||
1636 | val = mdio_read(ioaddr, phy_id, MII_ADVERTISE); | ||
1637 | |||
1638 | // Enable 10/100 Full/Half Mode, leave MII_ADVERTISE bit4:0 | ||
1639 | // unchanged. | ||
1640 | mdio_write(ioaddr, phy_id, MII_ADVERTISE, (val & ADVERTISE_SLCT) | | ||
1641 | ADVERTISE_100FULL | ADVERTISE_10FULL | | ||
1642 | ADVERTISE_100HALF | ADVERTISE_10HALF); | ||
1643 | |||
1644 | // Enable 1000 Full Mode. | ||
1645 | mdio_write(ioaddr, phy_id, MII_CTRL1000, ADVERTISE_1000FULL); | ||
1646 | |||
1647 | // Enable auto-negotiation and restart auto-negotiation. | ||
1648 | mdio_write(ioaddr, phy_id, MII_BMCR, | ||
1649 | BMCR_ANENABLE | BMCR_ANRESTART | BMCR_RESET); | ||
1650 | } | ||
1651 | |||
1652 | static int sis190_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1653 | { | ||
1654 | struct sis190_private *tp = netdev_priv(dev); | ||
1655 | |||
1656 | return mii_ethtool_gset(&tp->mii_if, cmd); | ||
1657 | } | ||
1658 | |||
1659 | static int sis190_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1660 | { | ||
1661 | struct sis190_private *tp = netdev_priv(dev); | ||
1662 | |||
1663 | return mii_ethtool_sset(&tp->mii_if, cmd); | ||
1664 | } | ||
1665 | |||
1666 | static void sis190_get_drvinfo(struct net_device *dev, | ||
1667 | struct ethtool_drvinfo *info) | ||
1668 | { | ||
1669 | struct sis190_private *tp = netdev_priv(dev); | ||
1670 | |||
1671 | strcpy(info->driver, DRV_NAME); | ||
1672 | strcpy(info->version, DRV_VERSION); | ||
1673 | strcpy(info->bus_info, pci_name(tp->pci_dev)); | ||
1674 | } | ||
1675 | |||
1676 | static int sis190_get_regs_len(struct net_device *dev) | ||
1677 | { | ||
1678 | return SIS190_REGS_SIZE; | ||
1679 | } | ||
1680 | |||
1681 | static void sis190_get_regs(struct net_device *dev, struct ethtool_regs *regs, | ||
1682 | void *p) | ||
1683 | { | ||
1684 | struct sis190_private *tp = netdev_priv(dev); | ||
1685 | unsigned long flags; | ||
1686 | |||
1687 | if (regs->len > SIS190_REGS_SIZE) | ||
1688 | regs->len = SIS190_REGS_SIZE; | ||
1689 | |||
1690 | spin_lock_irqsave(&tp->lock, flags); | ||
1691 | memcpy_fromio(p, tp->mmio_addr, regs->len); | ||
1692 | spin_unlock_irqrestore(&tp->lock, flags); | ||
1693 | } | ||
1694 | |||
1695 | static int sis190_nway_reset(struct net_device *dev) | ||
1696 | { | ||
1697 | struct sis190_private *tp = netdev_priv(dev); | ||
1698 | |||
1699 | return mii_nway_restart(&tp->mii_if); | ||
1700 | } | ||
1701 | |||
1702 | static u32 sis190_get_msglevel(struct net_device *dev) | ||
1703 | { | ||
1704 | struct sis190_private *tp = netdev_priv(dev); | ||
1705 | |||
1706 | return tp->msg_enable; | ||
1707 | } | ||
1708 | |||
1709 | static void sis190_set_msglevel(struct net_device *dev, u32 value) | ||
1710 | { | ||
1711 | struct sis190_private *tp = netdev_priv(dev); | ||
1712 | |||
1713 | tp->msg_enable = value; | ||
1714 | } | ||
1715 | |||
1716 | static struct ethtool_ops sis190_ethtool_ops = { | ||
1717 | .get_settings = sis190_get_settings, | ||
1718 | .set_settings = sis190_set_settings, | ||
1719 | .get_drvinfo = sis190_get_drvinfo, | ||
1720 | .get_regs_len = sis190_get_regs_len, | ||
1721 | .get_regs = sis190_get_regs, | ||
1722 | .get_link = ethtool_op_get_link, | ||
1723 | .get_msglevel = sis190_get_msglevel, | ||
1724 | .set_msglevel = sis190_set_msglevel, | ||
1725 | .nway_reset = sis190_nway_reset, | ||
1726 | }; | ||
1727 | |||
1728 | static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
1729 | { | ||
1730 | struct sis190_private *tp = netdev_priv(dev); | ||
1731 | |||
1732 | return !netif_running(dev) ? -EINVAL : | ||
1733 | generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); | ||
1734 | } | ||
1735 | |||
1736 | static int __devinit sis190_init_one(struct pci_dev *pdev, | ||
1737 | const struct pci_device_id *ent) | ||
1738 | { | ||
1739 | static int printed_version = 0; | ||
1740 | struct sis190_private *tp; | ||
1741 | struct net_device *dev; | ||
1742 | void __iomem *ioaddr; | ||
1743 | int rc; | ||
1744 | |||
1745 | if (!printed_version) { | ||
1746 | net_drv(&debug, KERN_INFO SIS190_DRIVER_NAME " loaded.\n"); | ||
1747 | printed_version = 1; | ||
1748 | } | ||
1749 | |||
1750 | dev = sis190_init_board(pdev); | ||
1751 | if (IS_ERR(dev)) { | ||
1752 | rc = PTR_ERR(dev); | ||
1753 | goto out; | ||
1754 | } | ||
1755 | |||
1756 | tp = netdev_priv(dev); | ||
1757 | ioaddr = tp->mmio_addr; | ||
1758 | |||
1759 | rc = sis190_get_mac_addr(pdev, dev); | ||
1760 | if (rc < 0) | ||
1761 | goto err_release_board; | ||
1762 | |||
1763 | sis190_init_rxfilter(dev); | ||
1764 | |||
1765 | INIT_WORK(&tp->phy_task, sis190_phy_task, dev); | ||
1766 | |||
1767 | dev->open = sis190_open; | ||
1768 | dev->stop = sis190_close; | ||
1769 | dev->do_ioctl = sis190_ioctl; | ||
1770 | dev->get_stats = sis190_get_stats; | ||
1771 | dev->tx_timeout = sis190_tx_timeout; | ||
1772 | dev->watchdog_timeo = SIS190_TX_TIMEOUT; | ||
1773 | dev->hard_start_xmit = sis190_start_xmit; | ||
1774 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
1775 | dev->poll_controller = sis190_netpoll; | ||
1776 | #endif | ||
1777 | dev->set_multicast_list = sis190_set_rx_mode; | ||
1778 | SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops); | ||
1779 | dev->irq = pdev->irq; | ||
1780 | dev->base_addr = (unsigned long) 0xdead; | ||
1781 | |||
1782 | spin_lock_init(&tp->lock); | ||
1783 | |||
1784 | rc = sis190_mii_probe(dev); | ||
1785 | if (rc < 0) | ||
1786 | goto err_release_board; | ||
1787 | |||
1788 | rc = register_netdev(dev); | ||
1789 | if (rc < 0) | ||
1790 | goto err_remove_mii; | ||
1791 | |||
1792 | pci_set_drvdata(pdev, dev); | ||
1793 | |||
1794 | net_probe(tp, KERN_INFO "%s: %s at %p (IRQ: %d), " | ||
1795 | "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | ||
1796 | pci_name(pdev), sis_chip_info[ent->driver_data].name, | ||
1797 | ioaddr, dev->irq, | ||
1798 | dev->dev_addr[0], dev->dev_addr[1], | ||
1799 | dev->dev_addr[2], dev->dev_addr[3], | ||
1800 | dev->dev_addr[4], dev->dev_addr[5]); | ||
1801 | |||
1802 | netif_carrier_off(dev); | ||
1803 | |||
1804 | sis190_set_speed_auto(dev); | ||
1805 | out: | ||
1806 | return rc; | ||
1807 | |||
1808 | err_remove_mii: | ||
1809 | sis190_mii_remove(dev); | ||
1810 | err_release_board: | ||
1811 | sis190_release_board(pdev); | ||
1812 | goto out; | ||
1813 | } | ||
1814 | |||
1815 | static void __devexit sis190_remove_one(struct pci_dev *pdev) | ||
1816 | { | ||
1817 | struct net_device *dev = pci_get_drvdata(pdev); | ||
1818 | |||
1819 | sis190_mii_remove(dev); | ||
1820 | unregister_netdev(dev); | ||
1821 | sis190_release_board(pdev); | ||
1822 | pci_set_drvdata(pdev, NULL); | ||
1823 | } | ||
1824 | |||
1825 | static struct pci_driver sis190_pci_driver = { | ||
1826 | .name = DRV_NAME, | ||
1827 | .id_table = sis190_pci_tbl, | ||
1828 | .probe = sis190_init_one, | ||
1829 | .remove = __devexit_p(sis190_remove_one), | ||
1830 | }; | ||
1831 | |||
1832 | static int __init sis190_init_module(void) | ||
1833 | { | ||
1834 | return pci_module_init(&sis190_pci_driver); | ||
1835 | } | ||
1836 | |||
1837 | static void __exit sis190_cleanup_module(void) | ||
1838 | { | ||
1839 | pci_unregister_driver(&sis190_pci_driver); | ||
1840 | } | ||
1841 | |||
1842 | module_init(sis190_init_module); | ||
1843 | module_exit(sis190_cleanup_module); | ||
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index f15739481d62..d7c98515fdfd 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include "skge.h" | 42 | #include "skge.h" |
43 | 43 | ||
44 | #define DRV_NAME "skge" | 44 | #define DRV_NAME "skge" |
45 | #define DRV_VERSION "0.8" | 45 | #define DRV_VERSION "0.9" |
46 | #define PFX DRV_NAME " " | 46 | #define PFX DRV_NAME " " |
47 | 47 | ||
48 | #define DEFAULT_TX_RING_SIZE 128 | 48 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -79,8 +79,8 @@ static const struct pci_device_id skge_id_table[] = { | |||
79 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, |
80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ | 80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ |
81 | { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, | 81 | { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, |
82 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) }, | ||
83 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, | 82 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, |
83 | { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, }, | ||
84 | { 0 } | 84 | { 0 } |
85 | }; | 85 | }; |
86 | MODULE_DEVICE_TABLE(pci, skge_id_table); | 86 | MODULE_DEVICE_TABLE(pci, skge_id_table); |
@@ -189,7 +189,7 @@ static u32 skge_supported_modes(const struct skge_hw *hw) | |||
189 | { | 189 | { |
190 | u32 supported; | 190 | u32 supported; |
191 | 191 | ||
192 | if (iscopper(hw)) { | 192 | if (hw->copper) { |
193 | supported = SUPPORTED_10baseT_Half | 193 | supported = SUPPORTED_10baseT_Half |
194 | | SUPPORTED_10baseT_Full | 194 | | SUPPORTED_10baseT_Full |
195 | | SUPPORTED_100baseT_Half | 195 | | SUPPORTED_100baseT_Half |
@@ -222,7 +222,7 @@ static int skge_get_settings(struct net_device *dev, | |||
222 | ecmd->transceiver = XCVR_INTERNAL; | 222 | ecmd->transceiver = XCVR_INTERNAL; |
223 | ecmd->supported = skge_supported_modes(hw); | 223 | ecmd->supported = skge_supported_modes(hw); |
224 | 224 | ||
225 | if (iscopper(hw)) { | 225 | if (hw->copper) { |
226 | ecmd->port = PORT_TP; | 226 | ecmd->port = PORT_TP; |
227 | ecmd->phy_address = hw->phy_addr; | 227 | ecmd->phy_address = hw->phy_addr; |
228 | } else | 228 | } else |
@@ -876,6 +876,9 @@ static int skge_rx_fill(struct skge_port *skge) | |||
876 | 876 | ||
877 | static void skge_link_up(struct skge_port *skge) | 877 | static void skge_link_up(struct skge_port *skge) |
878 | { | 878 | { |
879 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), | ||
880 | LED_BLK_OFF|LED_SYNC_OFF|LED_ON); | ||
881 | |||
879 | netif_carrier_on(skge->netdev); | 882 | netif_carrier_on(skge->netdev); |
880 | if (skge->tx_avail > MAX_SKB_FRAGS + 1) | 883 | if (skge->tx_avail > MAX_SKB_FRAGS + 1) |
881 | netif_wake_queue(skge->netdev); | 884 | netif_wake_queue(skge->netdev); |
@@ -894,6 +897,7 @@ static void skge_link_up(struct skge_port *skge) | |||
894 | 897 | ||
895 | static void skge_link_down(struct skge_port *skge) | 898 | static void skge_link_down(struct skge_port *skge) |
896 | { | 899 | { |
900 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); | ||
897 | netif_carrier_off(skge->netdev); | 901 | netif_carrier_off(skge->netdev); |
898 | netif_stop_queue(skge->netdev); | 902 | netif_stop_queue(skge->netdev); |
899 | 903 | ||
@@ -1599,7 +1603,7 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1599 | adv = PHY_AN_CSMA; | 1603 | adv = PHY_AN_CSMA; |
1600 | 1604 | ||
1601 | if (skge->autoneg == AUTONEG_ENABLE) { | 1605 | if (skge->autoneg == AUTONEG_ENABLE) { |
1602 | if (iscopper(hw)) { | 1606 | if (hw->copper) { |
1603 | if (skge->advertising & ADVERTISED_1000baseT_Full) | 1607 | if (skge->advertising & ADVERTISED_1000baseT_Full) |
1604 | ct1000 |= PHY_M_1000C_AFD; | 1608 | ct1000 |= PHY_M_1000C_AFD; |
1605 | if (skge->advertising & ADVERTISED_1000baseT_Half) | 1609 | if (skge->advertising & ADVERTISED_1000baseT_Half) |
@@ -1691,7 +1695,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1691 | /* Set hardware config mode */ | 1695 | /* Set hardware config mode */ |
1692 | reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | | 1696 | reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | |
1693 | GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE; | 1697 | GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE; |
1694 | reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; | 1698 | reg |= hw->copper ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; |
1695 | 1699 | ||
1696 | /* Clear GMC reset */ | 1700 | /* Clear GMC reset */ |
1697 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); | 1701 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); |
@@ -1780,7 +1784,12 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1780 | reg &= ~GMF_RX_F_FL_ON; | 1784 | reg &= ~GMF_RX_F_FL_ON; |
1781 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 1785 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
1782 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); | 1786 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); |
1783 | skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); | 1787 | /* |
1788 | * because Pause Packet Truncation in GMAC is not working | ||
1789 | * we have to increase the Flush Threshold to 64 bytes | ||
1790 | * in order to flush pause packets in Rx FIFO on Yukon-1 | ||
1791 | */ | ||
1792 | skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1); | ||
1784 | 1793 | ||
1785 | /* Configure Tx MAC FIFO */ | 1794 | /* Configure Tx MAC FIFO */ |
1786 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); | 1795 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); |
@@ -2670,18 +2679,6 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2670 | /* Timestamp (unused) overflow */ | 2679 | /* Timestamp (unused) overflow */ |
2671 | if (hwstatus & IS_IRQ_TIST_OV) | 2680 | if (hwstatus & IS_IRQ_TIST_OV) |
2672 | skge_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ); | 2681 | skge_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ); |
2673 | |||
2674 | if (hwstatus & IS_IRQ_SENSOR) { | ||
2675 | /* no sensors on 32-bit Yukon */ | ||
2676 | if (!(skge_read16(hw, B0_CTST) & CS_BUS_SLOT_SZ)) { | ||
2677 | printk(KERN_ERR PFX "ignoring bogus sensor interrups\n"); | ||
2678 | skge_write32(hw, B0_HWE_IMSK, | ||
2679 | IS_ERR_MSK & ~IS_IRQ_SENSOR); | ||
2680 | } else | ||
2681 | printk(KERN_WARNING PFX "sensor interrupt\n"); | ||
2682 | } | ||
2683 | |||
2684 | |||
2685 | } | 2682 | } |
2686 | 2683 | ||
2687 | if (hwstatus & IS_RAM_RD_PAR) { | 2684 | if (hwstatus & IS_RAM_RD_PAR) { |
@@ -2712,9 +2709,10 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2712 | 2709 | ||
2713 | skge_pci_clear(hw); | 2710 | skge_pci_clear(hw); |
2714 | 2711 | ||
2712 | /* if error still set then just ignore it */ | ||
2715 | hwstatus = skge_read32(hw, B0_HWE_ISRC); | 2713 | hwstatus = skge_read32(hw, B0_HWE_ISRC); |
2716 | if (hwstatus & IS_IRQ_STAT) { | 2714 | if (hwstatus & IS_IRQ_STAT) { |
2717 | printk(KERN_WARNING PFX "IRQ status %x: still set ignoring hardware errors\n", | 2715 | pr_debug("IRQ status %x: still set ignoring hardware errors\n", |
2718 | hwstatus); | 2716 | hwstatus); |
2719 | hw->intr_mask &= ~IS_HW_ERR; | 2717 | hw->intr_mask &= ~IS_HW_ERR; |
2720 | } | 2718 | } |
@@ -2876,7 +2874,7 @@ static const char *skge_board_name(const struct skge_hw *hw) | |||
2876 | static int skge_reset(struct skge_hw *hw) | 2874 | static int skge_reset(struct skge_hw *hw) |
2877 | { | 2875 | { |
2878 | u16 ctst; | 2876 | u16 ctst; |
2879 | u8 t8, mac_cfg; | 2877 | u8 t8, mac_cfg, pmd_type, phy_type; |
2880 | int i; | 2878 | int i; |
2881 | 2879 | ||
2882 | ctst = skge_read16(hw, B0_CTST); | 2880 | ctst = skge_read16(hw, B0_CTST); |
@@ -2895,18 +2893,19 @@ static int skge_reset(struct skge_hw *hw) | |||
2895 | ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); | 2893 | ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); |
2896 | 2894 | ||
2897 | hw->chip_id = skge_read8(hw, B2_CHIP_ID); | 2895 | hw->chip_id = skge_read8(hw, B2_CHIP_ID); |
2898 | hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; | 2896 | phy_type = skge_read8(hw, B2_E_1) & 0xf; |
2899 | hw->pmd_type = skge_read8(hw, B2_PMD_TYP); | 2897 | pmd_type = skge_read8(hw, B2_PMD_TYP); |
2898 | hw->copper = (pmd_type == 'T' || pmd_type == '1'); | ||
2900 | 2899 | ||
2901 | switch (hw->chip_id) { | 2900 | switch (hw->chip_id) { |
2902 | case CHIP_ID_GENESIS: | 2901 | case CHIP_ID_GENESIS: |
2903 | switch (hw->phy_type) { | 2902 | switch (phy_type) { |
2904 | case SK_PHY_BCOM: | 2903 | case SK_PHY_BCOM: |
2905 | hw->phy_addr = PHY_ADDR_BCOM; | 2904 | hw->phy_addr = PHY_ADDR_BCOM; |
2906 | break; | 2905 | break; |
2907 | default: | 2906 | default: |
2908 | printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", | 2907 | printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", |
2909 | pci_name(hw->pdev), hw->phy_type); | 2908 | pci_name(hw->pdev), phy_type); |
2910 | return -EOPNOTSUPP; | 2909 | return -EOPNOTSUPP; |
2911 | } | 2910 | } |
2912 | break; | 2911 | break; |
@@ -2914,13 +2913,10 @@ static int skge_reset(struct skge_hw *hw) | |||
2914 | case CHIP_ID_YUKON: | 2913 | case CHIP_ID_YUKON: |
2915 | case CHIP_ID_YUKON_LITE: | 2914 | case CHIP_ID_YUKON_LITE: |
2916 | case CHIP_ID_YUKON_LP: | 2915 | case CHIP_ID_YUKON_LP: |
2917 | if (hw->phy_type < SK_PHY_MARV_COPPER && hw->pmd_type != 'S') | 2916 | if (phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S') |
2918 | hw->phy_type = SK_PHY_MARV_COPPER; | 2917 | hw->copper = 1; |
2919 | 2918 | ||
2920 | hw->phy_addr = PHY_ADDR_MARV; | 2919 | hw->phy_addr = PHY_ADDR_MARV; |
2921 | if (!iscopper(hw)) | ||
2922 | hw->phy_type = SK_PHY_MARV_FIBER; | ||
2923 | |||
2924 | break; | 2920 | break; |
2925 | 2921 | ||
2926 | default: | 2922 | default: |
@@ -2948,12 +2944,20 @@ static int skge_reset(struct skge_hw *hw) | |||
2948 | else | 2944 | else |
2949 | hw->ram_size = t8 * 4096; | 2945 | hw->ram_size = t8 * 4096; |
2950 | 2946 | ||
2947 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG; | ||
2951 | if (hw->chip_id == CHIP_ID_GENESIS) | 2948 | if (hw->chip_id == CHIP_ID_GENESIS) |
2952 | genesis_init(hw); | 2949 | genesis_init(hw); |
2953 | else { | 2950 | else { |
2954 | /* switch power to VCC (WA for VAUX problem) */ | 2951 | /* switch power to VCC (WA for VAUX problem) */ |
2955 | skge_write8(hw, B0_POWER_CTRL, | 2952 | skge_write8(hw, B0_POWER_CTRL, |
2956 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); | 2953 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); |
2954 | /* avoid boards with stuck Hardware error bits */ | ||
2955 | if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && | ||
2956 | (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { | ||
2957 | printk(KERN_WARNING PFX "stuck hardware sensor bit\n"); | ||
2958 | hw->intr_mask &= ~IS_HW_ERR; | ||
2959 | } | ||
2960 | |||
2957 | for (i = 0; i < hw->ports; i++) { | 2961 | for (i = 0; i < hw->ports; i++) { |
2958 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); | 2962 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); |
2959 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); | 2963 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); |
@@ -2994,7 +2998,6 @@ static int skge_reset(struct skge_hw *hw) | |||
2994 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); | 2998 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); |
2995 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); | 2999 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); |
2996 | 3000 | ||
2997 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG; | ||
2998 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 3001 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2999 | 3002 | ||
3000 | if (hw->chip_id != CHIP_ID_GENESIS) | 3003 | if (hw->chip_id != CHIP_ID_GENESIS) |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index b432f1bb8168..f1680beb8e68 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -214,8 +214,6 @@ enum { | |||
214 | 214 | ||
215 | /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ | 215 | /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ |
216 | enum { | 216 | enum { |
217 | IS_ERR_MSK = 0x00003fff,/* All Error bits */ | ||
218 | |||
219 | IS_IRQ_TIST_OV = 1<<13, /* Time Stamp Timer Overflow (YUKON only) */ | 217 | IS_IRQ_TIST_OV = 1<<13, /* Time Stamp Timer Overflow (YUKON only) */ |
220 | IS_IRQ_SENSOR = 1<<12, /* IRQ from Sensor (YUKON only) */ | 218 | IS_IRQ_SENSOR = 1<<12, /* IRQ from Sensor (YUKON only) */ |
221 | IS_IRQ_MST_ERR = 1<<11, /* IRQ master error detected */ | 219 | IS_IRQ_MST_ERR = 1<<11, /* IRQ master error detected */ |
@@ -230,6 +228,12 @@ enum { | |||
230 | IS_M2_PAR_ERR = 1<<2, /* MAC 2 Parity Error */ | 228 | IS_M2_PAR_ERR = 1<<2, /* MAC 2 Parity Error */ |
231 | IS_R1_PAR_ERR = 1<<1, /* Queue R1 Parity Error */ | 229 | IS_R1_PAR_ERR = 1<<1, /* Queue R1 Parity Error */ |
232 | IS_R2_PAR_ERR = 1<<0, /* Queue R2 Parity Error */ | 230 | IS_R2_PAR_ERR = 1<<0, /* Queue R2 Parity Error */ |
231 | |||
232 | IS_ERR_MSK = IS_IRQ_MST_ERR | IS_IRQ_STAT | ||
233 | | IS_NO_STAT_M1 | IS_NO_STAT_M2 | ||
234 | | IS_RAM_RD_PAR | IS_RAM_WR_PAR | ||
235 | | IS_M1_PAR_ERR | IS_M2_PAR_ERR | ||
236 | | IS_R1_PAR_ERR | IS_R2_PAR_ERR, | ||
233 | }; | 237 | }; |
234 | 238 | ||
235 | /* B2_TST_CTRL1 8 bit Test Control Register 1 */ | 239 | /* B2_TST_CTRL1 8 bit Test Control Register 1 */ |
@@ -2456,24 +2460,17 @@ struct skge_hw { | |||
2456 | 2460 | ||
2457 | u8 chip_id; | 2461 | u8 chip_id; |
2458 | u8 chip_rev; | 2462 | u8 chip_rev; |
2459 | u8 phy_type; | 2463 | u8 copper; |
2460 | u8 pmd_type; | ||
2461 | u16 phy_addr; | ||
2462 | u8 ports; | 2464 | u8 ports; |
2463 | 2465 | ||
2464 | u32 ram_size; | 2466 | u32 ram_size; |
2465 | u32 ram_offset; | 2467 | u32 ram_offset; |
2468 | u16 phy_addr; | ||
2466 | 2469 | ||
2467 | struct tasklet_struct ext_tasklet; | 2470 | struct tasklet_struct ext_tasklet; |
2468 | spinlock_t phy_lock; | 2471 | spinlock_t phy_lock; |
2469 | }; | 2472 | }; |
2470 | 2473 | ||
2471 | |||
2472 | static inline int iscopper(const struct skge_hw *hw) | ||
2473 | { | ||
2474 | return (hw->pmd_type == 'T'); | ||
2475 | } | ||
2476 | |||
2477 | enum { | 2474 | enum { |
2478 | FLOW_MODE_NONE = 0, /* No Flow-Control */ | 2475 | FLOW_MODE_NONE = 0, /* No Flow-Control */ |
2479 | FLOW_MODE_LOC_SEND = 1, /* Local station sends PAUSE */ | 2476 | FLOW_MODE_LOC_SEND = 1, /* Local station sends PAUSE */ |
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c index 6d9dae60a697..ba8593ac3f8a 100644 --- a/drivers/net/smc-ultra.c +++ b/drivers/net/smc-ultra.c | |||
@@ -68,6 +68,7 @@ static const char version[] = | |||
68 | #include <linux/etherdevice.h> | 68 | #include <linux/etherdevice.h> |
69 | 69 | ||
70 | #include <asm/io.h> | 70 | #include <asm/io.h> |
71 | #include <asm/irq.h> | ||
71 | #include <asm/system.h> | 72 | #include <asm/system.h> |
72 | 73 | ||
73 | #include "8390.h" | 74 | #include "8390.h" |
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index cdc9cc873e06..90b818a8de6e 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c | |||
@@ -1,6 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * sonic.c | 2 | * sonic.c |
3 | * | 3 | * |
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, added zero-copy buffer handling, and | ||
7 | * (from the mac68k project) introduced dhd's support for 16-bit cards. | ||
8 | * | ||
4 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
5 | * | 10 | * |
6 | * This driver is based on work from Andreas Busse, but most of | 11 | * This driver is based on work from Andreas Busse, but most of |
@@ -9,12 +14,23 @@ | |||
9 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) | 14 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) |
10 | * | 15 | * |
11 | * Core code included by system sonic drivers | 16 | * Core code included by system sonic drivers |
17 | * | ||
18 | * And... partially rewritten again by David Huggins-Daines in order | ||
19 | * to cope with screwed up Macintosh NICs that may or may not use | ||
20 | * 16-bit DMA. | ||
21 | * | ||
22 | * (C) 1999 David Huggins-Daines <dhd@debian.org> | ||
23 | * | ||
12 | */ | 24 | */ |
13 | 25 | ||
14 | /* | 26 | /* |
15 | * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook, | 27 | * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook, |
16 | * National Semiconductors data sheet for the DP83932B Sonic Ethernet | 28 | * National Semiconductors data sheet for the DP83932B Sonic Ethernet |
17 | * controller, and the files "8390.c" and "skeleton.c" in this directory. | 29 | * controller, and the files "8390.c" and "skeleton.c" in this directory. |
30 | * | ||
31 | * Additional sources: Nat Semi data sheet for the DP83932C and Nat Semi | ||
32 | * Application Note AN-746, the files "lance.c" and "ibmlana.c". See also | ||
33 | * the NetBSD file "sys/arch/mac68k/dev/if_sn.c". | ||
18 | */ | 34 | */ |
19 | 35 | ||
20 | 36 | ||
@@ -28,6 +44,9 @@ | |||
28 | */ | 44 | */ |
29 | static int sonic_open(struct net_device *dev) | 45 | static int sonic_open(struct net_device *dev) |
30 | { | 46 | { |
47 | struct sonic_local *lp = netdev_priv(dev); | ||
48 | int i; | ||
49 | |||
31 | if (sonic_debug > 2) | 50 | if (sonic_debug > 2) |
32 | printk("sonic_open: initializing sonic driver.\n"); | 51 | printk("sonic_open: initializing sonic driver.\n"); |
33 | 52 | ||
@@ -40,14 +59,59 @@ static int sonic_open(struct net_device *dev) | |||
40 | * This means that during execution of the handler interrupt are disabled | 59 | * This means that during execution of the handler interrupt are disabled |
41 | * covering another bug otherwise corrupting data. This doesn't mean | 60 | * covering another bug otherwise corrupting data. This doesn't mean |
42 | * this glue works ok under all situations. | 61 | * this glue works ok under all situations. |
62 | * | ||
63 | * Note (dhd): this also appears to prevent lockups on the Macintrash | ||
64 | * when more than one Ethernet card is installed (knock on wood) | ||
65 | * | ||
66 | * Note (fthain): whether the above is still true is anyones guess. Certainly | ||
67 | * the buffer handling algorithms will not tolerate re-entrance without some | ||
68 | * mutual exclusion added. Anyway, the memcpy has now been eliminated from the | ||
69 | * rx code to make this a faster "fast interrupt". | ||
43 | */ | 70 | */ |
44 | // if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) { | 71 | if (request_irq(dev->irq, &sonic_interrupt, SONIC_IRQ_FLAG, "sonic", dev)) { |
45 | if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT, | 72 | printk(KERN_ERR "\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); |
46 | "sonic", dev)) { | ||
47 | printk("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); | ||
48 | return -EAGAIN; | 73 | return -EAGAIN; |
49 | } | 74 | } |
50 | 75 | ||
76 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
77 | struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2); | ||
78 | if (skb == NULL) { | ||
79 | while(i > 0) { /* free any that were allocated successfully */ | ||
80 | i--; | ||
81 | dev_kfree_skb(lp->rx_skb[i]); | ||
82 | lp->rx_skb[i] = NULL; | ||
83 | } | ||
84 | printk(KERN_ERR "%s: couldn't allocate receive buffers\n", | ||
85 | dev->name); | ||
86 | return -ENOMEM; | ||
87 | } | ||
88 | skb->dev = dev; | ||
89 | /* align IP header unless DMA requires otherwise */ | ||
90 | if (SONIC_BUS_SCALE(lp->dma_bitmode) == 2) | ||
91 | skb_reserve(skb, 2); | ||
92 | lp->rx_skb[i] = skb; | ||
93 | } | ||
94 | |||
95 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
96 | dma_addr_t laddr = dma_map_single(lp->device, skb_put(lp->rx_skb[i], SONIC_RBSIZE), | ||
97 | SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
98 | if (!laddr) { | ||
99 | while(i > 0) { /* free any that were mapped successfully */ | ||
100 | i--; | ||
101 | dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
102 | lp->rx_laddr[i] = (dma_addr_t)0; | ||
103 | } | ||
104 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
105 | dev_kfree_skb(lp->rx_skb[i]); | ||
106 | lp->rx_skb[i] = NULL; | ||
107 | } | ||
108 | printk(KERN_ERR "%s: couldn't map rx DMA buffers\n", | ||
109 | dev->name); | ||
110 | return -ENOMEM; | ||
111 | } | ||
112 | lp->rx_laddr[i] = laddr; | ||
113 | } | ||
114 | |||
51 | /* | 115 | /* |
52 | * Initialize the SONIC | 116 | * Initialize the SONIC |
53 | */ | 117 | */ |
@@ -67,7 +131,8 @@ static int sonic_open(struct net_device *dev) | |||
67 | */ | 131 | */ |
68 | static int sonic_close(struct net_device *dev) | 132 | static int sonic_close(struct net_device *dev) |
69 | { | 133 | { |
70 | unsigned int base_addr = dev->base_addr; | 134 | struct sonic_local *lp = netdev_priv(dev); |
135 | int i; | ||
71 | 136 | ||
72 | if (sonic_debug > 2) | 137 | if (sonic_debug > 2) |
73 | printk("sonic_close\n"); | 138 | printk("sonic_close\n"); |
@@ -77,20 +142,56 @@ static int sonic_close(struct net_device *dev) | |||
77 | /* | 142 | /* |
78 | * stop the SONIC, disable interrupts | 143 | * stop the SONIC, disable interrupts |
79 | */ | 144 | */ |
80 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
81 | SONIC_WRITE(SONIC_IMR, 0); | 145 | SONIC_WRITE(SONIC_IMR, 0); |
146 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
82 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | 147 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
83 | 148 | ||
84 | sonic_free_irq(dev->irq, dev); /* release the IRQ */ | 149 | /* unmap and free skbs that haven't been transmitted */ |
150 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
151 | if(lp->tx_laddr[i]) { | ||
152 | dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE); | ||
153 | lp->tx_laddr[i] = (dma_addr_t)0; | ||
154 | } | ||
155 | if(lp->tx_skb[i]) { | ||
156 | dev_kfree_skb(lp->tx_skb[i]); | ||
157 | lp->tx_skb[i] = NULL; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* unmap and free the receive buffers */ | ||
162 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
163 | if(lp->rx_laddr[i]) { | ||
164 | dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
165 | lp->rx_laddr[i] = (dma_addr_t)0; | ||
166 | } | ||
167 | if(lp->rx_skb[i]) { | ||
168 | dev_kfree_skb(lp->rx_skb[i]); | ||
169 | lp->rx_skb[i] = NULL; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | free_irq(dev->irq, dev); /* release the IRQ */ | ||
85 | 174 | ||
86 | return 0; | 175 | return 0; |
87 | } | 176 | } |
88 | 177 | ||
89 | static void sonic_tx_timeout(struct net_device *dev) | 178 | static void sonic_tx_timeout(struct net_device *dev) |
90 | { | 179 | { |
91 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 180 | struct sonic_local *lp = netdev_priv(dev); |
92 | printk("%s: transmit timed out.\n", dev->name); | 181 | int i; |
93 | 182 | /* Stop the interrupts for this */ | |
183 | SONIC_WRITE(SONIC_IMR, 0); | ||
184 | /* We could resend the original skbs. Easier to re-initialise. */ | ||
185 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
186 | if(lp->tx_laddr[i]) { | ||
187 | dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE); | ||
188 | lp->tx_laddr[i] = (dma_addr_t)0; | ||
189 | } | ||
190 | if(lp->tx_skb[i]) { | ||
191 | dev_kfree_skb(lp->tx_skb[i]); | ||
192 | lp->tx_skb[i] = NULL; | ||
193 | } | ||
194 | } | ||
94 | /* Try to restart the adaptor. */ | 195 | /* Try to restart the adaptor. */ |
95 | sonic_init(dev); | 196 | sonic_init(dev); |
96 | lp->stats.tx_errors++; | 197 | lp->stats.tx_errors++; |
@@ -100,60 +201,92 @@ static void sonic_tx_timeout(struct net_device *dev) | |||
100 | 201 | ||
101 | /* | 202 | /* |
102 | * transmit packet | 203 | * transmit packet |
204 | * | ||
205 | * Appends new TD during transmission thus avoiding any TX interrupts | ||
206 | * until we run out of TDs. | ||
207 | * This routine interacts closely with the ISR in that it may, | ||
208 | * set tx_skb[i] | ||
209 | * reset the status flags of the new TD | ||
210 | * set and reset EOL flags | ||
211 | * stop the tx queue | ||
212 | * The ISR interacts with this routine in various ways. It may, | ||
213 | * reset tx_skb[i] | ||
214 | * test the EOL and status flags of the TDs | ||
215 | * wake the tx queue | ||
216 | * Concurrently with all of this, the SONIC is potentially writing to | ||
217 | * the status flags of the TDs. | ||
218 | * Until some mutual exclusion is added, this code will not work with SMP. However, | ||
219 | * MIPS Jazz machines and m68k Macs were all uni-processor machines. | ||
103 | */ | 220 | */ |
221 | |||
104 | static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) | 222 | static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) |
105 | { | 223 | { |
106 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 224 | struct sonic_local *lp = netdev_priv(dev); |
107 | unsigned int base_addr = dev->base_addr; | 225 | dma_addr_t laddr; |
108 | unsigned int laddr; | 226 | int length; |
109 | int entry, length; | 227 | int entry = lp->next_tx; |
110 | |||
111 | netif_stop_queue(dev); | ||
112 | 228 | ||
113 | if (sonic_debug > 2) | 229 | if (sonic_debug > 2) |
114 | printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); | 230 | printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); |
115 | 231 | ||
232 | length = skb->len; | ||
233 | if (length < ETH_ZLEN) { | ||
234 | skb = skb_padto(skb, ETH_ZLEN); | ||
235 | if (skb == NULL) | ||
236 | return 0; | ||
237 | length = ETH_ZLEN; | ||
238 | } | ||
239 | |||
116 | /* | 240 | /* |
117 | * Map the packet data into the logical DMA address space | 241 | * Map the packet data into the logical DMA address space |
118 | */ | 242 | */ |
119 | if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) { | 243 | |
120 | printk("%s: no VDMA entry for transmit available.\n", | 244 | laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE); |
121 | dev->name); | 245 | if (!laddr) { |
246 | printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name); | ||
122 | dev_kfree_skb(skb); | 247 | dev_kfree_skb(skb); |
123 | netif_start_queue(dev); | ||
124 | return 1; | 248 | return 1; |
125 | } | 249 | } |
126 | entry = lp->cur_tx & SONIC_TDS_MASK; | 250 | |
251 | sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ | ||
252 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_COUNT, 1); /* single fragment */ | ||
253 | sonic_tda_put(dev, entry, SONIC_TD_PKTSIZE, length); /* length of packet */ | ||
254 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_PTR_L, laddr & 0xffff); | ||
255 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_PTR_H, laddr >> 16); | ||
256 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_SIZE, length); | ||
257 | sonic_tda_put(dev, entry, SONIC_TD_LINK, | ||
258 | sonic_tda_get(dev, entry, SONIC_TD_LINK) | SONIC_EOL); | ||
259 | |||
260 | /* | ||
261 | * Must set tx_skb[entry] only after clearing status, and | ||
262 | * before clearing EOL and before stopping queue | ||
263 | */ | ||
264 | wmb(); | ||
265 | lp->tx_len[entry] = length; | ||
127 | lp->tx_laddr[entry] = laddr; | 266 | lp->tx_laddr[entry] = laddr; |
128 | lp->tx_skb[entry] = skb; | 267 | lp->tx_skb[entry] = skb; |
129 | 268 | ||
130 | length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; | 269 | wmb(); |
131 | flush_cache_all(); | 270 | sonic_tda_put(dev, lp->eol_tx, SONIC_TD_LINK, |
271 | sonic_tda_get(dev, lp->eol_tx, SONIC_TD_LINK) & ~SONIC_EOL); | ||
272 | lp->eol_tx = entry; | ||
132 | 273 | ||
133 | /* | 274 | lp->next_tx = (entry + 1) & SONIC_TDS_MASK; |
134 | * Setup the transmit descriptor and issue the transmit command. | 275 | if (lp->tx_skb[lp->next_tx] != NULL) { |
135 | */ | 276 | /* The ring is full, the ISR has yet to process the next TD. */ |
136 | lp->tda[entry].tx_status = 0; /* clear status */ | 277 | if (sonic_debug > 3) |
137 | lp->tda[entry].tx_frag_count = 1; /* single fragment */ | 278 | printk("%s: stopping queue\n", dev->name); |
138 | lp->tda[entry].tx_pktsize = length; /* length of packet */ | 279 | netif_stop_queue(dev); |
139 | lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff; | 280 | /* after this packet, wait for ISR to free up some TDAs */ |
140 | lp->tda[entry].tx_frag_ptr_h = laddr >> 16; | 281 | } else netif_start_queue(dev); |
141 | lp->tda[entry].tx_frag_size = length; | ||
142 | lp->cur_tx++; | ||
143 | lp->stats.tx_bytes += length; | ||
144 | 282 | ||
145 | if (sonic_debug > 2) | 283 | if (sonic_debug > 2) |
146 | printk("sonic_send_packet: issueing Tx command\n"); | 284 | printk("sonic_send_packet: issuing Tx command\n"); |
147 | 285 | ||
148 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); | 286 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); |
149 | 287 | ||
150 | dev->trans_start = jiffies; | 288 | dev->trans_start = jiffies; |
151 | 289 | ||
152 | if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS) | ||
153 | netif_start_queue(dev); | ||
154 | else | ||
155 | lp->tx_full = 1; | ||
156 | |||
157 | return 0; | 290 | return 0; |
158 | } | 291 | } |
159 | 292 | ||
@@ -164,175 +297,199 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
164 | static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 297 | static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
165 | { | 298 | { |
166 | struct net_device *dev = (struct net_device *) dev_id; | 299 | struct net_device *dev = (struct net_device *) dev_id; |
167 | unsigned int base_addr = dev->base_addr; | 300 | struct sonic_local *lp = netdev_priv(dev); |
168 | struct sonic_local *lp; | ||
169 | int status; | 301 | int status; |
170 | 302 | ||
171 | if (dev == NULL) { | 303 | if (dev == NULL) { |
172 | printk("sonic_interrupt: irq %d for unknown device.\n", irq); | 304 | printk(KERN_ERR "sonic_interrupt: irq %d for unknown device.\n", irq); |
173 | return IRQ_NONE; | 305 | return IRQ_NONE; |
174 | } | 306 | } |
175 | 307 | ||
176 | lp = (struct sonic_local *) dev->priv; | 308 | if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)) |
177 | 309 | return IRQ_NONE; | |
178 | status = SONIC_READ(SONIC_ISR); | ||
179 | SONIC_WRITE(SONIC_ISR, 0x7fff); /* clear all bits */ | ||
180 | |||
181 | if (sonic_debug > 2) | ||
182 | printk("sonic_interrupt: ISR=%x\n", status); | ||
183 | |||
184 | if (status & SONIC_INT_PKTRX) { | ||
185 | sonic_rx(dev); /* got packet(s) */ | ||
186 | } | ||
187 | |||
188 | if (status & SONIC_INT_TXDN) { | ||
189 | int dirty_tx = lp->dirty_tx; | ||
190 | |||
191 | while (dirty_tx < lp->cur_tx) { | ||
192 | int entry = dirty_tx & SONIC_TDS_MASK; | ||
193 | int status = lp->tda[entry].tx_status; | ||
194 | 310 | ||
195 | if (sonic_debug > 3) | 311 | do { |
196 | printk | 312 | if (status & SONIC_INT_PKTRX) { |
197 | ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n", | 313 | if (sonic_debug > 2) |
198 | status, lp->cur_tx, lp->dirty_tx); | 314 | printk("%s: packet rx\n", dev->name); |
315 | sonic_rx(dev); /* got packet(s) */ | ||
316 | SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */ | ||
317 | } | ||
199 | 318 | ||
200 | if (status == 0) { | 319 | if (status & SONIC_INT_TXDN) { |
201 | /* It still hasn't been Txed, kick the sonic again */ | 320 | int entry = lp->cur_tx; |
202 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); | 321 | int td_status; |
203 | break; | 322 | int freed_some = 0; |
204 | } | ||
205 | 323 | ||
206 | /* put back EOL and free descriptor */ | 324 | /* At this point, cur_tx is the index of a TD that is one of: |
207 | lp->tda[entry].tx_frag_count = 0; | 325 | * unallocated/freed (status set & tx_skb[entry] clear) |
208 | lp->tda[entry].tx_status = 0; | 326 | * allocated and sent (status set & tx_skb[entry] set ) |
209 | 327 | * allocated and not yet sent (status clear & tx_skb[entry] set ) | |
210 | if (status & 0x0001) | 328 | * still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear) |
211 | lp->stats.tx_packets++; | 329 | */ |
212 | else { | ||
213 | lp->stats.tx_errors++; | ||
214 | if (status & 0x0642) | ||
215 | lp->stats.tx_aborted_errors++; | ||
216 | if (status & 0x0180) | ||
217 | lp->stats.tx_carrier_errors++; | ||
218 | if (status & 0x0020) | ||
219 | lp->stats.tx_window_errors++; | ||
220 | if (status & 0x0004) | ||
221 | lp->stats.tx_fifo_errors++; | ||
222 | } | ||
223 | 330 | ||
224 | /* We must free the original skb */ | 331 | if (sonic_debug > 2) |
225 | if (lp->tx_skb[entry]) { | 332 | printk("%s: tx done\n", dev->name); |
333 | |||
334 | while (lp->tx_skb[entry] != NULL) { | ||
335 | if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0) | ||
336 | break; | ||
337 | |||
338 | if (td_status & 0x0001) { | ||
339 | lp->stats.tx_packets++; | ||
340 | lp->stats.tx_bytes += sonic_tda_get(dev, entry, SONIC_TD_PKTSIZE); | ||
341 | } else { | ||
342 | lp->stats.tx_errors++; | ||
343 | if (td_status & 0x0642) | ||
344 | lp->stats.tx_aborted_errors++; | ||
345 | if (td_status & 0x0180) | ||
346 | lp->stats.tx_carrier_errors++; | ||
347 | if (td_status & 0x0020) | ||
348 | lp->stats.tx_window_errors++; | ||
349 | if (td_status & 0x0004) | ||
350 | lp->stats.tx_fifo_errors++; | ||
351 | } | ||
352 | |||
353 | /* We must free the original skb */ | ||
226 | dev_kfree_skb_irq(lp->tx_skb[entry]); | 354 | dev_kfree_skb_irq(lp->tx_skb[entry]); |
227 | lp->tx_skb[entry] = 0; | 355 | lp->tx_skb[entry] = NULL; |
356 | /* and unmap DMA buffer */ | ||
357 | dma_unmap_single(lp->device, lp->tx_laddr[entry], lp->tx_len[entry], DMA_TO_DEVICE); | ||
358 | lp->tx_laddr[entry] = (dma_addr_t)0; | ||
359 | freed_some = 1; | ||
360 | |||
361 | if (sonic_tda_get(dev, entry, SONIC_TD_LINK) & SONIC_EOL) { | ||
362 | entry = (entry + 1) & SONIC_TDS_MASK; | ||
363 | break; | ||
364 | } | ||
365 | entry = (entry + 1) & SONIC_TDS_MASK; | ||
228 | } | 366 | } |
229 | /* and the VDMA address */ | ||
230 | vdma_free(lp->tx_laddr[entry]); | ||
231 | dirty_tx++; | ||
232 | } | ||
233 | 367 | ||
234 | if (lp->tx_full | 368 | if (freed_some || lp->tx_skb[entry] == NULL) |
235 | && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) { | 369 | netif_wake_queue(dev); /* The ring is no longer full */ |
236 | /* The ring is no longer full, clear tbusy. */ | 370 | lp->cur_tx = entry; |
237 | lp->tx_full = 0; | 371 | SONIC_WRITE(SONIC_ISR, SONIC_INT_TXDN); /* clear the interrupt */ |
238 | netif_wake_queue(dev); | ||
239 | } | 372 | } |
240 | 373 | ||
241 | lp->dirty_tx = dirty_tx; | 374 | /* |
242 | } | 375 | * check error conditions |
376 | */ | ||
377 | if (status & SONIC_INT_RFO) { | ||
378 | if (sonic_debug > 1) | ||
379 | printk("%s: rx fifo overrun\n", dev->name); | ||
380 | lp->stats.rx_fifo_errors++; | ||
381 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */ | ||
382 | } | ||
383 | if (status & SONIC_INT_RDE) { | ||
384 | if (sonic_debug > 1) | ||
385 | printk("%s: rx descriptors exhausted\n", dev->name); | ||
386 | lp->stats.rx_dropped++; | ||
387 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */ | ||
388 | } | ||
389 | if (status & SONIC_INT_RBAE) { | ||
390 | if (sonic_debug > 1) | ||
391 | printk("%s: rx buffer area exceeded\n", dev->name); | ||
392 | lp->stats.rx_dropped++; | ||
393 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */ | ||
394 | } | ||
243 | 395 | ||
244 | /* | 396 | /* counter overruns; all counters are 16bit wide */ |
245 | * check error conditions | 397 | if (status & SONIC_INT_FAE) { |
246 | */ | 398 | lp->stats.rx_frame_errors += 65536; |
247 | if (status & SONIC_INT_RFO) { | 399 | SONIC_WRITE(SONIC_ISR, SONIC_INT_FAE); /* clear the interrupt */ |
248 | printk("%s: receive fifo underrun\n", dev->name); | 400 | } |
249 | lp->stats.rx_fifo_errors++; | 401 | if (status & SONIC_INT_CRC) { |
250 | } | 402 | lp->stats.rx_crc_errors += 65536; |
251 | if (status & SONIC_INT_RDE) { | 403 | SONIC_WRITE(SONIC_ISR, SONIC_INT_CRC); /* clear the interrupt */ |
252 | printk("%s: receive descriptors exhausted\n", dev->name); | 404 | } |
253 | lp->stats.rx_dropped++; | 405 | if (status & SONIC_INT_MP) { |
254 | } | 406 | lp->stats.rx_missed_errors += 65536; |
255 | if (status & SONIC_INT_RBE) { | 407 | SONIC_WRITE(SONIC_ISR, SONIC_INT_MP); /* clear the interrupt */ |
256 | printk("%s: receive buffer exhausted\n", dev->name); | 408 | } |
257 | lp->stats.rx_dropped++; | ||
258 | } | ||
259 | if (status & SONIC_INT_RBAE) { | ||
260 | printk("%s: receive buffer area exhausted\n", dev->name); | ||
261 | lp->stats.rx_dropped++; | ||
262 | } | ||
263 | 409 | ||
264 | /* counter overruns; all counters are 16bit wide */ | 410 | /* transmit error */ |
265 | if (status & SONIC_INT_FAE) | 411 | if (status & SONIC_INT_TXER) { |
266 | lp->stats.rx_frame_errors += 65536; | 412 | if ((SONIC_READ(SONIC_TCR) & SONIC_TCR_FU) && (sonic_debug > 2)) |
267 | if (status & SONIC_INT_CRC) | 413 | printk(KERN_ERR "%s: tx fifo underrun\n", dev->name); |
268 | lp->stats.rx_crc_errors += 65536; | 414 | SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */ |
269 | if (status & SONIC_INT_MP) | 415 | } |
270 | lp->stats.rx_missed_errors += 65536; | ||
271 | 416 | ||
272 | /* transmit error */ | 417 | /* bus retry */ |
273 | if (status & SONIC_INT_TXER) | 418 | if (status & SONIC_INT_BR) { |
274 | lp->stats.tx_errors++; | 419 | printk(KERN_ERR "%s: Bus retry occurred! Device interrupt disabled.\n", |
420 | dev->name); | ||
421 | /* ... to help debug DMA problems causing endless interrupts. */ | ||
422 | /* Bounce the eth interface to turn on the interrupt again. */ | ||
423 | SONIC_WRITE(SONIC_IMR, 0); | ||
424 | SONIC_WRITE(SONIC_ISR, SONIC_INT_BR); /* clear the interrupt */ | ||
425 | } | ||
275 | 426 | ||
276 | /* | 427 | /* load CAM done */ |
277 | * clear interrupt bits and return | 428 | if (status & SONIC_INT_LCD) |
278 | */ | 429 | SONIC_WRITE(SONIC_ISR, SONIC_INT_LCD); /* clear the interrupt */ |
279 | SONIC_WRITE(SONIC_ISR, status); | 430 | } while((status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)); |
280 | return IRQ_HANDLED; | 431 | return IRQ_HANDLED; |
281 | } | 432 | } |
282 | 433 | ||
283 | /* | 434 | /* |
284 | * We have a good packet(s), get it/them out of the buffers. | 435 | * We have a good packet(s), pass it/them up the network stack. |
285 | */ | 436 | */ |
286 | static void sonic_rx(struct net_device *dev) | 437 | static void sonic_rx(struct net_device *dev) |
287 | { | 438 | { |
288 | unsigned int base_addr = dev->base_addr; | 439 | struct sonic_local *lp = netdev_priv(dev); |
289 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | ||
290 | sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK]; | ||
291 | int status; | 440 | int status; |
292 | 441 | int entry = lp->cur_rx; | |
293 | while (rd->in_use == 0) { | 442 | |
294 | struct sk_buff *skb; | 443 | while (sonic_rda_get(dev, entry, SONIC_RD_IN_USE) == 0) { |
444 | struct sk_buff *used_skb; | ||
445 | struct sk_buff *new_skb; | ||
446 | dma_addr_t new_laddr; | ||
447 | u16 bufadr_l; | ||
448 | u16 bufadr_h; | ||
295 | int pkt_len; | 449 | int pkt_len; |
296 | unsigned char *pkt_ptr; | ||
297 | 450 | ||
298 | status = rd->rx_status; | 451 | status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); |
299 | if (sonic_debug > 3) | ||
300 | printk("status %x, cur_rx %d, cur_rra %x\n", | ||
301 | status, lp->cur_rx, lp->cur_rra); | ||
302 | if (status & SONIC_RCR_PRX) { | 452 | if (status & SONIC_RCR_PRX) { |
303 | pkt_len = rd->rx_pktlen; | ||
304 | pkt_ptr = | ||
305 | (char *) | ||
306 | sonic_chiptomem((rd->rx_pktptr_h << 16) + | ||
307 | rd->rx_pktptr_l); | ||
308 | |||
309 | if (sonic_debug > 3) | ||
310 | printk | ||
311 | ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", | ||
312 | pkt_ptr, lp->rba, rd->rx_pktptr_h, | ||
313 | rd->rx_pktptr_l, | ||
314 | SONIC_READ(SONIC_RBWC1), | ||
315 | SONIC_READ(SONIC_RBWC0)); | ||
316 | |||
317 | /* Malloc up new buffer. */ | 453 | /* Malloc up new buffer. */ |
318 | skb = dev_alloc_skb(pkt_len + 2); | 454 | new_skb = dev_alloc_skb(SONIC_RBSIZE + 2); |
319 | if (skb == NULL) { | 455 | if (new_skb == NULL) { |
320 | printk | 456 | printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); |
321 | ("%s: Memory squeeze, dropping packet.\n", | 457 | lp->stats.rx_dropped++; |
322 | dev->name); | 458 | break; |
459 | } | ||
460 | new_skb->dev = dev; | ||
461 | /* provide 16 byte IP header alignment unless DMA requires otherwise */ | ||
462 | if(SONIC_BUS_SCALE(lp->dma_bitmode) == 2) | ||
463 | skb_reserve(new_skb, 2); | ||
464 | |||
465 | new_laddr = dma_map_single(lp->device, skb_put(new_skb, SONIC_RBSIZE), | ||
466 | SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
467 | if (!new_laddr) { | ||
468 | dev_kfree_skb(new_skb); | ||
469 | printk(KERN_ERR "%s: Failed to map rx buffer, dropping packet.\n", dev->name); | ||
323 | lp->stats.rx_dropped++; | 470 | lp->stats.rx_dropped++; |
324 | break; | 471 | break; |
325 | } | 472 | } |
326 | skb->dev = dev; | 473 | |
327 | skb_reserve(skb, 2); /* 16 byte align */ | 474 | /* now we have a new skb to replace it, pass the used one up the stack */ |
328 | skb_put(skb, pkt_len); /* Make room */ | 475 | dma_unmap_single(lp->device, lp->rx_laddr[entry], SONIC_RBSIZE, DMA_FROM_DEVICE); |
329 | eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0); | 476 | used_skb = lp->rx_skb[entry]; |
330 | skb->protocol = eth_type_trans(skb, dev); | 477 | pkt_len = sonic_rda_get(dev, entry, SONIC_RD_PKTLEN); |
331 | netif_rx(skb); /* pass the packet to upper layers */ | 478 | skb_trim(used_skb, pkt_len); |
479 | used_skb->protocol = eth_type_trans(used_skb, dev); | ||
480 | netif_rx(used_skb); | ||
332 | dev->last_rx = jiffies; | 481 | dev->last_rx = jiffies; |
333 | lp->stats.rx_packets++; | 482 | lp->stats.rx_packets++; |
334 | lp->stats.rx_bytes += pkt_len; | 483 | lp->stats.rx_bytes += pkt_len; |
335 | 484 | ||
485 | /* and insert the new skb */ | ||
486 | lp->rx_laddr[entry] = new_laddr; | ||
487 | lp->rx_skb[entry] = new_skb; | ||
488 | |||
489 | bufadr_l = (unsigned long)new_laddr & 0xffff; | ||
490 | bufadr_h = (unsigned long)new_laddr >> 16; | ||
491 | sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, bufadr_l); | ||
492 | sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, bufadr_h); | ||
336 | } else { | 493 | } else { |
337 | /* This should only happen, if we enable accepting broken packets. */ | 494 | /* This should only happen, if we enable accepting broken packets. */ |
338 | lp->stats.rx_errors++; | 495 | lp->stats.rx_errors++; |
@@ -341,29 +498,35 @@ static void sonic_rx(struct net_device *dev) | |||
341 | if (status & SONIC_RCR_CRCR) | 498 | if (status & SONIC_RCR_CRCR) |
342 | lp->stats.rx_crc_errors++; | 499 | lp->stats.rx_crc_errors++; |
343 | } | 500 | } |
344 | |||
345 | rd->in_use = 1; | ||
346 | rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK]; | ||
347 | /* now give back the buffer to the receive buffer area */ | ||
348 | if (status & SONIC_RCR_LPKT) { | 501 | if (status & SONIC_RCR_LPKT) { |
349 | /* | 502 | /* |
350 | * this was the last packet out of the current receice buffer | 503 | * this was the last packet out of the current receive buffer |
351 | * give the buffer back to the SONIC | 504 | * give the buffer back to the SONIC |
352 | */ | 505 | */ |
353 | lp->cur_rra += sizeof(sonic_rr_t); | 506 | lp->cur_rwp += SIZEOF_SONIC_RR * SONIC_BUS_SCALE(lp->dma_bitmode); |
354 | if (lp->cur_rra > | 507 | if (lp->cur_rwp >= lp->rra_end) lp->cur_rwp = lp->rra_laddr & 0xffff; |
355 | (lp->rra_laddr + | 508 | SONIC_WRITE(SONIC_RWP, lp->cur_rwp); |
356 | (SONIC_NUM_RRS - | 509 | if (SONIC_READ(SONIC_ISR) & SONIC_INT_RBE) { |
357 | 1) * sizeof(sonic_rr_t))) lp->cur_rra = | 510 | if (sonic_debug > 2) |
358 | lp->rra_laddr; | 511 | printk("%s: rx buffer exhausted\n", dev->name); |
359 | SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff); | 512 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* clear the flag */ |
513 | } | ||
360 | } else | 514 | } else |
361 | printk | 515 | printk(KERN_ERR "%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", |
362 | ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", | ||
363 | dev->name); | 516 | dev->name); |
517 | /* | ||
518 | * give back the descriptor | ||
519 | */ | ||
520 | sonic_rda_put(dev, entry, SONIC_RD_LINK, | ||
521 | sonic_rda_get(dev, entry, SONIC_RD_LINK) | SONIC_EOL); | ||
522 | sonic_rda_put(dev, entry, SONIC_RD_IN_USE, 1); | ||
523 | sonic_rda_put(dev, lp->eol_rx, SONIC_RD_LINK, | ||
524 | sonic_rda_get(dev, lp->eol_rx, SONIC_RD_LINK) & ~SONIC_EOL); | ||
525 | lp->eol_rx = entry; | ||
526 | lp->cur_rx = entry = (entry + 1) & SONIC_RDS_MASK; | ||
364 | } | 527 | } |
365 | /* | 528 | /* |
366 | * If any worth-while packets have been received, dev_rint() | 529 | * If any worth-while packets have been received, netif_rx() |
367 | * has done a mark_bh(NET_BH) for us and will work on them | 530 | * has done a mark_bh(NET_BH) for us and will work on them |
368 | * when we get to the bottom-half routine. | 531 | * when we get to the bottom-half routine. |
369 | */ | 532 | */ |
@@ -376,8 +539,7 @@ static void sonic_rx(struct net_device *dev) | |||
376 | */ | 539 | */ |
377 | static struct net_device_stats *sonic_get_stats(struct net_device *dev) | 540 | static struct net_device_stats *sonic_get_stats(struct net_device *dev) |
378 | { | 541 | { |
379 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 542 | struct sonic_local *lp = netdev_priv(dev); |
380 | unsigned int base_addr = dev->base_addr; | ||
381 | 543 | ||
382 | /* read the tally counter from the SONIC and reset them */ | 544 | /* read the tally counter from the SONIC and reset them */ |
383 | lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT); | 545 | lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT); |
@@ -396,8 +558,7 @@ static struct net_device_stats *sonic_get_stats(struct net_device *dev) | |||
396 | */ | 558 | */ |
397 | static void sonic_multicast_list(struct net_device *dev) | 559 | static void sonic_multicast_list(struct net_device *dev) |
398 | { | 560 | { |
399 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 561 | struct sonic_local *lp = netdev_priv(dev); |
400 | unsigned int base_addr = dev->base_addr; | ||
401 | unsigned int rcr; | 562 | unsigned int rcr; |
402 | struct dev_mc_list *dmi = dev->mc_list; | 563 | struct dev_mc_list *dmi = dev->mc_list; |
403 | unsigned char *addr; | 564 | unsigned char *addr; |
@@ -413,20 +574,15 @@ static void sonic_multicast_list(struct net_device *dev) | |||
413 | rcr |= SONIC_RCR_AMC; | 574 | rcr |= SONIC_RCR_AMC; |
414 | } else { | 575 | } else { |
415 | if (sonic_debug > 2) | 576 | if (sonic_debug > 2) |
416 | printk | 577 | printk("sonic_multicast_list: mc_count %d\n", dev->mc_count); |
417 | ("sonic_multicast_list: mc_count %d\n", | 578 | sonic_set_cam_enable(dev, 1); /* always enable our own address */ |
418 | dev->mc_count); | ||
419 | lp->cda.cam_enable = 1; /* always enable our own address */ | ||
420 | for (i = 1; i <= dev->mc_count; i++) { | 579 | for (i = 1; i <= dev->mc_count; i++) { |
421 | addr = dmi->dmi_addr; | 580 | addr = dmi->dmi_addr; |
422 | dmi = dmi->next; | 581 | dmi = dmi->next; |
423 | lp->cda.cam_desc[i].cam_cap0 = | 582 | sonic_cda_put(dev, i, SONIC_CD_CAP0, addr[1] << 8 | addr[0]); |
424 | addr[1] << 8 | addr[0]; | 583 | sonic_cda_put(dev, i, SONIC_CD_CAP1, addr[3] << 8 | addr[2]); |
425 | lp->cda.cam_desc[i].cam_cap1 = | 584 | sonic_cda_put(dev, i, SONIC_CD_CAP2, addr[5] << 8 | addr[4]); |
426 | addr[3] << 8 | addr[2]; | 585 | sonic_set_cam_enable(dev, sonic_get_cam_enable(dev) | (1 << i)); |
427 | lp->cda.cam_desc[i].cam_cap2 = | ||
428 | addr[5] << 8 | addr[4]; | ||
429 | lp->cda.cam_enable |= (1 << i); | ||
430 | } | 586 | } |
431 | SONIC_WRITE(SONIC_CDC, 16); | 587 | SONIC_WRITE(SONIC_CDC, 16); |
432 | /* issue Load CAM command */ | 588 | /* issue Load CAM command */ |
@@ -447,19 +603,16 @@ static void sonic_multicast_list(struct net_device *dev) | |||
447 | */ | 603 | */ |
448 | static int sonic_init(struct net_device *dev) | 604 | static int sonic_init(struct net_device *dev) |
449 | { | 605 | { |
450 | unsigned int base_addr = dev->base_addr; | ||
451 | unsigned int cmd; | 606 | unsigned int cmd; |
452 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 607 | struct sonic_local *lp = netdev_priv(dev); |
453 | unsigned int rra_start; | ||
454 | unsigned int rra_end; | ||
455 | int i; | 608 | int i; |
456 | 609 | ||
457 | /* | 610 | /* |
458 | * put the Sonic into software-reset mode and | 611 | * put the Sonic into software-reset mode and |
459 | * disable all interrupts | 612 | * disable all interrupts |
460 | */ | 613 | */ |
461 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
462 | SONIC_WRITE(SONIC_IMR, 0); | 614 | SONIC_WRITE(SONIC_IMR, 0); |
615 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
463 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | 616 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
464 | 617 | ||
465 | /* | 618 | /* |
@@ -475,34 +628,32 @@ static int sonic_init(struct net_device *dev) | |||
475 | if (sonic_debug > 2) | 628 | if (sonic_debug > 2) |
476 | printk("sonic_init: initialize receive resource area\n"); | 629 | printk("sonic_init: initialize receive resource area\n"); |
477 | 630 | ||
478 | rra_start = lp->rra_laddr & 0xffff; | ||
479 | rra_end = | ||
480 | (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff; | ||
481 | |||
482 | for (i = 0; i < SONIC_NUM_RRS; i++) { | 631 | for (i = 0; i < SONIC_NUM_RRS; i++) { |
483 | lp->rra[i].rx_bufadr_l = | 632 | u16 bufadr_l = (unsigned long)lp->rx_laddr[i] & 0xffff; |
484 | (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff; | 633 | u16 bufadr_h = (unsigned long)lp->rx_laddr[i] >> 16; |
485 | lp->rra[i].rx_bufadr_h = | 634 | sonic_rra_put(dev, i, SONIC_RR_BUFADR_L, bufadr_l); |
486 | (lp->rba_laddr + i * SONIC_RBSIZE) >> 16; | 635 | sonic_rra_put(dev, i, SONIC_RR_BUFADR_H, bufadr_h); |
487 | lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1; | 636 | sonic_rra_put(dev, i, SONIC_RR_BUFSIZE_L, SONIC_RBSIZE >> 1); |
488 | lp->rra[i].rx_bufsize_h = 0; | 637 | sonic_rra_put(dev, i, SONIC_RR_BUFSIZE_H, 0); |
489 | } | 638 | } |
490 | 639 | ||
491 | /* initialize all RRA registers */ | 640 | /* initialize all RRA registers */ |
492 | SONIC_WRITE(SONIC_RSA, rra_start); | 641 | lp->rra_end = (lp->rra_laddr + SONIC_NUM_RRS * SIZEOF_SONIC_RR * |
493 | SONIC_WRITE(SONIC_REA, rra_end); | 642 | SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; |
494 | SONIC_WRITE(SONIC_RRP, rra_start); | 643 | lp->cur_rwp = (lp->rra_laddr + (SONIC_NUM_RRS - 1) * SIZEOF_SONIC_RR * |
495 | SONIC_WRITE(SONIC_RWP, rra_end); | 644 | SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; |
645 | |||
646 | SONIC_WRITE(SONIC_RSA, lp->rra_laddr & 0xffff); | ||
647 | SONIC_WRITE(SONIC_REA, lp->rra_end); | ||
648 | SONIC_WRITE(SONIC_RRP, lp->rra_laddr & 0xffff); | ||
649 | SONIC_WRITE(SONIC_RWP, lp->cur_rwp); | ||
496 | SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); | 650 | SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); |
497 | SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE - 2) >> 1); | 651 | SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE >> 1) - (lp->dma_bitmode ? 2 : 1)); |
498 | |||
499 | lp->cur_rra = | ||
500 | lp->rra_laddr + (SONIC_NUM_RRS - 1) * sizeof(sonic_rr_t); | ||
501 | 652 | ||
502 | /* load the resource pointers */ | 653 | /* load the resource pointers */ |
503 | if (sonic_debug > 3) | 654 | if (sonic_debug > 3) |
504 | printk("sonic_init: issueing RRRA command\n"); | 655 | printk("sonic_init: issuing RRRA command\n"); |
505 | 656 | ||
506 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); | 657 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); |
507 | i = 0; | 658 | i = 0; |
508 | while (i++ < 100) { | 659 | while (i++ < 100) { |
@@ -511,27 +662,30 @@ static int sonic_init(struct net_device *dev) | |||
511 | } | 662 | } |
512 | 663 | ||
513 | if (sonic_debug > 2) | 664 | if (sonic_debug > 2) |
514 | printk("sonic_init: status=%x\n", SONIC_READ(SONIC_CMD)); | 665 | printk("sonic_init: status=%x i=%d\n", SONIC_READ(SONIC_CMD), i); |
515 | 666 | ||
516 | /* | 667 | /* |
517 | * Initialize the receive descriptors so that they | 668 | * Initialize the receive descriptors so that they |
518 | * become a circular linked list, ie. let the last | 669 | * become a circular linked list, ie. let the last |
519 | * descriptor point to the first again. | 670 | * descriptor point to the first again. |
520 | */ | 671 | */ |
521 | if (sonic_debug > 2) | 672 | if (sonic_debug > 2) |
522 | printk("sonic_init: initialize receive descriptors\n"); | 673 | printk("sonic_init: initialize receive descriptors\n"); |
523 | for (i = 0; i < SONIC_NUM_RDS; i++) { | 674 | for (i=0; i<SONIC_NUM_RDS; i++) { |
524 | lp->rda[i].rx_status = 0; | 675 | sonic_rda_put(dev, i, SONIC_RD_STATUS, 0); |
525 | lp->rda[i].rx_pktlen = 0; | 676 | sonic_rda_put(dev, i, SONIC_RD_PKTLEN, 0); |
526 | lp->rda[i].rx_pktptr_l = 0; | 677 | sonic_rda_put(dev, i, SONIC_RD_PKTPTR_L, 0); |
527 | lp->rda[i].rx_pktptr_h = 0; | 678 | sonic_rda_put(dev, i, SONIC_RD_PKTPTR_H, 0); |
528 | lp->rda[i].rx_seqno = 0; | 679 | sonic_rda_put(dev, i, SONIC_RD_SEQNO, 0); |
529 | lp->rda[i].in_use = 1; | 680 | sonic_rda_put(dev, i, SONIC_RD_IN_USE, 1); |
530 | lp->rda[i].link = | 681 | sonic_rda_put(dev, i, SONIC_RD_LINK, |
531 | lp->rda_laddr + (i + 1) * sizeof(sonic_rd_t); | 682 | lp->rda_laddr + |
683 | ((i+1) * SIZEOF_SONIC_RD * SONIC_BUS_SCALE(lp->dma_bitmode))); | ||
532 | } | 684 | } |
533 | /* fix last descriptor */ | 685 | /* fix last descriptor */ |
534 | lp->rda[SONIC_NUM_RDS - 1].link = lp->rda_laddr; | 686 | sonic_rda_put(dev, SONIC_NUM_RDS - 1, SONIC_RD_LINK, |
687 | (lp->rda_laddr & 0xffff) | SONIC_EOL); | ||
688 | lp->eol_rx = SONIC_NUM_RDS - 1; | ||
535 | lp->cur_rx = 0; | 689 | lp->cur_rx = 0; |
536 | SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16); | 690 | SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16); |
537 | SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff); | 691 | SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff); |
@@ -542,34 +696,34 @@ static int sonic_init(struct net_device *dev) | |||
542 | if (sonic_debug > 2) | 696 | if (sonic_debug > 2) |
543 | printk("sonic_init: initialize transmit descriptors\n"); | 697 | printk("sonic_init: initialize transmit descriptors\n"); |
544 | for (i = 0; i < SONIC_NUM_TDS; i++) { | 698 | for (i = 0; i < SONIC_NUM_TDS; i++) { |
545 | lp->tda[i].tx_status = 0; | 699 | sonic_tda_put(dev, i, SONIC_TD_STATUS, 0); |
546 | lp->tda[i].tx_config = 0; | 700 | sonic_tda_put(dev, i, SONIC_TD_CONFIG, 0); |
547 | lp->tda[i].tx_pktsize = 0; | 701 | sonic_tda_put(dev, i, SONIC_TD_PKTSIZE, 0); |
548 | lp->tda[i].tx_frag_count = 0; | 702 | sonic_tda_put(dev, i, SONIC_TD_FRAG_COUNT, 0); |
549 | lp->tda[i].link = | 703 | sonic_tda_put(dev, i, SONIC_TD_LINK, |
550 | (lp->tda_laddr + | 704 | (lp->tda_laddr & 0xffff) + |
551 | (i + 1) * sizeof(sonic_td_t)) | SONIC_END_OF_LINKS; | 705 | (i + 1) * SIZEOF_SONIC_TD * SONIC_BUS_SCALE(lp->dma_bitmode)); |
706 | lp->tx_skb[i] = NULL; | ||
552 | } | 707 | } |
553 | lp->tda[SONIC_NUM_TDS - 1].link = | 708 | /* fix last descriptor */ |
554 | (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS; | 709 | sonic_tda_put(dev, SONIC_NUM_TDS - 1, SONIC_TD_LINK, |
710 | (lp->tda_laddr & 0xffff)); | ||
555 | 711 | ||
556 | SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); | 712 | SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); |
557 | SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); | 713 | SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); |
558 | lp->cur_tx = lp->dirty_tx = 0; | 714 | lp->cur_tx = lp->next_tx = 0; |
559 | 715 | lp->eol_tx = SONIC_NUM_TDS - 1; | |
716 | |||
560 | /* | 717 | /* |
561 | * put our own address to CAM desc[0] | 718 | * put our own address to CAM desc[0] |
562 | */ | 719 | */ |
563 | lp->cda.cam_desc[0].cam_cap0 = | 720 | sonic_cda_put(dev, 0, SONIC_CD_CAP0, dev->dev_addr[1] << 8 | dev->dev_addr[0]); |
564 | dev->dev_addr[1] << 8 | dev->dev_addr[0]; | 721 | sonic_cda_put(dev, 0, SONIC_CD_CAP1, dev->dev_addr[3] << 8 | dev->dev_addr[2]); |
565 | lp->cda.cam_desc[0].cam_cap1 = | 722 | sonic_cda_put(dev, 0, SONIC_CD_CAP2, dev->dev_addr[5] << 8 | dev->dev_addr[4]); |
566 | dev->dev_addr[3] << 8 | dev->dev_addr[2]; | 723 | sonic_set_cam_enable(dev, 1); |
567 | lp->cda.cam_desc[0].cam_cap2 = | ||
568 | dev->dev_addr[5] << 8 | dev->dev_addr[4]; | ||
569 | lp->cda.cam_enable = 1; | ||
570 | 724 | ||
571 | for (i = 0; i < 16; i++) | 725 | for (i = 0; i < 16; i++) |
572 | lp->cda.cam_desc[i].cam_entry_pointer = i; | 726 | sonic_cda_put(dev, i, SONIC_CD_ENTRY_POINTER, i); |
573 | 727 | ||
574 | /* | 728 | /* |
575 | * initialize CAM registers | 729 | * initialize CAM registers |
@@ -588,8 +742,8 @@ static int sonic_init(struct net_device *dev) | |||
588 | break; | 742 | break; |
589 | } | 743 | } |
590 | if (sonic_debug > 2) { | 744 | if (sonic_debug > 2) { |
591 | printk("sonic_init: CMD=%x, ISR=%x\n", | 745 | printk("sonic_init: CMD=%x, ISR=%x\n, i=%d", |
592 | SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR)); | 746 | SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR), i); |
593 | } | 747 | } |
594 | 748 | ||
595 | /* | 749 | /* |
@@ -604,7 +758,7 @@ static int sonic_init(struct net_device *dev) | |||
604 | 758 | ||
605 | cmd = SONIC_READ(SONIC_CMD); | 759 | cmd = SONIC_READ(SONIC_CMD); |
606 | if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) | 760 | if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) |
607 | printk("sonic_init: failed, status=%x\n", cmd); | 761 | printk(KERN_ERR "sonic_init: failed, status=%x\n", cmd); |
608 | 762 | ||
609 | if (sonic_debug > 2) | 763 | if (sonic_debug > 2) |
610 | printk("sonic_init: new status=%x\n", | 764 | printk("sonic_init: new status=%x\n", |
diff --git a/drivers/net/sonic.h b/drivers/net/sonic.h index c4a6d58e4afb..cede969a8baa 100644 --- a/drivers/net/sonic.h +++ b/drivers/net/sonic.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Helpfile for sonic.c | 2 | * Header file for sonic.c |
3 | * | 3 | * |
4 | * (C) Waldorf Electronics, Germany | 4 | * (C) Waldorf Electronics, Germany |
5 | * Written by Andreas Busse | 5 | * Written by Andreas Busse |
@@ -9,10 +9,16 @@ | |||
9 | * and pad structure members must be exchanged. Also, the structures | 9 | * and pad structure members must be exchanged. Also, the structures |
10 | * need to be changed accordingly to the bus size. | 10 | * need to be changed accordingly to the bus size. |
11 | * | 11 | * |
12 | * 981229 MSch: did just that for the 68k Mac port (32 bit, big endian), | 12 | * 981229 MSch: did just that for the 68k Mac port (32 bit, big endian) |
13 | * see CONFIG_MACSONIC branch below. | ||
14 | * | 13 | * |
14 | * 990611 David Huggins-Daines <dhd@debian.org>: This machine abstraction | ||
15 | * does not cope with 16-bit bus sizes very well. Therefore I have | ||
16 | * rewritten it with ugly macros and evil inlines. | ||
17 | * | ||
18 | * 050625 Finn Thain: introduced more 32-bit cards and dhd's support | ||
19 | * for 16-bit cards (from the mac68k project). | ||
15 | */ | 20 | */ |
21 | |||
16 | #ifndef SONIC_H | 22 | #ifndef SONIC_H |
17 | #define SONIC_H | 23 | #define SONIC_H |
18 | 24 | ||
@@ -83,6 +89,7 @@ | |||
83 | /* | 89 | /* |
84 | * Error counters | 90 | * Error counters |
85 | */ | 91 | */ |
92 | |||
86 | #define SONIC_CRCT 0x2c | 93 | #define SONIC_CRCT 0x2c |
87 | #define SONIC_FAET 0x2d | 94 | #define SONIC_FAET 0x2d |
88 | #define SONIC_MPT 0x2e | 95 | #define SONIC_MPT 0x2e |
@@ -182,14 +189,14 @@ | |||
182 | 189 | ||
183 | #define SONIC_INT_BR 0x4000 | 190 | #define SONIC_INT_BR 0x4000 |
184 | #define SONIC_INT_HBL 0x2000 | 191 | #define SONIC_INT_HBL 0x2000 |
185 | #define SONIC_INT_LCD 0x1000 | 192 | #define SONIC_INT_LCD 0x1000 |
186 | #define SONIC_INT_PINT 0x0800 | 193 | #define SONIC_INT_PINT 0x0800 |
187 | #define SONIC_INT_PKTRX 0x0400 | 194 | #define SONIC_INT_PKTRX 0x0400 |
188 | #define SONIC_INT_TXDN 0x0200 | 195 | #define SONIC_INT_TXDN 0x0200 |
189 | #define SONIC_INT_TXER 0x0100 | 196 | #define SONIC_INT_TXER 0x0100 |
190 | #define SONIC_INT_TC 0x0080 | 197 | #define SONIC_INT_TC 0x0080 |
191 | #define SONIC_INT_RDE 0x0040 | 198 | #define SONIC_INT_RDE 0x0040 |
192 | #define SONIC_INT_RBE 0x0020 | 199 | #define SONIC_INT_RBE 0x0020 |
193 | #define SONIC_INT_RBAE 0x0010 | 200 | #define SONIC_INT_RBAE 0x0010 |
194 | #define SONIC_INT_CRC 0x0008 | 201 | #define SONIC_INT_CRC 0x0008 |
195 | #define SONIC_INT_FAE 0x0004 | 202 | #define SONIC_INT_FAE 0x0004 |
@@ -201,224 +208,61 @@ | |||
201 | * The interrupts we allow. | 208 | * The interrupts we allow. |
202 | */ | 209 | */ |
203 | 210 | ||
204 | #define SONIC_IMR_DEFAULT (SONIC_INT_BR | \ | 211 | #define SONIC_IMR_DEFAULT ( SONIC_INT_BR | \ |
205 | SONIC_INT_LCD | \ | 212 | SONIC_INT_LCD | \ |
206 | SONIC_INT_PINT | \ | 213 | SONIC_INT_RFO | \ |
207 | SONIC_INT_PKTRX | \ | 214 | SONIC_INT_PKTRX | \ |
208 | SONIC_INT_TXDN | \ | 215 | SONIC_INT_TXDN | \ |
209 | SONIC_INT_TXER | \ | 216 | SONIC_INT_TXER | \ |
210 | SONIC_INT_RDE | \ | 217 | SONIC_INT_RDE | \ |
211 | SONIC_INT_RBE | \ | ||
212 | SONIC_INT_RBAE | \ | 218 | SONIC_INT_RBAE | \ |
213 | SONIC_INT_CRC | \ | 219 | SONIC_INT_CRC | \ |
214 | SONIC_INT_FAE | \ | 220 | SONIC_INT_FAE | \ |
215 | SONIC_INT_MP) | 221 | SONIC_INT_MP) |
216 | 222 | ||
217 | 223 | ||
218 | #define SONIC_END_OF_LINKS 0x0001 | 224 | #define SONIC_EOL 0x0001 |
219 | |||
220 | |||
221 | #ifdef CONFIG_MACSONIC | ||
222 | /* | ||
223 | * Big endian like structures on 680x0 Macs | ||
224 | */ | ||
225 | |||
226 | typedef struct { | ||
227 | u32 rx_bufadr_l; /* receive buffer ptr */ | ||
228 | u32 rx_bufadr_h; | ||
229 | |||
230 | u32 rx_bufsize_l; /* no. of words in the receive buffer */ | ||
231 | u32 rx_bufsize_h; | ||
232 | } sonic_rr_t; | ||
233 | |||
234 | /* | ||
235 | * Sonic receive descriptor. Receive descriptors are | ||
236 | * kept in a linked list of these structures. | ||
237 | */ | ||
238 | |||
239 | typedef struct { | ||
240 | SREGS_PAD(pad0); | ||
241 | u16 rx_status; /* status after reception of a packet */ | ||
242 | SREGS_PAD(pad1); | ||
243 | u16 rx_pktlen; /* length of the packet incl. CRC */ | ||
244 | |||
245 | /* | ||
246 | * Pointers to the location in the receive buffer area (RBA) | ||
247 | * where the packet resides. A packet is always received into | ||
248 | * a contiguous piece of memory. | ||
249 | */ | ||
250 | SREGS_PAD(pad2); | ||
251 | u16 rx_pktptr_l; | ||
252 | SREGS_PAD(pad3); | ||
253 | u16 rx_pktptr_h; | ||
254 | |||
255 | SREGS_PAD(pad4); | ||
256 | u16 rx_seqno; /* sequence no. */ | ||
257 | |||
258 | SREGS_PAD(pad5); | ||
259 | u16 link; /* link to next RDD (end if EOL bit set) */ | ||
260 | |||
261 | /* | ||
262 | * Owner of this descriptor, 0= driver, 1=sonic | ||
263 | */ | ||
264 | |||
265 | SREGS_PAD(pad6); | ||
266 | u16 in_use; | ||
267 | |||
268 | caddr_t rda_next; /* pointer to next RD */ | ||
269 | } sonic_rd_t; | ||
270 | |||
271 | |||
272 | /* | ||
273 | * Describes a Transmit Descriptor | ||
274 | */ | ||
275 | typedef struct { | ||
276 | SREGS_PAD(pad0); | ||
277 | u16 tx_status; /* status after transmission of a packet */ | ||
278 | SREGS_PAD(pad1); | ||
279 | u16 tx_config; /* transmit configuration for this packet */ | ||
280 | SREGS_PAD(pad2); | ||
281 | u16 tx_pktsize; /* size of the packet to be transmitted */ | ||
282 | SREGS_PAD(pad3); | ||
283 | u16 tx_frag_count; /* no. of fragments */ | ||
284 | |||
285 | SREGS_PAD(pad4); | ||
286 | u16 tx_frag_ptr_l; | ||
287 | SREGS_PAD(pad5); | ||
288 | u16 tx_frag_ptr_h; | ||
289 | SREGS_PAD(pad6); | ||
290 | u16 tx_frag_size; | ||
291 | |||
292 | SREGS_PAD(pad7); | ||
293 | u16 link; /* ptr to next descriptor */ | ||
294 | } sonic_td_t; | ||
295 | |||
296 | |||
297 | /* | ||
298 | * Describes an entry in the CAM Descriptor Area. | ||
299 | */ | ||
300 | |||
301 | typedef struct { | ||
302 | SREGS_PAD(pad0); | ||
303 | u16 cam_entry_pointer; | ||
304 | SREGS_PAD(pad1); | ||
305 | u16 cam_cap0; | ||
306 | SREGS_PAD(pad2); | ||
307 | u16 cam_cap1; | ||
308 | SREGS_PAD(pad3); | ||
309 | u16 cam_cap2; | ||
310 | } sonic_cd_t; | ||
311 | |||
312 | #define CAM_DESCRIPTORS 16 | 225 | #define CAM_DESCRIPTORS 16 |
313 | 226 | ||
314 | 227 | /* Offsets in the various DMA buffers accessed by the SONIC */ | |
315 | typedef struct { | 228 | |
316 | sonic_cd_t cam_desc[CAM_DESCRIPTORS]; | 229 | #define SONIC_BITMODE16 0 |
317 | SREGS_PAD(pad); | 230 | #define SONIC_BITMODE32 1 |
318 | u16 cam_enable; | 231 | #define SONIC_BUS_SCALE(bitmode) ((bitmode) ? 4 : 2) |
319 | } sonic_cda_t; | 232 | /* Note! These are all measured in bus-size units, so use SONIC_BUS_SCALE */ |
320 | 233 | #define SIZEOF_SONIC_RR 4 | |
321 | #else /* original declarations, little endian 32 bit */ | 234 | #define SONIC_RR_BUFADR_L 0 |
322 | 235 | #define SONIC_RR_BUFADR_H 1 | |
323 | /* | 236 | #define SONIC_RR_BUFSIZE_L 2 |
324 | * structure definitions | 237 | #define SONIC_RR_BUFSIZE_H 3 |
325 | */ | 238 | |
326 | 239 | #define SIZEOF_SONIC_RD 7 | |
327 | typedef struct { | 240 | #define SONIC_RD_STATUS 0 |
328 | u32 rx_bufadr_l; /* receive buffer ptr */ | 241 | #define SONIC_RD_PKTLEN 1 |
329 | u32 rx_bufadr_h; | 242 | #define SONIC_RD_PKTPTR_L 2 |
330 | 243 | #define SONIC_RD_PKTPTR_H 3 | |
331 | u32 rx_bufsize_l; /* no. of words in the receive buffer */ | 244 | #define SONIC_RD_SEQNO 4 |
332 | u32 rx_bufsize_h; | 245 | #define SONIC_RD_LINK 5 |
333 | } sonic_rr_t; | 246 | #define SONIC_RD_IN_USE 6 |
334 | 247 | ||
335 | /* | 248 | #define SIZEOF_SONIC_TD 8 |
336 | * Sonic receive descriptor. Receive descriptors are | 249 | #define SONIC_TD_STATUS 0 |
337 | * kept in a linked list of these structures. | 250 | #define SONIC_TD_CONFIG 1 |
338 | */ | 251 | #define SONIC_TD_PKTSIZE 2 |
339 | 252 | #define SONIC_TD_FRAG_COUNT 3 | |
340 | typedef struct { | 253 | #define SONIC_TD_FRAG_PTR_L 4 |
341 | u16 rx_status; /* status after reception of a packet */ | 254 | #define SONIC_TD_FRAG_PTR_H 5 |
342 | SREGS_PAD(pad0); | 255 | #define SONIC_TD_FRAG_SIZE 6 |
343 | u16 rx_pktlen; /* length of the packet incl. CRC */ | 256 | #define SONIC_TD_LINK 7 |
344 | SREGS_PAD(pad1); | 257 | |
345 | 258 | #define SIZEOF_SONIC_CD 4 | |
346 | /* | 259 | #define SONIC_CD_ENTRY_POINTER 0 |
347 | * Pointers to the location in the receive buffer area (RBA) | 260 | #define SONIC_CD_CAP0 1 |
348 | * where the packet resides. A packet is always received into | 261 | #define SONIC_CD_CAP1 2 |
349 | * a contiguous piece of memory. | 262 | #define SONIC_CD_CAP2 3 |
350 | */ | 263 | |
351 | u16 rx_pktptr_l; | 264 | #define SIZEOF_SONIC_CDA ((CAM_DESCRIPTORS * SIZEOF_SONIC_CD) + 1) |
352 | SREGS_PAD(pad2); | 265 | #define SONIC_CDA_CAM_ENABLE (CAM_DESCRIPTORS * SIZEOF_SONIC_CD) |
353 | u16 rx_pktptr_h; | ||
354 | SREGS_PAD(pad3); | ||
355 | |||
356 | u16 rx_seqno; /* sequence no. */ | ||
357 | SREGS_PAD(pad4); | ||
358 | |||
359 | u16 link; /* link to next RDD (end if EOL bit set) */ | ||
360 | SREGS_PAD(pad5); | ||
361 | |||
362 | /* | ||
363 | * Owner of this descriptor, 0= driver, 1=sonic | ||
364 | */ | ||
365 | |||
366 | u16 in_use; | ||
367 | SREGS_PAD(pad6); | ||
368 | |||
369 | caddr_t rda_next; /* pointer to next RD */ | ||
370 | } sonic_rd_t; | ||
371 | |||
372 | |||
373 | /* | ||
374 | * Describes a Transmit Descriptor | ||
375 | */ | ||
376 | typedef struct { | ||
377 | u16 tx_status; /* status after transmission of a packet */ | ||
378 | SREGS_PAD(pad0); | ||
379 | u16 tx_config; /* transmit configuration for this packet */ | ||
380 | SREGS_PAD(pad1); | ||
381 | u16 tx_pktsize; /* size of the packet to be transmitted */ | ||
382 | SREGS_PAD(pad2); | ||
383 | u16 tx_frag_count; /* no. of fragments */ | ||
384 | SREGS_PAD(pad3); | ||
385 | |||
386 | u16 tx_frag_ptr_l; | ||
387 | SREGS_PAD(pad4); | ||
388 | u16 tx_frag_ptr_h; | ||
389 | SREGS_PAD(pad5); | ||
390 | u16 tx_frag_size; | ||
391 | SREGS_PAD(pad6); | ||
392 | |||
393 | u16 link; /* ptr to next descriptor */ | ||
394 | SREGS_PAD(pad7); | ||
395 | } sonic_td_t; | ||
396 | |||
397 | |||
398 | /* | ||
399 | * Describes an entry in the CAM Descriptor Area. | ||
400 | */ | ||
401 | |||
402 | typedef struct { | ||
403 | u16 cam_entry_pointer; | ||
404 | SREGS_PAD(pad0); | ||
405 | u16 cam_cap0; | ||
406 | SREGS_PAD(pad1); | ||
407 | u16 cam_cap1; | ||
408 | SREGS_PAD(pad2); | ||
409 | u16 cam_cap2; | ||
410 | SREGS_PAD(pad3); | ||
411 | } sonic_cd_t; | ||
412 | |||
413 | #define CAM_DESCRIPTORS 16 | ||
414 | |||
415 | |||
416 | typedef struct { | ||
417 | sonic_cd_t cam_desc[CAM_DESCRIPTORS]; | ||
418 | u16 cam_enable; | ||
419 | SREGS_PAD(pad); | ||
420 | } sonic_cda_t; | ||
421 | #endif /* endianness */ | ||
422 | 266 | ||
423 | /* | 267 | /* |
424 | * Some tunables for the buffer areas. Power of 2 is required | 268 | * Some tunables for the buffer areas. Power of 2 is required |
@@ -426,44 +270,60 @@ typedef struct { | |||
426 | * | 270 | * |
427 | * MSch: use more buffer space for the slow m68k Macs! | 271 | * MSch: use more buffer space for the slow m68k Macs! |
428 | */ | 272 | */ |
429 | #ifdef CONFIG_MACSONIC | 273 | #define SONIC_NUM_RRS 16 /* number of receive resources */ |
430 | #define SONIC_NUM_RRS 32 /* number of receive resources */ | 274 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ |
431 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ | 275 | #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ |
432 | #define SONIC_NUM_TDS 32 /* number of transmit descriptors */ | ||
433 | #else | ||
434 | #define SONIC_NUM_RRS 16 /* number of receive resources */ | ||
435 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ | ||
436 | #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ | ||
437 | #endif | ||
438 | #define SONIC_RBSIZE 1520 /* size of one resource buffer */ | ||
439 | 276 | ||
440 | #define SONIC_RDS_MASK (SONIC_NUM_RDS-1) | 277 | #define SONIC_RDS_MASK (SONIC_NUM_RDS-1) |
441 | #define SONIC_TDS_MASK (SONIC_NUM_TDS-1) | 278 | #define SONIC_TDS_MASK (SONIC_NUM_TDS-1) |
442 | 279 | ||
280 | #define SONIC_RBSIZE 1520 /* size of one resource buffer */ | ||
281 | |||
282 | /* Again, measured in bus size units! */ | ||
283 | #define SIZEOF_SONIC_DESC (SIZEOF_SONIC_CDA \ | ||
284 | + (SIZEOF_SONIC_TD * SONIC_NUM_TDS) \ | ||
285 | + (SIZEOF_SONIC_RD * SONIC_NUM_RDS) \ | ||
286 | + (SIZEOF_SONIC_RR * SONIC_NUM_RRS)) | ||
443 | 287 | ||
444 | /* Information that need to be kept for each board. */ | 288 | /* Information that need to be kept for each board. */ |
445 | struct sonic_local { | 289 | struct sonic_local { |
446 | sonic_cda_t cda; /* virtual CPU address of CDA */ | 290 | /* Bus size. 0 == 16 bits, 1 == 32 bits. */ |
447 | sonic_td_t tda[SONIC_NUM_TDS]; /* transmit descriptor area */ | 291 | int dma_bitmode; |
448 | sonic_rr_t rra[SONIC_NUM_RRS]; /* receive resource area */ | 292 | /* Register offset within the longword (independent of endianness, |
449 | sonic_rd_t rda[SONIC_NUM_RDS]; /* receive descriptor area */ | 293 | and varies from one type of Macintosh SONIC to another |
450 | struct sk_buff *tx_skb[SONIC_NUM_TDS]; /* skbuffs for packets to transmit */ | 294 | (Aarrgh)) */ |
451 | unsigned int tx_laddr[SONIC_NUM_TDS]; /* logical DMA address fro skbuffs */ | 295 | int reg_offset; |
452 | unsigned char *rba; /* start of receive buffer areas */ | 296 | void *descriptors; |
453 | unsigned int cda_laddr; /* logical DMA address of CDA */ | 297 | /* Crud. These areas have to be within the same 64K. Therefore |
454 | unsigned int tda_laddr; /* logical DMA address of TDA */ | 298 | we allocate a desriptors page, and point these to places within it. */ |
455 | unsigned int rra_laddr; /* logical DMA address of RRA */ | 299 | void *cda; /* CAM descriptor area */ |
456 | unsigned int rda_laddr; /* logical DMA address of RDA */ | 300 | void *tda; /* Transmit descriptor area */ |
457 | unsigned int rba_laddr; /* logical DMA address of RBA */ | 301 | void *rra; /* Receive resource area */ |
458 | unsigned int cur_rra; /* current indexes to resource areas */ | 302 | void *rda; /* Receive descriptor area */ |
303 | struct sk_buff* volatile rx_skb[SONIC_NUM_RRS]; /* packets to be received */ | ||
304 | struct sk_buff* volatile tx_skb[SONIC_NUM_TDS]; /* packets to be transmitted */ | ||
305 | unsigned int tx_len[SONIC_NUM_TDS]; /* lengths of tx DMA mappings */ | ||
306 | /* Logical DMA addresses on MIPS, bus addresses on m68k | ||
307 | * (so "laddr" is a bit misleading) */ | ||
308 | dma_addr_t descriptors_laddr; | ||
309 | u32 cda_laddr; /* logical DMA address of CDA */ | ||
310 | u32 tda_laddr; /* logical DMA address of TDA */ | ||
311 | u32 rra_laddr; /* logical DMA address of RRA */ | ||
312 | u32 rda_laddr; /* logical DMA address of RDA */ | ||
313 | dma_addr_t rx_laddr[SONIC_NUM_RRS]; /* logical DMA addresses of rx skbuffs */ | ||
314 | dma_addr_t tx_laddr[SONIC_NUM_TDS]; /* logical DMA addresses of tx skbuffs */ | ||
315 | unsigned int rra_end; | ||
316 | unsigned int cur_rwp; | ||
459 | unsigned int cur_rx; | 317 | unsigned int cur_rx; |
460 | unsigned int cur_tx; | 318 | unsigned int cur_tx; /* first unacked transmit packet */ |
461 | unsigned int dirty_tx; /* last unacked transmit packet */ | 319 | unsigned int eol_rx; |
462 | char tx_full; | 320 | unsigned int eol_tx; /* last unacked transmit packet */ |
321 | unsigned int next_tx; /* next free TD */ | ||
322 | struct device *device; /* generic device */ | ||
463 | struct net_device_stats stats; | 323 | struct net_device_stats stats; |
464 | }; | 324 | }; |
465 | 325 | ||
466 | #define TX_TIMEOUT 6 | 326 | #define TX_TIMEOUT (3 * HZ) |
467 | 327 | ||
468 | /* Index to functions, as function prototypes. */ | 328 | /* Index to functions, as function prototypes. */ |
469 | 329 | ||
@@ -477,6 +337,114 @@ static void sonic_multicast_list(struct net_device *dev); | |||
477 | static int sonic_init(struct net_device *dev); | 337 | static int sonic_init(struct net_device *dev); |
478 | static void sonic_tx_timeout(struct net_device *dev); | 338 | static void sonic_tx_timeout(struct net_device *dev); |
479 | 339 | ||
340 | /* Internal inlines for reading/writing DMA buffers. Note that bus | ||
341 | size and endianness matter here, whereas they don't for registers, | ||
342 | as far as we can tell. */ | ||
343 | /* OpenBSD calls this "SWO". I'd like to think that sonic_buf_put() | ||
344 | is a much better name. */ | ||
345 | static inline void sonic_buf_put(void* base, int bitmode, | ||
346 | int offset, __u16 val) | ||
347 | { | ||
348 | if (bitmode) | ||
349 | #ifdef __BIG_ENDIAN | ||
350 | ((__u16 *) base + (offset*2))[1] = val; | ||
351 | #else | ||
352 | ((__u16 *) base + (offset*2))[0] = val; | ||
353 | #endif | ||
354 | else | ||
355 | ((__u16 *) base)[offset] = val; | ||
356 | } | ||
357 | |||
358 | static inline __u16 sonic_buf_get(void* base, int bitmode, | ||
359 | int offset) | ||
360 | { | ||
361 | if (bitmode) | ||
362 | #ifdef __BIG_ENDIAN | ||
363 | return ((volatile __u16 *) base + (offset*2))[1]; | ||
364 | #else | ||
365 | return ((volatile __u16 *) base + (offset*2))[0]; | ||
366 | #endif | ||
367 | else | ||
368 | return ((volatile __u16 *) base)[offset]; | ||
369 | } | ||
370 | |||
371 | /* Inlines that you should actually use for reading/writing DMA buffers */ | ||
372 | static inline void sonic_cda_put(struct net_device* dev, int entry, | ||
373 | int offset, __u16 val) | ||
374 | { | ||
375 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
376 | sonic_buf_put(lp->cda, lp->dma_bitmode, | ||
377 | (entry * SIZEOF_SONIC_CD) + offset, val); | ||
378 | } | ||
379 | |||
380 | static inline __u16 sonic_cda_get(struct net_device* dev, int entry, | ||
381 | int offset) | ||
382 | { | ||
383 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
384 | return sonic_buf_get(lp->cda, lp->dma_bitmode, | ||
385 | (entry * SIZEOF_SONIC_CD) + offset); | ||
386 | } | ||
387 | |||
388 | static inline void sonic_set_cam_enable(struct net_device* dev, __u16 val) | ||
389 | { | ||
390 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
391 | sonic_buf_put(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE, val); | ||
392 | } | ||
393 | |||
394 | static inline __u16 sonic_get_cam_enable(struct net_device* dev) | ||
395 | { | ||
396 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
397 | return sonic_buf_get(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE); | ||
398 | } | ||
399 | |||
400 | static inline void sonic_tda_put(struct net_device* dev, int entry, | ||
401 | int offset, __u16 val) | ||
402 | { | ||
403 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
404 | sonic_buf_put(lp->tda, lp->dma_bitmode, | ||
405 | (entry * SIZEOF_SONIC_TD) + offset, val); | ||
406 | } | ||
407 | |||
408 | static inline __u16 sonic_tda_get(struct net_device* dev, int entry, | ||
409 | int offset) | ||
410 | { | ||
411 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
412 | return sonic_buf_get(lp->tda, lp->dma_bitmode, | ||
413 | (entry * SIZEOF_SONIC_TD) + offset); | ||
414 | } | ||
415 | |||
416 | static inline void sonic_rda_put(struct net_device* dev, int entry, | ||
417 | int offset, __u16 val) | ||
418 | { | ||
419 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
420 | sonic_buf_put(lp->rda, lp->dma_bitmode, | ||
421 | (entry * SIZEOF_SONIC_RD) + offset, val); | ||
422 | } | ||
423 | |||
424 | static inline __u16 sonic_rda_get(struct net_device* dev, int entry, | ||
425 | int offset) | ||
426 | { | ||
427 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
428 | return sonic_buf_get(lp->rda, lp->dma_bitmode, | ||
429 | (entry * SIZEOF_SONIC_RD) + offset); | ||
430 | } | ||
431 | |||
432 | static inline void sonic_rra_put(struct net_device* dev, int entry, | ||
433 | int offset, __u16 val) | ||
434 | { | ||
435 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
436 | sonic_buf_put(lp->rra, lp->dma_bitmode, | ||
437 | (entry * SIZEOF_SONIC_RR) + offset, val); | ||
438 | } | ||
439 | |||
440 | static inline __u16 sonic_rra_get(struct net_device* dev, int entry, | ||
441 | int offset) | ||
442 | { | ||
443 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
444 | return sonic_buf_get(lp->rra, lp->dma_bitmode, | ||
445 | (entry * SIZEOF_SONIC_RR) + offset); | ||
446 | } | ||
447 | |||
480 | static const char *version = | 448 | static const char *version = |
481 | "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; | 449 | "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; |
482 | 450 | ||
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 01419aff333e..af8263a1580e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -66,8 +66,8 @@ | |||
66 | 66 | ||
67 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
68 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
69 | #define DRV_MODULE_VERSION "3.36" | 69 | #define DRV_MODULE_VERSION "3.37" |
70 | #define DRV_MODULE_RELDATE "August 19, 2005" | 70 | #define DRV_MODULE_RELDATE "August 25, 2005" |
71 | 71 | ||
72 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
73 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
@@ -340,41 +340,92 @@ static struct { | |||
340 | 340 | ||
341 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 341 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
342 | { | 342 | { |
343 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 343 | unsigned long flags; |
344 | spin_lock_bh(&tp->indirect_lock); | 344 | |
345 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 345 | spin_lock_irqsave(&tp->indirect_lock, flags); |
346 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 346 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); |
347 | spin_unlock_bh(&tp->indirect_lock); | 347 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); |
348 | } else { | 348 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
349 | writel(val, tp->regs + off); | 349 | } |
350 | if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0) | 350 | |
351 | readl(tp->regs + off); | 351 | static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val) |
352 | { | ||
353 | writel(val, tp->regs + off); | ||
354 | readl(tp->regs + off); | ||
355 | } | ||
356 | |||
357 | static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off) | ||
358 | { | ||
359 | unsigned long flags; | ||
360 | u32 val; | ||
361 | |||
362 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
363 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | ||
364 | pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val); | ||
365 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | ||
366 | return val; | ||
367 | } | ||
368 | |||
369 | static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val) | ||
370 | { | ||
371 | unsigned long flags; | ||
372 | |||
373 | if (off == (MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW)) { | ||
374 | pci_write_config_dword(tp->pdev, TG3PCI_RCV_RET_RING_CON_IDX + | ||
375 | TG3_64BIT_REG_LOW, val); | ||
376 | return; | ||
377 | } | ||
378 | if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) { | ||
379 | pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX + | ||
380 | TG3_64BIT_REG_LOW, val); | ||
381 | return; | ||
382 | } | ||
383 | |||
384 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
385 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600); | ||
386 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | ||
387 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | ||
388 | |||
389 | /* In indirect mode when disabling interrupts, we also need | ||
390 | * to clear the interrupt bit in the GRC local ctrl register. | ||
391 | */ | ||
392 | if ((off == (MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW)) && | ||
393 | (val == 0x1)) { | ||
394 | pci_write_config_dword(tp->pdev, TG3PCI_MISC_LOCAL_CTRL, | ||
395 | tp->grc_local_ctrl|GRC_LCLCTRL_CLEARINT); | ||
352 | } | 396 | } |
353 | } | 397 | } |
354 | 398 | ||
399 | static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off) | ||
400 | { | ||
401 | unsigned long flags; | ||
402 | u32 val; | ||
403 | |||
404 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
405 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600); | ||
406 | pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val); | ||
407 | spin_unlock_irqrestore(&tp->indirect_lock, flags); | ||
408 | return val; | ||
409 | } | ||
410 | |||
355 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) | 411 | static void _tw32_flush(struct tg3 *tp, u32 off, u32 val) |
356 | { | 412 | { |
357 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 413 | tp->write32(tp, off, val); |
358 | spin_lock_bh(&tp->indirect_lock); | 414 | if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) && |
359 | pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off); | 415 | !(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) && |
360 | pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val); | 416 | !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) |
361 | spin_unlock_bh(&tp->indirect_lock); | 417 | tp->read32(tp, off); /* flush */ |
362 | } else { | ||
363 | void __iomem *dest = tp->regs + off; | ||
364 | writel(val, dest); | ||
365 | readl(dest); /* always flush PCI write */ | ||
366 | } | ||
367 | } | 418 | } |
368 | 419 | ||
369 | static inline void _tw32_rx_mbox(struct tg3 *tp, u32 off, u32 val) | 420 | static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val) |
370 | { | 421 | { |
371 | void __iomem *mbox = tp->regs + off; | 422 | tp->write32_mbox(tp, off, val); |
372 | writel(val, mbox); | 423 | if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) && |
373 | if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) | 424 | !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND)) |
374 | readl(mbox); | 425 | tp->read32_mbox(tp, off); |
375 | } | 426 | } |
376 | 427 | ||
377 | static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | 428 | static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val) |
378 | { | 429 | { |
379 | void __iomem *mbox = tp->regs + off; | 430 | void __iomem *mbox = tp->regs + off; |
380 | writel(val, mbox); | 431 | writel(val, mbox); |
@@ -384,46 +435,57 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val) | |||
384 | readl(mbox); | 435 | readl(mbox); |
385 | } | 436 | } |
386 | 437 | ||
387 | #define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tp->regs + (reg)) | 438 | static void tg3_write32(struct tg3 *tp, u32 off, u32 val) |
388 | #define tw32_rx_mbox(reg, val) _tw32_rx_mbox(tp, reg, val) | 439 | { |
389 | #define tw32_tx_mbox(reg, val) _tw32_tx_mbox(tp, reg, val) | 440 | writel(val, tp->regs + off); |
441 | } | ||
442 | |||
443 | static u32 tg3_read32(struct tg3 *tp, u32 off) | ||
444 | { | ||
445 | return (readl(tp->regs + off)); | ||
446 | } | ||
447 | |||
448 | #define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val) | ||
449 | #define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val)) | ||
450 | #define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val) | ||
451 | #define tw32_tx_mbox(reg, val) tp->write32_tx_mbox(tp, reg, val) | ||
452 | #define tr32_mailbox(reg) tp->read32_mbox(tp, reg) | ||
390 | 453 | ||
391 | #define tw32(reg,val) tg3_write_indirect_reg32(tp,(reg),(val)) | 454 | #define tw32(reg,val) tp->write32(tp, reg, val) |
392 | #define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) | 455 | #define tw32_f(reg,val) _tw32_flush(tp,(reg),(val)) |
393 | #define tw16(reg,val) writew(((val) & 0xffff), tp->regs + (reg)) | 456 | #define tr32(reg) tp->read32(tp, reg) |
394 | #define tw8(reg,val) writeb(((val) & 0xff), tp->regs + (reg)) | ||
395 | #define tr32(reg) readl(tp->regs + (reg)) | ||
396 | #define tr16(reg) readw(tp->regs + (reg)) | ||
397 | #define tr8(reg) readb(tp->regs + (reg)) | ||
398 | 457 | ||
399 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) | 458 | static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val) |
400 | { | 459 | { |
401 | spin_lock_bh(&tp->indirect_lock); | 460 | unsigned long flags; |
461 | |||
462 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
402 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 463 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
403 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 464 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); |
404 | 465 | ||
405 | /* Always leave this as zero. */ | 466 | /* Always leave this as zero. */ |
406 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 467 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
407 | spin_unlock_bh(&tp->indirect_lock); | 468 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
408 | } | 469 | } |
409 | 470 | ||
410 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) | 471 | static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val) |
411 | { | 472 | { |
412 | spin_lock_bh(&tp->indirect_lock); | 473 | unsigned long flags; |
474 | |||
475 | spin_lock_irqsave(&tp->indirect_lock, flags); | ||
413 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); | 476 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off); |
414 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); | 477 | pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val); |
415 | 478 | ||
416 | /* Always leave this as zero. */ | 479 | /* Always leave this as zero. */ |
417 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); | 480 | pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0); |
418 | spin_unlock_bh(&tp->indirect_lock); | 481 | spin_unlock_irqrestore(&tp->indirect_lock, flags); |
419 | } | 482 | } |
420 | 483 | ||
421 | static void tg3_disable_ints(struct tg3 *tp) | 484 | static void tg3_disable_ints(struct tg3 *tp) |
422 | { | 485 | { |
423 | tw32(TG3PCI_MISC_HOST_CTRL, | 486 | tw32(TG3PCI_MISC_HOST_CTRL, |
424 | (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); | 487 | (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT)); |
425 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 488 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
426 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
427 | } | 489 | } |
428 | 490 | ||
429 | static inline void tg3_cond_int(struct tg3 *tp) | 491 | static inline void tg3_cond_int(struct tg3 *tp) |
@@ -439,9 +501,8 @@ static void tg3_enable_ints(struct tg3 *tp) | |||
439 | 501 | ||
440 | tw32(TG3PCI_MISC_HOST_CTRL, | 502 | tw32(TG3PCI_MISC_HOST_CTRL, |
441 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | 503 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); |
442 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 504 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
443 | (tp->last_tag << 24)); | 505 | (tp->last_tag << 24)); |
444 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
445 | tg3_cond_int(tp); | 506 | tg3_cond_int(tp); |
446 | } | 507 | } |
447 | 508 | ||
@@ -472,8 +533,6 @@ static inline unsigned int tg3_has_work(struct tg3 *tp) | |||
472 | */ | 533 | */ |
473 | static void tg3_restart_ints(struct tg3 *tp) | 534 | static void tg3_restart_ints(struct tg3 *tp) |
474 | { | 535 | { |
475 | tw32(TG3PCI_MISC_HOST_CTRL, | ||
476 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | ||
477 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 536 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
478 | tp->last_tag << 24); | 537 | tp->last_tag << 24); |
479 | mmiowb(); | 538 | mmiowb(); |
@@ -3278,9 +3337,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
3278 | /* No work, shared interrupt perhaps? re-enable | 3337 | /* No work, shared interrupt perhaps? re-enable |
3279 | * interrupts, and flush that PCI write | 3338 | * interrupts, and flush that PCI write |
3280 | */ | 3339 | */ |
3281 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3340 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3282 | 0x00000000); | 3341 | 0x00000000); |
3283 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
3284 | } | 3342 | } |
3285 | } else { /* shared interrupt */ | 3343 | } else { /* shared interrupt */ |
3286 | handled = 0; | 3344 | handled = 0; |
@@ -3323,9 +3381,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3323 | /* no work, shared interrupt perhaps? re-enable | 3381 | /* no work, shared interrupt perhaps? re-enable |
3324 | * interrupts, and flush that PCI write | 3382 | * interrupts, and flush that PCI write |
3325 | */ | 3383 | */ |
3326 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3384 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3327 | tp->last_tag << 24); | 3385 | tp->last_tag << 24); |
3328 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
3329 | } | 3386 | } |
3330 | } else { /* shared interrupt */ | 3387 | } else { /* shared interrupt */ |
3331 | handled = 0; | 3388 | handled = 0; |
@@ -4216,7 +4273,7 @@ static void tg3_stop_fw(struct tg3 *); | |||
4216 | static int tg3_chip_reset(struct tg3 *tp) | 4273 | static int tg3_chip_reset(struct tg3 *tp) |
4217 | { | 4274 | { |
4218 | u32 val; | 4275 | u32 val; |
4219 | u32 flags_save; | 4276 | void (*write_op)(struct tg3 *, u32, u32); |
4220 | int i; | 4277 | int i; |
4221 | 4278 | ||
4222 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | 4279 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) |
@@ -4228,8 +4285,9 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
4228 | * fun things. So, temporarily disable the 5701 | 4285 | * fun things. So, temporarily disable the 5701 |
4229 | * hardware workaround, while we do the reset. | 4286 | * hardware workaround, while we do the reset. |
4230 | */ | 4287 | */ |
4231 | flags_save = tp->tg3_flags; | 4288 | write_op = tp->write32; |
4232 | tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG; | 4289 | if (write_op == tg3_write_flush_reg32) |
4290 | tp->write32 = tg3_write32; | ||
4233 | 4291 | ||
4234 | /* do the reset */ | 4292 | /* do the reset */ |
4235 | val = GRC_MISC_CFG_CORECLK_RESET; | 4293 | val = GRC_MISC_CFG_CORECLK_RESET; |
@@ -4248,8 +4306,8 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
4248 | val |= GRC_MISC_CFG_KEEP_GPHY_POWER; | 4306 | val |= GRC_MISC_CFG_KEEP_GPHY_POWER; |
4249 | tw32(GRC_MISC_CFG, val); | 4307 | tw32(GRC_MISC_CFG, val); |
4250 | 4308 | ||
4251 | /* restore 5701 hardware bug workaround flag */ | 4309 | /* restore 5701 hardware bug workaround write method */ |
4252 | tp->tg3_flags = flags_save; | 4310 | tp->write32 = write_op; |
4253 | 4311 | ||
4254 | /* Unfortunately, we have to delay before the PCI read back. | 4312 | /* Unfortunately, we have to delay before the PCI read back. |
4255 | * Some 575X chips even will not respond to a PCI cfg access | 4313 | * Some 575X chips even will not respond to a PCI cfg access |
@@ -4635,7 +4693,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4635 | int cpu_scratch_size, struct fw_info *info) | 4693 | int cpu_scratch_size, struct fw_info *info) |
4636 | { | 4694 | { |
4637 | int err, i; | 4695 | int err, i; |
4638 | u32 orig_tg3_flags = tp->tg3_flags; | ||
4639 | void (*write_op)(struct tg3 *, u32, u32); | 4696 | void (*write_op)(struct tg3 *, u32, u32); |
4640 | 4697 | ||
4641 | if (cpu_base == TX_CPU_BASE && | 4698 | if (cpu_base == TX_CPU_BASE && |
@@ -4651,11 +4708,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4651 | else | 4708 | else |
4652 | write_op = tg3_write_indirect_reg32; | 4709 | write_op = tg3_write_indirect_reg32; |
4653 | 4710 | ||
4654 | /* Force use of PCI config space for indirect register | ||
4655 | * write calls. | ||
4656 | */ | ||
4657 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | ||
4658 | |||
4659 | /* It is possible that bootcode is still loading at this point. | 4711 | /* It is possible that bootcode is still loading at this point. |
4660 | * Get the nvram lock first before halting the cpu. | 4712 | * Get the nvram lock first before halting the cpu. |
4661 | */ | 4713 | */ |
@@ -4691,7 +4743,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4691 | err = 0; | 4743 | err = 0; |
4692 | 4744 | ||
4693 | out: | 4745 | out: |
4694 | tp->tg3_flags = orig_tg3_flags; | ||
4695 | return err; | 4746 | return err; |
4696 | } | 4747 | } |
4697 | 4748 | ||
@@ -5808,8 +5859,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5808 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); | 5859 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); |
5809 | udelay(100); | 5860 | udelay(100); |
5810 | 5861 | ||
5811 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); | 5862 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); |
5812 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
5813 | tp->last_tag = 0; | 5863 | tp->last_tag = 0; |
5814 | 5864 | ||
5815 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | 5865 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { |
@@ -6198,7 +6248,8 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
6198 | HOSTCC_MODE_NOW); | 6248 | HOSTCC_MODE_NOW); |
6199 | 6249 | ||
6200 | for (i = 0; i < 5; i++) { | 6250 | for (i = 0; i < 5; i++) { |
6201 | int_mbox = tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 6251 | int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 + |
6252 | TG3_64BIT_REG_LOW); | ||
6202 | if (int_mbox != 0) | 6253 | if (int_mbox != 0) |
6203 | break; | 6254 | break; |
6204 | msleep(10); | 6255 | msleep(10); |
@@ -6598,10 +6649,10 @@ static int tg3_open(struct net_device *dev) | |||
6598 | 6649 | ||
6599 | /* Mailboxes */ | 6650 | /* Mailboxes */ |
6600 | printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n", | 6651 | printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n", |
6601 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0), | 6652 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0), |
6602 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4), | 6653 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4), |
6603 | tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0), | 6654 | tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0), |
6604 | tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4)); | 6655 | tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4)); |
6605 | 6656 | ||
6606 | /* NIC side send descriptors. */ | 6657 | /* NIC side send descriptors. */ |
6607 | for (i = 0; i < 6; i++) { | 6658 | for (i = 0; i < 6; i++) { |
@@ -7865,8 +7916,6 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7865 | 7916 | ||
7866 | err = -EIO; | 7917 | err = -EIO; |
7867 | 7918 | ||
7868 | tg3_abort_hw(tp, 1); | ||
7869 | |||
7870 | tg3_reset_hw(tp); | 7919 | tg3_reset_hw(tp); |
7871 | 7920 | ||
7872 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7921 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
@@ -7903,7 +7952,7 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7903 | num_pkts++; | 7952 | num_pkts++; |
7904 | 7953 | ||
7905 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | 7954 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); |
7906 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | 7955 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); |
7907 | 7956 | ||
7908 | udelay(10); | 7957 | udelay(10); |
7909 | 7958 | ||
@@ -9155,14 +9204,6 @@ static int __devinit tg3_is_sun_570X(struct tg3 *tp) | |||
9155 | static int __devinit tg3_get_invariants(struct tg3 *tp) | 9204 | static int __devinit tg3_get_invariants(struct tg3 *tp) |
9156 | { | 9205 | { |
9157 | static struct pci_device_id write_reorder_chipsets[] = { | 9206 | static struct pci_device_id write_reorder_chipsets[] = { |
9158 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9159 | PCI_DEVICE_ID_INTEL_82801AA_8) }, | ||
9160 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9161 | PCI_DEVICE_ID_INTEL_82801AB_8) }, | ||
9162 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9163 | PCI_DEVICE_ID_INTEL_82801BA_11) }, | ||
9164 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | ||
9165 | PCI_DEVICE_ID_INTEL_82801BA_6) }, | ||
9166 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, | 9207 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, |
9167 | PCI_DEVICE_ID_AMD_FE_GATE_700C) }, | 9208 | PCI_DEVICE_ID_AMD_FE_GATE_700C) }, |
9168 | { }, | 9209 | { }, |
@@ -9179,7 +9220,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9179 | tp->tg3_flags2 |= TG3_FLG2_SUN_570X; | 9220 | tp->tg3_flags2 |= TG3_FLG2_SUN_570X; |
9180 | #endif | 9221 | #endif |
9181 | 9222 | ||
9182 | /* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write | 9223 | /* If we have an AMD 762 chipset, write |
9183 | * reordering to the mailbox registers done by the host | 9224 | * reordering to the mailbox registers done by the host |
9184 | * controller can cause major troubles. We read back from | 9225 | * controller can cause major troubles. We read back from |
9185 | * every mailbox register write to force the writes to be | 9226 | * every mailbox register write to force the writes to be |
@@ -9217,6 +9258,69 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9217 | if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) | 9258 | if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW) |
9218 | tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; | 9259 | tp->pci_chip_rev_id = CHIPREV_ID_5752_A0; |
9219 | 9260 | ||
9261 | /* If we have 5702/03 A1 or A2 on certain ICH chipsets, | ||
9262 | * we need to disable memory and use config. cycles | ||
9263 | * only to access all registers. The 5702/03 chips | ||
9264 | * can mistakenly decode the special cycles from the | ||
9265 | * ICH chipsets as memory write cycles, causing corruption | ||
9266 | * of register and memory space. Only certain ICH bridges | ||
9267 | * will drive special cycles with non-zero data during the | ||
9268 | * address phase which can fall within the 5703's address | ||
9269 | * range. This is not an ICH bug as the PCI spec allows | ||
9270 | * non-zero address during special cycles. However, only | ||
9271 | * these ICH bridges are known to drive non-zero addresses | ||
9272 | * during special cycles. | ||
9273 | * | ||
9274 | * Since special cycles do not cross PCI bridges, we only | ||
9275 | * enable this workaround if the 5703 is on the secondary | ||
9276 | * bus of these ICH bridges. | ||
9277 | */ | ||
9278 | if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) || | ||
9279 | (tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)) { | ||
9280 | static struct tg3_dev_id { | ||
9281 | u32 vendor; | ||
9282 | u32 device; | ||
9283 | u32 rev; | ||
9284 | } ich_chipsets[] = { | ||
9285 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8, | ||
9286 | PCI_ANY_ID }, | ||
9287 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8, | ||
9288 | PCI_ANY_ID }, | ||
9289 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11, | ||
9290 | 0xa }, | ||
9291 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6, | ||
9292 | PCI_ANY_ID }, | ||
9293 | { }, | ||
9294 | }; | ||
9295 | struct tg3_dev_id *pci_id = &ich_chipsets[0]; | ||
9296 | struct pci_dev *bridge = NULL; | ||
9297 | |||
9298 | while (pci_id->vendor != 0) { | ||
9299 | bridge = pci_get_device(pci_id->vendor, pci_id->device, | ||
9300 | bridge); | ||
9301 | if (!bridge) { | ||
9302 | pci_id++; | ||
9303 | continue; | ||
9304 | } | ||
9305 | if (pci_id->rev != PCI_ANY_ID) { | ||
9306 | u8 rev; | ||
9307 | |||
9308 | pci_read_config_byte(bridge, PCI_REVISION_ID, | ||
9309 | &rev); | ||
9310 | if (rev > pci_id->rev) | ||
9311 | continue; | ||
9312 | } | ||
9313 | if (bridge->subordinate && | ||
9314 | (bridge->subordinate->number == | ||
9315 | tp->pdev->bus->number)) { | ||
9316 | |||
9317 | tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND; | ||
9318 | pci_dev_put(bridge); | ||
9319 | break; | ||
9320 | } | ||
9321 | } | ||
9322 | } | ||
9323 | |||
9220 | /* Find msi capability. */ | 9324 | /* Find msi capability. */ |
9221 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) | 9325 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) |
9222 | tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); | 9326 | tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI); |
@@ -9304,6 +9408,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9304 | } | 9408 | } |
9305 | } | 9409 | } |
9306 | 9410 | ||
9411 | /* 5700 BX chips need to have their TX producer index mailboxes | ||
9412 | * written twice to workaround a bug. | ||
9413 | */ | ||
9414 | if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) | ||
9415 | tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG; | ||
9416 | |||
9307 | /* Back to back register writes can cause problems on this chip, | 9417 | /* Back to back register writes can cause problems on this chip, |
9308 | * the workaround is to read back all reg writes except those to | 9418 | * the workaround is to read back all reg writes except those to |
9309 | * mailbox regs. See tg3_write_indirect_reg32(). | 9419 | * mailbox regs. See tg3_write_indirect_reg32(). |
@@ -9327,6 +9437,43 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9327 | pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); | 9437 | pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg); |
9328 | } | 9438 | } |
9329 | 9439 | ||
9440 | /* Default fast path register access methods */ | ||
9441 | tp->read32 = tg3_read32; | ||
9442 | tp->write32 = tg3_write32; | ||
9443 | tp->read32_mbox = tg3_read32; | ||
9444 | tp->write32_mbox = tg3_write32; | ||
9445 | tp->write32_tx_mbox = tg3_write32; | ||
9446 | tp->write32_rx_mbox = tg3_write32; | ||
9447 | |||
9448 | /* Various workaround register access methods */ | ||
9449 | if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) | ||
9450 | tp->write32 = tg3_write_indirect_reg32; | ||
9451 | else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) | ||
9452 | tp->write32 = tg3_write_flush_reg32; | ||
9453 | |||
9454 | if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) || | ||
9455 | (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) { | ||
9456 | tp->write32_tx_mbox = tg3_write32_tx_mbox; | ||
9457 | if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) | ||
9458 | tp->write32_rx_mbox = tg3_write_flush_reg32; | ||
9459 | } | ||
9460 | |||
9461 | if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) { | ||
9462 | tp->read32 = tg3_read_indirect_reg32; | ||
9463 | tp->write32 = tg3_write_indirect_reg32; | ||
9464 | tp->read32_mbox = tg3_read_indirect_mbox; | ||
9465 | tp->write32_mbox = tg3_write_indirect_mbox; | ||
9466 | tp->write32_tx_mbox = tg3_write_indirect_mbox; | ||
9467 | tp->write32_rx_mbox = tg3_write_indirect_mbox; | ||
9468 | |||
9469 | iounmap(tp->regs); | ||
9470 | tp->regs = 0; | ||
9471 | |||
9472 | pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd); | ||
9473 | pci_cmd &= ~PCI_COMMAND_MEMORY; | ||
9474 | pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd); | ||
9475 | } | ||
9476 | |||
9330 | /* Get eeprom hw config before calling tg3_set_power_state(). | 9477 | /* Get eeprom hw config before calling tg3_set_power_state(). |
9331 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be | 9478 | * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be |
9332 | * determined before calling tg3_set_power_state() so that | 9479 | * determined before calling tg3_set_power_state() so that |
@@ -9541,14 +9688,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
9541 | else | 9688 | else |
9542 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; | 9689 | tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; |
9543 | 9690 | ||
9544 | /* 5700 BX chips need to have their TX producer index mailboxes | ||
9545 | * written twice to workaround a bug. | ||
9546 | */ | ||
9547 | if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX) | ||
9548 | tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG; | ||
9549 | else | ||
9550 | tp->tg3_flags &= ~TG3_FLAG_TXD_MBOX_HWBUG; | ||
9551 | |||
9552 | /* It seems all chips can get confused if TX buffers | 9691 | /* It seems all chips can get confused if TX buffers |
9553 | * straddle the 4GB address boundary in some cases. | 9692 | * straddle the 4GB address boundary in some cases. |
9554 | */ | 9693 | */ |
@@ -10471,7 +10610,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
10471 | return 0; | 10610 | return 0; |
10472 | 10611 | ||
10473 | err_out_iounmap: | 10612 | err_out_iounmap: |
10474 | iounmap(tp->regs); | 10613 | if (tp->regs) { |
10614 | iounmap(tp->regs); | ||
10615 | tp->regs = 0; | ||
10616 | } | ||
10475 | 10617 | ||
10476 | err_out_free_dev: | 10618 | err_out_free_dev: |
10477 | free_netdev(dev); | 10619 | free_netdev(dev); |
@@ -10493,7 +10635,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) | |||
10493 | struct tg3 *tp = netdev_priv(dev); | 10635 | struct tg3 *tp = netdev_priv(dev); |
10494 | 10636 | ||
10495 | unregister_netdev(dev); | 10637 | unregister_netdev(dev); |
10496 | iounmap(tp->regs); | 10638 | if (tp->regs) { |
10639 | iounmap(tp->regs); | ||
10640 | tp->regs = 0; | ||
10641 | } | ||
10497 | free_netdev(dev); | 10642 | free_netdev(dev); |
10498 | pci_release_regions(pdev); | 10643 | pci_release_regions(pdev); |
10499 | pci_disable_device(pdev); | 10644 | pci_disable_device(pdev); |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 5c4433c147fa..c184b773e585 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -2049,6 +2049,11 @@ struct tg3 { | |||
2049 | spinlock_t lock; | 2049 | spinlock_t lock; |
2050 | spinlock_t indirect_lock; | 2050 | spinlock_t indirect_lock; |
2051 | 2051 | ||
2052 | u32 (*read32) (struct tg3 *, u32); | ||
2053 | void (*write32) (struct tg3 *, u32, u32); | ||
2054 | u32 (*read32_mbox) (struct tg3 *, u32); | ||
2055 | void (*write32_mbox) (struct tg3 *, u32, | ||
2056 | u32); | ||
2052 | void __iomem *regs; | 2057 | void __iomem *regs; |
2053 | struct net_device *dev; | 2058 | struct net_device *dev; |
2054 | struct pci_dev *pdev; | 2059 | struct pci_dev *pdev; |
@@ -2060,6 +2065,8 @@ struct tg3 { | |||
2060 | u32 msg_enable; | 2065 | u32 msg_enable; |
2061 | 2066 | ||
2062 | /* begin "tx thread" cacheline section */ | 2067 | /* begin "tx thread" cacheline section */ |
2068 | void (*write32_tx_mbox) (struct tg3 *, u32, | ||
2069 | u32); | ||
2063 | u32 tx_prod; | 2070 | u32 tx_prod; |
2064 | u32 tx_cons; | 2071 | u32 tx_cons; |
2065 | u32 tx_pending; | 2072 | u32 tx_pending; |
@@ -2071,6 +2078,8 @@ struct tg3 { | |||
2071 | dma_addr_t tx_desc_mapping; | 2078 | dma_addr_t tx_desc_mapping; |
2072 | 2079 | ||
2073 | /* begin "rx thread" cacheline section */ | 2080 | /* begin "rx thread" cacheline section */ |
2081 | void (*write32_rx_mbox) (struct tg3 *, u32, | ||
2082 | u32); | ||
2074 | u32 rx_rcb_ptr; | 2083 | u32 rx_rcb_ptr; |
2075 | u32 rx_std_ptr; | 2084 | u32 rx_std_ptr; |
2076 | u32 rx_jumbo_ptr; | 2085 | u32 rx_jumbo_ptr; |
@@ -2165,6 +2174,7 @@ struct tg3 { | |||
2165 | #define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \ | 2174 | #define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \ |
2166 | TG3_FLG2_MII_SERDES) | 2175 | TG3_FLG2_MII_SERDES) |
2167 | #define TG3_FLG2_PARALLEL_DETECT 0x01000000 | 2176 | #define TG3_FLG2_PARALLEL_DETECT 0x01000000 |
2177 | #define TG3_FLG2_ICH_WORKAROUND 0x02000000 | ||
2168 | 2178 | ||
2169 | u32 split_mode_max_reqs; | 2179 | u32 split_mode_max_reqs; |
2170 | #define SPLIT_MODE_5704_MAX_REQ 3 | 2180 | #define SPLIT_MODE_5704_MAX_REQ 3 |
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index 7e99e9f8045e..e4cfc80b283b 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig | |||
@@ -84,7 +84,7 @@ config 3C359 | |||
84 | 84 | ||
85 | config TMS380TR | 85 | config TMS380TR |
86 | tristate "Generic TMS380 Token Ring ISA/PCI adapter support" | 86 | tristate "Generic TMS380 Token Ring ISA/PCI adapter support" |
87 | depends on TR && (PCI || ISA && ISA_DMA_API) | 87 | depends on TR && (PCI || ISA && ISA_DMA_API || MCA) |
88 | select FW_LOADER | 88 | select FW_LOADER |
89 | ---help--- | 89 | ---help--- |
90 | This driver provides generic support for token ring adapters | 90 | This driver provides generic support for token ring adapters |
@@ -158,7 +158,7 @@ config ABYSS | |||
158 | 158 | ||
159 | config MADGEMC | 159 | config MADGEMC |
160 | tristate "Madge Smart 16/4 Ringnode MicroChannel" | 160 | tristate "Madge Smart 16/4 Ringnode MicroChannel" |
161 | depends on TR && TMS380TR && MCA_LEGACY | 161 | depends on TR && TMS380TR && MCA |
162 | help | 162 | help |
163 | This tms380 module supports the Madge Smart 16/4 MC16 and MC32 | 163 | This tms380 module supports the Madge Smart 16/4 MC16 and MC32 |
164 | MicroChannel adapters. | 164 | MicroChannel adapters. |
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c index 87103c400999..9345e68c451e 100644 --- a/drivers/net/tokenring/abyss.c +++ b/drivers/net/tokenring/abyss.c | |||
@@ -139,7 +139,7 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_ | |||
139 | */ | 139 | */ |
140 | dev->base_addr += 0x10; | 140 | dev->base_addr += 0x10; |
141 | 141 | ||
142 | ret = tmsdev_init(dev, PCI_MAX_ADDRESS, pdev); | 142 | ret = tmsdev_init(dev, &pdev->dev); |
143 | if (ret) { | 143 | if (ret) { |
144 | printk("%s: unable to get memory for dev->priv.\n", | 144 | printk("%s: unable to get memory for dev->priv.\n", |
145 | dev->name); | 145 | dev->name); |
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 659cbdbef7f3..3a25d191ea4a 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c | |||
@@ -20,7 +20,7 @@ | |||
20 | static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; | 20 | static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/mca-legacy.h> | 23 | #include <linux/mca.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
@@ -38,9 +38,7 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; | |||
38 | #define MADGEMC_IO_EXTENT 32 | 38 | #define MADGEMC_IO_EXTENT 32 |
39 | #define MADGEMC_SIF_OFFSET 0x08 | 39 | #define MADGEMC_SIF_OFFSET 0x08 |
40 | 40 | ||
41 | struct madgemc_card { | 41 | struct card_info { |
42 | struct net_device *dev; | ||
43 | |||
44 | /* | 42 | /* |
45 | * These are read from the BIA ROM. | 43 | * These are read from the BIA ROM. |
46 | */ | 44 | */ |
@@ -57,16 +55,12 @@ struct madgemc_card { | |||
57 | unsigned int arblevel:4; | 55 | unsigned int arblevel:4; |
58 | unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ | 56 | unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ |
59 | unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ | 57 | unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ |
60 | |||
61 | struct madgemc_card *next; | ||
62 | }; | 58 | }; |
63 | static struct madgemc_card *madgemc_card_list; | ||
64 | |||
65 | 59 | ||
66 | static int madgemc_open(struct net_device *dev); | 60 | static int madgemc_open(struct net_device *dev); |
67 | static int madgemc_close(struct net_device *dev); | 61 | static int madgemc_close(struct net_device *dev); |
68 | static int madgemc_chipset_init(struct net_device *dev); | 62 | static int madgemc_chipset_init(struct net_device *dev); |
69 | static void madgemc_read_rom(struct madgemc_card *card); | 63 | static void madgemc_read_rom(struct net_device *dev, struct card_info *card); |
70 | static unsigned short madgemc_setnselout_pins(struct net_device *dev); | 64 | static unsigned short madgemc_setnselout_pins(struct net_device *dev); |
71 | static void madgemc_setcabletype(struct net_device *dev, int type); | 65 | static void madgemc_setcabletype(struct net_device *dev, int type); |
72 | 66 | ||
@@ -151,261 +145,237 @@ static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsign | |||
151 | 145 | ||
152 | 146 | ||
153 | 147 | ||
154 | static int __init madgemc_probe(void) | 148 | static int __devinit madgemc_probe(struct device *device) |
155 | { | 149 | { |
156 | static int versionprinted; | 150 | static int versionprinted; |
157 | struct net_device *dev; | 151 | struct net_device *dev; |
158 | struct net_local *tp; | 152 | struct net_local *tp; |
159 | struct madgemc_card *card; | 153 | struct card_info *card; |
160 | int i,slot = 0; | 154 | struct mca_device *mdev = to_mca_device(device); |
161 | __u8 posreg[4]; | 155 | int ret = 0, i = 0; |
162 | 156 | ||
163 | if (!MCA_bus) | 157 | if (versionprinted++ == 0) |
164 | return -1; | 158 | printk("%s", version); |
165 | 159 | ||
166 | while (slot != MCA_NOTFOUND) { | 160 | if(mca_device_claimed(mdev)) |
167 | /* | 161 | return -EBUSY; |
168 | * Currently we only support the MC16/32 (MCA ID 002d) | 162 | mca_device_set_claim(mdev, 1); |
169 | */ | 163 | |
170 | slot = mca_find_unused_adapter(0x002d, slot); | 164 | dev = alloc_trdev(sizeof(struct net_local)); |
171 | if (slot == MCA_NOTFOUND) | 165 | if (!dev) { |
172 | break; | 166 | printk("madgemc: unable to allocate dev space\n"); |
173 | 167 | mca_device_set_claim(mdev, 0); | |
174 | /* | 168 | ret = -ENOMEM; |
175 | * If we get here, we have an adapter. | 169 | goto getout; |
176 | */ | 170 | } |
177 | if (versionprinted++ == 0) | ||
178 | printk("%s", version); | ||
179 | |||
180 | dev = alloc_trdev(sizeof(struct net_local)); | ||
181 | if (dev == NULL) { | ||
182 | printk("madgemc: unable to allocate dev space\n"); | ||
183 | if (madgemc_card_list) | ||
184 | return 0; | ||
185 | return -1; | ||
186 | } | ||
187 | 171 | ||
188 | SET_MODULE_OWNER(dev); | 172 | SET_MODULE_OWNER(dev); |
189 | dev->dma = 0; | 173 | dev->dma = 0; |
190 | 174 | ||
191 | /* | 175 | card = kmalloc(sizeof(struct card_info), GFP_KERNEL); |
192 | * Fetch MCA config registers | 176 | if (card==NULL) { |
193 | */ | 177 | printk("madgemc: unable to allocate card struct\n"); |
194 | for(i=0;i<4;i++) | 178 | ret = -ENOMEM; |
195 | posreg[i] = mca_read_stored_pos(slot, i+2); | 179 | goto getout1; |
196 | 180 | } | |
197 | card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL); | 181 | |
198 | if (card==NULL) { | 182 | /* |
199 | printk("madgemc: unable to allocate card struct\n"); | 183 | * Parse configuration information. This all comes |
200 | free_netdev(dev); | 184 | * directly from the publicly available @002d.ADF. |
201 | if (madgemc_card_list) | 185 | * Get it from Madge or your local ADF library. |
202 | return 0; | 186 | */ |
203 | return -1; | 187 | |
204 | } | 188 | /* |
205 | card->dev = dev; | 189 | * Base address |
206 | 190 | */ | |
207 | /* | 191 | dev->base_addr = 0x0a20 + |
208 | * Parse configuration information. This all comes | 192 | ((mdev->pos[2] & MC16_POS2_ADDR2)?0x0400:0) + |
209 | * directly from the publicly available @002d.ADF. | 193 | ((mdev->pos[0] & MC16_POS0_ADDR1)?0x1000:0) + |
210 | * Get it from Madge or your local ADF library. | 194 | ((mdev->pos[3] & MC16_POS3_ADDR3)?0x2000:0); |
211 | */ | 195 | |
212 | 196 | /* | |
213 | /* | 197 | * Interrupt line |
214 | * Base address | 198 | */ |
215 | */ | 199 | switch(mdev->pos[0] >> 6) { /* upper two bits */ |
216 | dev->base_addr = 0x0a20 + | ||
217 | ((posreg[2] & MC16_POS2_ADDR2)?0x0400:0) + | ||
218 | ((posreg[0] & MC16_POS0_ADDR1)?0x1000:0) + | ||
219 | ((posreg[3] & MC16_POS3_ADDR3)?0x2000:0); | ||
220 | |||
221 | /* | ||
222 | * Interrupt line | ||
223 | */ | ||
224 | switch(posreg[0] >> 6) { /* upper two bits */ | ||
225 | case 0x1: dev->irq = 3; break; | 200 | case 0x1: dev->irq = 3; break; |
226 | case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ | 201 | case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ |
227 | case 0x3: dev->irq = 10; break; | 202 | case 0x3: dev->irq = 10; break; |
228 | default: dev->irq = 0; break; | 203 | default: dev->irq = 0; break; |
229 | } | 204 | } |
230 | 205 | ||
231 | if (dev->irq == 0) { | 206 | if (dev->irq == 0) { |
232 | printk("%s: invalid IRQ\n", dev->name); | 207 | printk("%s: invalid IRQ\n", dev->name); |
233 | goto getout1; | 208 | ret = -EBUSY; |
234 | } | 209 | goto getout2; |
210 | } | ||
235 | 211 | ||
236 | if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, | 212 | if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, |
237 | "madgemc")) { | 213 | "madgemc")) { |
238 | printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", slot, dev->base_addr); | 214 | printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", mdev->slot, dev->base_addr); |
239 | dev->base_addr += MADGEMC_SIF_OFFSET; | ||
240 | goto getout1; | ||
241 | } | ||
242 | dev->base_addr += MADGEMC_SIF_OFFSET; | 215 | dev->base_addr += MADGEMC_SIF_OFFSET; |
216 | ret = -EBUSY; | ||
217 | goto getout2; | ||
218 | } | ||
219 | dev->base_addr += MADGEMC_SIF_OFFSET; | ||
220 | |||
221 | /* | ||
222 | * Arbitration Level | ||
223 | */ | ||
224 | card->arblevel = ((mdev->pos[0] >> 1) & 0x7) + 8; | ||
225 | |||
226 | /* | ||
227 | * Burst mode and Fairness | ||
228 | */ | ||
229 | card->burstmode = ((mdev->pos[2] >> 6) & 0x3); | ||
230 | card->fairness = ((mdev->pos[2] >> 4) & 0x1); | ||
231 | |||
232 | /* | ||
233 | * Ring Speed | ||
234 | */ | ||
235 | if ((mdev->pos[1] >> 2)&0x1) | ||
236 | card->ringspeed = 2; /* not selected */ | ||
237 | else if ((mdev->pos[2] >> 5) & 0x1) | ||
238 | card->ringspeed = 1; /* 16Mb */ | ||
239 | else | ||
240 | card->ringspeed = 0; /* 4Mb */ | ||
241 | |||
242 | /* | ||
243 | * Cable type | ||
244 | */ | ||
245 | if ((mdev->pos[1] >> 6)&0x1) | ||
246 | card->cabletype = 1; /* STP/DB9 */ | ||
247 | else | ||
248 | card->cabletype = 0; /* UTP/RJ-45 */ | ||
249 | |||
250 | |||
251 | /* | ||
252 | * ROM Info. This requires us to actually twiddle | ||
253 | * bits on the card, so we must ensure above that | ||
254 | * the base address is free of conflict (request_region above). | ||
255 | */ | ||
256 | madgemc_read_rom(dev, card); | ||
243 | 257 | ||
244 | /* | 258 | if (card->manid != 0x4d) { /* something went wrong */ |
245 | * Arbitration Level | 259 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); |
246 | */ | 260 | goto getout3; |
247 | card->arblevel = ((posreg[0] >> 1) & 0x7) + 8; | 261 | } |
248 | |||
249 | /* | ||
250 | * Burst mode and Fairness | ||
251 | */ | ||
252 | card->burstmode = ((posreg[2] >> 6) & 0x3); | ||
253 | card->fairness = ((posreg[2] >> 4) & 0x1); | ||
254 | |||
255 | /* | ||
256 | * Ring Speed | ||
257 | */ | ||
258 | if ((posreg[1] >> 2)&0x1) | ||
259 | card->ringspeed = 2; /* not selected */ | ||
260 | else if ((posreg[2] >> 5) & 0x1) | ||
261 | card->ringspeed = 1; /* 16Mb */ | ||
262 | else | ||
263 | card->ringspeed = 0; /* 4Mb */ | ||
264 | |||
265 | /* | ||
266 | * Cable type | ||
267 | */ | ||
268 | if ((posreg[1] >> 6)&0x1) | ||
269 | card->cabletype = 1; /* STP/DB9 */ | ||
270 | else | ||
271 | card->cabletype = 0; /* UTP/RJ-45 */ | ||
272 | |||
273 | |||
274 | /* | ||
275 | * ROM Info. This requires us to actually twiddle | ||
276 | * bits on the card, so we must ensure above that | ||
277 | * the base address is free of conflict (request_region above). | ||
278 | */ | ||
279 | madgemc_read_rom(card); | ||
280 | |||
281 | if (card->manid != 0x4d) { /* something went wrong */ | ||
282 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); | ||
283 | goto getout; | ||
284 | } | ||
285 | 262 | ||
286 | if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { | 263 | if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { |
287 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); | 264 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); |
288 | goto getout; | 265 | ret = -EIO; |
289 | } | 266 | goto getout3; |
267 | } | ||
290 | 268 | ||
291 | /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ | 269 | /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ |
292 | if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) | 270 | if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) |
293 | card->ramsize = 128; | 271 | card->ramsize = 128; |
294 | else | 272 | else |
295 | card->ramsize = 256; | 273 | card->ramsize = 256; |
296 | 274 | ||
297 | printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", | 275 | printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", |
298 | dev->name, | 276 | dev->name, |
299 | (card->cardtype == 0x08)?MADGEMC16_CARDNAME: | 277 | (card->cardtype == 0x08)?MADGEMC16_CARDNAME: |
300 | MADGEMC32_CARDNAME, card->cardrev, | 278 | MADGEMC32_CARDNAME, card->cardrev, |
301 | dev->base_addr, dev->irq); | 279 | dev->base_addr, dev->irq); |
302 | 280 | ||
303 | if (card->cardtype == 0x0d) | 281 | if (card->cardtype == 0x0d) |
304 | printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); | 282 | printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); |
305 | 283 | ||
306 | if (card->ringspeed==2) { /* Unknown */ | 284 | if (card->ringspeed==2) { /* Unknown */ |
307 | printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); | 285 | printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); |
308 | card->ringspeed = 1; /* default to 16mb */ | 286 | card->ringspeed = 1; /* default to 16mb */ |
309 | } | 287 | } |
310 | 288 | ||
311 | printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); | 289 | printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); |
312 | 290 | ||
313 | printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, | 291 | printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, |
314 | (card->ringspeed)?16:4, | 292 | (card->ringspeed)?16:4, |
315 | card->cabletype?"STP/DB9":"UTP/RJ-45"); | 293 | card->cabletype?"STP/DB9":"UTP/RJ-45"); |
316 | printk("%s: Arbitration Level: %d\n", dev->name, | 294 | printk("%s: Arbitration Level: %d\n", dev->name, |
317 | card->arblevel); | 295 | card->arblevel); |
318 | 296 | ||
319 | printk("%s: Burst Mode: ", dev->name); | 297 | printk("%s: Burst Mode: ", dev->name); |
320 | switch(card->burstmode) { | 298 | switch(card->burstmode) { |
321 | case 0: printk("Cycle steal"); break; | 299 | case 0: printk("Cycle steal"); break; |
322 | case 1: printk("Limited burst"); break; | 300 | case 1: printk("Limited burst"); break; |
323 | case 2: printk("Delayed release"); break; | 301 | case 2: printk("Delayed release"); break; |
324 | case 3: printk("Immediate release"); break; | 302 | case 3: printk("Immediate release"); break; |
325 | } | 303 | } |
326 | printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); | 304 | printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); |
327 | |||
328 | |||
329 | /* | ||
330 | * Enable SIF before we assign the interrupt handler, | ||
331 | * just in case we get spurious interrupts that need | ||
332 | * handling. | ||
333 | */ | ||
334 | outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ | ||
335 | madgemc_setsifsel(dev, 1); | ||
336 | if (request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ, | ||
337 | "madgemc", dev)) | ||
338 | goto getout; | ||
339 | |||
340 | madgemc_chipset_init(dev); /* enables interrupts! */ | ||
341 | madgemc_setcabletype(dev, card->cabletype); | ||
342 | 305 | ||
343 | /* Setup MCA structures */ | ||
344 | mca_set_adapter_name(slot, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); | ||
345 | mca_set_adapter_procfn(slot, madgemc_mcaproc, dev); | ||
346 | mca_mark_as_used(slot); | ||
347 | 306 | ||
348 | printk("%s: Ring Station Address: ", dev->name); | 307 | /* |
349 | printk("%2.2x", dev->dev_addr[0]); | 308 | * Enable SIF before we assign the interrupt handler, |
350 | for (i = 1; i < 6; i++) | 309 | * just in case we get spurious interrupts that need |
351 | printk(":%2.2x", dev->dev_addr[i]); | 310 | * handling. |
352 | printk("\n"); | 311 | */ |
353 | 312 | outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ | |
354 | /* XXX is ISA_MAX_ADDRESS correct here? */ | 313 | madgemc_setsifsel(dev, 1); |
355 | if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) { | 314 | if (request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ, |
356 | printk("%s: unable to get memory for dev->priv.\n", | 315 | "madgemc", dev)) { |
357 | dev->name); | 316 | ret = -EBUSY; |
358 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, | 317 | goto getout3; |
359 | MADGEMC_IO_EXTENT); | ||
360 | |||
361 | kfree(card); | ||
362 | tmsdev_term(dev); | ||
363 | free_netdev(dev); | ||
364 | if (madgemc_card_list) | ||
365 | return 0; | ||
366 | return -1; | ||
367 | } | ||
368 | tp = netdev_priv(dev); | ||
369 | |||
370 | /* | ||
371 | * The MC16 is physically a 32bit card. However, Madge | ||
372 | * insists on calling it 16bit, so I'll assume here that | ||
373 | * they know what they're talking about. Cut off DMA | ||
374 | * at 16mb. | ||
375 | */ | ||
376 | tp->setnselout = madgemc_setnselout_pins; | ||
377 | tp->sifwriteb = madgemc_sifwriteb; | ||
378 | tp->sifreadb = madgemc_sifreadb; | ||
379 | tp->sifwritew = madgemc_sifwritew; | ||
380 | tp->sifreadw = madgemc_sifreadw; | ||
381 | tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; | ||
382 | |||
383 | memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); | ||
384 | |||
385 | dev->open = madgemc_open; | ||
386 | dev->stop = madgemc_close; | ||
387 | |||
388 | if (register_netdev(dev) == 0) { | ||
389 | /* Enlist in the card list */ | ||
390 | card->next = madgemc_card_list; | ||
391 | madgemc_card_list = card; | ||
392 | slot++; | ||
393 | continue; /* successful, try to find another */ | ||
394 | } | ||
395 | |||
396 | free_irq(dev->irq, dev); | ||
397 | getout: | ||
398 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, | ||
399 | MADGEMC_IO_EXTENT); | ||
400 | getout1: | ||
401 | kfree(card); | ||
402 | free_netdev(dev); | ||
403 | slot++; | ||
404 | } | 318 | } |
405 | 319 | ||
406 | if (madgemc_card_list) | 320 | madgemc_chipset_init(dev); /* enables interrupts! */ |
321 | madgemc_setcabletype(dev, card->cabletype); | ||
322 | |||
323 | /* Setup MCA structures */ | ||
324 | mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); | ||
325 | mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev); | ||
326 | |||
327 | printk("%s: Ring Station Address: ", dev->name); | ||
328 | printk("%2.2x", dev->dev_addr[0]); | ||
329 | for (i = 1; i < 6; i++) | ||
330 | printk(":%2.2x", dev->dev_addr[i]); | ||
331 | printk("\n"); | ||
332 | |||
333 | if (tmsdev_init(dev, device)) { | ||
334 | printk("%s: unable to get memory for dev->priv.\n", | ||
335 | dev->name); | ||
336 | ret = -ENOMEM; | ||
337 | goto getout4; | ||
338 | } | ||
339 | tp = netdev_priv(dev); | ||
340 | |||
341 | /* | ||
342 | * The MC16 is physically a 32bit card. However, Madge | ||
343 | * insists on calling it 16bit, so I'll assume here that | ||
344 | * they know what they're talking about. Cut off DMA | ||
345 | * at 16mb. | ||
346 | */ | ||
347 | tp->setnselout = madgemc_setnselout_pins; | ||
348 | tp->sifwriteb = madgemc_sifwriteb; | ||
349 | tp->sifreadb = madgemc_sifreadb; | ||
350 | tp->sifwritew = madgemc_sifwritew; | ||
351 | tp->sifreadw = madgemc_sifreadw; | ||
352 | tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; | ||
353 | |||
354 | memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); | ||
355 | |||
356 | dev->open = madgemc_open; | ||
357 | dev->stop = madgemc_close; | ||
358 | |||
359 | tp->tmspriv = card; | ||
360 | dev_set_drvdata(device, dev); | ||
361 | |||
362 | if (register_netdev(dev) == 0) | ||
407 | return 0; | 363 | return 0; |
408 | return -1; | 364 | |
365 | dev_set_drvdata(device, NULL); | ||
366 | ret = -ENOMEM; | ||
367 | getout4: | ||
368 | free_irq(dev->irq, dev); | ||
369 | getout3: | ||
370 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, | ||
371 | MADGEMC_IO_EXTENT); | ||
372 | getout2: | ||
373 | kfree(card); | ||
374 | getout1: | ||
375 | free_netdev(dev); | ||
376 | getout: | ||
377 | mca_device_set_claim(mdev, 0); | ||
378 | return ret; | ||
409 | } | 379 | } |
410 | 380 | ||
411 | /* | 381 | /* |
@@ -664,12 +634,12 @@ static void madgemc_chipset_close(struct net_device *dev) | |||
664 | * is complete. | 634 | * is complete. |
665 | * | 635 | * |
666 | */ | 636 | */ |
667 | static void madgemc_read_rom(struct madgemc_card *card) | 637 | static void madgemc_read_rom(struct net_device *dev, struct card_info *card) |
668 | { | 638 | { |
669 | unsigned long ioaddr; | 639 | unsigned long ioaddr; |
670 | unsigned char reg0, reg1, tmpreg0, i; | 640 | unsigned char reg0, reg1, tmpreg0, i; |
671 | 641 | ||
672 | ioaddr = card->dev->base_addr; | 642 | ioaddr = dev->base_addr; |
673 | 643 | ||
674 | reg0 = inb(ioaddr + MC_CONTROL_REG0); | 644 | reg0 = inb(ioaddr + MC_CONTROL_REG0); |
675 | reg1 = inb(ioaddr + MC_CONTROL_REG1); | 645 | reg1 = inb(ioaddr + MC_CONTROL_REG1); |
@@ -686,9 +656,9 @@ static void madgemc_read_rom(struct madgemc_card *card) | |||
686 | outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); | 656 | outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); |
687 | 657 | ||
688 | /* Read BIA */ | 658 | /* Read BIA */ |
689 | card->dev->addr_len = 6; | 659 | dev->addr_len = 6; |
690 | for (i = 0; i < 6; i++) | 660 | for (i = 0; i < 6; i++) |
691 | card->dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); | 661 | dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); |
692 | 662 | ||
693 | /* Restore original register values */ | 663 | /* Restore original register values */ |
694 | outb(reg0, ioaddr + MC_CONTROL_REG0); | 664 | outb(reg0, ioaddr + MC_CONTROL_REG0); |
@@ -721,14 +691,10 @@ static int madgemc_close(struct net_device *dev) | |||
721 | static int madgemc_mcaproc(char *buf, int slot, void *d) | 691 | static int madgemc_mcaproc(char *buf, int slot, void *d) |
722 | { | 692 | { |
723 | struct net_device *dev = (struct net_device *)d; | 693 | struct net_device *dev = (struct net_device *)d; |
724 | struct madgemc_card *curcard = madgemc_card_list; | 694 | struct net_local *tp = dev->priv; |
695 | struct card_info *curcard = tp->tmspriv; | ||
725 | int len = 0; | 696 | int len = 0; |
726 | 697 | ||
727 | while (curcard) { /* search for card struct */ | ||
728 | if (curcard->dev == dev) | ||
729 | break; | ||
730 | curcard = curcard->next; | ||
731 | } | ||
732 | len += sprintf(buf+len, "-------\n"); | 698 | len += sprintf(buf+len, "-------\n"); |
733 | if (curcard) { | 699 | if (curcard) { |
734 | struct net_local *tp = netdev_priv(dev); | 700 | struct net_local *tp = netdev_priv(dev); |
@@ -763,25 +729,56 @@ static int madgemc_mcaproc(char *buf, int slot, void *d) | |||
763 | return len; | 729 | return len; |
764 | } | 730 | } |
765 | 731 | ||
766 | static void __exit madgemc_exit(void) | 732 | static int __devexit madgemc_remove(struct device *device) |
767 | { | 733 | { |
768 | struct net_device *dev; | 734 | struct net_device *dev = dev_get_drvdata(device); |
769 | struct madgemc_card *this_card; | 735 | struct net_local *tp; |
770 | 736 | struct card_info *card; | |
771 | while (madgemc_card_list) { | 737 | |
772 | dev = madgemc_card_list->dev; | 738 | if (!dev) |
773 | unregister_netdev(dev); | 739 | BUG(); |
774 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); | 740 | |
775 | free_irq(dev->irq, dev); | 741 | tp = dev->priv; |
776 | tmsdev_term(dev); | 742 | card = tp->tmspriv; |
777 | free_netdev(dev); | 743 | kfree(card); |
778 | this_card = madgemc_card_list; | 744 | tp->tmspriv = NULL; |
779 | madgemc_card_list = this_card->next; | 745 | |
780 | kfree(this_card); | 746 | unregister_netdev(dev); |
781 | } | 747 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); |
748 | free_irq(dev->irq, dev); | ||
749 | tmsdev_term(dev); | ||
750 | free_netdev(dev); | ||
751 | dev_set_drvdata(device, NULL); | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static short madgemc_adapter_ids[] __initdata = { | ||
757 | 0x002d, | ||
758 | 0x0000 | ||
759 | }; | ||
760 | |||
761 | static struct mca_driver madgemc_driver = { | ||
762 | .id_table = madgemc_adapter_ids, | ||
763 | .driver = { | ||
764 | .name = "madgemc", | ||
765 | .bus = &mca_bus_type, | ||
766 | .probe = madgemc_probe, | ||
767 | .remove = __devexit_p(madgemc_remove), | ||
768 | }, | ||
769 | }; | ||
770 | |||
771 | static int __init madgemc_init (void) | ||
772 | { | ||
773 | return mca_register_driver (&madgemc_driver); | ||
774 | } | ||
775 | |||
776 | static void __exit madgemc_exit (void) | ||
777 | { | ||
778 | mca_unregister_driver (&madgemc_driver); | ||
782 | } | 779 | } |
783 | 780 | ||
784 | module_init(madgemc_probe); | 781 | module_init(madgemc_init); |
785 | module_exit(madgemc_exit); | 782 | module_exit(madgemc_exit); |
786 | 783 | ||
787 | MODULE_LICENSE("GPL"); | 784 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 40ad0fde28af..eb1423ede75c 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c | |||
@@ -62,8 +62,7 @@ static int dmalist[] __initdata = { | |||
62 | }; | 62 | }; |
63 | 63 | ||
64 | static char cardname[] = "Proteon 1392\0"; | 64 | static char cardname[] = "Proteon 1392\0"; |
65 | 65 | static u64 dma_mask = ISA_MAX_ADDRESS; | |
66 | struct net_device *proteon_probe(int unit); | ||
67 | static int proteon_open(struct net_device *dev); | 66 | static int proteon_open(struct net_device *dev); |
68 | static void proteon_read_eeprom(struct net_device *dev); | 67 | static void proteon_read_eeprom(struct net_device *dev); |
69 | static unsigned short proteon_setnselout_pins(struct net_device *dev); | 68 | static unsigned short proteon_setnselout_pins(struct net_device *dev); |
@@ -116,7 +115,7 @@ nodev: | |||
116 | return -ENODEV; | 115 | return -ENODEV; |
117 | } | 116 | } |
118 | 117 | ||
119 | static int __init setup_card(struct net_device *dev) | 118 | static int __init setup_card(struct net_device *dev, struct device *pdev) |
120 | { | 119 | { |
121 | struct net_local *tp; | 120 | struct net_local *tp; |
122 | static int versionprinted; | 121 | static int versionprinted; |
@@ -137,7 +136,7 @@ static int __init setup_card(struct net_device *dev) | |||
137 | } | 136 | } |
138 | } | 137 | } |
139 | if (err) | 138 | if (err) |
140 | goto out4; | 139 | goto out5; |
141 | 140 | ||
142 | /* At this point we have found a valid card. */ | 141 | /* At this point we have found a valid card. */ |
143 | 142 | ||
@@ -145,14 +144,15 @@ static int __init setup_card(struct net_device *dev) | |||
145 | printk(KERN_DEBUG "%s", version); | 144 | printk(KERN_DEBUG "%s", version); |
146 | 145 | ||
147 | err = -EIO; | 146 | err = -EIO; |
148 | if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) | 147 | pdev->dma_mask = &dma_mask; |
148 | if (tmsdev_init(dev, pdev)) | ||
149 | goto out4; | 149 | goto out4; |
150 | 150 | ||
151 | dev->base_addr &= ~3; | 151 | dev->base_addr &= ~3; |
152 | 152 | ||
153 | proteon_read_eeprom(dev); | 153 | proteon_read_eeprom(dev); |
154 | 154 | ||
155 | printk(KERN_DEBUG "%s: Ring Station Address: ", dev->name); | 155 | printk(KERN_DEBUG "proteon.c: Ring Station Address: "); |
156 | printk("%2.2x", dev->dev_addr[0]); | 156 | printk("%2.2x", dev->dev_addr[0]); |
157 | for (j = 1; j < 6; j++) | 157 | for (j = 1; j < 6; j++) |
158 | printk(":%2.2x", dev->dev_addr[j]); | 158 | printk(":%2.2x", dev->dev_addr[j]); |
@@ -185,7 +185,7 @@ static int __init setup_card(struct net_device *dev) | |||
185 | 185 | ||
186 | if(irqlist[j] == 0) | 186 | if(irqlist[j] == 0) |
187 | { | 187 | { |
188 | printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name); | 188 | printk(KERN_INFO "proteon.c: AutoSelect no IRQ available\n"); |
189 | goto out3; | 189 | goto out3; |
190 | } | 190 | } |
191 | } | 191 | } |
@@ -196,15 +196,15 @@ static int __init setup_card(struct net_device *dev) | |||
196 | break; | 196 | break; |
197 | if (irqlist[j] == 0) | 197 | if (irqlist[j] == 0) |
198 | { | 198 | { |
199 | printk(KERN_INFO "%s: Illegal IRQ %d specified\n", | 199 | printk(KERN_INFO "proteon.c: Illegal IRQ %d specified\n", |
200 | dev->name, dev->irq); | 200 | dev->irq); |
201 | goto out3; | 201 | goto out3; |
202 | } | 202 | } |
203 | if (request_irq(dev->irq, tms380tr_interrupt, 0, | 203 | if (request_irq(dev->irq, tms380tr_interrupt, 0, |
204 | cardname, dev)) | 204 | cardname, dev)) |
205 | { | 205 | { |
206 | printk(KERN_INFO "%s: Selected IRQ %d not available\n", | 206 | printk(KERN_INFO "proteon.c: Selected IRQ %d not available\n", |
207 | dev->name, dev->irq); | 207 | dev->irq); |
208 | goto out3; | 208 | goto out3; |
209 | } | 209 | } |
210 | } | 210 | } |
@@ -220,7 +220,7 @@ static int __init setup_card(struct net_device *dev) | |||
220 | 220 | ||
221 | if(dmalist[j] == 0) | 221 | if(dmalist[j] == 0) |
222 | { | 222 | { |
223 | printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name); | 223 | printk(KERN_INFO "proteon.c: AutoSelect no DMA available\n"); |
224 | goto out2; | 224 | goto out2; |
225 | } | 225 | } |
226 | } | 226 | } |
@@ -231,25 +231,25 @@ static int __init setup_card(struct net_device *dev) | |||
231 | break; | 231 | break; |
232 | if (dmalist[j] == 0) | 232 | if (dmalist[j] == 0) |
233 | { | 233 | { |
234 | printk(KERN_INFO "%s: Illegal DMA %d specified\n", | 234 | printk(KERN_INFO "proteon.c: Illegal DMA %d specified\n", |
235 | dev->name, dev->dma); | 235 | dev->dma); |
236 | goto out2; | 236 | goto out2; |
237 | } | 237 | } |
238 | if (request_dma(dev->dma, cardname)) | 238 | if (request_dma(dev->dma, cardname)) |
239 | { | 239 | { |
240 | printk(KERN_INFO "%s: Selected DMA %d not available\n", | 240 | printk(KERN_INFO "proteon.c: Selected DMA %d not available\n", |
241 | dev->name, dev->dma); | 241 | dev->dma); |
242 | goto out2; | 242 | goto out2; |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
247 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
248 | |||
249 | err = register_netdev(dev); | 246 | err = register_netdev(dev); |
250 | if (err) | 247 | if (err) |
251 | goto out; | 248 | goto out; |
252 | 249 | ||
250 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
251 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
252 | |||
253 | return 0; | 253 | return 0; |
254 | out: | 254 | out: |
255 | free_dma(dev->dma); | 255 | free_dma(dev->dma); |
@@ -258,34 +258,11 @@ out2: | |||
258 | out3: | 258 | out3: |
259 | tmsdev_term(dev); | 259 | tmsdev_term(dev); |
260 | out4: | 260 | out4: |
261 | release_region(dev->base_addr, PROTEON_IO_EXTENT); | 261 | release_region(dev->base_addr, PROTEON_IO_EXTENT); |
262 | out5: | ||
262 | return err; | 263 | return err; |
263 | } | 264 | } |
264 | 265 | ||
265 | struct net_device * __init proteon_probe(int unit) | ||
266 | { | ||
267 | struct net_device *dev = alloc_trdev(sizeof(struct net_local)); | ||
268 | int err = 0; | ||
269 | |||
270 | if (!dev) | ||
271 | return ERR_PTR(-ENOMEM); | ||
272 | |||
273 | if (unit >= 0) { | ||
274 | sprintf(dev->name, "tr%d", unit); | ||
275 | netdev_boot_setup_check(dev); | ||
276 | } | ||
277 | |||
278 | err = setup_card(dev); | ||
279 | if (err) | ||
280 | goto out; | ||
281 | |||
282 | return dev; | ||
283 | |||
284 | out: | ||
285 | free_netdev(dev); | ||
286 | return ERR_PTR(err); | ||
287 | } | ||
288 | |||
289 | /* | 266 | /* |
290 | * Reads MAC address from adapter RAM, which should've read it from | 267 | * Reads MAC address from adapter RAM, which should've read it from |
291 | * the onboard ROM. | 268 | * the onboard ROM. |
@@ -352,8 +329,6 @@ static int proteon_open(struct net_device *dev) | |||
352 | return tms380tr_open(dev); | 329 | return tms380tr_open(dev); |
353 | } | 330 | } |
354 | 331 | ||
355 | #ifdef MODULE | ||
356 | |||
357 | #define ISATR_MAX_ADAPTERS 3 | 332 | #define ISATR_MAX_ADAPTERS 3 |
358 | 333 | ||
359 | static int io[ISATR_MAX_ADAPTERS]; | 334 | static int io[ISATR_MAX_ADAPTERS]; |
@@ -366,13 +341,23 @@ module_param_array(io, int, NULL, 0); | |||
366 | module_param_array(irq, int, NULL, 0); | 341 | module_param_array(irq, int, NULL, 0); |
367 | module_param_array(dma, int, NULL, 0); | 342 | module_param_array(dma, int, NULL, 0); |
368 | 343 | ||
369 | static struct net_device *proteon_dev[ISATR_MAX_ADAPTERS]; | 344 | static struct platform_device *proteon_dev[ISATR_MAX_ADAPTERS]; |
345 | |||
346 | static struct device_driver proteon_driver = { | ||
347 | .name = "proteon", | ||
348 | .bus = &platform_bus_type, | ||
349 | }; | ||
370 | 350 | ||
371 | int init_module(void) | 351 | static int __init proteon_init(void) |
372 | { | 352 | { |
373 | struct net_device *dev; | 353 | struct net_device *dev; |
354 | struct platform_device *pdev; | ||
374 | int i, num = 0, err = 0; | 355 | int i, num = 0, err = 0; |
375 | 356 | ||
357 | err = driver_register(&proteon_driver); | ||
358 | if (err) | ||
359 | return err; | ||
360 | |||
376 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 361 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
377 | dev = alloc_trdev(sizeof(struct net_local)); | 362 | dev = alloc_trdev(sizeof(struct net_local)); |
378 | if (!dev) | 363 | if (!dev) |
@@ -381,11 +366,15 @@ int init_module(void) | |||
381 | dev->base_addr = io[i]; | 366 | dev->base_addr = io[i]; |
382 | dev->irq = irq[i]; | 367 | dev->irq = irq[i]; |
383 | dev->dma = dma[i]; | 368 | dev->dma = dma[i]; |
384 | err = setup_card(dev); | 369 | pdev = platform_device_register_simple("proteon", |
370 | i, NULL, 0); | ||
371 | err = setup_card(dev, &pdev->dev); | ||
385 | if (!err) { | 372 | if (!err) { |
386 | proteon_dev[i] = dev; | 373 | proteon_dev[i] = pdev; |
374 | dev_set_drvdata(&pdev->dev, dev); | ||
387 | ++num; | 375 | ++num; |
388 | } else { | 376 | } else { |
377 | platform_device_unregister(pdev); | ||
389 | free_netdev(dev); | 378 | free_netdev(dev); |
390 | } | 379 | } |
391 | } | 380 | } |
@@ -399,23 +388,28 @@ int init_module(void) | |||
399 | return (0); | 388 | return (0); |
400 | } | 389 | } |
401 | 390 | ||
402 | void cleanup_module(void) | 391 | static void __exit proteon_cleanup(void) |
403 | { | 392 | { |
393 | struct net_device *dev; | ||
404 | int i; | 394 | int i; |
405 | 395 | ||
406 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 396 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
407 | struct net_device *dev = proteon_dev[i]; | 397 | struct platform_device *pdev = proteon_dev[i]; |
408 | 398 | ||
409 | if (!dev) | 399 | if (!pdev) |
410 | continue; | 400 | continue; |
411 | 401 | dev = dev_get_drvdata(&pdev->dev); | |
412 | unregister_netdev(dev); | 402 | unregister_netdev(dev); |
413 | release_region(dev->base_addr, PROTEON_IO_EXTENT); | 403 | release_region(dev->base_addr, PROTEON_IO_EXTENT); |
414 | free_irq(dev->irq, dev); | 404 | free_irq(dev->irq, dev); |
415 | free_dma(dev->dma); | 405 | free_dma(dev->dma); |
416 | tmsdev_term(dev); | 406 | tmsdev_term(dev); |
417 | free_netdev(dev); | 407 | free_netdev(dev); |
408 | dev_set_drvdata(&pdev->dev, NULL); | ||
409 | platform_device_unregister(pdev); | ||
418 | } | 410 | } |
411 | driver_unregister(&proteon_driver); | ||
419 | } | 412 | } |
420 | #endif /* MODULE */ | ||
421 | 413 | ||
414 | module_init(proteon_init); | ||
415 | module_exit(proteon_cleanup); | ||
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index f26796e2d0e5..3c7c66204f74 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c | |||
@@ -68,8 +68,7 @@ static int dmalist[] __initdata = { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | static char isa_cardname[] = "SK NET TR 4/16 ISA\0"; | 70 | static char isa_cardname[] = "SK NET TR 4/16 ISA\0"; |
71 | 71 | static u64 dma_mask = ISA_MAX_ADDRESS; | |
72 | struct net_device *sk_isa_probe(int unit); | ||
73 | static int sk_isa_open(struct net_device *dev); | 72 | static int sk_isa_open(struct net_device *dev); |
74 | static void sk_isa_read_eeprom(struct net_device *dev); | 73 | static void sk_isa_read_eeprom(struct net_device *dev); |
75 | static unsigned short sk_isa_setnselout_pins(struct net_device *dev); | 74 | static unsigned short sk_isa_setnselout_pins(struct net_device *dev); |
@@ -133,7 +132,7 @@ static int __init sk_isa_probe1(struct net_device *dev, int ioaddr) | |||
133 | return 0; | 132 | return 0; |
134 | } | 133 | } |
135 | 134 | ||
136 | static int __init setup_card(struct net_device *dev) | 135 | static int __init setup_card(struct net_device *dev, struct device *pdev) |
137 | { | 136 | { |
138 | struct net_local *tp; | 137 | struct net_local *tp; |
139 | static int versionprinted; | 138 | static int versionprinted; |
@@ -154,7 +153,7 @@ static int __init setup_card(struct net_device *dev) | |||
154 | } | 153 | } |
155 | } | 154 | } |
156 | if (err) | 155 | if (err) |
157 | goto out4; | 156 | goto out5; |
158 | 157 | ||
159 | /* At this point we have found a valid card. */ | 158 | /* At this point we have found a valid card. */ |
160 | 159 | ||
@@ -162,14 +161,15 @@ static int __init setup_card(struct net_device *dev) | |||
162 | printk(KERN_DEBUG "%s", version); | 161 | printk(KERN_DEBUG "%s", version); |
163 | 162 | ||
164 | err = -EIO; | 163 | err = -EIO; |
165 | if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) | 164 | pdev->dma_mask = &dma_mask; |
165 | if (tmsdev_init(dev, pdev)) | ||
166 | goto out4; | 166 | goto out4; |
167 | 167 | ||
168 | dev->base_addr &= ~3; | 168 | dev->base_addr &= ~3; |
169 | 169 | ||
170 | sk_isa_read_eeprom(dev); | 170 | sk_isa_read_eeprom(dev); |
171 | 171 | ||
172 | printk(KERN_DEBUG "%s: Ring Station Address: ", dev->name); | 172 | printk(KERN_DEBUG "skisa.c: Ring Station Address: "); |
173 | printk("%2.2x", dev->dev_addr[0]); | 173 | printk("%2.2x", dev->dev_addr[0]); |
174 | for (j = 1; j < 6; j++) | 174 | for (j = 1; j < 6; j++) |
175 | printk(":%2.2x", dev->dev_addr[j]); | 175 | printk(":%2.2x", dev->dev_addr[j]); |
@@ -202,7 +202,7 @@ static int __init setup_card(struct net_device *dev) | |||
202 | 202 | ||
203 | if(irqlist[j] == 0) | 203 | if(irqlist[j] == 0) |
204 | { | 204 | { |
205 | printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name); | 205 | printk(KERN_INFO "skisa.c: AutoSelect no IRQ available\n"); |
206 | goto out3; | 206 | goto out3; |
207 | } | 207 | } |
208 | } | 208 | } |
@@ -213,15 +213,15 @@ static int __init setup_card(struct net_device *dev) | |||
213 | break; | 213 | break; |
214 | if (irqlist[j] == 0) | 214 | if (irqlist[j] == 0) |
215 | { | 215 | { |
216 | printk(KERN_INFO "%s: Illegal IRQ %d specified\n", | 216 | printk(KERN_INFO "skisa.c: Illegal IRQ %d specified\n", |
217 | dev->name, dev->irq); | 217 | dev->irq); |
218 | goto out3; | 218 | goto out3; |
219 | } | 219 | } |
220 | if (request_irq(dev->irq, tms380tr_interrupt, 0, | 220 | if (request_irq(dev->irq, tms380tr_interrupt, 0, |
221 | isa_cardname, dev)) | 221 | isa_cardname, dev)) |
222 | { | 222 | { |
223 | printk(KERN_INFO "%s: Selected IRQ %d not available\n", | 223 | printk(KERN_INFO "skisa.c: Selected IRQ %d not available\n", |
224 | dev->name, dev->irq); | 224 | dev->irq); |
225 | goto out3; | 225 | goto out3; |
226 | } | 226 | } |
227 | } | 227 | } |
@@ -237,7 +237,7 @@ static int __init setup_card(struct net_device *dev) | |||
237 | 237 | ||
238 | if(dmalist[j] == 0) | 238 | if(dmalist[j] == 0) |
239 | { | 239 | { |
240 | printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name); | 240 | printk(KERN_INFO "skisa.c: AutoSelect no DMA available\n"); |
241 | goto out2; | 241 | goto out2; |
242 | } | 242 | } |
243 | } | 243 | } |
@@ -248,25 +248,25 @@ static int __init setup_card(struct net_device *dev) | |||
248 | break; | 248 | break; |
249 | if (dmalist[j] == 0) | 249 | if (dmalist[j] == 0) |
250 | { | 250 | { |
251 | printk(KERN_INFO "%s: Illegal DMA %d specified\n", | 251 | printk(KERN_INFO "skisa.c: Illegal DMA %d specified\n", |
252 | dev->name, dev->dma); | 252 | dev->dma); |
253 | goto out2; | 253 | goto out2; |
254 | } | 254 | } |
255 | if (request_dma(dev->dma, isa_cardname)) | 255 | if (request_dma(dev->dma, isa_cardname)) |
256 | { | 256 | { |
257 | printk(KERN_INFO "%s: Selected DMA %d not available\n", | 257 | printk(KERN_INFO "skisa.c: Selected DMA %d not available\n", |
258 | dev->name, dev->dma); | 258 | dev->dma); |
259 | goto out2; | 259 | goto out2; |
260 | } | 260 | } |
261 | } | 261 | } |
262 | 262 | ||
263 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
264 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
265 | |||
266 | err = register_netdev(dev); | 263 | err = register_netdev(dev); |
267 | if (err) | 264 | if (err) |
268 | goto out; | 265 | goto out; |
269 | 266 | ||
267 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
268 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
269 | |||
270 | return 0; | 270 | return 0; |
271 | out: | 271 | out: |
272 | free_dma(dev->dma); | 272 | free_dma(dev->dma); |
@@ -275,33 +275,11 @@ out2: | |||
275 | out3: | 275 | out3: |
276 | tmsdev_term(dev); | 276 | tmsdev_term(dev); |
277 | out4: | 277 | out4: |
278 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); | 278 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); |
279 | out5: | ||
279 | return err; | 280 | return err; |
280 | } | 281 | } |
281 | 282 | ||
282 | struct net_device * __init sk_isa_probe(int unit) | ||
283 | { | ||
284 | struct net_device *dev = alloc_trdev(sizeof(struct net_local)); | ||
285 | int err = 0; | ||
286 | |||
287 | if (!dev) | ||
288 | return ERR_PTR(-ENOMEM); | ||
289 | |||
290 | if (unit >= 0) { | ||
291 | sprintf(dev->name, "tr%d", unit); | ||
292 | netdev_boot_setup_check(dev); | ||
293 | } | ||
294 | |||
295 | err = setup_card(dev); | ||
296 | if (err) | ||
297 | goto out; | ||
298 | |||
299 | return dev; | ||
300 | out: | ||
301 | free_netdev(dev); | ||
302 | return ERR_PTR(err); | ||
303 | } | ||
304 | |||
305 | /* | 283 | /* |
306 | * Reads MAC address from adapter RAM, which should've read it from | 284 | * Reads MAC address from adapter RAM, which should've read it from |
307 | * the onboard ROM. | 285 | * the onboard ROM. |
@@ -361,8 +339,6 @@ static int sk_isa_open(struct net_device *dev) | |||
361 | return tms380tr_open(dev); | 339 | return tms380tr_open(dev); |
362 | } | 340 | } |
363 | 341 | ||
364 | #ifdef MODULE | ||
365 | |||
366 | #define ISATR_MAX_ADAPTERS 3 | 342 | #define ISATR_MAX_ADAPTERS 3 |
367 | 343 | ||
368 | static int io[ISATR_MAX_ADAPTERS]; | 344 | static int io[ISATR_MAX_ADAPTERS]; |
@@ -375,13 +351,23 @@ module_param_array(io, int, NULL, 0); | |||
375 | module_param_array(irq, int, NULL, 0); | 351 | module_param_array(irq, int, NULL, 0); |
376 | module_param_array(dma, int, NULL, 0); | 352 | module_param_array(dma, int, NULL, 0); |
377 | 353 | ||
378 | static struct net_device *sk_isa_dev[ISATR_MAX_ADAPTERS]; | 354 | static struct platform_device *sk_isa_dev[ISATR_MAX_ADAPTERS]; |
379 | 355 | ||
380 | int init_module(void) | 356 | static struct device_driver sk_isa_driver = { |
357 | .name = "skisa", | ||
358 | .bus = &platform_bus_type, | ||
359 | }; | ||
360 | |||
361 | static int __init sk_isa_init(void) | ||
381 | { | 362 | { |
382 | struct net_device *dev; | 363 | struct net_device *dev; |
364 | struct platform_device *pdev; | ||
383 | int i, num = 0, err = 0; | 365 | int i, num = 0, err = 0; |
384 | 366 | ||
367 | err = driver_register(&sk_isa_driver); | ||
368 | if (err) | ||
369 | return err; | ||
370 | |||
385 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 371 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
386 | dev = alloc_trdev(sizeof(struct net_local)); | 372 | dev = alloc_trdev(sizeof(struct net_local)); |
387 | if (!dev) | 373 | if (!dev) |
@@ -390,12 +376,15 @@ int init_module(void) | |||
390 | dev->base_addr = io[i]; | 376 | dev->base_addr = io[i]; |
391 | dev->irq = irq[i]; | 377 | dev->irq = irq[i]; |
392 | dev->dma = dma[i]; | 378 | dev->dma = dma[i]; |
393 | err = setup_card(dev); | 379 | pdev = platform_device_register_simple("skisa", |
394 | 380 | i, NULL, 0); | |
381 | err = setup_card(dev, &pdev->dev); | ||
395 | if (!err) { | 382 | if (!err) { |
396 | sk_isa_dev[i] = dev; | 383 | sk_isa_dev[i] = pdev; |
384 | dev_set_drvdata(&sk_isa_dev[i]->dev, dev); | ||
397 | ++num; | 385 | ++num; |
398 | } else { | 386 | } else { |
387 | platform_device_unregister(pdev); | ||
399 | free_netdev(dev); | 388 | free_netdev(dev); |
400 | } | 389 | } |
401 | } | 390 | } |
@@ -409,23 +398,28 @@ int init_module(void) | |||
409 | return (0); | 398 | return (0); |
410 | } | 399 | } |
411 | 400 | ||
412 | void cleanup_module(void) | 401 | static void __exit sk_isa_cleanup(void) |
413 | { | 402 | { |
403 | struct net_device *dev; | ||
414 | int i; | 404 | int i; |
415 | 405 | ||
416 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 406 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
417 | struct net_device *dev = sk_isa_dev[i]; | 407 | struct platform_device *pdev = sk_isa_dev[i]; |
418 | 408 | ||
419 | if (!dev) | 409 | if (!pdev) |
420 | continue; | 410 | continue; |
421 | 411 | dev = dev_get_drvdata(&pdev->dev); | |
422 | unregister_netdev(dev); | 412 | unregister_netdev(dev); |
423 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); | 413 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); |
424 | free_irq(dev->irq, dev); | 414 | free_irq(dev->irq, dev); |
425 | free_dma(dev->dma); | 415 | free_dma(dev->dma); |
426 | tmsdev_term(dev); | 416 | tmsdev_term(dev); |
427 | free_netdev(dev); | 417 | free_netdev(dev); |
418 | dev_set_drvdata(&pdev->dev, NULL); | ||
419 | platform_device_unregister(pdev); | ||
428 | } | 420 | } |
421 | driver_unregister(&sk_isa_driver); | ||
429 | } | 422 | } |
430 | #endif /* MODULE */ | ||
431 | 423 | ||
424 | module_init(sk_isa_init); | ||
425 | module_exit(sk_isa_cleanup); | ||
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 5e0b0ce98ed7..2e39bf1f7462 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c | |||
@@ -62,6 +62,7 @@ | |||
62 | * normal operation. | 62 | * normal operation. |
63 | * 30-Dec-02 JF Removed incorrect __init from | 63 | * 30-Dec-02 JF Removed incorrect __init from |
64 | * tms380tr_init_card. | 64 | * tms380tr_init_card. |
65 | * 22-Jul-05 JF Converted to dma-mapping. | ||
65 | * | 66 | * |
66 | * To do: | 67 | * To do: |
67 | * 1. Multi/Broadcast packet handling (this may have fixed itself) | 68 | * 1. Multi/Broadcast packet handling (this may have fixed itself) |
@@ -89,7 +90,7 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A | |||
89 | #include <linux/time.h> | 90 | #include <linux/time.h> |
90 | #include <linux/errno.h> | 91 | #include <linux/errno.h> |
91 | #include <linux/init.h> | 92 | #include <linux/init.h> |
92 | #include <linux/pci.h> | 93 | #include <linux/dma-mapping.h> |
93 | #include <linux/delay.h> | 94 | #include <linux/delay.h> |
94 | #include <linux/netdevice.h> | 95 | #include <linux/netdevice.h> |
95 | #include <linux/etherdevice.h> | 96 | #include <linux/etherdevice.h> |
@@ -114,8 +115,6 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A | |||
114 | #endif | 115 | #endif |
115 | static unsigned int tms380tr_debug = TMS380TR_DEBUG; | 116 | static unsigned int tms380tr_debug = TMS380TR_DEBUG; |
116 | 117 | ||
117 | static struct device tms_device; | ||
118 | |||
119 | /* Index to functions, as function prototypes. | 118 | /* Index to functions, as function prototypes. |
120 | * Alphabetical by function name. | 119 | * Alphabetical by function name. |
121 | */ | 120 | */ |
@@ -434,7 +433,7 @@ static void tms380tr_init_net_local(struct net_device *dev) | |||
434 | skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); | 433 | skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); |
435 | 434 | ||
436 | /* data unreachable for DMA ? then use local buffer */ | 435 | /* data unreachable for DMA ? then use local buffer */ |
437 | dmabuf = pci_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, PCI_DMA_FROMDEVICE); | 436 | dmabuf = dma_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); |
438 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) | 437 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) |
439 | { | 438 | { |
440 | tp->Rpl[i].SkbStat = SKB_DATA_COPY; | 439 | tp->Rpl[i].SkbStat = SKB_DATA_COPY; |
@@ -638,10 +637,10 @@ static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device | |||
638 | /* Is buffer reachable for Busmaster-DMA? */ | 637 | /* Is buffer reachable for Busmaster-DMA? */ |
639 | 638 | ||
640 | length = skb->len; | 639 | length = skb->len; |
641 | dmabuf = pci_map_single(tp->pdev, skb->data, length, PCI_DMA_TODEVICE); | 640 | dmabuf = dma_map_single(tp->pdev, skb->data, length, DMA_TO_DEVICE); |
642 | if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) { | 641 | if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) { |
643 | /* Copy frame to local buffer */ | 642 | /* Copy frame to local buffer */ |
644 | pci_unmap_single(tp->pdev, dmabuf, length, PCI_DMA_TODEVICE); | 643 | dma_unmap_single(tp->pdev, dmabuf, length, DMA_TO_DEVICE); |
645 | dmabuf = 0; | 644 | dmabuf = 0; |
646 | i = tp->TplFree->TPLIndex; | 645 | i = tp->TplFree->TPLIndex; |
647 | buf = tp->LocalTxBuffers[i]; | 646 | buf = tp->LocalTxBuffers[i]; |
@@ -1284,9 +1283,7 @@ static int tms380tr_reset_adapter(struct net_device *dev) | |||
1284 | unsigned short count, c, count2; | 1283 | unsigned short count, c, count2; |
1285 | const struct firmware *fw_entry = NULL; | 1284 | const struct firmware *fw_entry = NULL; |
1286 | 1285 | ||
1287 | strncpy(tms_device.bus_id,dev->name, BUS_ID_SIZE); | 1286 | if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { |
1288 | |||
1289 | if (request_firmware(&fw_entry, "tms380tr.bin", &tms_device) != 0) { | ||
1290 | printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", | 1287 | printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", |
1291 | dev->name, "tms380tr.bin"); | 1288 | dev->name, "tms380tr.bin"); |
1292 | return (-1); | 1289 | return (-1); |
@@ -2021,7 +2018,7 @@ static void tms380tr_cancel_tx_queue(struct net_local* tp) | |||
2021 | 2018 | ||
2022 | printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl); | 2019 | printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl); |
2023 | if (tpl->DMABuff) | 2020 | if (tpl->DMABuff) |
2024 | pci_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, PCI_DMA_TODEVICE); | 2021 | dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); |
2025 | dev_kfree_skb_any(tpl->Skb); | 2022 | dev_kfree_skb_any(tpl->Skb); |
2026 | } | 2023 | } |
2027 | 2024 | ||
@@ -2090,7 +2087,7 @@ static void tms380tr_tx_status_irq(struct net_device *dev) | |||
2090 | 2087 | ||
2091 | tp->MacStat.tx_packets++; | 2088 | tp->MacStat.tx_packets++; |
2092 | if (tpl->DMABuff) | 2089 | if (tpl->DMABuff) |
2093 | pci_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, PCI_DMA_TODEVICE); | 2090 | dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); |
2094 | dev_kfree_skb_irq(tpl->Skb); | 2091 | dev_kfree_skb_irq(tpl->Skb); |
2095 | tpl->BusyFlag = 0; /* "free" TPL */ | 2092 | tpl->BusyFlag = 0; /* "free" TPL */ |
2096 | } | 2093 | } |
@@ -2209,7 +2206,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev) | |||
2209 | tp->MacStat.rx_errors++; | 2206 | tp->MacStat.rx_errors++; |
2210 | } | 2207 | } |
2211 | if (rpl->DMABuff) | 2208 | if (rpl->DMABuff) |
2212 | pci_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, PCI_DMA_TODEVICE); | 2209 | dma_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, DMA_TO_DEVICE); |
2213 | rpl->DMABuff = 0; | 2210 | rpl->DMABuff = 0; |
2214 | 2211 | ||
2215 | /* Allocate new skb for rpl */ | 2212 | /* Allocate new skb for rpl */ |
@@ -2227,7 +2224,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev) | |||
2227 | skb_put(rpl->Skb, tp->MaxPacketSize); | 2224 | skb_put(rpl->Skb, tp->MaxPacketSize); |
2228 | 2225 | ||
2229 | /* Data unreachable for DMA ? then use local buffer */ | 2226 | /* Data unreachable for DMA ? then use local buffer */ |
2230 | dmabuf = pci_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, PCI_DMA_FROMDEVICE); | 2227 | dmabuf = dma_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); |
2231 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) | 2228 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) |
2232 | { | 2229 | { |
2233 | rpl->SkbStat = SKB_DATA_COPY; | 2230 | rpl->SkbStat = SKB_DATA_COPY; |
@@ -2332,23 +2329,26 @@ void tmsdev_term(struct net_device *dev) | |||
2332 | struct net_local *tp; | 2329 | struct net_local *tp; |
2333 | 2330 | ||
2334 | tp = netdev_priv(dev); | 2331 | tp = netdev_priv(dev); |
2335 | pci_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), | 2332 | dma_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), |
2336 | PCI_DMA_BIDIRECTIONAL); | 2333 | DMA_BIDIRECTIONAL); |
2337 | } | 2334 | } |
2338 | 2335 | ||
2339 | int tmsdev_init(struct net_device *dev, unsigned long dmalimit, | 2336 | int tmsdev_init(struct net_device *dev, struct device *pdev) |
2340 | struct pci_dev *pdev) | ||
2341 | { | 2337 | { |
2342 | struct net_local *tms_local; | 2338 | struct net_local *tms_local; |
2343 | 2339 | ||
2344 | memset(dev->priv, 0, sizeof(struct net_local)); | 2340 | memset(dev->priv, 0, sizeof(struct net_local)); |
2345 | tms_local = netdev_priv(dev); | 2341 | tms_local = netdev_priv(dev); |
2346 | init_waitqueue_head(&tms_local->wait_for_tok_int); | 2342 | init_waitqueue_head(&tms_local->wait_for_tok_int); |
2347 | tms_local->dmalimit = dmalimit; | 2343 | if (pdev->dma_mask) |
2344 | tms_local->dmalimit = *pdev->dma_mask; | ||
2345 | else | ||
2346 | return -ENOMEM; | ||
2348 | tms_local->pdev = pdev; | 2347 | tms_local->pdev = pdev; |
2349 | tms_local->dmabuffer = pci_map_single(pdev, (void *)tms_local, | 2348 | tms_local->dmabuffer = dma_map_single(pdev, (void *)tms_local, |
2350 | sizeof(struct net_local), PCI_DMA_BIDIRECTIONAL); | 2349 | sizeof(struct net_local), DMA_BIDIRECTIONAL); |
2351 | if (tms_local->dmabuffer + sizeof(struct net_local) > dmalimit) | 2350 | if (tms_local->dmabuffer + sizeof(struct net_local) > |
2351 | tms_local->dmalimit) | ||
2352 | { | 2352 | { |
2353 | printk(KERN_INFO "%s: Memory not accessible for DMA\n", | 2353 | printk(KERN_INFO "%s: Memory not accessible for DMA\n", |
2354 | dev->name); | 2354 | dev->name); |
@@ -2370,8 +2370,6 @@ int tmsdev_init(struct net_device *dev, unsigned long dmalimit, | |||
2370 | return 0; | 2370 | return 0; |
2371 | } | 2371 | } |
2372 | 2372 | ||
2373 | #ifdef MODULE | ||
2374 | |||
2375 | EXPORT_SYMBOL(tms380tr_open); | 2373 | EXPORT_SYMBOL(tms380tr_open); |
2376 | EXPORT_SYMBOL(tms380tr_close); | 2374 | EXPORT_SYMBOL(tms380tr_close); |
2377 | EXPORT_SYMBOL(tms380tr_interrupt); | 2375 | EXPORT_SYMBOL(tms380tr_interrupt); |
@@ -2379,6 +2377,8 @@ EXPORT_SYMBOL(tmsdev_init); | |||
2379 | EXPORT_SYMBOL(tmsdev_term); | 2377 | EXPORT_SYMBOL(tmsdev_term); |
2380 | EXPORT_SYMBOL(tms380tr_wait); | 2378 | EXPORT_SYMBOL(tms380tr_wait); |
2381 | 2379 | ||
2380 | #ifdef MODULE | ||
2381 | |||
2382 | static struct module *TMS380_module = NULL; | 2382 | static struct module *TMS380_module = NULL; |
2383 | 2383 | ||
2384 | int init_module(void) | 2384 | int init_module(void) |
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h index f2c5ba0f37a5..30452c67bb68 100644 --- a/drivers/net/tokenring/tms380tr.h +++ b/drivers/net/tokenring/tms380tr.h | |||
@@ -17,8 +17,7 @@ | |||
17 | int tms380tr_open(struct net_device *dev); | 17 | int tms380tr_open(struct net_device *dev); |
18 | int tms380tr_close(struct net_device *dev); | 18 | int tms380tr_close(struct net_device *dev); |
19 | irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 19 | irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
20 | int tmsdev_init(struct net_device *dev, unsigned long dmalimit, | 20 | int tmsdev_init(struct net_device *dev, struct device *pdev); |
21 | struct pci_dev *pdev); | ||
22 | void tmsdev_term(struct net_device *dev); | 21 | void tmsdev_term(struct net_device *dev); |
23 | void tms380tr_wait(unsigned long time); | 22 | void tms380tr_wait(unsigned long time); |
24 | 23 | ||
@@ -719,7 +718,7 @@ struct s_TPL { /* Transmit Parameter List (align on even word boundaries) */ | |||
719 | struct sk_buff *Skb; | 718 | struct sk_buff *Skb; |
720 | unsigned char TPLIndex; | 719 | unsigned char TPLIndex; |
721 | volatile unsigned char BusyFlag;/* Flag: TPL busy? */ | 720 | volatile unsigned char BusyFlag;/* Flag: TPL busy? */ |
722 | dma_addr_t DMABuff; /* DMA IO bus address from pci_map */ | 721 | dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ |
723 | }; | 722 | }; |
724 | 723 | ||
725 | /* ---------------------Receive Functions-------------------------------* | 724 | /* ---------------------Receive Functions-------------------------------* |
@@ -1060,7 +1059,7 @@ struct s_RPL { /* Receive Parameter List */ | |||
1060 | struct sk_buff *Skb; | 1059 | struct sk_buff *Skb; |
1061 | SKB_STAT SkbStat; | 1060 | SKB_STAT SkbStat; |
1062 | int RPLIndex; | 1061 | int RPLIndex; |
1063 | dma_addr_t DMABuff; /* DMA IO bus address from pci_map */ | 1062 | dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ |
1064 | }; | 1063 | }; |
1065 | 1064 | ||
1066 | /* Information that need to be kept for each board. */ | 1065 | /* Information that need to be kept for each board. */ |
@@ -1091,7 +1090,7 @@ typedef struct net_local { | |||
1091 | RPL *RplTail; | 1090 | RPL *RplTail; |
1092 | unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE]; | 1091 | unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE]; |
1093 | 1092 | ||
1094 | struct pci_dev *pdev; | 1093 | struct device *pdev; |
1095 | int DataRate; | 1094 | int DataRate; |
1096 | unsigned char ScbInUse; | 1095 | unsigned char ScbInUse; |
1097 | unsigned short CMDqueue; | 1096 | unsigned short CMDqueue; |
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index 2e18c0a46482..ab47c0547a3b 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c | |||
@@ -100,7 +100,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
100 | unsigned int pci_irq_line; | 100 | unsigned int pci_irq_line; |
101 | unsigned long pci_ioaddr; | 101 | unsigned long pci_ioaddr; |
102 | struct card_info *cardinfo = &card_info_table[ent->driver_data]; | 102 | struct card_info *cardinfo = &card_info_table[ent->driver_data]; |
103 | 103 | ||
104 | if (versionprinted++ == 0) | 104 | if (versionprinted++ == 0) |
105 | printk("%s", version); | 105 | printk("%s", version); |
106 | 106 | ||
@@ -143,7 +143,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
143 | printk(":%2.2x", dev->dev_addr[i]); | 143 | printk(":%2.2x", dev->dev_addr[i]); |
144 | printk("\n"); | 144 | printk("\n"); |
145 | 145 | ||
146 | ret = tmsdev_init(dev, PCI_MAX_ADDRESS, pdev); | 146 | ret = tmsdev_init(dev, &pdev->dev); |
147 | if (ret) { | 147 | if (ret) { |
148 | printk("%s: unable to get memory for dev->priv.\n", dev->name); | 148 | printk("%s: unable to get memory for dev->priv.\n", dev->name); |
149 | goto err_out_irq; | 149 | goto err_out_irq; |
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index e2cdaf876201..8c9634a98c11 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig | |||
@@ -135,6 +135,18 @@ config DM9102 | |||
135 | <file:Documentation/networking/net-modules.txt>. The module will | 135 | <file:Documentation/networking/net-modules.txt>. The module will |
136 | be called dmfe. | 136 | be called dmfe. |
137 | 137 | ||
138 | config ULI526X | ||
139 | tristate "ULi M526x controller support" | ||
140 | depends on NET_TULIP && PCI | ||
141 | select CRC32 | ||
142 | ---help--- | ||
143 | This driver is for ULi M5261/M5263 10/100M Ethernet Controller | ||
144 | (<http://www.uli.com.tw/>). | ||
145 | |||
146 | To compile this driver as a module, choose M here and read | ||
147 | <file:Documentation/networking/net-modules.txt>. The module will | ||
148 | be called uli526x. | ||
149 | |||
138 | config PCMCIA_XIRCOM | 150 | config PCMCIA_XIRCOM |
139 | tristate "Xircom CardBus support (new driver)" | 151 | tristate "Xircom CardBus support (new driver)" |
140 | depends on NET_TULIP && CARDBUS | 152 | depends on NET_TULIP && CARDBUS |
diff --git a/drivers/net/tulip/Makefile b/drivers/net/tulip/Makefile index 8bb9b4683979..451090d6fcca 100644 --- a/drivers/net/tulip/Makefile +++ b/drivers/net/tulip/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_WINBOND_840) += winbond-840.o | |||
9 | obj-$(CONFIG_DE2104X) += de2104x.o | 9 | obj-$(CONFIG_DE2104X) += de2104x.o |
10 | obj-$(CONFIG_TULIP) += tulip.o | 10 | obj-$(CONFIG_TULIP) += tulip.o |
11 | obj-$(CONFIG_DE4X5) += de4x5.o | 11 | obj-$(CONFIG_DE4X5) += de4x5.o |
12 | obj-$(CONFIG_ULI526X) += uli526x.o | ||
12 | 13 | ||
13 | # Declare multi-part drivers. | 14 | # Declare multi-part drivers. |
14 | 15 | ||
diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index e26c31f944bf..f53396fe79c9 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c | |||
@@ -81,25 +81,6 @@ int tulip_mdio_read(struct net_device *dev, int phy_id, int location) | |||
81 | return retval & 0xffff; | 81 | return retval & 0xffff; |
82 | } | 82 | } |
83 | 83 | ||
84 | if(tp->chip_id == ULI526X && tp->revision >= 0x40) { | ||
85 | int value; | ||
86 | int i = 1000; | ||
87 | |||
88 | value = ioread32(ioaddr + CSR9); | ||
89 | iowrite32(value & 0xFFEFFFFF, ioaddr + CSR9); | ||
90 | |||
91 | value = (phy_id << 21) | (location << 16) | 0x08000000; | ||
92 | iowrite32(value, ioaddr + CSR10); | ||
93 | |||
94 | while(--i > 0) { | ||
95 | mdio_delay(); | ||
96 | if(ioread32(ioaddr + CSR10) & 0x10000000) | ||
97 | break; | ||
98 | } | ||
99 | retval = ioread32(ioaddr + CSR10); | ||
100 | spin_unlock_irqrestore(&tp->mii_lock, flags); | ||
101 | return retval & 0xFFFF; | ||
102 | } | ||
103 | /* Establish sync by sending at least 32 logic ones. */ | 84 | /* Establish sync by sending at least 32 logic ones. */ |
104 | for (i = 32; i >= 0; i--) { | 85 | for (i = 32; i >= 0; i--) { |
105 | iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); | 86 | iowrite32(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr); |
@@ -159,23 +140,6 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val) | |||
159 | spin_unlock_irqrestore(&tp->mii_lock, flags); | 140 | spin_unlock_irqrestore(&tp->mii_lock, flags); |
160 | return; | 141 | return; |
161 | } | 142 | } |
162 | if (tp->chip_id == ULI526X && tp->revision >= 0x40) { | ||
163 | int value; | ||
164 | int i = 1000; | ||
165 | |||
166 | value = ioread32(ioaddr + CSR9); | ||
167 | iowrite32(value & 0xFFEFFFFF, ioaddr + CSR9); | ||
168 | |||
169 | value = (phy_id << 21) | (location << 16) | 0x04000000 | (val & 0xFFFF); | ||
170 | iowrite32(value, ioaddr + CSR10); | ||
171 | |||
172 | while(--i > 0) { | ||
173 | if (ioread32(ioaddr + CSR10) & 0x10000000) | ||
174 | break; | ||
175 | } | ||
176 | spin_unlock_irqrestore(&tp->mii_lock, flags); | ||
177 | return; | ||
178 | } | ||
179 | 143 | ||
180 | /* Establish sync by sending 32 logic ones. */ | 144 | /* Establish sync by sending 32 logic ones. */ |
181 | for (i = 32; i >= 0; i--) { | 145 | for (i = 32; i >= 0; i--) { |
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index 691568283553..e058a9fbfe88 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c | |||
@@ -39,7 +39,6 @@ void tulip_timer(unsigned long data) | |||
39 | case MX98713: | 39 | case MX98713: |
40 | case COMPEX9881: | 40 | case COMPEX9881: |
41 | case DM910X: | 41 | case DM910X: |
42 | case ULI526X: | ||
43 | default: { | 42 | default: { |
44 | struct medialeaf *mleaf; | 43 | struct medialeaf *mleaf; |
45 | unsigned char *p; | 44 | unsigned char *p; |
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index 20346d847d9e..05d2d96f7be2 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h | |||
@@ -88,7 +88,6 @@ enum chips { | |||
88 | I21145, | 88 | I21145, |
89 | DM910X, | 89 | DM910X, |
90 | CONEXANT, | 90 | CONEXANT, |
91 | ULI526X | ||
92 | }; | 91 | }; |
93 | 92 | ||
94 | 93 | ||
@@ -482,11 +481,8 @@ static inline void tulip_stop_rxtx(struct tulip_private *tp) | |||
482 | 481 | ||
483 | static inline void tulip_restart_rxtx(struct tulip_private *tp) | 482 | static inline void tulip_restart_rxtx(struct tulip_private *tp) |
484 | { | 483 | { |
485 | if(!(tp->chip_id == ULI526X && | 484 | tulip_stop_rxtx(tp); |
486 | (tp->revision == 0x40 || tp->revision == 0x50))) { | 485 | udelay(5); |
487 | tulip_stop_rxtx(tp); | ||
488 | udelay(5); | ||
489 | } | ||
490 | tulip_start_rxtx(tp); | 486 | tulip_start_rxtx(tp); |
491 | } | 487 | } |
492 | 488 | ||
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index d45d8f56e5b4..05da5bea564c 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -199,9 +199,6 @@ struct tulip_chip_table tulip_tbl[] = { | |||
199 | { "Conexant LANfinity", 256, 0x0001ebef, | 199 | { "Conexant LANfinity", 256, 0x0001ebef, |
200 | HAS_MII | HAS_ACPI, tulip_timer }, | 200 | HAS_MII | HAS_ACPI, tulip_timer }, |
201 | 201 | ||
202 | /* ULi526X */ | ||
203 | { "ULi M5261/M5263", 128, 0x0001ebef, | ||
204 | HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI, tulip_timer }, | ||
205 | }; | 202 | }; |
206 | 203 | ||
207 | 204 | ||
@@ -239,8 +236,6 @@ static struct pci_device_id tulip_pci_tbl[] = { | |||
239 | { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, | 236 | { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, |
240 | { 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, | 237 | { 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, |
241 | { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, | 238 | { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, |
242 | { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */ | ||
243 | { 0x10b9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ULI526X }, /* ALi 1563 integrated ethernet */ | ||
244 | { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ | 239 | { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ |
245 | { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */ | 240 | { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */ |
246 | { } /* terminate list */ | 241 | { } /* terminate list */ |
@@ -522,7 +517,7 @@ static void tulip_tx_timeout(struct net_device *dev) | |||
522 | dev->name); | 517 | dev->name); |
523 | } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 | 518 | } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 |
524 | || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 | 519 | || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 |
525 | || tp->chip_id == DM910X || tp->chip_id == ULI526X) { | 520 | || tp->chip_id == DM910X) { |
526 | printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, " | 521 | printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, " |
527 | "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", | 522 | "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n", |
528 | dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12), | 523 | dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12), |
@@ -1103,18 +1098,16 @@ static void set_rx_mode(struct net_device *dev) | |||
1103 | entry = tp->cur_tx++ % TX_RING_SIZE; | 1098 | entry = tp->cur_tx++ % TX_RING_SIZE; |
1104 | 1099 | ||
1105 | if (entry != 0) { | 1100 | if (entry != 0) { |
1106 | /* Avoid a chip errata by prefixing a dummy entry. Don't do | 1101 | /* Avoid a chip errata by prefixing a dummy entry. */ |
1107 | this on the ULI526X as it triggers a different problem */ | 1102 | tp->tx_buffers[entry].skb = NULL; |
1108 | if (!(tp->chip_id == ULI526X && (tp->revision == 0x40 || tp->revision == 0x50))) { | 1103 | tp->tx_buffers[entry].mapping = 0; |
1109 | tp->tx_buffers[entry].skb = NULL; | 1104 | tp->tx_ring[entry].length = |
1110 | tp->tx_buffers[entry].mapping = 0; | 1105 | (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; |
1111 | tp->tx_ring[entry].length = | 1106 | tp->tx_ring[entry].buffer1 = 0; |
1112 | (entry == TX_RING_SIZE-1) ? cpu_to_le32(DESC_RING_WRAP) : 0; | 1107 | /* Must set DescOwned later to avoid race with chip */ |
1113 | tp->tx_ring[entry].buffer1 = 0; | 1108 | dummy = entry; |
1114 | /* Must set DescOwned later to avoid race with chip */ | 1109 | entry = tp->cur_tx++ % TX_RING_SIZE; |
1115 | dummy = entry; | 1110 | |
1116 | entry = tp->cur_tx++ % TX_RING_SIZE; | ||
1117 | } | ||
1118 | } | 1111 | } |
1119 | 1112 | ||
1120 | tp->tx_buffers[entry].skb = NULL; | 1113 | tp->tx_buffers[entry].skb = NULL; |
@@ -1235,10 +1228,6 @@ static int tulip_uli_dm_quirk(struct pci_dev *pdev) | |||
1235 | { | 1228 | { |
1236 | if (pdev->vendor == 0x1282 && pdev->device == 0x9102) | 1229 | if (pdev->vendor == 0x1282 && pdev->device == 0x9102) |
1237 | return 1; | 1230 | return 1; |
1238 | if (pdev->vendor == 0x10b9 && pdev->device == 0x5261) | ||
1239 | return 1; | ||
1240 | if (pdev->vendor == 0x10b9 && pdev->device == 0x5263) | ||
1241 | return 1; | ||
1242 | return 0; | 1231 | return 0; |
1243 | } | 1232 | } |
1244 | 1233 | ||
@@ -1680,7 +1669,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1680 | switch (chip_idx) { | 1669 | switch (chip_idx) { |
1681 | case DC21140: | 1670 | case DC21140: |
1682 | case DM910X: | 1671 | case DM910X: |
1683 | case ULI526X: | ||
1684 | default: | 1672 | default: |
1685 | if (tp->mtable) | 1673 | if (tp->mtable) |
1686 | iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); | 1674 | iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); |
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c new file mode 100644 index 000000000000..5ae22b7bc5ca --- /dev/null +++ b/drivers/net/tulip/uli526x.c | |||
@@ -0,0 +1,1749 @@ | |||
1 | /* | ||
2 | This program is free software; you can redistribute it and/or | ||
3 | modify it under the terms of the GNU General Public License | ||
4 | as published by the Free Software Foundation; either version 2 | ||
5 | of the License, or (at your option) any later version. | ||
6 | |||
7 | This program is distributed in the hope that it will be useful, | ||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | GNU General Public License for more details. | ||
11 | |||
12 | |||
13 | */ | ||
14 | |||
15 | #define DRV_NAME "uli526x" | ||
16 | #define DRV_VERSION "0.9.3" | ||
17 | #define DRV_RELDATE "2005-7-29" | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/string.h> | ||
23 | #include <linux/timer.h> | ||
24 | #include <linux/ptrace.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/ioport.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/netdevice.h> | ||
32 | #include <linux/etherdevice.h> | ||
33 | #include <linux/ethtool.h> | ||
34 | #include <linux/skbuff.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/spinlock.h> | ||
37 | |||
38 | #include <asm/processor.h> | ||
39 | #include <asm/bitops.h> | ||
40 | #include <asm/io.h> | ||
41 | #include <asm/dma.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | |||
44 | |||
45 | /* Board/System/Debug information/definition ---------------- */ | ||
46 | #define PCI_ULI5261_ID 0x526110B9 /* ULi M5261 ID*/ | ||
47 | #define PCI_ULI5263_ID 0x526310B9 /* ULi M5263 ID*/ | ||
48 | |||
49 | #define ULI526X_IO_SIZE 0x100 | ||
50 | #define TX_DESC_CNT 0x20 /* Allocated Tx descriptors */ | ||
51 | #define RX_DESC_CNT 0x30 /* Allocated Rx descriptors */ | ||
52 | #define TX_FREE_DESC_CNT (TX_DESC_CNT - 2) /* Max TX packet count */ | ||
53 | #define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3) /* TX wakeup count */ | ||
54 | #define DESC_ALL_CNT (TX_DESC_CNT + RX_DESC_CNT) | ||
55 | #define TX_BUF_ALLOC 0x600 | ||
56 | #define RX_ALLOC_SIZE 0x620 | ||
57 | #define ULI526X_RESET 1 | ||
58 | #define CR0_DEFAULT 0 | ||
59 | #define CR6_DEFAULT 0x22200000 | ||
60 | #define CR7_DEFAULT 0x180c1 | ||
61 | #define CR15_DEFAULT 0x06 /* TxJabber RxWatchdog */ | ||
62 | #define TDES0_ERR_MASK 0x4302 /* TXJT, LC, EC, FUE */ | ||
63 | #define MAX_PACKET_SIZE 1514 | ||
64 | #define ULI5261_MAX_MULTICAST 14 | ||
65 | #define RX_COPY_SIZE 100 | ||
66 | #define MAX_CHECK_PACKET 0x8000 | ||
67 | |||
68 | #define ULI526X_10MHF 0 | ||
69 | #define ULI526X_100MHF 1 | ||
70 | #define ULI526X_10MFD 4 | ||
71 | #define ULI526X_100MFD 5 | ||
72 | #define ULI526X_AUTO 8 | ||
73 | |||
74 | #define ULI526X_TXTH_72 0x400000 /* TX TH 72 byte */ | ||
75 | #define ULI526X_TXTH_96 0x404000 /* TX TH 96 byte */ | ||
76 | #define ULI526X_TXTH_128 0x0000 /* TX TH 128 byte */ | ||
77 | #define ULI526X_TXTH_256 0x4000 /* TX TH 256 byte */ | ||
78 | #define ULI526X_TXTH_512 0x8000 /* TX TH 512 byte */ | ||
79 | #define ULI526X_TXTH_1K 0xC000 /* TX TH 1K byte */ | ||
80 | |||
81 | #define ULI526X_TIMER_WUT (jiffies + HZ * 1)/* timer wakeup time : 1 second */ | ||
82 | #define ULI526X_TX_TIMEOUT ((16*HZ)/2) /* tx packet time-out time 8 s" */ | ||
83 | #define ULI526X_TX_KICK (4*HZ/2) /* tx packet Kick-out time 2 s" */ | ||
84 | |||
85 | #define ULI526X_DBUG(dbug_now, msg, value) if (uli526x_debug || (dbug_now)) printk(KERN_ERR DRV_NAME ": %s %lx\n", (msg), (long) (value)) | ||
86 | |||
87 | #define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR DRV_NAME ": Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half"); | ||
88 | |||
89 | |||
90 | /* CR9 definition: SROM/MII */ | ||
91 | #define CR9_SROM_READ 0x4800 | ||
92 | #define CR9_SRCS 0x1 | ||
93 | #define CR9_SRCLK 0x2 | ||
94 | #define CR9_CRDOUT 0x8 | ||
95 | #define SROM_DATA_0 0x0 | ||
96 | #define SROM_DATA_1 0x4 | ||
97 | #define PHY_DATA_1 0x20000 | ||
98 | #define PHY_DATA_0 0x00000 | ||
99 | #define MDCLKH 0x10000 | ||
100 | |||
101 | #define PHY_POWER_DOWN 0x800 | ||
102 | |||
103 | #define SROM_V41_CODE 0x14 | ||
104 | |||
105 | #define SROM_CLK_WRITE(data, ioaddr) \ | ||
106 | outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \ | ||
107 | udelay(5); \ | ||
108 | outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr); \ | ||
109 | udelay(5); \ | ||
110 | outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr); \ | ||
111 | udelay(5); | ||
112 | |||
113 | /* Structure/enum declaration ------------------------------- */ | ||
114 | struct tx_desc { | ||
115 | u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ | ||
116 | char *tx_buf_ptr; /* Data for us */ | ||
117 | struct tx_desc *next_tx_desc; | ||
118 | } __attribute__(( aligned(32) )); | ||
119 | |||
120 | struct rx_desc { | ||
121 | u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ | ||
122 | struct sk_buff *rx_skb_ptr; /* Data for us */ | ||
123 | struct rx_desc *next_rx_desc; | ||
124 | } __attribute__(( aligned(32) )); | ||
125 | |||
126 | struct uli526x_board_info { | ||
127 | u32 chip_id; /* Chip vendor/Device ID */ | ||
128 | struct net_device *next_dev; /* next device */ | ||
129 | struct pci_dev *pdev; /* PCI device */ | ||
130 | spinlock_t lock; | ||
131 | |||
132 | long ioaddr; /* I/O base address */ | ||
133 | u32 cr0_data; | ||
134 | u32 cr5_data; | ||
135 | u32 cr6_data; | ||
136 | u32 cr7_data; | ||
137 | u32 cr15_data; | ||
138 | |||
139 | /* pointer for memory physical address */ | ||
140 | dma_addr_t buf_pool_dma_ptr; /* Tx buffer pool memory */ | ||
141 | dma_addr_t buf_pool_dma_start; /* Tx buffer pool align dword */ | ||
142 | dma_addr_t desc_pool_dma_ptr; /* descriptor pool memory */ | ||
143 | dma_addr_t first_tx_desc_dma; | ||
144 | dma_addr_t first_rx_desc_dma; | ||
145 | |||
146 | /* descriptor pointer */ | ||
147 | unsigned char *buf_pool_ptr; /* Tx buffer pool memory */ | ||
148 | unsigned char *buf_pool_start; /* Tx buffer pool align dword */ | ||
149 | unsigned char *desc_pool_ptr; /* descriptor pool memory */ | ||
150 | struct tx_desc *first_tx_desc; | ||
151 | struct tx_desc *tx_insert_ptr; | ||
152 | struct tx_desc *tx_remove_ptr; | ||
153 | struct rx_desc *first_rx_desc; | ||
154 | struct rx_desc *rx_insert_ptr; | ||
155 | struct rx_desc *rx_ready_ptr; /* packet come pointer */ | ||
156 | unsigned long tx_packet_cnt; /* transmitted packet count */ | ||
157 | unsigned long rx_avail_cnt; /* available rx descriptor count */ | ||
158 | unsigned long interval_rx_cnt; /* rx packet count a callback time */ | ||
159 | |||
160 | u16 dbug_cnt; | ||
161 | u16 NIC_capability; /* NIC media capability */ | ||
162 | u16 PHY_reg4; /* Saved Phyxcer register 4 value */ | ||
163 | |||
164 | u8 media_mode; /* user specify media mode */ | ||
165 | u8 op_mode; /* real work media mode */ | ||
166 | u8 phy_addr; | ||
167 | u8 link_failed; /* Ever link failed */ | ||
168 | u8 wait_reset; /* Hardware failed, need to reset */ | ||
169 | struct timer_list timer; | ||
170 | |||
171 | /* System defined statistic counter */ | ||
172 | struct net_device_stats stats; | ||
173 | |||
174 | /* Driver defined statistic counter */ | ||
175 | unsigned long tx_fifo_underrun; | ||
176 | unsigned long tx_loss_carrier; | ||
177 | unsigned long tx_no_carrier; | ||
178 | unsigned long tx_late_collision; | ||
179 | unsigned long tx_excessive_collision; | ||
180 | unsigned long tx_jabber_timeout; | ||
181 | unsigned long reset_count; | ||
182 | unsigned long reset_cr8; | ||
183 | unsigned long reset_fatal; | ||
184 | unsigned long reset_TXtimeout; | ||
185 | |||
186 | /* NIC SROM data */ | ||
187 | unsigned char srom[128]; | ||
188 | u8 init; | ||
189 | }; | ||
190 | |||
191 | enum uli526x_offsets { | ||
192 | DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, | ||
193 | DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, | ||
194 | DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70, | ||
195 | DCR15 = 0x78 | ||
196 | }; | ||
197 | |||
198 | enum uli526x_CR6_bits { | ||
199 | CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, | ||
200 | CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000, | ||
201 | CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000 | ||
202 | }; | ||
203 | |||
204 | /* Global variable declaration ----------------------------- */ | ||
205 | static int __devinitdata printed_version; | ||
206 | static char version[] __devinitdata = | ||
207 | KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version " | ||
208 | DRV_VERSION " (" DRV_RELDATE ")\n"; | ||
209 | |||
210 | static int uli526x_debug; | ||
211 | static unsigned char uli526x_media_mode = ULI526X_AUTO; | ||
212 | static u32 uli526x_cr6_user_set; | ||
213 | |||
214 | /* For module input parameter */ | ||
215 | static int debug; | ||
216 | static u32 cr6set; | ||
217 | static unsigned char mode = 8; | ||
218 | |||
219 | /* function declaration ------------------------------------- */ | ||
220 | static int uli526x_open(struct net_device *); | ||
221 | static int uli526x_start_xmit(struct sk_buff *, struct net_device *); | ||
222 | static int uli526x_stop(struct net_device *); | ||
223 | static struct net_device_stats * uli526x_get_stats(struct net_device *); | ||
224 | static void uli526x_set_filter_mode(struct net_device *); | ||
225 | static struct ethtool_ops netdev_ethtool_ops; | ||
226 | static u16 read_srom_word(long, int); | ||
227 | static irqreturn_t uli526x_interrupt(int, void *, struct pt_regs *); | ||
228 | static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long); | ||
229 | static void allocate_rx_buffer(struct uli526x_board_info *); | ||
230 | static void update_cr6(u32, unsigned long); | ||
231 | static void send_filter_frame(struct net_device *, int); | ||
232 | static u16 phy_read(unsigned long, u8, u8, u32); | ||
233 | static u16 phy_readby_cr10(unsigned long, u8, u8); | ||
234 | static void phy_write(unsigned long, u8, u8, u16, u32); | ||
235 | static void phy_writeby_cr10(unsigned long, u8, u8, u16); | ||
236 | static void phy_write_1bit(unsigned long, u32, u32); | ||
237 | static u16 phy_read_1bit(unsigned long, u32); | ||
238 | static u8 uli526x_sense_speed(struct uli526x_board_info *); | ||
239 | static void uli526x_process_mode(struct uli526x_board_info *); | ||
240 | static void uli526x_timer(unsigned long); | ||
241 | static void uli526x_rx_packet(struct net_device *, struct uli526x_board_info *); | ||
242 | static void uli526x_free_tx_pkt(struct net_device *, struct uli526x_board_info *); | ||
243 | static void uli526x_reuse_skb(struct uli526x_board_info *, struct sk_buff *); | ||
244 | static void uli526x_dynamic_reset(struct net_device *); | ||
245 | static void uli526x_free_rxbuffer(struct uli526x_board_info *); | ||
246 | static void uli526x_init(struct net_device *); | ||
247 | static void uli526x_set_phyxcer(struct uli526x_board_info *); | ||
248 | |||
249 | /* ULI526X network board routine ---------------------------- */ | ||
250 | |||
251 | /* | ||
252 | * Search ULI526X board, allocate space and register it | ||
253 | */ | ||
254 | |||
255 | static int __devinit uli526x_init_one (struct pci_dev *pdev, | ||
256 | const struct pci_device_id *ent) | ||
257 | { | ||
258 | struct uli526x_board_info *db; /* board information structure */ | ||
259 | struct net_device *dev; | ||
260 | int i, err; | ||
261 | |||
262 | ULI526X_DBUG(0, "uli526x_init_one()", 0); | ||
263 | |||
264 | if (!printed_version++) | ||
265 | printk(version); | ||
266 | |||
267 | /* Init network device */ | ||
268 | dev = alloc_etherdev(sizeof(*db)); | ||
269 | if (dev == NULL) | ||
270 | return -ENOMEM; | ||
271 | SET_MODULE_OWNER(dev); | ||
272 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
273 | |||
274 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | ||
275 | printk(KERN_WARNING DRV_NAME ": 32-bit PCI DMA not available.\n"); | ||
276 | err = -ENODEV; | ||
277 | goto err_out_free; | ||
278 | } | ||
279 | |||
280 | /* Enable Master/IO access, Disable memory access */ | ||
281 | err = pci_enable_device(pdev); | ||
282 | if (err) | ||
283 | goto err_out_free; | ||
284 | |||
285 | if (!pci_resource_start(pdev, 0)) { | ||
286 | printk(KERN_ERR DRV_NAME ": I/O base is zero\n"); | ||
287 | err = -ENODEV; | ||
288 | goto err_out_disable; | ||
289 | } | ||
290 | |||
291 | if (pci_resource_len(pdev, 0) < (ULI526X_IO_SIZE) ) { | ||
292 | printk(KERN_ERR DRV_NAME ": Allocated I/O size too small\n"); | ||
293 | err = -ENODEV; | ||
294 | goto err_out_disable; | ||
295 | } | ||
296 | |||
297 | if (pci_request_regions(pdev, DRV_NAME)) { | ||
298 | printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n"); | ||
299 | err = -ENODEV; | ||
300 | goto err_out_disable; | ||
301 | } | ||
302 | |||
303 | /* Init system & device */ | ||
304 | db = netdev_priv(dev); | ||
305 | |||
306 | /* Allocate Tx/Rx descriptor memory */ | ||
307 | db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr); | ||
308 | if(db->desc_pool_ptr == NULL) | ||
309 | { | ||
310 | err = -ENOMEM; | ||
311 | goto err_out_nomem; | ||
312 | } | ||
313 | db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr); | ||
314 | if(db->buf_pool_ptr == NULL) | ||
315 | { | ||
316 | err = -ENOMEM; | ||
317 | goto err_out_nomem; | ||
318 | } | ||
319 | |||
320 | db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr; | ||
321 | db->first_tx_desc_dma = db->desc_pool_dma_ptr; | ||
322 | db->buf_pool_start = db->buf_pool_ptr; | ||
323 | db->buf_pool_dma_start = db->buf_pool_dma_ptr; | ||
324 | |||
325 | db->chip_id = ent->driver_data; | ||
326 | db->ioaddr = pci_resource_start(pdev, 0); | ||
327 | |||
328 | db->pdev = pdev; | ||
329 | db->init = 1; | ||
330 | |||
331 | dev->base_addr = db->ioaddr; | ||
332 | dev->irq = pdev->irq; | ||
333 | pci_set_drvdata(pdev, dev); | ||
334 | |||
335 | /* Register some necessary functions */ | ||
336 | dev->open = &uli526x_open; | ||
337 | dev->hard_start_xmit = &uli526x_start_xmit; | ||
338 | dev->stop = &uli526x_stop; | ||
339 | dev->get_stats = &uli526x_get_stats; | ||
340 | dev->set_multicast_list = &uli526x_set_filter_mode; | ||
341 | dev->ethtool_ops = &netdev_ethtool_ops; | ||
342 | spin_lock_init(&db->lock); | ||
343 | |||
344 | |||
345 | /* read 64 word srom data */ | ||
346 | for (i = 0; i < 64; i++) | ||
347 | ((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr, i)); | ||
348 | |||
349 | /* Set Node address */ | ||
350 | if(((u16 *) db->srom)[0] == 0xffff || ((u16 *) db->srom)[0] == 0) /* SROM absent, so read MAC address from ID Table */ | ||
351 | { | ||
352 | outl(0x10000, db->ioaddr + DCR0); //Diagnosis mode | ||
353 | outl(0x1c0, db->ioaddr + DCR13); //Reset dianostic pointer port | ||
354 | outl(0, db->ioaddr + DCR14); //Clear reset port | ||
355 | outl(0x10, db->ioaddr + DCR14); //Reset ID Table pointer | ||
356 | outl(0, db->ioaddr + DCR14); //Clear reset port | ||
357 | outl(0, db->ioaddr + DCR13); //Clear CR13 | ||
358 | outl(0x1b0, db->ioaddr + DCR13); //Select ID Table access port | ||
359 | //Read MAC address from CR14 | ||
360 | for (i = 0; i < 6; i++) | ||
361 | dev->dev_addr[i] = inl(db->ioaddr + DCR14); | ||
362 | //Read end | ||
363 | outl(0, db->ioaddr + DCR13); //Clear CR13 | ||
364 | outl(0, db->ioaddr + DCR0); //Clear CR0 | ||
365 | udelay(10); | ||
366 | } | ||
367 | else /*Exist SROM*/ | ||
368 | { | ||
369 | for (i = 0; i < 6; i++) | ||
370 | dev->dev_addr[i] = db->srom[20 + i]; | ||
371 | } | ||
372 | err = register_netdev (dev); | ||
373 | if (err) | ||
374 | goto err_out_res; | ||
375 | |||
376 | printk(KERN_INFO "%s: ULi M%04lx at pci%s,",dev->name,ent->driver_data >> 16,pci_name(pdev)); | ||
377 | |||
378 | for (i = 0; i < 6; i++) | ||
379 | printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]); | ||
380 | printk(", irq %d.\n", dev->irq); | ||
381 | |||
382 | pci_set_master(pdev); | ||
383 | |||
384 | return 0; | ||
385 | |||
386 | err_out_res: | ||
387 | pci_release_regions(pdev); | ||
388 | err_out_nomem: | ||
389 | if(db->desc_pool_ptr) | ||
390 | pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, | ||
391 | db->desc_pool_ptr, db->desc_pool_dma_ptr); | ||
392 | |||
393 | if(db->buf_pool_ptr != NULL) | ||
394 | pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, | ||
395 | db->buf_pool_ptr, db->buf_pool_dma_ptr); | ||
396 | err_out_disable: | ||
397 | pci_disable_device(pdev); | ||
398 | err_out_free: | ||
399 | pci_set_drvdata(pdev, NULL); | ||
400 | free_netdev(dev); | ||
401 | |||
402 | return err; | ||
403 | } | ||
404 | |||
405 | |||
406 | static void __devexit uli526x_remove_one (struct pci_dev *pdev) | ||
407 | { | ||
408 | struct net_device *dev = pci_get_drvdata(pdev); | ||
409 | struct uli526x_board_info *db = netdev_priv(dev); | ||
410 | |||
411 | ULI526X_DBUG(0, "uli526x_remove_one()", 0); | ||
412 | |||
413 | pci_free_consistent(db->pdev, sizeof(struct tx_desc) * | ||
414 | DESC_ALL_CNT + 0x20, db->desc_pool_ptr, | ||
415 | db->desc_pool_dma_ptr); | ||
416 | pci_free_consistent(db->pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, | ||
417 | db->buf_pool_ptr, db->buf_pool_dma_ptr); | ||
418 | unregister_netdev(dev); | ||
419 | pci_release_regions(pdev); | ||
420 | free_netdev(dev); /* free board information */ | ||
421 | pci_set_drvdata(pdev, NULL); | ||
422 | pci_disable_device(pdev); | ||
423 | ULI526X_DBUG(0, "uli526x_remove_one() exit", 0); | ||
424 | } | ||
425 | |||
426 | |||
427 | /* | ||
428 | * Open the interface. | ||
429 | * The interface is opened whenever "ifconfig" activates it. | ||
430 | */ | ||
431 | |||
432 | static int uli526x_open(struct net_device *dev) | ||
433 | { | ||
434 | int ret; | ||
435 | struct uli526x_board_info *db = netdev_priv(dev); | ||
436 | |||
437 | ULI526X_DBUG(0, "uli526x_open", 0); | ||
438 | |||
439 | ret = request_irq(dev->irq, &uli526x_interrupt, SA_SHIRQ, dev->name, dev); | ||
440 | if (ret) | ||
441 | return ret; | ||
442 | |||
443 | /* system variable init */ | ||
444 | db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set; | ||
445 | db->tx_packet_cnt = 0; | ||
446 | db->rx_avail_cnt = 0; | ||
447 | db->link_failed = 1; | ||
448 | netif_carrier_off(dev); | ||
449 | db->wait_reset = 0; | ||
450 | |||
451 | db->NIC_capability = 0xf; /* All capability*/ | ||
452 | db->PHY_reg4 = 0x1e0; | ||
453 | |||
454 | /* CR6 operation mode decision */ | ||
455 | db->cr6_data |= ULI526X_TXTH_256; | ||
456 | db->cr0_data = CR0_DEFAULT; | ||
457 | |||
458 | /* Initialize ULI526X board */ | ||
459 | uli526x_init(dev); | ||
460 | |||
461 | /* Active System Interface */ | ||
462 | netif_wake_queue(dev); | ||
463 | |||
464 | /* set and active a timer process */ | ||
465 | init_timer(&db->timer); | ||
466 | db->timer.expires = ULI526X_TIMER_WUT + HZ * 2; | ||
467 | db->timer.data = (unsigned long)dev; | ||
468 | db->timer.function = &uli526x_timer; | ||
469 | add_timer(&db->timer); | ||
470 | |||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | |||
475 | /* Initialize ULI526X board | ||
476 | * Reset ULI526X board | ||
477 | * Initialize TX/Rx descriptor chain structure | ||
478 | * Send the set-up frame | ||
479 | * Enable Tx/Rx machine | ||
480 | */ | ||
481 | |||
482 | static void uli526x_init(struct net_device *dev) | ||
483 | { | ||
484 | struct uli526x_board_info *db = netdev_priv(dev); | ||
485 | unsigned long ioaddr = db->ioaddr; | ||
486 | u8 phy_tmp; | ||
487 | u16 phy_value; | ||
488 | u16 phy_reg_reset; | ||
489 | |||
490 | ULI526X_DBUG(0, "uli526x_init()", 0); | ||
491 | |||
492 | /* Reset M526x MAC controller */ | ||
493 | outl(ULI526X_RESET, ioaddr + DCR0); /* RESET MAC */ | ||
494 | udelay(100); | ||
495 | outl(db->cr0_data, ioaddr + DCR0); | ||
496 | udelay(5); | ||
497 | |||
498 | /* Phy addr : In some boards,M5261/M5263 phy address != 1 */ | ||
499 | db->phy_addr = 1; | ||
500 | for(phy_tmp=0;phy_tmp<32;phy_tmp++) | ||
501 | { | ||
502 | phy_value=phy_read(db->ioaddr,phy_tmp,3,db->chip_id);//peer add | ||
503 | if(phy_value != 0xffff&&phy_value!=0) | ||
504 | { | ||
505 | db->phy_addr = phy_tmp; | ||
506 | break; | ||
507 | } | ||
508 | } | ||
509 | if(phy_tmp == 32) | ||
510 | printk(KERN_WARNING "Can not find the phy address!!!"); | ||
511 | /* Parser SROM and media mode */ | ||
512 | db->media_mode = uli526x_media_mode; | ||
513 | |||
514 | /* Phyxcer capability setting */ | ||
515 | phy_reg_reset = phy_read(db->ioaddr, db->phy_addr, 0, db->chip_id); | ||
516 | phy_reg_reset = (phy_reg_reset | 0x8000); | ||
517 | phy_write(db->ioaddr, db->phy_addr, 0, phy_reg_reset, db->chip_id); | ||
518 | udelay(500); | ||
519 | |||
520 | /* Process Phyxcer Media Mode */ | ||
521 | uli526x_set_phyxcer(db); | ||
522 | |||
523 | /* Media Mode Process */ | ||
524 | if ( !(db->media_mode & ULI526X_AUTO) ) | ||
525 | db->op_mode = db->media_mode; /* Force Mode */ | ||
526 | |||
527 | /* Initialize Transmit/Receive decriptor and CR3/4 */ | ||
528 | uli526x_descriptor_init(db, ioaddr); | ||
529 | |||
530 | /* Init CR6 to program M526X operation */ | ||
531 | update_cr6(db->cr6_data, ioaddr); | ||
532 | |||
533 | /* Send setup frame */ | ||
534 | send_filter_frame(dev, dev->mc_count); /* M5261/M5263 */ | ||
535 | |||
536 | /* Init CR7, interrupt active bit */ | ||
537 | db->cr7_data = CR7_DEFAULT; | ||
538 | outl(db->cr7_data, ioaddr + DCR7); | ||
539 | |||
540 | /* Init CR15, Tx jabber and Rx watchdog timer */ | ||
541 | outl(db->cr15_data, ioaddr + DCR15); | ||
542 | |||
543 | /* Enable ULI526X Tx/Rx function */ | ||
544 | db->cr6_data |= CR6_RXSC | CR6_TXSC; | ||
545 | update_cr6(db->cr6_data, ioaddr); | ||
546 | } | ||
547 | |||
548 | |||
549 | /* | ||
550 | * Hardware start transmission. | ||
551 | * Send a packet to media from the upper layer. | ||
552 | */ | ||
553 | |||
554 | static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
555 | { | ||
556 | struct uli526x_board_info *db = netdev_priv(dev); | ||
557 | struct tx_desc *txptr; | ||
558 | unsigned long flags; | ||
559 | |||
560 | ULI526X_DBUG(0, "uli526x_start_xmit", 0); | ||
561 | |||
562 | /* Resource flag check */ | ||
563 | netif_stop_queue(dev); | ||
564 | |||
565 | /* Too large packet check */ | ||
566 | if (skb->len > MAX_PACKET_SIZE) { | ||
567 | printk(KERN_ERR DRV_NAME ": big packet = %d\n", (u16)skb->len); | ||
568 | dev_kfree_skb(skb); | ||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | spin_lock_irqsave(&db->lock, flags); | ||
573 | |||
574 | /* No Tx resource check, it never happen nromally */ | ||
575 | if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) { | ||
576 | spin_unlock_irqrestore(&db->lock, flags); | ||
577 | printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", db->tx_packet_cnt); | ||
578 | return 1; | ||
579 | } | ||
580 | |||
581 | /* Disable NIC interrupt */ | ||
582 | outl(0, dev->base_addr + DCR7); | ||
583 | |||
584 | /* transmit this packet */ | ||
585 | txptr = db->tx_insert_ptr; | ||
586 | memcpy(txptr->tx_buf_ptr, skb->data, skb->len); | ||
587 | txptr->tdes1 = cpu_to_le32(0xe1000000 | skb->len); | ||
588 | |||
589 | /* Point to next transmit free descriptor */ | ||
590 | db->tx_insert_ptr = txptr->next_tx_desc; | ||
591 | |||
592 | /* Transmit Packet Process */ | ||
593 | if ( (db->tx_packet_cnt < TX_DESC_CNT) ) { | ||
594 | txptr->tdes0 = cpu_to_le32(0x80000000); /* Set owner bit */ | ||
595 | db->tx_packet_cnt++; /* Ready to send */ | ||
596 | outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */ | ||
597 | dev->trans_start = jiffies; /* saved time stamp */ | ||
598 | } | ||
599 | |||
600 | /* Tx resource check */ | ||
601 | if ( db->tx_packet_cnt < TX_FREE_DESC_CNT ) | ||
602 | netif_wake_queue(dev); | ||
603 | |||
604 | /* Restore CR7 to enable interrupt */ | ||
605 | spin_unlock_irqrestore(&db->lock, flags); | ||
606 | outl(db->cr7_data, dev->base_addr + DCR7); | ||
607 | |||
608 | /* free this SKB */ | ||
609 | dev_kfree_skb(skb); | ||
610 | |||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | |||
615 | /* | ||
616 | * Stop the interface. | ||
617 | * The interface is stopped when it is brought. | ||
618 | */ | ||
619 | |||
620 | static int uli526x_stop(struct net_device *dev) | ||
621 | { | ||
622 | struct uli526x_board_info *db = netdev_priv(dev); | ||
623 | unsigned long ioaddr = dev->base_addr; | ||
624 | |||
625 | ULI526X_DBUG(0, "uli526x_stop", 0); | ||
626 | |||
627 | /* disable system */ | ||
628 | netif_stop_queue(dev); | ||
629 | |||
630 | /* deleted timer */ | ||
631 | del_timer_sync(&db->timer); | ||
632 | |||
633 | /* Reset & stop ULI526X board */ | ||
634 | outl(ULI526X_RESET, ioaddr + DCR0); | ||
635 | udelay(5); | ||
636 | phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id); | ||
637 | |||
638 | /* free interrupt */ | ||
639 | free_irq(dev->irq, dev); | ||
640 | |||
641 | /* free allocated rx buffer */ | ||
642 | uli526x_free_rxbuffer(db); | ||
643 | |||
644 | #if 0 | ||
645 | /* show statistic counter */ | ||
646 | printk(DRV_NAME ": FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n", | ||
647 | db->tx_fifo_underrun, db->tx_excessive_collision, | ||
648 | db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier, | ||
649 | db->tx_jabber_timeout, db->reset_count, db->reset_cr8, | ||
650 | db->reset_fatal, db->reset_TXtimeout); | ||
651 | #endif | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | |||
657 | /* | ||
658 | * M5261/M5263 insterrupt handler | ||
659 | * receive the packet to upper layer, free the transmitted packet | ||
660 | */ | ||
661 | |||
662 | static irqreturn_t uli526x_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
663 | { | ||
664 | struct net_device *dev = dev_id; | ||
665 | struct uli526x_board_info *db = netdev_priv(dev); | ||
666 | unsigned long ioaddr = dev->base_addr; | ||
667 | unsigned long flags; | ||
668 | |||
669 | if (!dev) { | ||
670 | ULI526X_DBUG(1, "uli526x_interrupt() without DEVICE arg", 0); | ||
671 | return IRQ_NONE; | ||
672 | } | ||
673 | |||
674 | spin_lock_irqsave(&db->lock, flags); | ||
675 | outl(0, ioaddr + DCR7); | ||
676 | |||
677 | /* Got ULI526X status */ | ||
678 | db->cr5_data = inl(ioaddr + DCR5); | ||
679 | outl(db->cr5_data, ioaddr + DCR5); | ||
680 | if ( !(db->cr5_data & 0x180c1) ) { | ||
681 | spin_unlock_irqrestore(&db->lock, flags); | ||
682 | outl(db->cr7_data, ioaddr + DCR7); | ||
683 | return IRQ_HANDLED; | ||
684 | } | ||
685 | |||
686 | /* Check system status */ | ||
687 | if (db->cr5_data & 0x2000) { | ||
688 | /* system bus error happen */ | ||
689 | ULI526X_DBUG(1, "System bus error happen. CR5=", db->cr5_data); | ||
690 | db->reset_fatal++; | ||
691 | db->wait_reset = 1; /* Need to RESET */ | ||
692 | spin_unlock_irqrestore(&db->lock, flags); | ||
693 | return IRQ_HANDLED; | ||
694 | } | ||
695 | |||
696 | /* Received the coming packet */ | ||
697 | if ( (db->cr5_data & 0x40) && db->rx_avail_cnt ) | ||
698 | uli526x_rx_packet(dev, db); | ||
699 | |||
700 | /* reallocate rx descriptor buffer */ | ||
701 | if (db->rx_avail_cnt<RX_DESC_CNT) | ||
702 | allocate_rx_buffer(db); | ||
703 | |||
704 | /* Free the transmitted descriptor */ | ||
705 | if ( db->cr5_data & 0x01) | ||
706 | uli526x_free_tx_pkt(dev, db); | ||
707 | |||
708 | /* Restore CR7 to enable interrupt mask */ | ||
709 | outl(db->cr7_data, ioaddr + DCR7); | ||
710 | |||
711 | spin_unlock_irqrestore(&db->lock, flags); | ||
712 | return IRQ_HANDLED; | ||
713 | } | ||
714 | |||
715 | |||
716 | /* | ||
717 | * Free TX resource after TX complete | ||
718 | */ | ||
719 | |||
720 | static void uli526x_free_tx_pkt(struct net_device *dev, struct uli526x_board_info * db) | ||
721 | { | ||
722 | struct tx_desc *txptr; | ||
723 | u32 tdes0; | ||
724 | |||
725 | txptr = db->tx_remove_ptr; | ||
726 | while(db->tx_packet_cnt) { | ||
727 | tdes0 = le32_to_cpu(txptr->tdes0); | ||
728 | /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */ | ||
729 | if (tdes0 & 0x80000000) | ||
730 | break; | ||
731 | |||
732 | /* A packet sent completed */ | ||
733 | db->tx_packet_cnt--; | ||
734 | db->stats.tx_packets++; | ||
735 | |||
736 | /* Transmit statistic counter */ | ||
737 | if ( tdes0 != 0x7fffffff ) { | ||
738 | /* printk(DRV_NAME ": tdes0=%x\n", tdes0); */ | ||
739 | db->stats.collisions += (tdes0 >> 3) & 0xf; | ||
740 | db->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; | ||
741 | if (tdes0 & TDES0_ERR_MASK) { | ||
742 | db->stats.tx_errors++; | ||
743 | if (tdes0 & 0x0002) { /* UnderRun */ | ||
744 | db->tx_fifo_underrun++; | ||
745 | if ( !(db->cr6_data & CR6_SFT) ) { | ||
746 | db->cr6_data = db->cr6_data | CR6_SFT; | ||
747 | update_cr6(db->cr6_data, db->ioaddr); | ||
748 | } | ||
749 | } | ||
750 | if (tdes0 & 0x0100) | ||
751 | db->tx_excessive_collision++; | ||
752 | if (tdes0 & 0x0200) | ||
753 | db->tx_late_collision++; | ||
754 | if (tdes0 & 0x0400) | ||
755 | db->tx_no_carrier++; | ||
756 | if (tdes0 & 0x0800) | ||
757 | db->tx_loss_carrier++; | ||
758 | if (tdes0 & 0x4000) | ||
759 | db->tx_jabber_timeout++; | ||
760 | } | ||
761 | } | ||
762 | |||
763 | txptr = txptr->next_tx_desc; | ||
764 | }/* End of while */ | ||
765 | |||
766 | /* Update TX remove pointer to next */ | ||
767 | db->tx_remove_ptr = txptr; | ||
768 | |||
769 | /* Resource available check */ | ||
770 | if ( db->tx_packet_cnt < TX_WAKE_DESC_CNT ) | ||
771 | netif_wake_queue(dev); /* Active upper layer, send again */ | ||
772 | } | ||
773 | |||
774 | |||
775 | /* | ||
776 | * Receive the come packet and pass to upper layer | ||
777 | */ | ||
778 | |||
779 | static void uli526x_rx_packet(struct net_device *dev, struct uli526x_board_info * db) | ||
780 | { | ||
781 | struct rx_desc *rxptr; | ||
782 | struct sk_buff *skb; | ||
783 | int rxlen; | ||
784 | u32 rdes0; | ||
785 | |||
786 | rxptr = db->rx_ready_ptr; | ||
787 | |||
788 | while(db->rx_avail_cnt) { | ||
789 | rdes0 = le32_to_cpu(rxptr->rdes0); | ||
790 | if (rdes0 & 0x80000000) /* packet owner check */ | ||
791 | { | ||
792 | break; | ||
793 | } | ||
794 | |||
795 | db->rx_avail_cnt--; | ||
796 | db->interval_rx_cnt++; | ||
797 | |||
798 | pci_unmap_single(db->pdev, le32_to_cpu(rxptr->rdes2), RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE); | ||
799 | if ( (rdes0 & 0x300) != 0x300) { | ||
800 | /* A packet without First/Last flag */ | ||
801 | /* reuse this SKB */ | ||
802 | ULI526X_DBUG(0, "Reuse SK buffer, rdes0", rdes0); | ||
803 | uli526x_reuse_skb(db, rxptr->rx_skb_ptr); | ||
804 | } else { | ||
805 | /* A packet with First/Last flag */ | ||
806 | rxlen = ( (rdes0 >> 16) & 0x3fff) - 4; | ||
807 | |||
808 | /* error summary bit check */ | ||
809 | if (rdes0 & 0x8000) { | ||
810 | /* This is a error packet */ | ||
811 | //printk(DRV_NAME ": rdes0: %lx\n", rdes0); | ||
812 | db->stats.rx_errors++; | ||
813 | if (rdes0 & 1) | ||
814 | db->stats.rx_fifo_errors++; | ||
815 | if (rdes0 & 2) | ||
816 | db->stats.rx_crc_errors++; | ||
817 | if (rdes0 & 0x80) | ||
818 | db->stats.rx_length_errors++; | ||
819 | } | ||
820 | |||
821 | if ( !(rdes0 & 0x8000) || | ||
822 | ((db->cr6_data & CR6_PM) && (rxlen>6)) ) { | ||
823 | skb = rxptr->rx_skb_ptr; | ||
824 | |||
825 | /* Good packet, send to upper layer */ | ||
826 | /* Shorst packet used new SKB */ | ||
827 | if ( (rxlen < RX_COPY_SIZE) && | ||
828 | ( (skb = dev_alloc_skb(rxlen + 2) ) | ||
829 | != NULL) ) { | ||
830 | /* size less than COPY_SIZE, allocate a rxlen SKB */ | ||
831 | skb->dev = dev; | ||
832 | skb_reserve(skb, 2); /* 16byte align */ | ||
833 | memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen); | ||
834 | uli526x_reuse_skb(db, rxptr->rx_skb_ptr); | ||
835 | } else { | ||
836 | skb->dev = dev; | ||
837 | skb_put(skb, rxlen); | ||
838 | } | ||
839 | skb->protocol = eth_type_trans(skb, dev); | ||
840 | netif_rx(skb); | ||
841 | dev->last_rx = jiffies; | ||
842 | db->stats.rx_packets++; | ||
843 | db->stats.rx_bytes += rxlen; | ||
844 | |||
845 | } else { | ||
846 | /* Reuse SKB buffer when the packet is error */ | ||
847 | ULI526X_DBUG(0, "Reuse SK buffer, rdes0", rdes0); | ||
848 | uli526x_reuse_skb(db, rxptr->rx_skb_ptr); | ||
849 | } | ||
850 | } | ||
851 | |||
852 | rxptr = rxptr->next_rx_desc; | ||
853 | } | ||
854 | |||
855 | db->rx_ready_ptr = rxptr; | ||
856 | } | ||
857 | |||
858 | |||
859 | /* | ||
860 | * Get statistics from driver. | ||
861 | */ | ||
862 | |||
863 | static struct net_device_stats * uli526x_get_stats(struct net_device *dev) | ||
864 | { | ||
865 | struct uli526x_board_info *db = netdev_priv(dev); | ||
866 | |||
867 | ULI526X_DBUG(0, "uli526x_get_stats", 0); | ||
868 | return &db->stats; | ||
869 | } | ||
870 | |||
871 | |||
872 | /* | ||
873 | * Set ULI526X multicast address | ||
874 | */ | ||
875 | |||
876 | static void uli526x_set_filter_mode(struct net_device * dev) | ||
877 | { | ||
878 | struct uli526x_board_info *db = dev->priv; | ||
879 | unsigned long flags; | ||
880 | |||
881 | ULI526X_DBUG(0, "uli526x_set_filter_mode()", 0); | ||
882 | spin_lock_irqsave(&db->lock, flags); | ||
883 | |||
884 | if (dev->flags & IFF_PROMISC) { | ||
885 | ULI526X_DBUG(0, "Enable PROM Mode", 0); | ||
886 | db->cr6_data |= CR6_PM | CR6_PBF; | ||
887 | update_cr6(db->cr6_data, db->ioaddr); | ||
888 | spin_unlock_irqrestore(&db->lock, flags); | ||
889 | return; | ||
890 | } | ||
891 | |||
892 | if (dev->flags & IFF_ALLMULTI || dev->mc_count > ULI5261_MAX_MULTICAST) { | ||
893 | ULI526X_DBUG(0, "Pass all multicast address", dev->mc_count); | ||
894 | db->cr6_data &= ~(CR6_PM | CR6_PBF); | ||
895 | db->cr6_data |= CR6_PAM; | ||
896 | spin_unlock_irqrestore(&db->lock, flags); | ||
897 | return; | ||
898 | } | ||
899 | |||
900 | ULI526X_DBUG(0, "Set multicast address", dev->mc_count); | ||
901 | send_filter_frame(dev, dev->mc_count); /* M5261/M5263 */ | ||
902 | spin_unlock_irqrestore(&db->lock, flags); | ||
903 | } | ||
904 | |||
905 | static void | ||
906 | ULi_ethtool_gset(struct uli526x_board_info *db, struct ethtool_cmd *ecmd) | ||
907 | { | ||
908 | ecmd->supported = (SUPPORTED_10baseT_Half | | ||
909 | SUPPORTED_10baseT_Full | | ||
910 | SUPPORTED_100baseT_Half | | ||
911 | SUPPORTED_100baseT_Full | | ||
912 | SUPPORTED_Autoneg | | ||
913 | SUPPORTED_MII); | ||
914 | |||
915 | ecmd->advertising = (ADVERTISED_10baseT_Half | | ||
916 | ADVERTISED_10baseT_Full | | ||
917 | ADVERTISED_100baseT_Half | | ||
918 | ADVERTISED_100baseT_Full | | ||
919 | ADVERTISED_Autoneg | | ||
920 | ADVERTISED_MII); | ||
921 | |||
922 | |||
923 | ecmd->port = PORT_MII; | ||
924 | ecmd->phy_address = db->phy_addr; | ||
925 | |||
926 | ecmd->transceiver = XCVR_EXTERNAL; | ||
927 | |||
928 | ecmd->speed = 10; | ||
929 | ecmd->duplex = DUPLEX_HALF; | ||
930 | |||
931 | if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD) | ||
932 | { | ||
933 | ecmd->speed = 100; | ||
934 | } | ||
935 | if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD) | ||
936 | { | ||
937 | ecmd->duplex = DUPLEX_FULL; | ||
938 | } | ||
939 | if(db->link_failed) | ||
940 | { | ||
941 | ecmd->speed = -1; | ||
942 | ecmd->duplex = -1; | ||
943 | } | ||
944 | |||
945 | if (db->media_mode & ULI526X_AUTO) | ||
946 | { | ||
947 | ecmd->autoneg = AUTONEG_ENABLE; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | static void netdev_get_drvinfo(struct net_device *dev, | ||
952 | struct ethtool_drvinfo *info) | ||
953 | { | ||
954 | struct uli526x_board_info *np = netdev_priv(dev); | ||
955 | |||
956 | strcpy(info->driver, DRV_NAME); | ||
957 | strcpy(info->version, DRV_VERSION); | ||
958 | if (np->pdev) | ||
959 | strcpy(info->bus_info, pci_name(np->pdev)); | ||
960 | else | ||
961 | sprintf(info->bus_info, "EISA 0x%lx %d", | ||
962 | dev->base_addr, dev->irq); | ||
963 | } | ||
964 | |||
965 | static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { | ||
966 | struct uli526x_board_info *np = netdev_priv(dev); | ||
967 | |||
968 | ULi_ethtool_gset(np, cmd); | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | static u32 netdev_get_link(struct net_device *dev) { | ||
974 | struct uli526x_board_info *np = netdev_priv(dev); | ||
975 | |||
976 | if(np->link_failed) | ||
977 | return 0; | ||
978 | else | ||
979 | return 1; | ||
980 | } | ||
981 | |||
982 | static void uli526x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | ||
983 | { | ||
984 | wol->supported = WAKE_PHY | WAKE_MAGIC; | ||
985 | wol->wolopts = 0; | ||
986 | } | ||
987 | |||
988 | static struct ethtool_ops netdev_ethtool_ops = { | ||
989 | .get_drvinfo = netdev_get_drvinfo, | ||
990 | .get_settings = netdev_get_settings, | ||
991 | .get_link = netdev_get_link, | ||
992 | .get_wol = uli526x_get_wol, | ||
993 | }; | ||
994 | |||
995 | /* | ||
996 | * A periodic timer routine | ||
997 | * Dynamic media sense, allocate Rx buffer... | ||
998 | */ | ||
999 | |||
1000 | static void uli526x_timer(unsigned long data) | ||
1001 | { | ||
1002 | u32 tmp_cr8; | ||
1003 | unsigned char tmp_cr12=0; | ||
1004 | struct net_device *dev = (struct net_device *) data; | ||
1005 | struct uli526x_board_info *db = netdev_priv(dev); | ||
1006 | unsigned long flags; | ||
1007 | u8 TmpSpeed=10; | ||
1008 | |||
1009 | //ULI526X_DBUG(0, "uli526x_timer()", 0); | ||
1010 | spin_lock_irqsave(&db->lock, flags); | ||
1011 | |||
1012 | |||
1013 | /* Dynamic reset ULI526X : system error or transmit time-out */ | ||
1014 | tmp_cr8 = inl(db->ioaddr + DCR8); | ||
1015 | if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) { | ||
1016 | db->reset_cr8++; | ||
1017 | db->wait_reset = 1; | ||
1018 | } | ||
1019 | db->interval_rx_cnt = 0; | ||
1020 | |||
1021 | /* TX polling kick monitor */ | ||
1022 | if ( db->tx_packet_cnt && | ||
1023 | time_after(jiffies, dev->trans_start + ULI526X_TX_KICK) ) { | ||
1024 | outl(0x1, dev->base_addr + DCR1); // Tx polling again | ||
1025 | |||
1026 | // TX Timeout | ||
1027 | if ( time_after(jiffies, dev->trans_start + ULI526X_TX_TIMEOUT) ) { | ||
1028 | db->reset_TXtimeout++; | ||
1029 | db->wait_reset = 1; | ||
1030 | printk( "%s: Tx timeout - resetting\n", | ||
1031 | dev->name); | ||
1032 | } | ||
1033 | } | ||
1034 | |||
1035 | if (db->wait_reset) { | ||
1036 | ULI526X_DBUG(0, "Dynamic Reset device", db->tx_packet_cnt); | ||
1037 | db->reset_count++; | ||
1038 | uli526x_dynamic_reset(dev); | ||
1039 | db->timer.expires = ULI526X_TIMER_WUT; | ||
1040 | add_timer(&db->timer); | ||
1041 | spin_unlock_irqrestore(&db->lock, flags); | ||
1042 | return; | ||
1043 | } | ||
1044 | |||
1045 | /* Link status check, Dynamic media type change */ | ||
1046 | if((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)!=0) | ||
1047 | tmp_cr12 = 3; | ||
1048 | |||
1049 | if ( !(tmp_cr12 & 0x3) && !db->link_failed ) { | ||
1050 | /* Link Failed */ | ||
1051 | ULI526X_DBUG(0, "Link Failed", tmp_cr12); | ||
1052 | netif_carrier_off(dev); | ||
1053 | printk(KERN_INFO "uli526x: %s NIC Link is Down\n",dev->name); | ||
1054 | db->link_failed = 1; | ||
1055 | |||
1056 | /* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */ | ||
1057 | /* AUTO don't need */ | ||
1058 | if ( !(db->media_mode & 0x8) ) | ||
1059 | phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id); | ||
1060 | |||
1061 | /* AUTO mode, if INT phyxcer link failed, select EXT device */ | ||
1062 | if (db->media_mode & ULI526X_AUTO) { | ||
1063 | db->cr6_data&=~0x00000200; /* bit9=0, HD mode */ | ||
1064 | update_cr6(db->cr6_data, db->ioaddr); | ||
1065 | } | ||
1066 | } else | ||
1067 | if ((tmp_cr12 & 0x3) && db->link_failed) { | ||
1068 | ULI526X_DBUG(0, "Link link OK", tmp_cr12); | ||
1069 | db->link_failed = 0; | ||
1070 | |||
1071 | /* Auto Sense Speed */ | ||
1072 | if ( (db->media_mode & ULI526X_AUTO) && | ||
1073 | uli526x_sense_speed(db) ) | ||
1074 | db->link_failed = 1; | ||
1075 | uli526x_process_mode(db); | ||
1076 | |||
1077 | if(db->link_failed==0) | ||
1078 | { | ||
1079 | if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD) | ||
1080 | { | ||
1081 | TmpSpeed = 100; | ||
1082 | } | ||
1083 | if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD) | ||
1084 | { | ||
1085 | printk(KERN_INFO "uli526x: %s NIC Link is Up %d Mbps Full duplex\n",dev->name,TmpSpeed); | ||
1086 | } | ||
1087 | else | ||
1088 | { | ||
1089 | printk(KERN_INFO "uli526x: %s NIC Link is Up %d Mbps Half duplex\n",dev->name,TmpSpeed); | ||
1090 | } | ||
1091 | netif_carrier_on(dev); | ||
1092 | } | ||
1093 | /* SHOW_MEDIA_TYPE(db->op_mode); */ | ||
1094 | } | ||
1095 | else if(!(tmp_cr12 & 0x3) && db->link_failed) | ||
1096 | { | ||
1097 | if(db->init==1) | ||
1098 | { | ||
1099 | printk(KERN_INFO "uli526x: %s NIC Link is Down\n",dev->name); | ||
1100 | netif_carrier_off(dev); | ||
1101 | } | ||
1102 | } | ||
1103 | db->init=0; | ||
1104 | |||
1105 | /* Timer active again */ | ||
1106 | db->timer.expires = ULI526X_TIMER_WUT; | ||
1107 | add_timer(&db->timer); | ||
1108 | spin_unlock_irqrestore(&db->lock, flags); | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | /* | ||
1113 | * Dynamic reset the ULI526X board | ||
1114 | * Stop ULI526X board | ||
1115 | * Free Tx/Rx allocated memory | ||
1116 | * Reset ULI526X board | ||
1117 | * Re-initialize ULI526X board | ||
1118 | */ | ||
1119 | |||
1120 | static void uli526x_dynamic_reset(struct net_device *dev) | ||
1121 | { | ||
1122 | struct uli526x_board_info *db = netdev_priv(dev); | ||
1123 | |||
1124 | ULI526X_DBUG(0, "uli526x_dynamic_reset()", 0); | ||
1125 | |||
1126 | /* Sopt MAC controller */ | ||
1127 | db->cr6_data &= ~(CR6_RXSC | CR6_TXSC); /* Disable Tx/Rx */ | ||
1128 | update_cr6(db->cr6_data, dev->base_addr); | ||
1129 | outl(0, dev->base_addr + DCR7); /* Disable Interrupt */ | ||
1130 | outl(inl(dev->base_addr + DCR5), dev->base_addr + DCR5); | ||
1131 | |||
1132 | /* Disable upper layer interface */ | ||
1133 | netif_stop_queue(dev); | ||
1134 | |||
1135 | /* Free Rx Allocate buffer */ | ||
1136 | uli526x_free_rxbuffer(db); | ||
1137 | |||
1138 | /* system variable init */ | ||
1139 | db->tx_packet_cnt = 0; | ||
1140 | db->rx_avail_cnt = 0; | ||
1141 | db->link_failed = 1; | ||
1142 | db->init=1; | ||
1143 | db->wait_reset = 0; | ||
1144 | |||
1145 | /* Re-initialize ULI526X board */ | ||
1146 | uli526x_init(dev); | ||
1147 | |||
1148 | /* Restart upper layer interface */ | ||
1149 | netif_wake_queue(dev); | ||
1150 | } | ||
1151 | |||
1152 | |||
1153 | /* | ||
1154 | * free all allocated rx buffer | ||
1155 | */ | ||
1156 | |||
1157 | static void uli526x_free_rxbuffer(struct uli526x_board_info * db) | ||
1158 | { | ||
1159 | ULI526X_DBUG(0, "uli526x_free_rxbuffer()", 0); | ||
1160 | |||
1161 | /* free allocated rx buffer */ | ||
1162 | while (db->rx_avail_cnt) { | ||
1163 | dev_kfree_skb(db->rx_ready_ptr->rx_skb_ptr); | ||
1164 | db->rx_ready_ptr = db->rx_ready_ptr->next_rx_desc; | ||
1165 | db->rx_avail_cnt--; | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | |||
1170 | /* | ||
1171 | * Reuse the SK buffer | ||
1172 | */ | ||
1173 | |||
1174 | static void uli526x_reuse_skb(struct uli526x_board_info *db, struct sk_buff * skb) | ||
1175 | { | ||
1176 | struct rx_desc *rxptr = db->rx_insert_ptr; | ||
1177 | |||
1178 | if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) { | ||
1179 | rxptr->rx_skb_ptr = skb; | ||
1180 | rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); | ||
1181 | wmb(); | ||
1182 | rxptr->rdes0 = cpu_to_le32(0x80000000); | ||
1183 | db->rx_avail_cnt++; | ||
1184 | db->rx_insert_ptr = rxptr->next_rx_desc; | ||
1185 | } else | ||
1186 | ULI526X_DBUG(0, "SK Buffer reuse method error", db->rx_avail_cnt); | ||
1187 | } | ||
1188 | |||
1189 | |||
1190 | /* | ||
1191 | * Initialize transmit/Receive descriptor | ||
1192 | * Using Chain structure, and allocate Tx/Rx buffer | ||
1193 | */ | ||
1194 | |||
1195 | static void uli526x_descriptor_init(struct uli526x_board_info *db, unsigned long ioaddr) | ||
1196 | { | ||
1197 | struct tx_desc *tmp_tx; | ||
1198 | struct rx_desc *tmp_rx; | ||
1199 | unsigned char *tmp_buf; | ||
1200 | dma_addr_t tmp_tx_dma, tmp_rx_dma; | ||
1201 | dma_addr_t tmp_buf_dma; | ||
1202 | int i; | ||
1203 | |||
1204 | ULI526X_DBUG(0, "uli526x_descriptor_init()", 0); | ||
1205 | |||
1206 | /* tx descriptor start pointer */ | ||
1207 | db->tx_insert_ptr = db->first_tx_desc; | ||
1208 | db->tx_remove_ptr = db->first_tx_desc; | ||
1209 | outl(db->first_tx_desc_dma, ioaddr + DCR4); /* TX DESC address */ | ||
1210 | |||
1211 | /* rx descriptor start pointer */ | ||
1212 | db->first_rx_desc = (void *)db->first_tx_desc + sizeof(struct tx_desc) * TX_DESC_CNT; | ||
1213 | db->first_rx_desc_dma = db->first_tx_desc_dma + sizeof(struct tx_desc) * TX_DESC_CNT; | ||
1214 | db->rx_insert_ptr = db->first_rx_desc; | ||
1215 | db->rx_ready_ptr = db->first_rx_desc; | ||
1216 | outl(db->first_rx_desc_dma, ioaddr + DCR3); /* RX DESC address */ | ||
1217 | |||
1218 | /* Init Transmit chain */ | ||
1219 | tmp_buf = db->buf_pool_start; | ||
1220 | tmp_buf_dma = db->buf_pool_dma_start; | ||
1221 | tmp_tx_dma = db->first_tx_desc_dma; | ||
1222 | for (tmp_tx = db->first_tx_desc, i = 0; i < TX_DESC_CNT; i++, tmp_tx++) { | ||
1223 | tmp_tx->tx_buf_ptr = tmp_buf; | ||
1224 | tmp_tx->tdes0 = cpu_to_le32(0); | ||
1225 | tmp_tx->tdes1 = cpu_to_le32(0x81000000); /* IC, chain */ | ||
1226 | tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma); | ||
1227 | tmp_tx_dma += sizeof(struct tx_desc); | ||
1228 | tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma); | ||
1229 | tmp_tx->next_tx_desc = tmp_tx + 1; | ||
1230 | tmp_buf = tmp_buf + TX_BUF_ALLOC; | ||
1231 | tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC; | ||
1232 | } | ||
1233 | (--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma); | ||
1234 | tmp_tx->next_tx_desc = db->first_tx_desc; | ||
1235 | |||
1236 | /* Init Receive descriptor chain */ | ||
1237 | tmp_rx_dma=db->first_rx_desc_dma; | ||
1238 | for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT; i++, tmp_rx++) { | ||
1239 | tmp_rx->rdes0 = cpu_to_le32(0); | ||
1240 | tmp_rx->rdes1 = cpu_to_le32(0x01000600); | ||
1241 | tmp_rx_dma += sizeof(struct rx_desc); | ||
1242 | tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma); | ||
1243 | tmp_rx->next_rx_desc = tmp_rx + 1; | ||
1244 | } | ||
1245 | (--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma); | ||
1246 | tmp_rx->next_rx_desc = db->first_rx_desc; | ||
1247 | |||
1248 | /* pre-allocate Rx buffer */ | ||
1249 | allocate_rx_buffer(db); | ||
1250 | } | ||
1251 | |||
1252 | |||
1253 | /* | ||
1254 | * Update CR6 value | ||
1255 | * Firstly stop ULI526X, then written value and start | ||
1256 | */ | ||
1257 | |||
1258 | static void update_cr6(u32 cr6_data, unsigned long ioaddr) | ||
1259 | { | ||
1260 | |||
1261 | outl(cr6_data, ioaddr + DCR6); | ||
1262 | udelay(5); | ||
1263 | } | ||
1264 | |||
1265 | |||
1266 | /* | ||
1267 | * Send a setup frame for M5261/M5263 | ||
1268 | * This setup frame initialize ULI526X address filter mode | ||
1269 | */ | ||
1270 | |||
1271 | static void send_filter_frame(struct net_device *dev, int mc_cnt) | ||
1272 | { | ||
1273 | struct uli526x_board_info *db = netdev_priv(dev); | ||
1274 | struct dev_mc_list *mcptr; | ||
1275 | struct tx_desc *txptr; | ||
1276 | u16 * addrptr; | ||
1277 | u32 * suptr; | ||
1278 | int i; | ||
1279 | |||
1280 | ULI526X_DBUG(0, "send_filter_frame()", 0); | ||
1281 | |||
1282 | txptr = db->tx_insert_ptr; | ||
1283 | suptr = (u32 *) txptr->tx_buf_ptr; | ||
1284 | |||
1285 | /* Node address */ | ||
1286 | addrptr = (u16 *) dev->dev_addr; | ||
1287 | *suptr++ = addrptr[0]; | ||
1288 | *suptr++ = addrptr[1]; | ||
1289 | *suptr++ = addrptr[2]; | ||
1290 | |||
1291 | /* broadcast address */ | ||
1292 | *suptr++ = 0xffff; | ||
1293 | *suptr++ = 0xffff; | ||
1294 | *suptr++ = 0xffff; | ||
1295 | |||
1296 | /* fit the multicast address */ | ||
1297 | for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) { | ||
1298 | addrptr = (u16 *) mcptr->dmi_addr; | ||
1299 | *suptr++ = addrptr[0]; | ||
1300 | *suptr++ = addrptr[1]; | ||
1301 | *suptr++ = addrptr[2]; | ||
1302 | } | ||
1303 | |||
1304 | for (; i<14; i++) { | ||
1305 | *suptr++ = 0xffff; | ||
1306 | *suptr++ = 0xffff; | ||
1307 | *suptr++ = 0xffff; | ||
1308 | } | ||
1309 | |||
1310 | /* prepare the setup frame */ | ||
1311 | db->tx_insert_ptr = txptr->next_tx_desc; | ||
1312 | txptr->tdes1 = cpu_to_le32(0x890000c0); | ||
1313 | |||
1314 | /* Resource Check and Send the setup packet */ | ||
1315 | if (db->tx_packet_cnt < TX_DESC_CNT) { | ||
1316 | /* Resource Empty */ | ||
1317 | db->tx_packet_cnt++; | ||
1318 | txptr->tdes0 = cpu_to_le32(0x80000000); | ||
1319 | update_cr6(db->cr6_data | 0x2000, dev->base_addr); | ||
1320 | outl(0x1, dev->base_addr + DCR1); /* Issue Tx polling */ | ||
1321 | update_cr6(db->cr6_data, dev->base_addr); | ||
1322 | dev->trans_start = jiffies; | ||
1323 | } else | ||
1324 | printk(KERN_ERR DRV_NAME ": No Tx resource - Send_filter_frame!\n"); | ||
1325 | } | ||
1326 | |||
1327 | |||
1328 | /* | ||
1329 | * Allocate rx buffer, | ||
1330 | * As possible as allocate maxiumn Rx buffer | ||
1331 | */ | ||
1332 | |||
1333 | static void allocate_rx_buffer(struct uli526x_board_info *db) | ||
1334 | { | ||
1335 | struct rx_desc *rxptr; | ||
1336 | struct sk_buff *skb; | ||
1337 | |||
1338 | rxptr = db->rx_insert_ptr; | ||
1339 | |||
1340 | while(db->rx_avail_cnt < RX_DESC_CNT) { | ||
1341 | if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) | ||
1342 | break; | ||
1343 | rxptr->rx_skb_ptr = skb; /* FIXME (?) */ | ||
1344 | rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); | ||
1345 | wmb(); | ||
1346 | rxptr->rdes0 = cpu_to_le32(0x80000000); | ||
1347 | rxptr = rxptr->next_rx_desc; | ||
1348 | db->rx_avail_cnt++; | ||
1349 | } | ||
1350 | |||
1351 | db->rx_insert_ptr = rxptr; | ||
1352 | } | ||
1353 | |||
1354 | |||
1355 | /* | ||
1356 | * Read one word data from the serial ROM | ||
1357 | */ | ||
1358 | |||
1359 | static u16 read_srom_word(long ioaddr, int offset) | ||
1360 | { | ||
1361 | int i; | ||
1362 | u16 srom_data = 0; | ||
1363 | long cr9_ioaddr = ioaddr + DCR9; | ||
1364 | |||
1365 | outl(CR9_SROM_READ, cr9_ioaddr); | ||
1366 | outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); | ||
1367 | |||
1368 | /* Send the Read Command 110b */ | ||
1369 | SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); | ||
1370 | SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr); | ||
1371 | SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr); | ||
1372 | |||
1373 | /* Send the offset */ | ||
1374 | for (i = 5; i >= 0; i--) { | ||
1375 | srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0; | ||
1376 | SROM_CLK_WRITE(srom_data, cr9_ioaddr); | ||
1377 | } | ||
1378 | |||
1379 | outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); | ||
1380 | |||
1381 | for (i = 16; i > 0; i--) { | ||
1382 | outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr); | ||
1383 | udelay(5); | ||
1384 | srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT) ? 1 : 0); | ||
1385 | outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr); | ||
1386 | udelay(5); | ||
1387 | } | ||
1388 | |||
1389 | outl(CR9_SROM_READ, cr9_ioaddr); | ||
1390 | return srom_data; | ||
1391 | } | ||
1392 | |||
1393 | |||
1394 | /* | ||
1395 | * Auto sense the media mode | ||
1396 | */ | ||
1397 | |||
1398 | static u8 uli526x_sense_speed(struct uli526x_board_info * db) | ||
1399 | { | ||
1400 | u8 ErrFlag = 0; | ||
1401 | u16 phy_mode; | ||
1402 | |||
1403 | phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id); | ||
1404 | phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id); | ||
1405 | |||
1406 | if ( (phy_mode & 0x24) == 0x24 ) { | ||
1407 | |||
1408 | phy_mode = ((phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id) & 0x01e0)<<7); | ||
1409 | if(phy_mode&0x8000) | ||
1410 | phy_mode = 0x8000; | ||
1411 | else if(phy_mode&0x4000) | ||
1412 | phy_mode = 0x4000; | ||
1413 | else if(phy_mode&0x2000) | ||
1414 | phy_mode = 0x2000; | ||
1415 | else | ||
1416 | phy_mode = 0x1000; | ||
1417 | |||
1418 | /* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */ | ||
1419 | switch (phy_mode) { | ||
1420 | case 0x1000: db->op_mode = ULI526X_10MHF; break; | ||
1421 | case 0x2000: db->op_mode = ULI526X_10MFD; break; | ||
1422 | case 0x4000: db->op_mode = ULI526X_100MHF; break; | ||
1423 | case 0x8000: db->op_mode = ULI526X_100MFD; break; | ||
1424 | default: db->op_mode = ULI526X_10MHF; ErrFlag = 1; break; | ||
1425 | } | ||
1426 | } else { | ||
1427 | db->op_mode = ULI526X_10MHF; | ||
1428 | ULI526X_DBUG(0, "Link Failed :", phy_mode); | ||
1429 | ErrFlag = 1; | ||
1430 | } | ||
1431 | |||
1432 | return ErrFlag; | ||
1433 | } | ||
1434 | |||
1435 | |||
1436 | /* | ||
1437 | * Set 10/100 phyxcer capability | ||
1438 | * AUTO mode : phyxcer register4 is NIC capability | ||
1439 | * Force mode: phyxcer register4 is the force media | ||
1440 | */ | ||
1441 | |||
1442 | static void uli526x_set_phyxcer(struct uli526x_board_info *db) | ||
1443 | { | ||
1444 | u16 phy_reg; | ||
1445 | |||
1446 | /* Phyxcer capability setting */ | ||
1447 | phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0; | ||
1448 | |||
1449 | if (db->media_mode & ULI526X_AUTO) { | ||
1450 | /* AUTO Mode */ | ||
1451 | phy_reg |= db->PHY_reg4; | ||
1452 | } else { | ||
1453 | /* Force Mode */ | ||
1454 | switch(db->media_mode) { | ||
1455 | case ULI526X_10MHF: phy_reg |= 0x20; break; | ||
1456 | case ULI526X_10MFD: phy_reg |= 0x40; break; | ||
1457 | case ULI526X_100MHF: phy_reg |= 0x80; break; | ||
1458 | case ULI526X_100MFD: phy_reg |= 0x100; break; | ||
1459 | } | ||
1460 | |||
1461 | } | ||
1462 | |||
1463 | /* Write new capability to Phyxcer Reg4 */ | ||
1464 | if ( !(phy_reg & 0x01e0)) { | ||
1465 | phy_reg|=db->PHY_reg4; | ||
1466 | db->media_mode|=ULI526X_AUTO; | ||
1467 | } | ||
1468 | phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id); | ||
1469 | |||
1470 | /* Restart Auto-Negotiation */ | ||
1471 | phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id); | ||
1472 | udelay(50); | ||
1473 | } | ||
1474 | |||
1475 | |||
1476 | /* | ||
1477 | * Process op-mode | ||
1478 | AUTO mode : PHY controller in Auto-negotiation Mode | ||
1479 | * Force mode: PHY controller in force mode with HUB | ||
1480 | * N-way force capability with SWITCH | ||
1481 | */ | ||
1482 | |||
1483 | static void uli526x_process_mode(struct uli526x_board_info *db) | ||
1484 | { | ||
1485 | u16 phy_reg; | ||
1486 | |||
1487 | /* Full Duplex Mode Check */ | ||
1488 | if (db->op_mode & 0x4) | ||
1489 | db->cr6_data |= CR6_FDM; /* Set Full Duplex Bit */ | ||
1490 | else | ||
1491 | db->cr6_data &= ~CR6_FDM; /* Clear Full Duplex Bit */ | ||
1492 | |||
1493 | update_cr6(db->cr6_data, db->ioaddr); | ||
1494 | |||
1495 | /* 10/100M phyxcer force mode need */ | ||
1496 | if ( !(db->media_mode & 0x8)) { | ||
1497 | /* Forece Mode */ | ||
1498 | phy_reg = phy_read(db->ioaddr, db->phy_addr, 6, db->chip_id); | ||
1499 | if ( !(phy_reg & 0x1) ) { | ||
1500 | /* parter without N-Way capability */ | ||
1501 | phy_reg = 0x0; | ||
1502 | switch(db->op_mode) { | ||
1503 | case ULI526X_10MHF: phy_reg = 0x0; break; | ||
1504 | case ULI526X_10MFD: phy_reg = 0x100; break; | ||
1505 | case ULI526X_100MHF: phy_reg = 0x2000; break; | ||
1506 | case ULI526X_100MFD: phy_reg = 0x2100; break; | ||
1507 | } | ||
1508 | phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id); | ||
1509 | phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id); | ||
1510 | } | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1514 | |||
1515 | /* | ||
1516 | * Write a word to Phy register | ||
1517 | */ | ||
1518 | |||
1519 | static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id) | ||
1520 | { | ||
1521 | u16 i; | ||
1522 | unsigned long ioaddr; | ||
1523 | |||
1524 | if(chip_id == PCI_ULI5263_ID) | ||
1525 | { | ||
1526 | phy_writeby_cr10(iobase, phy_addr, offset, phy_data); | ||
1527 | return; | ||
1528 | } | ||
1529 | /* M5261/M5263 Chip */ | ||
1530 | ioaddr = iobase + DCR9; | ||
1531 | |||
1532 | /* Send 33 synchronization clock to Phy controller */ | ||
1533 | for (i = 0; i < 35; i++) | ||
1534 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1535 | |||
1536 | /* Send start command(01) to Phy */ | ||
1537 | phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); | ||
1538 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1539 | |||
1540 | /* Send write command(01) to Phy */ | ||
1541 | phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); | ||
1542 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1543 | |||
1544 | /* Send Phy address */ | ||
1545 | for (i = 0x10; i > 0; i = i >> 1) | ||
1546 | phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id); | ||
1547 | |||
1548 | /* Send register address */ | ||
1549 | for (i = 0x10; i > 0; i = i >> 1) | ||
1550 | phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id); | ||
1551 | |||
1552 | /* written trasnition */ | ||
1553 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1554 | phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); | ||
1555 | |||
1556 | /* Write a word data to PHY controller */ | ||
1557 | for ( i = 0x8000; i > 0; i >>= 1) | ||
1558 | phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0, chip_id); | ||
1559 | |||
1560 | } | ||
1561 | |||
1562 | |||
1563 | /* | ||
1564 | * Read a word data from phy register | ||
1565 | */ | ||
1566 | |||
1567 | static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id) | ||
1568 | { | ||
1569 | int i; | ||
1570 | u16 phy_data; | ||
1571 | unsigned long ioaddr; | ||
1572 | |||
1573 | if(chip_id == PCI_ULI5263_ID) | ||
1574 | return phy_readby_cr10(iobase, phy_addr, offset); | ||
1575 | /* M5261/M5263 Chip */ | ||
1576 | ioaddr = iobase + DCR9; | ||
1577 | |||
1578 | /* Send 33 synchronization clock to Phy controller */ | ||
1579 | for (i = 0; i < 35; i++) | ||
1580 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1581 | |||
1582 | /* Send start command(01) to Phy */ | ||
1583 | phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); | ||
1584 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1585 | |||
1586 | /* Send read command(10) to Phy */ | ||
1587 | phy_write_1bit(ioaddr, PHY_DATA_1, chip_id); | ||
1588 | phy_write_1bit(ioaddr, PHY_DATA_0, chip_id); | ||
1589 | |||
1590 | /* Send Phy address */ | ||
1591 | for (i = 0x10; i > 0; i = i >> 1) | ||
1592 | phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0, chip_id); | ||
1593 | |||
1594 | /* Send register address */ | ||
1595 | for (i = 0x10; i > 0; i = i >> 1) | ||
1596 | phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0, chip_id); | ||
1597 | |||
1598 | /* Skip transition state */ | ||
1599 | phy_read_1bit(ioaddr, chip_id); | ||
1600 | |||
1601 | /* read 16bit data */ | ||
1602 | for (phy_data = 0, i = 0; i < 16; i++) { | ||
1603 | phy_data <<= 1; | ||
1604 | phy_data |= phy_read_1bit(ioaddr, chip_id); | ||
1605 | } | ||
1606 | |||
1607 | return phy_data; | ||
1608 | } | ||
1609 | |||
1610 | static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset) | ||
1611 | { | ||
1612 | unsigned long ioaddr,cr10_value; | ||
1613 | |||
1614 | ioaddr = iobase + DCR10; | ||
1615 | cr10_value = phy_addr; | ||
1616 | cr10_value = (cr10_value<<5) + offset; | ||
1617 | cr10_value = (cr10_value<<16) + 0x08000000; | ||
1618 | outl(cr10_value,ioaddr); | ||
1619 | udelay(1); | ||
1620 | while(1) | ||
1621 | { | ||
1622 | cr10_value = inl(ioaddr); | ||
1623 | if(cr10_value&0x10000000) | ||
1624 | break; | ||
1625 | } | ||
1626 | return (cr10_value&0x0ffff); | ||
1627 | } | ||
1628 | |||
1629 | static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data) | ||
1630 | { | ||
1631 | unsigned long ioaddr,cr10_value; | ||
1632 | |||
1633 | ioaddr = iobase + DCR10; | ||
1634 | cr10_value = phy_addr; | ||
1635 | cr10_value = (cr10_value<<5) + offset; | ||
1636 | cr10_value = (cr10_value<<16) + 0x04000000 + phy_data; | ||
1637 | outl(cr10_value,ioaddr); | ||
1638 | udelay(1); | ||
1639 | } | ||
1640 | /* | ||
1641 | * Write one bit data to Phy Controller | ||
1642 | */ | ||
1643 | |||
1644 | static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id) | ||
1645 | { | ||
1646 | outl(phy_data , ioaddr); /* MII Clock Low */ | ||
1647 | udelay(1); | ||
1648 | outl(phy_data | MDCLKH, ioaddr); /* MII Clock High */ | ||
1649 | udelay(1); | ||
1650 | outl(phy_data , ioaddr); /* MII Clock Low */ | ||
1651 | udelay(1); | ||
1652 | } | ||
1653 | |||
1654 | |||
1655 | /* | ||
1656 | * Read one bit phy data from PHY controller | ||
1657 | */ | ||
1658 | |||
1659 | static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id) | ||
1660 | { | ||
1661 | u16 phy_data; | ||
1662 | |||
1663 | outl(0x50000 , ioaddr); | ||
1664 | udelay(1); | ||
1665 | phy_data = ( inl(ioaddr) >> 19 ) & 0x1; | ||
1666 | outl(0x40000 , ioaddr); | ||
1667 | udelay(1); | ||
1668 | |||
1669 | return phy_data; | ||
1670 | } | ||
1671 | |||
1672 | |||
1673 | static struct pci_device_id uli526x_pci_tbl[] = { | ||
1674 | { 0x10B9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5261_ID }, | ||
1675 | { 0x10B9, 0x5263, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_ULI5263_ID }, | ||
1676 | { 0, } | ||
1677 | }; | ||
1678 | MODULE_DEVICE_TABLE(pci, uli526x_pci_tbl); | ||
1679 | |||
1680 | |||
1681 | static struct pci_driver uli526x_driver = { | ||
1682 | .name = "uli526x", | ||
1683 | .id_table = uli526x_pci_tbl, | ||
1684 | .probe = uli526x_init_one, | ||
1685 | .remove = __devexit_p(uli526x_remove_one), | ||
1686 | }; | ||
1687 | |||
1688 | MODULE_AUTHOR("Peer Chen, peer.chen@uli.com.tw"); | ||
1689 | MODULE_DESCRIPTION("ULi M5261/M5263 fast ethernet driver"); | ||
1690 | MODULE_LICENSE("GPL"); | ||
1691 | |||
1692 | MODULE_PARM(debug, "i"); | ||
1693 | MODULE_PARM(mode, "i"); | ||
1694 | MODULE_PARM(cr6set, "i"); | ||
1695 | MODULE_PARM_DESC(debug, "ULi M5261/M5263 enable debugging (0-1)"); | ||
1696 | MODULE_PARM_DESC(mode, "ULi M5261/M5263: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA"); | ||
1697 | |||
1698 | /* Description: | ||
1699 | * when user used insmod to add module, system invoked init_module() | ||
1700 | * to register the services. | ||
1701 | */ | ||
1702 | |||
1703 | static int __init uli526x_init_module(void) | ||
1704 | { | ||
1705 | int rc; | ||
1706 | |||
1707 | printk(version); | ||
1708 | printed_version = 1; | ||
1709 | |||
1710 | ULI526X_DBUG(0, "init_module() ", debug); | ||
1711 | |||
1712 | if (debug) | ||
1713 | uli526x_debug = debug; /* set debug flag */ | ||
1714 | if (cr6set) | ||
1715 | uli526x_cr6_user_set = cr6set; | ||
1716 | |||
1717 | switch(mode) { | ||
1718 | case ULI526X_10MHF: | ||
1719 | case ULI526X_100MHF: | ||
1720 | case ULI526X_10MFD: | ||
1721 | case ULI526X_100MFD: | ||
1722 | uli526x_media_mode = mode; | ||
1723 | break; | ||
1724 | default:uli526x_media_mode = ULI526X_AUTO; | ||
1725 | break; | ||
1726 | } | ||
1727 | |||
1728 | rc = pci_module_init(&uli526x_driver); | ||
1729 | if (rc < 0) | ||
1730 | return rc; | ||
1731 | |||
1732 | return 0; | ||
1733 | } | ||
1734 | |||
1735 | |||
1736 | /* | ||
1737 | * Description: | ||
1738 | * when user used rmmod to delete module, system invoked clean_module() | ||
1739 | * to un-register all registered services. | ||
1740 | */ | ||
1741 | |||
1742 | static void __exit uli526x_cleanup_module(void) | ||
1743 | { | ||
1744 | ULI526X_DBUG(0, "uli526x_clean_module() ", debug); | ||
1745 | pci_unregister_driver(&uli526x_driver); | ||
1746 | } | ||
1747 | |||
1748 | module_init(uli526x_init_module); | ||
1749 | module_exit(uli526x_cleanup_module); | ||
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index 6e74af62ca08..9e56fc346ba4 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <linux/sched.h> /* for jiffies, HZ, etc. */ | 56 | #include <linux/sched.h> /* for jiffies, HZ, etc. */ |
57 | #include <linux/cycx_drv.h> /* API definitions */ | 57 | #include <linux/cycx_drv.h> /* API definitions */ |
58 | #include <linux/cycx_cfm.h> /* CYCX firmware module definitions */ | 58 | #include <linux/cycx_cfm.h> /* CYCX firmware module definitions */ |
59 | #include <linux/delay.h> /* udelay */ | 59 | #include <linux/delay.h> /* udelay, msleep_interruptible */ |
60 | #include <asm/io.h> /* read[wl], write[wl], ioremap, iounmap */ | 60 | #include <asm/io.h> /* read[wl], write[wl], ioremap, iounmap */ |
61 | 61 | ||
62 | #define MOD_VERSION 0 | 62 | #define MOD_VERSION 0 |
@@ -74,7 +74,6 @@ static int reset_cyc2x(void __iomem *addr); | |||
74 | static int detect_cyc2x(void __iomem *addr); | 74 | static int detect_cyc2x(void __iomem *addr); |
75 | 75 | ||
76 | /* Miscellaneous functions */ | 76 | /* Miscellaneous functions */ |
77 | static void delay_cycx(int sec); | ||
78 | static int get_option_index(long *optlist, long optval); | 77 | static int get_option_index(long *optlist, long optval); |
79 | static u16 checksum(u8 *buf, u32 len); | 78 | static u16 checksum(u8 *buf, u32 len); |
80 | 79 | ||
@@ -259,7 +258,7 @@ static int memory_exists(void __iomem *addr) | |||
259 | if (readw(addr + 0x10) == TEST_PATTERN) | 258 | if (readw(addr + 0x10) == TEST_PATTERN) |
260 | return 1; | 259 | return 1; |
261 | 260 | ||
262 | delay_cycx(1); | 261 | msleep_interruptible(1 * 1000); |
263 | } | 262 | } |
264 | 263 | ||
265 | return 0; | 264 | return 0; |
@@ -316,7 +315,7 @@ static void cycx_reset_boot(void __iomem *addr, u8 *code, u32 len) | |||
316 | 315 | ||
317 | /* 80186 was in hold, go */ | 316 | /* 80186 was in hold, go */ |
318 | writeb(0, addr + START_CPU); | 317 | writeb(0, addr + START_CPU); |
319 | delay_cycx(1); | 318 | msleep_interruptible(1 * 1000); |
320 | } | 319 | } |
321 | 320 | ||
322 | /* Load data.bin file through boot (reset) interface. */ | 321 | /* Load data.bin file through boot (reset) interface. */ |
@@ -462,13 +461,13 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) | |||
462 | cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size); | 461 | cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size); |
463 | /* reset is waiting for boot */ | 462 | /* reset is waiting for boot */ |
464 | writew(GEN_POWER_ON, pt_cycld); | 463 | writew(GEN_POWER_ON, pt_cycld); |
465 | delay_cycx(1); | 464 | msleep_interruptible(1 * 1000); |
466 | 465 | ||
467 | for (j = 0 ; j < 3 ; j++) | 466 | for (j = 0 ; j < 3 ; j++) |
468 | if (!readw(pt_cycld)) | 467 | if (!readw(pt_cycld)) |
469 | goto reset_loaded; | 468 | goto reset_loaded; |
470 | else | 469 | else |
471 | delay_cycx(1); | 470 | msleep_interruptible(1 * 1000); |
472 | } | 471 | } |
473 | 472 | ||
474 | printk(KERN_ERR "%s: reset not started.\n", modname); | 473 | printk(KERN_ERR "%s: reset not started.\n", modname); |
@@ -495,7 +494,7 @@ reset_loaded: | |||
495 | 494 | ||
496 | /* Arthur Ganzert's tip: wait a while after the firmware loading... | 495 | /* Arthur Ganzert's tip: wait a while after the firmware loading... |
497 | seg abr 26 17:17:12 EST 1999 - acme */ | 496 | seg abr 26 17:17:12 EST 1999 - acme */ |
498 | delay_cycx(7); | 497 | msleep_interruptible(7 * 1000); |
499 | printk(KERN_INFO "%s: firmware loaded!\n", modname); | 498 | printk(KERN_INFO "%s: firmware loaded!\n", modname); |
500 | 499 | ||
501 | /* enable interrupts */ | 500 | /* enable interrupts */ |
@@ -547,20 +546,13 @@ static int get_option_index(long *optlist, long optval) | |||
547 | static int reset_cyc2x(void __iomem *addr) | 546 | static int reset_cyc2x(void __iomem *addr) |
548 | { | 547 | { |
549 | writeb(0, addr + RST_ENABLE); | 548 | writeb(0, addr + RST_ENABLE); |
550 | delay_cycx(2); | 549 | msleep_interruptible(2 * 1000); |
551 | writeb(0, addr + RST_DISABLE); | 550 | writeb(0, addr + RST_DISABLE); |
552 | delay_cycx(2); | 551 | msleep_interruptible(2 * 1000); |
553 | 552 | ||
554 | return memory_exists(addr); | 553 | return memory_exists(addr); |
555 | } | 554 | } |
556 | 555 | ||
557 | /* Delay */ | ||
558 | static void delay_cycx(int sec) | ||
559 | { | ||
560 | set_current_state(TASK_INTERRUPTIBLE); | ||
561 | schedule_timeout(sec * HZ); | ||
562 | } | ||
563 | |||
564 | /* Calculate 16-bit CRC using CCITT polynomial. */ | 556 | /* Calculate 16-bit CRC using CCITT polynomial. */ |
565 | static u16 checksum(u8 *buf, u32 len) | 557 | static u16 checksum(u8 *buf, u32 len) |
566 | { | 558 | { |
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc_generic.c index a63f6a2cc4f7..cdd4c09c2d90 100644 --- a/drivers/net/wan/hdlc_generic.c +++ b/drivers/net/wan/hdlc_generic.c | |||
@@ -61,7 +61,7 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev) | |||
61 | 61 | ||
62 | 62 | ||
63 | static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, | 63 | static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, |
64 | struct packet_type *p) | 64 | struct packet_type *p, struct net_device *orig_dev) |
65 | { | 65 | { |
66 | hdlc_device *hdlc = dev_to_hdlc(dev); | 66 | hdlc_device *hdlc = dev_to_hdlc(dev); |
67 | if (hdlc->proto.netif_rx) | 67 | if (hdlc->proto.netif_rx) |
diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 7f2e3653c5e5..6c302e9dbca2 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c | |||
@@ -86,7 +86,7 @@ static __inline__ int dev_is_ethdev(struct net_device *dev) | |||
86 | /* | 86 | /* |
87 | * Receive a LAPB frame via an ethernet interface. | 87 | * Receive a LAPB frame via an ethernet interface. |
88 | */ | 88 | */ |
89 | static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) | 89 | static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev) |
90 | { | 90 | { |
91 | int len, err; | 91 | int len, err; |
92 | struct lapbethdev *lapbeth; | 92 | struct lapbethdev *lapbeth; |
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c index c5f5e62aab8b..0497dbdb8631 100644 --- a/drivers/net/wan/sdla_fr.c +++ b/drivers/net/wan/sdla_fr.c | |||
@@ -445,7 +445,7 @@ void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags); | |||
445 | void s508_s514_lock(sdla_t *card, unsigned long *smp_flags); | 445 | void s508_s514_lock(sdla_t *card, unsigned long *smp_flags); |
446 | 446 | ||
447 | unsigned short calc_checksum (char *, int); | 447 | unsigned short calc_checksum (char *, int); |
448 | static int setup_fr_header(struct sk_buff** skb, | 448 | static int setup_fr_header(struct sk_buff *skb, |
449 | struct net_device* dev, char op_mode); | 449 | struct net_device* dev, char op_mode); |
450 | 450 | ||
451 | 451 | ||
@@ -1372,7 +1372,7 @@ static int if_send(struct sk_buff* skb, struct net_device* dev) | |||
1372 | /* Move the if_header() code to here. By inserting frame | 1372 | /* Move the if_header() code to here. By inserting frame |
1373 | * relay header in if_header() we would break the | 1373 | * relay header in if_header() we would break the |
1374 | * tcpdump and other packet sniffers */ | 1374 | * tcpdump and other packet sniffers */ |
1375 | chan->fr_header_len = setup_fr_header(&skb,dev,chan->common.usedby); | 1375 | chan->fr_header_len = setup_fr_header(skb,dev,chan->common.usedby); |
1376 | if (chan->fr_header_len < 0 ){ | 1376 | if (chan->fr_header_len < 0 ){ |
1377 | ++chan->ifstats.tx_dropped; | 1377 | ++chan->ifstats.tx_dropped; |
1378 | ++card->wandev.stats.tx_dropped; | 1378 | ++card->wandev.stats.tx_dropped; |
@@ -1597,8 +1597,6 @@ static int setup_for_delayed_transmit(struct net_device* dev, | |||
1597 | return 1; | 1597 | return 1; |
1598 | } | 1598 | } |
1599 | 1599 | ||
1600 | skb_unlink(skb); | ||
1601 | |||
1602 | chan->transmit_length = len; | 1600 | chan->transmit_length = len; |
1603 | chan->delay_skb = skb; | 1601 | chan->delay_skb = skb; |
1604 | 1602 | ||
@@ -4871,18 +4869,15 @@ static void unconfig_fr (sdla_t *card) | |||
4871 | } | 4869 | } |
4872 | } | 4870 | } |
4873 | 4871 | ||
4874 | static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev, | 4872 | static int setup_fr_header(struct sk_buff *skb, struct net_device* dev, |
4875 | char op_mode) | 4873 | char op_mode) |
4876 | { | 4874 | { |
4877 | struct sk_buff *skb = *skb_orig; | ||
4878 | fr_channel_t *chan=dev->priv; | 4875 | fr_channel_t *chan=dev->priv; |
4879 | 4876 | ||
4880 | if (op_mode == WANPIPE){ | 4877 | if (op_mode == WANPIPE) { |
4881 | |||
4882 | chan->fr_header[0]=Q922_UI; | 4878 | chan->fr_header[0]=Q922_UI; |
4883 | 4879 | ||
4884 | switch (htons(skb->protocol)){ | 4880 | switch (htons(skb->protocol)){ |
4885 | |||
4886 | case ETH_P_IP: | 4881 | case ETH_P_IP: |
4887 | chan->fr_header[1]=NLPID_IP; | 4882 | chan->fr_header[1]=NLPID_IP; |
4888 | break; | 4883 | break; |
@@ -4894,16 +4889,14 @@ static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev, | |||
4894 | } | 4889 | } |
4895 | 4890 | ||
4896 | /* If we are in bridging mode, we must apply | 4891 | /* If we are in bridging mode, we must apply |
4897 | * an Ethernet header */ | 4892 | * an Ethernet header |
4898 | if (op_mode == BRIDGE || op_mode == BRIDGE_NODE){ | 4893 | */ |
4899 | 4894 | if (op_mode == BRIDGE || op_mode == BRIDGE_NODE) { | |
4900 | |||
4901 | /* Encapsulate the packet as a bridged Ethernet frame. */ | 4895 | /* Encapsulate the packet as a bridged Ethernet frame. */ |
4902 | #ifdef DEBUG | 4896 | #ifdef DEBUG |
4903 | printk(KERN_INFO "%s: encapsulating skb for frame relay\n", | 4897 | printk(KERN_INFO "%s: encapsulating skb for frame relay\n", |
4904 | dev->name); | 4898 | dev->name); |
4905 | #endif | 4899 | #endif |
4906 | |||
4907 | chan->fr_header[0] = 0x03; | 4900 | chan->fr_header[0] = 0x03; |
4908 | chan->fr_header[1] = 0x00; | 4901 | chan->fr_header[1] = 0x00; |
4909 | chan->fr_header[2] = 0x80; | 4902 | chan->fr_header[2] = 0x80; |
@@ -4916,7 +4909,6 @@ static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev, | |||
4916 | /* Yuck. */ | 4909 | /* Yuck. */ |
4917 | skb->protocol = ETH_P_802_3; | 4910 | skb->protocol = ETH_P_802_3; |
4918 | return 8; | 4911 | return 8; |
4919 | |||
4920 | } | 4912 | } |
4921 | 4913 | ||
4922 | return 0; | 4914 | return 0; |
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c index 84b65c60c799..f58c794a963a 100644 --- a/drivers/net/wan/syncppp.c +++ b/drivers/net/wan/syncppp.c | |||
@@ -1447,7 +1447,7 @@ static void sppp_print_bytes (u_char *p, u16 len) | |||
1447 | * after interrupt servicing to process frames queued via netif_rx. | 1447 | * after interrupt servicing to process frames queued via netif_rx. |
1448 | */ | 1448 | */ |
1449 | 1449 | ||
1450 | static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p) | 1450 | static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev) |
1451 | { | 1451 | { |
1452 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) | 1452 | if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) |
1453 | return NET_RX_DROP; | 1453 | return NET_RX_DROP; |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 4d0b5a336bd7..d7947358e49d 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -4323,36 +4323,36 @@ static const struct iw_priv_args orinoco_privtab[] = { | |||
4323 | */ | 4323 | */ |
4324 | 4324 | ||
4325 | static const iw_handler orinoco_handler[] = { | 4325 | static const iw_handler orinoco_handler[] = { |
4326 | [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit, | 4326 | [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit, |
4327 | [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname, | 4327 | [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname, |
4328 | [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq, | 4328 | [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq, |
4329 | [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq, | 4329 | [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq, |
4330 | [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode, | 4330 | [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode, |
4331 | [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode, | 4331 | [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode, |
4332 | [SIOCSIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens, | 4332 | [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, |
4333 | [SIOCGIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens, | 4333 | [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, |
4334 | [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange, | 4334 | [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, |
4335 | [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy, | 4335 | [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, |
4336 | [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getspy, | 4336 | [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy, |
4337 | [SIOCSIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setwap, | 4337 | [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, |
4338 | [SIOCGIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getwap, | 4338 | [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, |
4339 | [SIOCSIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setscan, | 4339 | [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, |
4340 | [SIOCGIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getscan, | 4340 | [SIOCGIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan, |
4341 | [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setessid, | 4341 | [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid, |
4342 | [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getessid, | 4342 | [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid, |
4343 | [SIOCSIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setnick, | 4343 | [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick, |
4344 | [SIOCGIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getnick, | 4344 | [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick, |
4345 | [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrate, | 4345 | [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate, |
4346 | [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrate, | 4346 | [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate, |
4347 | [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrts, | 4347 | [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts, |
4348 | [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrts, | 4348 | [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts, |
4349 | [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfrag, | 4349 | [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag, |
4350 | [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfrag, | 4350 | [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag, |
4351 | [SIOCGIWRETRY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getretry, | 4351 | [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry, |
4352 | [SIOCSIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_setiwencode, | 4352 | [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode, |
4353 | [SIOCGIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwencode, | 4353 | [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode, |
4354 | [SIOCSIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setpower, | 4354 | [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower, |
4355 | [SIOCGIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getpower, | 4355 | [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower, |
4356 | }; | 4356 | }; |
4357 | 4357 | ||
4358 | 4358 | ||
@@ -4360,15 +4360,15 @@ static const iw_handler orinoco_handler[] = { | |||
4360 | Added typecasting since we no longer use iwreq_data -- Moustafa | 4360 | Added typecasting since we no longer use iwreq_data -- Moustafa |
4361 | */ | 4361 | */ |
4362 | static const iw_handler orinoco_private_handler[] = { | 4362 | static const iw_handler orinoco_private_handler[] = { |
4363 | [0] (iw_handler) orinoco_ioctl_reset, | 4363 | [0] = (iw_handler) orinoco_ioctl_reset, |
4364 | [1] (iw_handler) orinoco_ioctl_reset, | 4364 | [1] = (iw_handler) orinoco_ioctl_reset, |
4365 | [2] (iw_handler) orinoco_ioctl_setport3, | 4365 | [2] = (iw_handler) orinoco_ioctl_setport3, |
4366 | [3] (iw_handler) orinoco_ioctl_getport3, | 4366 | [3] = (iw_handler) orinoco_ioctl_getport3, |
4367 | [4] (iw_handler) orinoco_ioctl_setpreamble, | 4367 | [4] = (iw_handler) orinoco_ioctl_setpreamble, |
4368 | [5] (iw_handler) orinoco_ioctl_getpreamble, | 4368 | [5] = (iw_handler) orinoco_ioctl_getpreamble, |
4369 | [6] (iw_handler) orinoco_ioctl_setibssport, | 4369 | [6] = (iw_handler) orinoco_ioctl_setibssport, |
4370 | [7] (iw_handler) orinoco_ioctl_getibssport, | 4370 | [7] = (iw_handler) orinoco_ioctl_getibssport, |
4371 | [9] (iw_handler) orinoco_ioctl_getrid, | 4371 | [9] = (iw_handler) orinoco_ioctl_getrid, |
4372 | }; | 4372 | }; |
4373 | 4373 | ||
4374 | static const struct iw_handler_def orinoco_handler_def = { | 4374 | static const struct iw_handler_def orinoco_handler_def = { |