aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sky2.c93
-rw-r--r--drivers/net/sky2.h2
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 725static 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 */
732static 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 {
755setnew:
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;
1006nomem: 975nomem:
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
1305out_unlock: 1273out_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;