diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 189 |
1 files changed, 96 insertions, 93 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index de91609ca112..7ce0663baf45 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include "sky2.h" | 50 | #include "sky2.h" |
51 | 51 | ||
52 | #define DRV_NAME "sky2" | 52 | #define DRV_NAME "sky2" |
53 | #define DRV_VERSION "1.5" | 53 | #define DRV_VERSION "1.7" |
54 | #define PFX DRV_NAME " " | 54 | #define PFX DRV_NAME " " |
55 | 55 | ||
56 | /* | 56 | /* |
@@ -106,6 +106,7 @@ static const struct pci_device_id sky2_id_table[] = { | |||
106 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, | 106 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, |
107 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, | 107 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, |
108 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ | 108 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */ |
109 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, /* DGE-550SX */ | ||
109 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, | 110 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, |
110 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, | 111 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, |
111 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, | 112 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, |
@@ -117,10 +118,17 @@ static const struct pci_device_id sky2_id_table[] = { | |||
117 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, | 118 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) }, |
118 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, | 119 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, |
119 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, | 120 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, |
121 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, | ||
120 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, | 122 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, |
121 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, | 123 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, |
122 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, | 124 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, |
123 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, | 125 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, |
126 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, | ||
127 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, | ||
128 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, | ||
129 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, | ||
130 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, | ||
131 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, | ||
124 | { 0 } | 132 | { 0 } |
125 | }; | 133 | }; |
126 | 134 | ||
@@ -190,7 +198,6 @@ static u16 gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg) | |||
190 | static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | 198 | static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) |
191 | { | 199 | { |
192 | u16 power_control; | 200 | u16 power_control; |
193 | u32 reg1; | ||
194 | int vaux; | 201 | int vaux; |
195 | 202 | ||
196 | pr_debug("sky2_set_power_state %d\n", state); | 203 | pr_debug("sky2_set_power_state %d\n", state); |
@@ -223,18 +230,9 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
223 | else | 230 | else |
224 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 231 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
225 | 232 | ||
226 | /* Turn off phy power saving */ | ||
227 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | ||
228 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | ||
229 | |||
230 | /* looks like this XL is back asswards .. */ | ||
231 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) { | ||
232 | reg1 |= PCI_Y2_PHY1_COMA; | ||
233 | if (hw->ports > 1) | ||
234 | reg1 |= PCI_Y2_PHY2_COMA; | ||
235 | } | ||
236 | |||
237 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 233 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
234 | u32 reg1; | ||
235 | |||
238 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 236 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
239 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | 237 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); |
240 | reg1 &= P_ASPM_CONTROL_MSK; | 238 | reg1 &= P_ASPM_CONTROL_MSK; |
@@ -242,22 +240,10 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
242 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | 240 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); |
243 | } | 241 | } |
244 | 242 | ||
245 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
246 | udelay(100); | ||
247 | |||
248 | break; | 243 | break; |
249 | 244 | ||
250 | case PCI_D3hot: | 245 | case PCI_D3hot: |
251 | case PCI_D3cold: | 246 | case PCI_D3cold: |
252 | /* Turn on phy power saving */ | ||
253 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | ||
254 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | ||
255 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | ||
256 | else | ||
257 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | ||
258 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
259 | udelay(100); | ||
260 | |||
261 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | 247 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
262 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 248 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
263 | else | 249 | else |
@@ -281,7 +267,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
281 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 267 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
282 | } | 268 | } |
283 | 269 | ||
284 | static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) | 270 | static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) |
285 | { | 271 | { |
286 | u16 reg; | 272 | u16 reg; |
287 | 273 | ||
@@ -529,6 +515,29 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
529 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); | 515 | gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); |
530 | } | 516 | } |
531 | 517 | ||
518 | static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) | ||
519 | { | ||
520 | u32 reg1; | ||
521 | static const u32 phy_power[] | ||
522 | = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; | ||
523 | |||
524 | /* looks like this XL is back asswards .. */ | ||
525 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | ||
526 | onoff = !onoff; | ||
527 | |||
528 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | ||
529 | |||
530 | if (onoff) | ||
531 | /* Turn off phy power saving */ | ||
532 | reg1 &= ~phy_power[port]; | ||
533 | else | ||
534 | reg1 |= phy_power[port]; | ||
535 | |||
536 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
537 | sky2_pci_read32(hw, PCI_DEV_REG1); | ||
538 | udelay(100); | ||
539 | } | ||
540 | |||
532 | /* Force a renegotiation */ | 541 | /* Force a renegotiation */ |
533 | static void sky2_phy_reinit(struct sky2_port *sky2) | 542 | static void sky2_phy_reinit(struct sky2_port *sky2) |
534 | { | 543 | { |
@@ -761,9 +770,10 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) | |||
761 | /* Update chip's next pointer */ | 770 | /* Update chip's next pointer */ |
762 | static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) | 771 | static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) |
763 | { | 772 | { |
773 | q = Y2_QADDR(q, PREF_UNIT_PUT_IDX); | ||
764 | wmb(); | 774 | wmb(); |
765 | sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); | 775 | sky2_write16(hw, q, idx); |
766 | mmiowb(); | 776 | sky2_read16(hw, q); |
767 | } | 777 | } |
768 | 778 | ||
769 | 779 | ||
@@ -950,14 +960,16 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
950 | /* | 960 | /* |
951 | * It appears the hardware has a bug in the FIFO logic that | 961 | * It appears the hardware has a bug in the FIFO logic that |
952 | * cause it to hang if the FIFO gets overrun and the receive buffer | 962 | * cause it to hang if the FIFO gets overrun and the receive buffer |
953 | * is not aligned. ALso alloc_skb() won't align properly if slab | 963 | * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is |
954 | * debugging is enabled. | 964 | * aligned except if slab debugging is enabled. |
955 | */ | 965 | */ |
956 | static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) | 966 | static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev, |
967 | unsigned int length, | ||
968 | gfp_t gfp_mask) | ||
957 | { | 969 | { |
958 | struct sk_buff *skb; | 970 | struct sk_buff *skb; |
959 | 971 | ||
960 | skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); | 972 | skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask); |
961 | if (likely(skb)) { | 973 | if (likely(skb)) { |
962 | unsigned long p = (unsigned long) skb->data; | 974 | unsigned long p = (unsigned long) skb->data; |
963 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); | 975 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); |
@@ -993,7 +1005,8 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
993 | for (i = 0; i < sky2->rx_pending; i++) { | 1005 | for (i = 0; i < sky2->rx_pending; i++) { |
994 | struct ring_info *re = sky2->rx_ring + i; | 1006 | struct ring_info *re = sky2->rx_ring + i; |
995 | 1007 | ||
996 | re->skb = sky2_alloc_skb(sky2->rx_bufsize, GFP_KERNEL); | 1008 | re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize, |
1009 | GFP_KERNEL); | ||
997 | if (!re->skb) | 1010 | if (!re->skb) |
998 | goto nomem; | 1011 | goto nomem; |
999 | 1012 | ||
@@ -1081,6 +1094,8 @@ static int sky2_up(struct net_device *dev) | |||
1081 | if (!sky2->rx_ring) | 1094 | if (!sky2->rx_ring) |
1082 | goto err_out; | 1095 | goto err_out; |
1083 | 1096 | ||
1097 | sky2_phy_power(hw, port, 1); | ||
1098 | |||
1084 | sky2_mac_init(hw, port); | 1099 | sky2_mac_init(hw, port); |
1085 | 1100 | ||
1086 | /* Determine available ram buffer space (in 4K blocks). | 1101 | /* Determine available ram buffer space (in 4K blocks). |
@@ -1185,7 +1200,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1185 | struct sky2_tx_le *le = NULL; | 1200 | struct sky2_tx_le *le = NULL; |
1186 | struct tx_ring_info *re; | 1201 | struct tx_ring_info *re; |
1187 | unsigned i, len; | 1202 | unsigned i, len; |
1188 | int avail; | ||
1189 | dma_addr_t mapping; | 1203 | dma_addr_t mapping; |
1190 | u32 addr64; | 1204 | u32 addr64; |
1191 | u16 mss; | 1205 | u16 mss; |
@@ -1235,25 +1249,18 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1235 | /* Check for TCP Segmentation Offload */ | 1249 | /* Check for TCP Segmentation Offload */ |
1236 | mss = skb_shinfo(skb)->gso_size; | 1250 | mss = skb_shinfo(skb)->gso_size; |
1237 | if (mss != 0) { | 1251 | if (mss != 0) { |
1238 | /* just drop the packet if non-linear expansion fails */ | ||
1239 | if (skb_header_cloned(skb) && | ||
1240 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { | ||
1241 | dev_kfree_skb(skb); | ||
1242 | goto out_unlock; | ||
1243 | } | ||
1244 | |||
1245 | mss += ((skb->h.th->doff - 5) * 4); /* TCP options */ | 1252 | mss += ((skb->h.th->doff - 5) * 4); /* TCP options */ |
1246 | mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); | 1253 | mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); |
1247 | mss += ETH_HLEN; | 1254 | mss += ETH_HLEN; |
1248 | } | ||
1249 | 1255 | ||
1250 | if (mss != sky2->tx_last_mss) { | 1256 | if (mss != sky2->tx_last_mss) { |
1251 | le = get_tx_le(sky2); | 1257 | le = get_tx_le(sky2); |
1252 | le->tx.tso.size = cpu_to_le16(mss); | 1258 | le->tx.tso.size = cpu_to_le16(mss); |
1253 | le->tx.tso.rsvd = 0; | 1259 | le->tx.tso.rsvd = 0; |
1254 | le->opcode = OP_LRGLEN | HW_OWNER; | 1260 | le->opcode = OP_LRGLEN | HW_OWNER; |
1255 | le->ctrl = 0; | 1261 | le->ctrl = 0; |
1256 | sky2->tx_last_mss = mss; | 1262 | sky2->tx_last_mss = mss; |
1263 | } | ||
1257 | } | 1264 | } |
1258 | 1265 | ||
1259 | ctrl = 0; | 1266 | ctrl = 0; |
@@ -1281,12 +1288,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1281 | if (skb->nh.iph->protocol == IPPROTO_UDP) | 1288 | if (skb->nh.iph->protocol == IPPROTO_UDP) |
1282 | ctrl |= UDPTCP; | 1289 | ctrl |= UDPTCP; |
1283 | 1290 | ||
1284 | le = get_tx_le(sky2); | 1291 | if (hdr != sky2->tx_csum_start || offset != sky2->tx_csum_offset) { |
1285 | le->tx.csum.start = cpu_to_le16(hdr); | 1292 | sky2->tx_csum_start = hdr; |
1286 | le->tx.csum.offset = cpu_to_le16(offset); | 1293 | sky2->tx_csum_offset = offset; |
1287 | le->length = 0; /* initial checksum value */ | 1294 | |
1288 | le->ctrl = 1; /* one packet */ | 1295 | le = get_tx_le(sky2); |
1289 | le->opcode = OP_TCPLISW | HW_OWNER; | 1296 | le->tx.csum.start = cpu_to_le16(hdr); |
1297 | le->tx.csum.offset = cpu_to_le16(offset); | ||
1298 | le->length = 0; /* initial checksum value */ | ||
1299 | le->ctrl = 1; /* one packet */ | ||
1300 | le->opcode = OP_TCPLISW | HW_OWNER; | ||
1301 | } | ||
1290 | } | 1302 | } |
1291 | 1303 | ||
1292 | le = get_tx_le(sky2); | 1304 | le = get_tx_le(sky2); |
@@ -1321,23 +1333,18 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1321 | le->opcode = OP_BUFFER | HW_OWNER; | 1333 | le->opcode = OP_BUFFER | HW_OWNER; |
1322 | 1334 | ||
1323 | fre = sky2->tx_ring | 1335 | fre = sky2->tx_ring |
1324 | + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); | 1336 | + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); |
1325 | pci_unmap_addr_set(fre, mapaddr, mapping); | 1337 | pci_unmap_addr_set(fre, mapaddr, mapping); |
1326 | } | 1338 | } |
1327 | 1339 | ||
1328 | re->idx = sky2->tx_prod; | 1340 | re->idx = sky2->tx_prod; |
1329 | le->ctrl |= EOP; | 1341 | le->ctrl |= EOP; |
1330 | 1342 | ||
1331 | avail = tx_avail(sky2); | 1343 | if (tx_avail(sky2) <= MAX_SKB_TX_LE) |
1332 | if (mss != 0 || avail < TX_MIN_PENDING) { | 1344 | netif_stop_queue(dev); |
1333 | le->ctrl |= FRC_STAT; | ||
1334 | if (avail <= MAX_SKB_TX_LE) | ||
1335 | netif_stop_queue(dev); | ||
1336 | } | ||
1337 | 1345 | ||
1338 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); | 1346 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); |
1339 | 1347 | ||
1340 | out_unlock: | ||
1341 | spin_unlock(&sky2->tx_lock); | 1348 | spin_unlock(&sky2->tx_lock); |
1342 | 1349 | ||
1343 | dev->trans_start = jiffies; | 1350 | dev->trans_start = jiffies; |
@@ -1422,7 +1429,7 @@ static int sky2_down(struct net_device *dev) | |||
1422 | /* Stop more packets from being queued */ | 1429 | /* Stop more packets from being queued */ |
1423 | netif_stop_queue(dev); | 1430 | netif_stop_queue(dev); |
1424 | 1431 | ||
1425 | sky2_phy_reset(hw, port); | 1432 | sky2_gmac_reset(hw, port); |
1426 | 1433 | ||
1427 | /* Stop transmitter */ | 1434 | /* Stop transmitter */ |
1428 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); | 1435 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); |
@@ -1470,6 +1477,8 @@ static int sky2_down(struct net_device *dev) | |||
1470 | imask &= ~portirq_msk[port]; | 1477 | imask &= ~portirq_msk[port]; |
1471 | sky2_write32(hw, B0_IMSK, imask); | 1478 | sky2_write32(hw, B0_IMSK, imask); |
1472 | 1479 | ||
1480 | sky2_phy_power(hw, port, 0); | ||
1481 | |||
1473 | /* turn off LED's */ | 1482 | /* turn off LED's */ |
1474 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); | 1483 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
1475 | 1484 | ||
@@ -1833,15 +1842,16 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
1833 | * For small packets or errors, just reuse existing skb. | 1842 | * For small packets or errors, just reuse existing skb. |
1834 | * For larger packets, get new buffer. | 1843 | * For larger packets, get new buffer. |
1835 | */ | 1844 | */ |
1836 | static struct sk_buff *sky2_receive(struct sky2_port *sky2, | 1845 | static struct sk_buff *sky2_receive(struct net_device *dev, |
1837 | u16 length, u32 status) | 1846 | u16 length, u32 status) |
1838 | { | 1847 | { |
1848 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1839 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; | 1849 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; |
1840 | struct sk_buff *skb = NULL; | 1850 | struct sk_buff *skb = NULL; |
1841 | 1851 | ||
1842 | if (unlikely(netif_msg_rx_status(sky2))) | 1852 | if (unlikely(netif_msg_rx_status(sky2))) |
1843 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", | 1853 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", |
1844 | sky2->netdev->name, sky2->rx_next, status, length); | 1854 | dev->name, sky2->rx_next, status, length); |
1845 | 1855 | ||
1846 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; | 1856 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; |
1847 | prefetch(sky2->rx_ring + sky2->rx_next); | 1857 | prefetch(sky2->rx_ring + sky2->rx_next); |
@@ -1852,11 +1862,11 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1852 | if (!(status & GMR_FS_RX_OK)) | 1862 | if (!(status & GMR_FS_RX_OK)) |
1853 | goto resubmit; | 1863 | goto resubmit; |
1854 | 1864 | ||
1855 | if (length > sky2->netdev->mtu + ETH_HLEN) | 1865 | if (length > dev->mtu + ETH_HLEN) |
1856 | goto oversize; | 1866 | goto oversize; |
1857 | 1867 | ||
1858 | if (length < copybreak) { | 1868 | if (length < copybreak) { |
1859 | skb = alloc_skb(length + 2, GFP_ATOMIC); | 1869 | skb = netdev_alloc_skb(dev, length + 2); |
1860 | if (!skb) | 1870 | if (!skb) |
1861 | goto resubmit; | 1871 | goto resubmit; |
1862 | 1872 | ||
@@ -1871,7 +1881,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1871 | } else { | 1881 | } else { |
1872 | struct sk_buff *nskb; | 1882 | struct sk_buff *nskb; |
1873 | 1883 | ||
1874 | nskb = sky2_alloc_skb(sky2->rx_bufsize, GFP_ATOMIC); | 1884 | nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC); |
1875 | if (!nskb) | 1885 | if (!nskb) |
1876 | goto resubmit; | 1886 | goto resubmit; |
1877 | 1887 | ||
@@ -1901,7 +1911,7 @@ error: | |||
1901 | 1911 | ||
1902 | if (netif_msg_rx_err(sky2) && net_ratelimit()) | 1912 | if (netif_msg_rx_err(sky2) && net_ratelimit()) |
1903 | printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", | 1913 | printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", |
1904 | sky2->netdev->name, status, length); | 1914 | dev->name, status, length); |
1905 | 1915 | ||
1906 | if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE)) | 1916 | if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE)) |
1907 | sky2->net_stats.rx_length_errors++; | 1917 | sky2->net_stats.rx_length_errors++; |
@@ -1927,12 +1937,6 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) | |||
1927 | } | 1937 | } |
1928 | } | 1938 | } |
1929 | 1939 | ||
1930 | /* Is status ring empty or is there more to do? */ | ||
1931 | static inline int sky2_more_work(const struct sky2_hw *hw) | ||
1932 | { | ||
1933 | return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)); | ||
1934 | } | ||
1935 | |||
1936 | /* Process status response ring */ | 1940 | /* Process status response ring */ |
1937 | static int sky2_status_intr(struct sky2_hw *hw, int to_do) | 1941 | static int sky2_status_intr(struct sky2_hw *hw, int to_do) |
1938 | { | 1942 | { |
@@ -1961,11 +1965,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1961 | 1965 | ||
1962 | switch (le->opcode & ~HW_OWNER) { | 1966 | switch (le->opcode & ~HW_OWNER) { |
1963 | case OP_RXSTAT: | 1967 | case OP_RXSTAT: |
1964 | skb = sky2_receive(sky2, length, status); | 1968 | skb = sky2_receive(dev, length, status); |
1965 | if (!skb) | 1969 | if (!skb) |
1966 | break; | 1970 | break; |
1967 | 1971 | ||
1968 | skb->dev = dev; | ||
1969 | skb->protocol = eth_type_trans(skb, dev); | 1972 | skb->protocol = eth_type_trans(skb, dev); |
1970 | dev->last_rx = jiffies; | 1973 | dev->last_rx = jiffies; |
1971 | 1974 | ||
@@ -2023,6 +2026,9 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2023 | } | 2026 | } |
2024 | } | 2027 | } |
2025 | 2028 | ||
2029 | /* Fully processed status ring so clear irq */ | ||
2030 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
2031 | |||
2026 | exit_loop: | 2032 | exit_loop: |
2027 | if (buf_write[0]) { | 2033 | if (buf_write[0]) { |
2028 | sky2 = netdev_priv(hw->dev[0]); | 2034 | sky2 = netdev_priv(hw->dev[0]); |
@@ -2232,19 +2238,16 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2232 | sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); | 2238 | sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); |
2233 | 2239 | ||
2234 | work_done = sky2_status_intr(hw, work_limit); | 2240 | work_done = sky2_status_intr(hw, work_limit); |
2235 | *budget -= work_done; | 2241 | if (work_done < work_limit) { |
2236 | dev0->quota -= work_done; | 2242 | netif_rx_complete(dev0); |
2237 | 2243 | ||
2238 | if (status & Y2_IS_STAT_BMU) | 2244 | sky2_read32(hw, B0_Y2_SP_LISR); |
2239 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2245 | return 0; |
2240 | 2246 | } else { | |
2241 | if (sky2_more_work(hw)) | 2247 | *budget -= work_done; |
2248 | dev0->quota -= work_done; | ||
2242 | return 1; | 2249 | return 1; |
2243 | 2250 | } | |
2244 | netif_rx_complete(dev0); | ||
2245 | |||
2246 | sky2_read32(hw, B0_Y2_SP_LISR); | ||
2247 | return 0; | ||
2248 | } | 2251 | } |
2249 | 2252 | ||
2250 | static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) | 2253 | static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) |
@@ -2410,7 +2413,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2410 | sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); | 2413 | sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); |
2411 | 2414 | ||
2412 | for (i = 0; i < hw->ports; i++) | 2415 | for (i = 0; i < hw->ports; i++) |
2413 | sky2_phy_reset(hw, i); | 2416 | sky2_gmac_reset(hw, i); |
2414 | 2417 | ||
2415 | memset(hw->st_le, 0, STATUS_LE_BYTES); | 2418 | memset(hw->st_le, 0, STATUS_LE_BYTES); |
2416 | hw->st_idx = 0; | 2419 | hw->st_idx = 0; |
@@ -3201,6 +3204,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3201 | struct pci_dev *pdev = hw->pdev; | 3204 | struct pci_dev *pdev = hw->pdev; |
3202 | int err; | 3205 | int err; |
3203 | 3206 | ||
3207 | init_waitqueue_head (&hw->msi_wait); | ||
3208 | |||
3204 | sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); | 3209 | sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); |
3205 | 3210 | ||
3206 | err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw); | 3211 | err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw); |
@@ -3210,10 +3215,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3210 | return err; | 3215 | return err; |
3211 | } | 3216 | } |
3212 | 3217 | ||
3213 | init_waitqueue_head (&hw->msi_wait); | ||
3214 | |||
3215 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); | 3218 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); |
3216 | wmb(); | 3219 | sky2_read8(hw, B0_CTST); |
3217 | 3220 | ||
3218 | wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); | 3221 | wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); |
3219 | 3222 | ||