diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 215 |
1 files changed, 151 insertions, 64 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 088c797eb73b..2111c7bbf578 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -53,7 +53,7 @@ | |||
53 | #include "sky2.h" | 53 | #include "sky2.h" |
54 | 54 | ||
55 | #define DRV_NAME "sky2" | 55 | #define DRV_NAME "sky2" |
56 | #define DRV_VERSION "1.27" | 56 | #define DRV_VERSION "1.28" |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * The Yukon II chipset takes 64 bit command blocks (called list elements) | 59 | * The Yukon II chipset takes 64 bit command blocks (called list elements) |
@@ -70,18 +70,15 @@ | |||
70 | VLAN:GSO + CKSUM + Data + skb_frags * DMA */ | 70 | VLAN:GSO + CKSUM + Data + skb_frags * DMA */ |
71 | #define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1)) | 71 | #define MAX_SKB_TX_LE (2 + (sizeof(dma_addr_t)/sizeof(u32))*(MAX_SKB_FRAGS+1)) |
72 | #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) | 72 | #define TX_MIN_PENDING (MAX_SKB_TX_LE+1) |
73 | #define TX_MAX_PENDING 4096 | 73 | #define TX_MAX_PENDING 1024 |
74 | #define TX_DEF_PENDING 127 | 74 | #define TX_DEF_PENDING 127 |
75 | 75 | ||
76 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | ||
77 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | ||
78 | #define TX_WATCHDOG (5 * HZ) | 76 | #define TX_WATCHDOG (5 * HZ) |
79 | #define NAPI_WEIGHT 64 | 77 | #define NAPI_WEIGHT 64 |
80 | #define PHY_RETRIES 1000 | 78 | #define PHY_RETRIES 1000 |
81 | 79 | ||
82 | #define SKY2_EEPROM_MAGIC 0x9955aabb | 80 | #define SKY2_EEPROM_MAGIC 0x9955aabb |
83 | 81 | ||
84 | |||
85 | #define RING_NEXT(x,s) (((x)+1) & ((s)-1)) | 82 | #define RING_NEXT(x,s) (((x)+1) & ((s)-1)) |
86 | 83 | ||
87 | static const u32 default_msg = | 84 | static const u32 default_msg = |
@@ -227,7 +224,7 @@ static void sky2_power_on(struct sky2_hw *hw) | |||
227 | /* disable Core Clock Division, */ | 224 | /* disable Core Clock Division, */ |
228 | sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); | 225 | sky2_write32(hw, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); |
229 | 226 | ||
230 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 227 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1) |
231 | /* enable bits are inverted */ | 228 | /* enable bits are inverted */ |
232 | sky2_write8(hw, B2_Y2_CLK_GATE, | 229 | sky2_write8(hw, B2_Y2_CLK_GATE, |
233 | Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | | 230 | Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | |
@@ -269,7 +266,7 @@ static void sky2_power_on(struct sky2_hw *hw) | |||
269 | 266 | ||
270 | static void sky2_power_aux(struct sky2_hw *hw) | 267 | static void sky2_power_aux(struct sky2_hw *hw) |
271 | { | 268 | { |
272 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 269 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1) |
273 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 270 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
274 | else | 271 | else |
275 | /* enable bits are inverted */ | 272 | /* enable bits are inverted */ |
@@ -652,7 +649,7 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) | |||
652 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | 649 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
653 | reg1 &= ~phy_power[port]; | 650 | reg1 &= ~phy_power[port]; |
654 | 651 | ||
655 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 652 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > CHIP_REV_YU_XL_A1) |
656 | reg1 |= coma_mode[port]; | 653 | reg1 |= coma_mode[port]; |
657 | 654 | ||
658 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | 655 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
@@ -824,7 +821,9 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
824 | 821 | ||
825 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); | 822 | sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); |
826 | 823 | ||
827 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && port == 1) { | 824 | if (hw->chip_id == CHIP_ID_YUKON_XL && |
825 | hw->chip_rev == CHIP_REV_YU_XL_A0 && | ||
826 | port == 1) { | ||
828 | /* WA DEV_472 -- looks like crossed wires on port 2 */ | 827 | /* WA DEV_472 -- looks like crossed wires on port 2 */ |
829 | /* clear GMAC 1 Control reset */ | 828 | /* clear GMAC 1 Control reset */ |
830 | sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR); | 829 | sky2_write8(hw, SK_REG(0, GMAC_CTRL), GMC_RST_CLR); |
@@ -878,6 +877,10 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
878 | if (hw->dev[port]->mtu > ETH_DATA_LEN) | 877 | if (hw->dev[port]->mtu > ETH_DATA_LEN) |
879 | reg |= GM_SMOD_JUMBO_ENA; | 878 | reg |= GM_SMOD_JUMBO_ENA; |
880 | 879 | ||
880 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && | ||
881 | hw->chip_rev == CHIP_REV_YU_EC_U_B1) | ||
882 | reg |= GM_NEW_FLOW_CTRL; | ||
883 | |||
881 | gma_write16(hw, port, GM_SERIAL_MODE, reg); | 884 | gma_write16(hw, port, GM_SERIAL_MODE, reg); |
882 | 885 | ||
883 | /* virtual address for data */ | 886 | /* virtual address for data */ |
@@ -1126,7 +1129,7 @@ static int sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, | |||
1126 | if (pci_dma_mapping_error(pdev, re->data_addr)) | 1129 | if (pci_dma_mapping_error(pdev, re->data_addr)) |
1127 | goto mapping_error; | 1130 | goto mapping_error; |
1128 | 1131 | ||
1129 | pci_unmap_len_set(re, data_size, size); | 1132 | dma_unmap_len_set(re, data_size, size); |
1130 | 1133 | ||
1131 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 1134 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
1132 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 1135 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
@@ -1148,7 +1151,7 @@ map_page_error: | |||
1148 | PCI_DMA_FROMDEVICE); | 1151 | PCI_DMA_FROMDEVICE); |
1149 | } | 1152 | } |
1150 | 1153 | ||
1151 | pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size), | 1154 | pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size), |
1152 | PCI_DMA_FROMDEVICE); | 1155 | PCI_DMA_FROMDEVICE); |
1153 | 1156 | ||
1154 | mapping_error: | 1157 | mapping_error: |
@@ -1163,7 +1166,7 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) | |||
1163 | struct sk_buff *skb = re->skb; | 1166 | struct sk_buff *skb = re->skb; |
1164 | int i; | 1167 | int i; |
1165 | 1168 | ||
1166 | pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size), | 1169 | pci_unmap_single(pdev, re->data_addr, dma_unmap_len(re, data_size), |
1167 | PCI_DMA_FROMDEVICE); | 1170 | PCI_DMA_FROMDEVICE); |
1168 | 1171 | ||
1169 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 1172 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
@@ -1190,6 +1193,39 @@ static void rx_set_checksum(struct sky2_port *sky2) | |||
1190 | ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | 1193 | ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); |
1191 | } | 1194 | } |
1192 | 1195 | ||
1196 | /* Enable/disable receive hash calculation (RSS) */ | ||
1197 | static void rx_set_rss(struct net_device *dev) | ||
1198 | { | ||
1199 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1200 | struct sky2_hw *hw = sky2->hw; | ||
1201 | int i, nkeys = 4; | ||
1202 | |||
1203 | /* Supports IPv6 and other modes */ | ||
1204 | if (hw->flags & SKY2_HW_NEW_LE) { | ||
1205 | nkeys = 10; | ||
1206 | sky2_write32(hw, SK_REG(sky2->port, RSS_CFG), HASH_ALL); | ||
1207 | } | ||
1208 | |||
1209 | /* Program RSS initial values */ | ||
1210 | if (dev->features & NETIF_F_RXHASH) { | ||
1211 | u32 key[nkeys]; | ||
1212 | |||
1213 | get_random_bytes(key, nkeys * sizeof(u32)); | ||
1214 | for (i = 0; i < nkeys; i++) | ||
1215 | sky2_write32(hw, SK_REG(sky2->port, RSS_KEY + i * 4), | ||
1216 | key[i]); | ||
1217 | |||
1218 | /* Need to turn on (undocumented) flag to make hashing work */ | ||
1219 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), | ||
1220 | RX_STFW_ENA); | ||
1221 | |||
1222 | sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
1223 | BMU_ENA_RX_RSS_HASH); | ||
1224 | } else | ||
1225 | sky2_write32(hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
1226 | BMU_DIS_RX_RSS_HASH); | ||
1227 | } | ||
1228 | |||
1193 | /* | 1229 | /* |
1194 | * The RX Stop command will not work for Yukon-2 if the BMU does not | 1230 | * The RX Stop command will not work for Yukon-2 if the BMU does not |
1195 | * reach the end of packet and since we can't make sure that we have | 1231 | * reach the end of packet and since we can't make sure that we have |
@@ -1414,8 +1450,7 @@ static void sky2_rx_start(struct sky2_port *sky2) | |||
1414 | /* These chips have no ram buffer? | 1450 | /* These chips have no ram buffer? |
1415 | * MAC Rx RAM Read is controlled by hardware */ | 1451 | * MAC Rx RAM Read is controlled by hardware */ |
1416 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && | 1452 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && |
1417 | (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || | 1453 | hw->chip_rev > CHIP_REV_YU_EC_U_A0) |
1418 | hw->chip_rev == CHIP_REV_YU_EC_U_B0)) | ||
1419 | sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS); | 1454 | sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS); |
1420 | 1455 | ||
1421 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 1456 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
@@ -1423,6 +1458,9 @@ static void sky2_rx_start(struct sky2_port *sky2) | |||
1423 | if (!(hw->flags & SKY2_HW_NEW_LE)) | 1458 | if (!(hw->flags & SKY2_HW_NEW_LE)) |
1424 | rx_set_checksum(sky2); | 1459 | rx_set_checksum(sky2); |
1425 | 1460 | ||
1461 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | ||
1462 | rx_set_rss(sky2->netdev); | ||
1463 | |||
1426 | /* submit Rx ring */ | 1464 | /* submit Rx ring */ |
1427 | for (i = 0; i < sky2->rx_pending; i++) { | 1465 | for (i = 0; i < sky2->rx_pending; i++) { |
1428 | re = sky2->rx_ring + i; | 1466 | re = sky2->rx_ring + i; |
@@ -1657,12 +1695,12 @@ static unsigned tx_le_req(const struct sk_buff *skb) | |||
1657 | static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re) | 1695 | static void sky2_tx_unmap(struct pci_dev *pdev, struct tx_ring_info *re) |
1658 | { | 1696 | { |
1659 | if (re->flags & TX_MAP_SINGLE) | 1697 | if (re->flags & TX_MAP_SINGLE) |
1660 | pci_unmap_single(pdev, pci_unmap_addr(re, mapaddr), | 1698 | pci_unmap_single(pdev, dma_unmap_addr(re, mapaddr), |
1661 | pci_unmap_len(re, maplen), | 1699 | dma_unmap_len(re, maplen), |
1662 | PCI_DMA_TODEVICE); | 1700 | PCI_DMA_TODEVICE); |
1663 | else if (re->flags & TX_MAP_PAGE) | 1701 | else if (re->flags & TX_MAP_PAGE) |
1664 | pci_unmap_page(pdev, pci_unmap_addr(re, mapaddr), | 1702 | pci_unmap_page(pdev, dma_unmap_addr(re, mapaddr), |
1665 | pci_unmap_len(re, maplen), | 1703 | dma_unmap_len(re, maplen), |
1666 | PCI_DMA_TODEVICE); | 1704 | PCI_DMA_TODEVICE); |
1667 | re->flags = 0; | 1705 | re->flags = 0; |
1668 | } | 1706 | } |
@@ -1773,8 +1811,8 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, | |||
1773 | 1811 | ||
1774 | re = sky2->tx_ring + slot; | 1812 | re = sky2->tx_ring + slot; |
1775 | re->flags = TX_MAP_SINGLE; | 1813 | re->flags = TX_MAP_SINGLE; |
1776 | pci_unmap_addr_set(re, mapaddr, mapping); | 1814 | dma_unmap_addr_set(re, mapaddr, mapping); |
1777 | pci_unmap_len_set(re, maplen, len); | 1815 | dma_unmap_len_set(re, maplen, len); |
1778 | 1816 | ||
1779 | le = get_tx_le(sky2, &slot); | 1817 | le = get_tx_le(sky2, &slot); |
1780 | le->addr = cpu_to_le32(lower_32_bits(mapping)); | 1818 | le->addr = cpu_to_le32(lower_32_bits(mapping)); |
@@ -1802,8 +1840,8 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, | |||
1802 | 1840 | ||
1803 | re = sky2->tx_ring + slot; | 1841 | re = sky2->tx_ring + slot; |
1804 | re->flags = TX_MAP_PAGE; | 1842 | re->flags = TX_MAP_PAGE; |
1805 | pci_unmap_addr_set(re, mapaddr, mapping); | 1843 | dma_unmap_addr_set(re, mapaddr, mapping); |
1806 | pci_unmap_len_set(re, maplen, frag->size); | 1844 | dma_unmap_len_set(re, maplen, frag->size); |
1807 | 1845 | ||
1808 | le = get_tx_le(sky2, &slot); | 1846 | le = get_tx_le(sky2, &slot); |
1809 | le->addr = cpu_to_le32(lower_32_bits(mapping)); | 1847 | le->addr = cpu_to_le32(lower_32_bits(mapping)); |
@@ -2142,7 +2180,8 @@ static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) | |||
2142 | istatus, phystat); | 2180 | istatus, phystat); |
2143 | 2181 | ||
2144 | if (istatus & PHY_M_IS_AN_COMPL) { | 2182 | if (istatus & PHY_M_IS_AN_COMPL) { |
2145 | if (sky2_autoneg_done(sky2, phystat) == 0) | 2183 | if (sky2_autoneg_done(sky2, phystat) == 0 && |
2184 | !netif_carrier_ok(dev)) | ||
2146 | sky2_link_up(sky2); | 2185 | sky2_link_up(sky2); |
2147 | goto out; | 2186 | goto out; |
2148 | } | 2187 | } |
@@ -2236,8 +2275,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
2236 | sky2_write32(hw, B0_IMSK, 0); | 2275 | sky2_write32(hw, B0_IMSK, 0); |
2237 | 2276 | ||
2238 | dev->trans_start = jiffies; /* prevent tx timeout */ | 2277 | dev->trans_start = jiffies; /* prevent tx timeout */ |
2239 | netif_stop_queue(dev); | ||
2240 | napi_disable(&hw->napi); | 2278 | napi_disable(&hw->napi); |
2279 | netif_tx_disable(dev); | ||
2241 | 2280 | ||
2242 | synchronize_irq(hw->pdev->irq); | 2281 | synchronize_irq(hw->pdev->irq); |
2243 | 2282 | ||
@@ -2531,6 +2570,14 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) | |||
2531 | } | 2570 | } |
2532 | } | 2571 | } |
2533 | 2572 | ||
2573 | static void sky2_rx_hash(struct sky2_port *sky2, u32 status) | ||
2574 | { | ||
2575 | struct sk_buff *skb; | ||
2576 | |||
2577 | skb = sky2->rx_ring[sky2->rx_next].skb; | ||
2578 | skb->rxhash = le32_to_cpu(status); | ||
2579 | } | ||
2580 | |||
2534 | /* Process status response ring */ | 2581 | /* Process status response ring */ |
2535 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | 2582 | static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) |
2536 | { | 2583 | { |
@@ -2552,7 +2599,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2552 | if (!(opcode & HW_OWNER)) | 2599 | if (!(opcode & HW_OWNER)) |
2553 | break; | 2600 | break; |
2554 | 2601 | ||
2555 | hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); | 2602 | hw->st_idx = RING_NEXT(hw->st_idx, hw->st_size); |
2556 | 2603 | ||
2557 | port = le->css & CSS_LINK_BIT; | 2604 | port = le->css & CSS_LINK_BIT; |
2558 | dev = hw->dev[port]; | 2605 | dev = hw->dev[port]; |
@@ -2603,6 +2650,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2603 | sky2_rx_checksum(sky2, status); | 2650 | sky2_rx_checksum(sky2, status); |
2604 | break; | 2651 | break; |
2605 | 2652 | ||
2653 | case OP_RSS_HASH: | ||
2654 | sky2_rx_hash(sky2, status); | ||
2655 | break; | ||
2656 | |||
2606 | case OP_TXINDEXLE: | 2657 | case OP_TXINDEXLE: |
2607 | /* TX index reports status for both ports */ | 2658 | /* TX index reports status for both ports */ |
2608 | sky2_tx_done(hw->dev[0], status & 0xfff); | 2659 | sky2_tx_done(hw->dev[0], status & 0xfff); |
@@ -2957,6 +3008,8 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
2957 | switch(hw->chip_id) { | 3008 | switch(hw->chip_id) { |
2958 | case CHIP_ID_YUKON_XL: | 3009 | case CHIP_ID_YUKON_XL: |
2959 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY; | 3010 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY; |
3011 | if (hw->chip_rev < CHIP_REV_YU_XL_A2) | ||
3012 | hw->flags |= SKY2_HW_RSS_BROKEN; | ||
2960 | break; | 3013 | break; |
2961 | 3014 | ||
2962 | case CHIP_ID_YUKON_EC_U: | 3015 | case CHIP_ID_YUKON_EC_U: |
@@ -2982,10 +3035,11 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
2982 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); | 3035 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); |
2983 | return -EOPNOTSUPP; | 3036 | return -EOPNOTSUPP; |
2984 | } | 3037 | } |
2985 | hw->flags = SKY2_HW_GIGABIT; | 3038 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RSS_BROKEN; |
2986 | break; | 3039 | break; |
2987 | 3040 | ||
2988 | case CHIP_ID_YUKON_FE: | 3041 | case CHIP_ID_YUKON_FE: |
3042 | hw->flags = SKY2_HW_RSS_BROKEN; | ||
2989 | break; | 3043 | break; |
2990 | 3044 | ||
2991 | case CHIP_ID_YUKON_FE_P: | 3045 | case CHIP_ID_YUKON_FE_P: |
@@ -3192,7 +3246,7 @@ static void sky2_reset(struct sky2_hw *hw) | |||
3192 | for (i = 0; i < hw->ports; i++) | 3246 | for (i = 0; i < hw->ports; i++) |
3193 | sky2_gmac_reset(hw, i); | 3247 | sky2_gmac_reset(hw, i); |
3194 | 3248 | ||
3195 | memset(hw->st_le, 0, STATUS_LE_BYTES); | 3249 | memset(hw->st_le, 0, hw->st_size * sizeof(struct sky2_status_le)); |
3196 | hw->st_idx = 0; | 3250 | hw->st_idx = 0; |
3197 | 3251 | ||
3198 | sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET); | 3252 | sky2_write32(hw, STAT_CTRL, SC_STAT_RST_SET); |
@@ -3202,7 +3256,7 @@ static void sky2_reset(struct sky2_hw *hw) | |||
3202 | sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32); | 3256 | sky2_write32(hw, STAT_LIST_ADDR_HI, (u64) hw->st_dma >> 32); |
3203 | 3257 | ||
3204 | /* Set the list last index */ | 3258 | /* Set the list last index */ |
3205 | sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); | 3259 | sky2_write16(hw, STAT_LAST_IDX, hw->st_size - 1); |
3206 | 3260 | ||
3207 | sky2_write16(hw, STAT_TX_IDX_TH, 10); | 3261 | sky2_write16(hw, STAT_TX_IDX_TH, 10); |
3208 | sky2_write8(hw, STAT_FIFO_WM, 16); | 3262 | sky2_write8(hw, STAT_FIFO_WM, 16); |
@@ -3258,18 +3312,14 @@ static int sky2_reattach(struct net_device *dev) | |||
3258 | return err; | 3312 | return err; |
3259 | } | 3313 | } |
3260 | 3314 | ||
3261 | static void sky2_restart(struct work_struct *work) | 3315 | static void sky2_all_down(struct sky2_hw *hw) |
3262 | { | 3316 | { |
3263 | struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work); | ||
3264 | u32 imask; | ||
3265 | int i; | 3317 | int i; |
3266 | 3318 | ||
3267 | rtnl_lock(); | 3319 | sky2_read32(hw, B0_IMSK); |
3268 | |||
3269 | napi_disable(&hw->napi); | ||
3270 | synchronize_irq(hw->pdev->irq); | ||
3271 | imask = sky2_read32(hw, B0_IMSK); | ||
3272 | sky2_write32(hw, B0_IMSK, 0); | 3320 | sky2_write32(hw, B0_IMSK, 0); |
3321 | synchronize_irq(hw->pdev->irq); | ||
3322 | napi_disable(&hw->napi); | ||
3273 | 3323 | ||
3274 | for (i = 0; i < hw->ports; i++) { | 3324 | for (i = 0; i < hw->ports; i++) { |
3275 | struct net_device *dev = hw->dev[i]; | 3325 | struct net_device *dev = hw->dev[i]; |
@@ -3282,8 +3332,12 @@ static void sky2_restart(struct work_struct *work) | |||
3282 | netif_tx_disable(dev); | 3332 | netif_tx_disable(dev); |
3283 | sky2_hw_down(sky2); | 3333 | sky2_hw_down(sky2); |
3284 | } | 3334 | } |
3335 | } | ||
3285 | 3336 | ||
3286 | sky2_reset(hw); | 3337 | static void sky2_all_up(struct sky2_hw *hw) |
3338 | { | ||
3339 | u32 imask = Y2_IS_BASE; | ||
3340 | int i; | ||
3287 | 3341 | ||
3288 | for (i = 0; i < hw->ports; i++) { | 3342 | for (i = 0; i < hw->ports; i++) { |
3289 | struct net_device *dev = hw->dev[i]; | 3343 | struct net_device *dev = hw->dev[i]; |
@@ -3293,6 +3347,8 @@ static void sky2_restart(struct work_struct *work) | |||
3293 | continue; | 3347 | continue; |
3294 | 3348 | ||
3295 | sky2_hw_up(sky2); | 3349 | sky2_hw_up(sky2); |
3350 | sky2_set_multicast(dev); | ||
3351 | imask |= portirq_msk[i]; | ||
3296 | netif_wake_queue(dev); | 3352 | netif_wake_queue(dev); |
3297 | } | 3353 | } |
3298 | 3354 | ||
@@ -3301,6 +3357,17 @@ static void sky2_restart(struct work_struct *work) | |||
3301 | 3357 | ||
3302 | sky2_read32(hw, B0_Y2_SP_LISR); | 3358 | sky2_read32(hw, B0_Y2_SP_LISR); |
3303 | napi_enable(&hw->napi); | 3359 | napi_enable(&hw->napi); |
3360 | } | ||
3361 | |||
3362 | static void sky2_restart(struct work_struct *work) | ||
3363 | { | ||
3364 | struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work); | ||
3365 | |||
3366 | rtnl_lock(); | ||
3367 | |||
3368 | sky2_all_down(hw); | ||
3369 | sky2_reset(hw); | ||
3370 | sky2_all_up(hw); | ||
3304 | 3371 | ||
3305 | rtnl_unlock(); | 3372 | rtnl_unlock(); |
3306 | } | 3373 | } |
@@ -3622,7 +3689,7 @@ static void sky2_set_multicast(struct net_device *dev) | |||
3622 | struct sky2_port *sky2 = netdev_priv(dev); | 3689 | struct sky2_port *sky2 = netdev_priv(dev); |
3623 | struct sky2_hw *hw = sky2->hw; | 3690 | struct sky2_hw *hw = sky2->hw; |
3624 | unsigned port = sky2->port; | 3691 | unsigned port = sky2->port; |
3625 | struct dev_mc_list *list; | 3692 | struct netdev_hw_addr *ha; |
3626 | u16 reg; | 3693 | u16 reg; |
3627 | u8 filter[8]; | 3694 | u8 filter[8]; |
3628 | int rx_pause; | 3695 | int rx_pause; |
@@ -3646,8 +3713,8 @@ static void sky2_set_multicast(struct net_device *dev) | |||
3646 | if (rx_pause) | 3713 | if (rx_pause) |
3647 | sky2_add_filter(filter, pause_mc_addr); | 3714 | sky2_add_filter(filter, pause_mc_addr); |
3648 | 3715 | ||
3649 | netdev_for_each_mc_addr(list, dev) | 3716 | netdev_for_each_mc_addr(ha, dev) |
3650 | sky2_add_filter(filter, list->dmi_addr); | 3717 | sky2_add_filter(filter, ha->addr); |
3651 | } | 3718 | } |
3652 | 3719 | ||
3653 | gma_write16(hw, port, GM_MC_ADDR_H1, | 3720 | gma_write16(hw, port, GM_MC_ADDR_H1, |
@@ -4109,6 +4176,25 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom | |||
4109 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); | 4176 | return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len); |
4110 | } | 4177 | } |
4111 | 4178 | ||
4179 | static int sky2_set_flags(struct net_device *dev, u32 data) | ||
4180 | { | ||
4181 | struct sky2_port *sky2 = netdev_priv(dev); | ||
4182 | |||
4183 | if (data & ~ETH_FLAG_RXHASH) | ||
4184 | return -EOPNOTSUPP; | ||
4185 | |||
4186 | if (data & ETH_FLAG_RXHASH) { | ||
4187 | if (sky2->hw->flags & SKY2_HW_RSS_BROKEN) | ||
4188 | return -EINVAL; | ||
4189 | |||
4190 | dev->features |= NETIF_F_RXHASH; | ||
4191 | } else | ||
4192 | dev->features &= ~NETIF_F_RXHASH; | ||
4193 | |||
4194 | rx_set_rss(dev); | ||
4195 | |||
4196 | return 0; | ||
4197 | } | ||
4112 | 4198 | ||
4113 | static const struct ethtool_ops sky2_ethtool_ops = { | 4199 | static const struct ethtool_ops sky2_ethtool_ops = { |
4114 | .get_settings = sky2_get_settings, | 4200 | .get_settings = sky2_get_settings, |
@@ -4140,6 +4226,7 @@ static const struct ethtool_ops sky2_ethtool_ops = { | |||
4140 | .phys_id = sky2_phys_id, | 4226 | .phys_id = sky2_phys_id, |
4141 | .get_sset_count = sky2_get_sset_count, | 4227 | .get_sset_count = sky2_get_sset_count, |
4142 | .get_ethtool_stats = sky2_get_ethtool_stats, | 4228 | .get_ethtool_stats = sky2_get_ethtool_stats, |
4229 | .set_flags = sky2_set_flags, | ||
4143 | }; | 4230 | }; |
4144 | 4231 | ||
4145 | #ifdef CONFIG_SKY2_DEBUG | 4232 | #ifdef CONFIG_SKY2_DEBUG |
@@ -4250,12 +4337,13 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
4250 | napi_disable(&hw->napi); | 4337 | napi_disable(&hw->napi); |
4251 | last = sky2_read16(hw, STAT_PUT_IDX); | 4338 | last = sky2_read16(hw, STAT_PUT_IDX); |
4252 | 4339 | ||
4340 | seq_printf(seq, "Status ring %u\n", hw->st_size); | ||
4253 | if (hw->st_idx == last) | 4341 | if (hw->st_idx == last) |
4254 | seq_puts(seq, "Status ring (empty)\n"); | 4342 | seq_puts(seq, "Status ring (empty)\n"); |
4255 | else { | 4343 | else { |
4256 | seq_puts(seq, "Status ring\n"); | 4344 | seq_puts(seq, "Status ring\n"); |
4257 | for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE; | 4345 | for (idx = hw->st_idx; idx != last && idx < hw->st_size; |
4258 | idx = RING_NEXT(idx, STATUS_RING_SIZE)) { | 4346 | idx = RING_NEXT(idx, hw->st_size)) { |
4259 | const struct sky2_status_le *le = hw->st_le + idx; | 4347 | const struct sky2_status_le *le = hw->st_le + idx; |
4260 | seq_printf(seq, "[%d] %#x %d %#x\n", | 4348 | seq_printf(seq, "[%d] %#x %d %#x\n", |
4261 | idx, le->opcode, le->length, le->status); | 4349 | idx, le->opcode, le->length, le->status); |
@@ -4492,6 +4580,10 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
4492 | if (highmem) | 4580 | if (highmem) |
4493 | dev->features |= NETIF_F_HIGHDMA; | 4581 | dev->features |= NETIF_F_HIGHDMA; |
4494 | 4582 | ||
4583 | /* Enable receive hashing unless hardware is known broken */ | ||
4584 | if (!(hw->flags & SKY2_HW_RSS_BROKEN)) | ||
4585 | dev->features |= NETIF_F_RXHASH; | ||
4586 | |||
4495 | #ifdef SKY2_VLAN_TAG_USED | 4587 | #ifdef SKY2_VLAN_TAG_USED |
4496 | /* The workaround for FE+ status conflicts with VLAN tag detection. */ | 4588 | /* The workaround for FE+ status conflicts with VLAN tag detection. */ |
4497 | if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && | 4589 | if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P && |
@@ -4683,15 +4775,17 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4683 | goto err_out_free_hw; | 4775 | goto err_out_free_hw; |
4684 | } | 4776 | } |
4685 | 4777 | ||
4686 | /* ring for status responses */ | ||
4687 | hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma); | ||
4688 | if (!hw->st_le) | ||
4689 | goto err_out_iounmap; | ||
4690 | |||
4691 | err = sky2_init(hw); | 4778 | err = sky2_init(hw); |
4692 | if (err) | 4779 | if (err) |
4693 | goto err_out_iounmap; | 4780 | goto err_out_iounmap; |
4694 | 4781 | ||
4782 | /* ring for status responses */ | ||
4783 | hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING); | ||
4784 | hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le), | ||
4785 | &hw->st_dma); | ||
4786 | if (!hw->st_le) | ||
4787 | goto err_out_reset; | ||
4788 | |||
4695 | dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n", | 4789 | dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n", |
4696 | sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev); | 4790 | sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev); |
4697 | 4791 | ||
@@ -4765,8 +4859,10 @@ err_out_unregister: | |||
4765 | err_out_free_netdev: | 4859 | err_out_free_netdev: |
4766 | free_netdev(dev); | 4860 | free_netdev(dev); |
4767 | err_out_free_pci: | 4861 | err_out_free_pci: |
4862 | pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le), | ||
4863 | hw->st_le, hw->st_dma); | ||
4864 | err_out_reset: | ||
4768 | sky2_write8(hw, B0_CTST, CS_RST_SET); | 4865 | sky2_write8(hw, B0_CTST, CS_RST_SET); |
4769 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | ||
4770 | err_out_iounmap: | 4866 | err_out_iounmap: |
4771 | iounmap(hw->regs); | 4867 | iounmap(hw->regs); |
4772 | err_out_free_hw: | 4868 | err_out_free_hw: |
@@ -4804,7 +4900,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
4804 | free_irq(pdev->irq, hw); | 4900 | free_irq(pdev->irq, hw); |
4805 | if (hw->flags & SKY2_HW_USE_MSI) | 4901 | if (hw->flags & SKY2_HW_USE_MSI) |
4806 | pci_disable_msi(pdev); | 4902 | pci_disable_msi(pdev); |
4807 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | 4903 | pci_free_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le), |
4904 | hw->st_le, hw->st_dma); | ||
4808 | pci_release_regions(pdev); | 4905 | pci_release_regions(pdev); |
4809 | pci_disable_device(pdev); | 4906 | pci_disable_device(pdev); |
4810 | 4907 | ||
@@ -4829,12 +4926,12 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4829 | cancel_work_sync(&hw->restart_work); | 4926 | cancel_work_sync(&hw->restart_work); |
4830 | 4927 | ||
4831 | rtnl_lock(); | 4928 | rtnl_lock(); |
4929 | |||
4930 | sky2_all_down(hw); | ||
4832 | for (i = 0; i < hw->ports; i++) { | 4931 | for (i = 0; i < hw->ports; i++) { |
4833 | struct net_device *dev = hw->dev[i]; | 4932 | struct net_device *dev = hw->dev[i]; |
4834 | struct sky2_port *sky2 = netdev_priv(dev); | 4933 | struct sky2_port *sky2 = netdev_priv(dev); |
4835 | 4934 | ||
4836 | sky2_detach(dev); | ||
4837 | |||
4838 | if (sky2->wol) | 4935 | if (sky2->wol) |
4839 | sky2_wol_init(sky2); | 4936 | sky2_wol_init(sky2); |
4840 | 4937 | ||
@@ -4843,8 +4940,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4843 | 4940 | ||
4844 | device_set_wakeup_enable(&pdev->dev, wol != 0); | 4941 | device_set_wakeup_enable(&pdev->dev, wol != 0); |
4845 | 4942 | ||
4846 | sky2_write32(hw, B0_IMSK, 0); | ||
4847 | napi_disable(&hw->napi); | ||
4848 | sky2_power_aux(hw); | 4943 | sky2_power_aux(hw); |
4849 | rtnl_unlock(); | 4944 | rtnl_unlock(); |
4850 | 4945 | ||
@@ -4859,12 +4954,11 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4859 | static int sky2_resume(struct pci_dev *pdev) | 4954 | static int sky2_resume(struct pci_dev *pdev) |
4860 | { | 4955 | { |
4861 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 4956 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
4862 | int i, err; | 4957 | int err; |
4863 | 4958 | ||
4864 | if (!hw) | 4959 | if (!hw) |
4865 | return 0; | 4960 | return 0; |
4866 | 4961 | ||
4867 | rtnl_lock(); | ||
4868 | err = pci_set_power_state(pdev, PCI_D0); | 4962 | err = pci_set_power_state(pdev, PCI_D0); |
4869 | if (err) | 4963 | if (err) |
4870 | goto out; | 4964 | goto out; |
@@ -4882,20 +4976,13 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4882 | goto out; | 4976 | goto out; |
4883 | } | 4977 | } |
4884 | 4978 | ||
4979 | rtnl_lock(); | ||
4885 | sky2_reset(hw); | 4980 | sky2_reset(hw); |
4886 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); | 4981 | sky2_all_up(hw); |
4887 | napi_enable(&hw->napi); | ||
4888 | |||
4889 | for (i = 0; i < hw->ports; i++) { | ||
4890 | err = sky2_reattach(hw->dev[i]); | ||
4891 | if (err) | ||
4892 | goto out; | ||
4893 | } | ||
4894 | rtnl_unlock(); | 4982 | rtnl_unlock(); |
4895 | 4983 | ||
4896 | return 0; | 4984 | return 0; |
4897 | out: | 4985 | out: |
4898 | rtnl_unlock(); | ||
4899 | 4986 | ||
4900 | dev_err(&pdev->dev, "resume failed (%d)\n", err); | 4987 | dev_err(&pdev->dev, "resume failed (%d)\n", err); |
4901 | pci_disable_device(pdev); | 4988 | pci_disable_device(pdev); |