diff options
-rw-r--r-- | drivers/net/sky2.c | 93 | ||||
-rw-r--r-- | drivers/net/sky2.h | 2 |
2 files changed, 32 insertions, 63 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 73260364cba3..3086e52032a8 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -61,10 +61,6 @@ | |||
61 | * a receive requires one (or two if using 64 bit dma). | 61 | * a receive requires one (or two if using 64 bit dma). |
62 | */ | 62 | */ |
63 | 63 | ||
64 | #define is_ec_a1(hw) \ | ||
65 | unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \ | ||
66 | (hw)->chip_rev == CHIP_REV_YU_EC_A1) | ||
67 | |||
68 | #define RX_LE_SIZE 512 | 64 | #define RX_LE_SIZE 512 |
69 | #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) | 65 | #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) |
70 | #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) | 66 | #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) |
@@ -725,37 +721,11 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) | |||
725 | return le; | 721 | return le; |
726 | } | 722 | } |
727 | 723 | ||
728 | /* | 724 | /* Update chip's next pointer */ |
729 | * This is a workaround code taken from SysKonnect sk98lin driver | 725 | static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) |
730 | * to deal with chip bug on Yukon EC rev 0 in the wraparound case. | ||
731 | */ | ||
732 | static void sky2_put_idx(struct sky2_hw *hw, unsigned q, | ||
733 | u16 idx, u16 *last, u16 size) | ||
734 | { | 726 | { |
735 | wmb(); | 727 | wmb(); |
736 | if (is_ec_a1(hw) && idx < *last) { | 728 | sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); |
737 | u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX)); | ||
738 | |||
739 | if (hwget == 0) { | ||
740 | /* Start prefetching again */ | ||
741 | sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0); | ||
742 | goto setnew; | ||
743 | } | ||
744 | |||
745 | if (hwget == size - 1) { | ||
746 | /* set watermark to one list element */ | ||
747 | sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8); | ||
748 | |||
749 | /* set put index to first list element */ | ||
750 | sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0); | ||
751 | } else /* have hardware go to end of list */ | ||
752 | sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), | ||
753 | size - 1); | ||
754 | } else { | ||
755 | setnew: | ||
756 | sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); | ||
757 | } | ||
758 | *last = idx; | ||
759 | mmiowb(); | 729 | mmiowb(); |
760 | } | 730 | } |
761 | 731 | ||
@@ -1001,7 +971,6 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1001 | 971 | ||
1002 | /* Tell chip about available buffers */ | 972 | /* Tell chip about available buffers */ |
1003 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); | 973 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
1004 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); | ||
1005 | return 0; | 974 | return 0; |
1006 | nomem: | 975 | nomem: |
1007 | sky2_rx_clean(sky2); | 976 | sky2_rx_clean(sky2); |
@@ -1299,8 +1268,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1299 | netif_stop_queue(dev); | 1268 | netif_stop_queue(dev); |
1300 | } | 1269 | } |
1301 | 1270 | ||
1302 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, | 1271 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); |
1303 | &sky2->tx_last_put, TX_RING_SIZE); | ||
1304 | 1272 | ||
1305 | out_unlock: | 1273 | out_unlock: |
1306 | spin_unlock(&sky2->tx_lock); | 1274 | spin_unlock(&sky2->tx_lock); |
@@ -1843,8 +1811,7 @@ resubmit: | |||
1843 | sky2_rx_add(sky2, re->mapaddr); | 1811 | sky2_rx_add(sky2, re->mapaddr); |
1844 | 1812 | ||
1845 | /* Tell receiver about new buffers. */ | 1813 | /* Tell receiver about new buffers. */ |
1846 | sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put, | 1814 | sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); |
1847 | &sky2->rx_last_put, RX_LE_SIZE); | ||
1848 | 1815 | ||
1849 | return skb; | 1816 | return skb; |
1850 | 1817 | ||
@@ -2238,6 +2205,23 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2238 | return -EOPNOTSUPP; | 2205 | return -EOPNOTSUPP; |
2239 | } | 2206 | } |
2240 | 2207 | ||
2208 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; | ||
2209 | |||
2210 | /* This rev is really old, and requires untested workarounds */ | ||
2211 | if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) { | ||
2212 | printk(KERN_ERR PFX "%s: unsupported revision Yukon-%s (0x%x) rev %d\n", | ||
2213 | pci_name(hw->pdev), yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], | ||
2214 | hw->chip_id, hw->chip_rev); | ||
2215 | return -EOPNOTSUPP; | ||
2216 | } | ||
2217 | |||
2218 | /* This chip is new and not tested yet */ | ||
2219 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | ||
2220 | pr_info(PFX "%s: is a version of Yukon 2 chipset that has not been tested yet.\n", | ||
2221 | pci_name(hw->pdev)); | ||
2222 | pr_info("Please report success/failure to maintainer <shemminger@osdl.org>\n"); | ||
2223 | } | ||
2224 | |||
2241 | /* disable ASF */ | 2225 | /* disable ASF */ |
2242 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2226 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2243 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2227 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); |
@@ -2271,7 +2255,6 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2271 | if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) | 2255 | if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) |
2272 | ++hw->ports; | 2256 | ++hw->ports; |
2273 | } | 2257 | } |
2274 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; | ||
2275 | 2258 | ||
2276 | sky2_set_power_state(hw, PCI_D0); | 2259 | sky2_set_power_state(hw, PCI_D0); |
2277 | 2260 | ||
@@ -2338,29 +2321,17 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2338 | sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); | 2321 | sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); |
2339 | 2322 | ||
2340 | /* These status setup values are copied from SysKonnect's driver */ | 2323 | /* These status setup values are copied from SysKonnect's driver */ |
2341 | if (is_ec_a1(hw)) { | 2324 | sky2_write16(hw, STAT_TX_IDX_TH, 10); |
2342 | /* WA for dev. #4.3 */ | 2325 | sky2_write8(hw, STAT_FIFO_WM, 16); |
2343 | sky2_write16(hw, STAT_TX_IDX_TH, 0xfff); /* Tx Threshold */ | ||
2344 | 2326 | ||
2345 | /* set Status-FIFO watermark */ | 2327 | /* set Status-FIFO ISR watermark */ |
2346 | sky2_write8(hw, STAT_FIFO_WM, 0x21); /* WA for dev. #4.18 */ | 2328 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0) |
2347 | 2329 | sky2_write8(hw, STAT_FIFO_ISR_WM, 4); | |
2348 | /* set Status-FIFO ISR watermark */ | 2330 | else |
2349 | sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07); /* WA for dev. #4.18 */ | 2331 | sky2_write8(hw, STAT_FIFO_ISR_WM, 16); |
2350 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000)); | ||
2351 | } else { | ||
2352 | sky2_write16(hw, STAT_TX_IDX_TH, 10); | ||
2353 | sky2_write8(hw, STAT_FIFO_WM, 16); | ||
2354 | |||
2355 | /* set Status-FIFO ISR watermark */ | ||
2356 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0) | ||
2357 | sky2_write8(hw, STAT_FIFO_ISR_WM, 4); | ||
2358 | else | ||
2359 | sky2_write8(hw, STAT_FIFO_ISR_WM, 16); | ||
2360 | 2332 | ||
2361 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); | 2333 | sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); |
2362 | sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7)); | 2334 | sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7)); |
2363 | } | ||
2364 | 2335 | ||
2365 | /* enable status unit */ | 2336 | /* enable status unit */ |
2366 | sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON); | 2337 | sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON); |
@@ -3091,7 +3062,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3091 | INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2); | 3062 | INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2); |
3092 | init_MUTEX(&sky2->phy_sema); | 3063 | init_MUTEX(&sky2->phy_sema); |
3093 | sky2->tx_pending = TX_DEF_PENDING; | 3064 | sky2->tx_pending = TX_DEF_PENDING; |
3094 | sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING; | 3065 | sky2->rx_pending = RX_DEF_PENDING; |
3095 | sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); | 3066 | sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); |
3096 | 3067 | ||
3097 | hw->dev[port] = dev; | 3068 | hw->dev[port] = dev; |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index dce955c76f3c..e2bf1d37ed0e 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -1840,7 +1840,6 @@ struct sky2_port { | |||
1840 | u16 tx_prod; /* next le to use */ | 1840 | u16 tx_prod; /* next le to use */ |
1841 | u32 tx_addr64; | 1841 | u32 tx_addr64; |
1842 | u16 tx_pending; | 1842 | u16 tx_pending; |
1843 | u16 tx_last_put; | ||
1844 | u16 tx_last_mss; | 1843 | u16 tx_last_mss; |
1845 | 1844 | ||
1846 | struct ring_info *rx_ring ____cacheline_aligned_in_smp; | 1845 | struct ring_info *rx_ring ____cacheline_aligned_in_smp; |
@@ -1849,7 +1848,6 @@ struct sky2_port { | |||
1849 | u16 rx_next; /* next re to check */ | 1848 | u16 rx_next; /* next re to check */ |
1850 | u16 rx_put; /* next le index to use */ | 1849 | u16 rx_put; /* next le index to use */ |
1851 | u16 rx_pending; | 1850 | u16 rx_pending; |
1852 | u16 rx_last_put; | ||
1853 | u16 rx_bufsize; | 1851 | u16 rx_bufsize; |
1854 | #ifdef SKY2_VLAN_TAG_USED | 1852 | #ifdef SKY2_VLAN_TAG_USED |
1855 | u16 rx_tag; | 1853 | u16 rx_tag; |