diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 188 |
1 files changed, 96 insertions, 92 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 933e87f1cc68..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,20 +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 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
237 | udelay(100); | ||
238 | |||
239 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { | 233 | if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
234 | u32 reg1; | ||
235 | |||
240 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 236 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
241 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | 237 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); |
242 | reg1 &= P_ASPM_CONTROL_MSK; | 238 | reg1 &= P_ASPM_CONTROL_MSK; |
@@ -248,15 +244,6 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
248 | 244 | ||
249 | case PCI_D3hot: | 245 | case PCI_D3hot: |
250 | case PCI_D3cold: | 246 | case PCI_D3cold: |
251 | /* Turn on phy power saving */ | ||
252 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); | ||
253 | if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) | ||
254 | reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | ||
255 | else | ||
256 | reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); | ||
257 | sky2_pci_write32(hw, PCI_DEV_REG1, reg1); | ||
258 | udelay(100); | ||
259 | |||
260 | 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) |
261 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 248 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
262 | else | 249 | else |
@@ -280,7 +267,7 @@ static void sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
280 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 267 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
281 | } | 268 | } |
282 | 269 | ||
283 | static void sky2_phy_reset(struct sky2_hw *hw, unsigned port) | 270 | static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port) |
284 | { | 271 | { |
285 | u16 reg; | 272 | u16 reg; |
286 | 273 | ||
@@ -528,6 +515,29 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
528 | 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); |
529 | } | 516 | } |
530 | 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 | |||
531 | /* Force a renegotiation */ | 541 | /* Force a renegotiation */ |
532 | static void sky2_phy_reinit(struct sky2_port *sky2) | 542 | static void sky2_phy_reinit(struct sky2_port *sky2) |
533 | { | 543 | { |
@@ -760,9 +770,10 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2) | |||
760 | /* Update chip's next pointer */ | 770 | /* Update chip's next pointer */ |
761 | 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) |
762 | { | 772 | { |
773 | q = Y2_QADDR(q, PREF_UNIT_PUT_IDX); | ||
763 | wmb(); | 774 | wmb(); |
764 | sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); | 775 | sky2_write16(hw, q, idx); |
765 | mmiowb(); | 776 | sky2_read16(hw, q); |
766 | } | 777 | } |
767 | 778 | ||
768 | 779 | ||
@@ -949,14 +960,16 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
949 | /* | 960 | /* |
950 | * 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 |
951 | * 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 |
952 | * 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 |
953 | * debugging is enabled. | 964 | * aligned except if slab debugging is enabled. |
954 | */ | 965 | */ |
955 | 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) | ||
956 | { | 969 | { |
957 | struct sk_buff *skb; | 970 | struct sk_buff *skb; |
958 | 971 | ||
959 | skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); | 972 | skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask); |
960 | if (likely(skb)) { | 973 | if (likely(skb)) { |
961 | unsigned long p = (unsigned long) skb->data; | 974 | unsigned long p = (unsigned long) skb->data; |
962 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); | 975 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); |
@@ -992,7 +1005,8 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
992 | for (i = 0; i < sky2->rx_pending; i++) { | 1005 | for (i = 0; i < sky2->rx_pending; i++) { |
993 | struct ring_info *re = sky2->rx_ring + i; | 1006 | struct ring_info *re = sky2->rx_ring + i; |
994 | 1007 | ||
995 | re->skb = sky2_alloc_skb(sky2->rx_bufsize, GFP_KERNEL); | 1008 | re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize, |
1009 | GFP_KERNEL); | ||
996 | if (!re->skb) | 1010 | if (!re->skb) |
997 | goto nomem; | 1011 | goto nomem; |
998 | 1012 | ||
@@ -1080,6 +1094,8 @@ static int sky2_up(struct net_device *dev) | |||
1080 | if (!sky2->rx_ring) | 1094 | if (!sky2->rx_ring) |
1081 | goto err_out; | 1095 | goto err_out; |
1082 | 1096 | ||
1097 | sky2_phy_power(hw, port, 1); | ||
1098 | |||
1083 | sky2_mac_init(hw, port); | 1099 | sky2_mac_init(hw, port); |
1084 | 1100 | ||
1085 | /* Determine available ram buffer space (in 4K blocks). | 1101 | /* Determine available ram buffer space (in 4K blocks). |
@@ -1184,7 +1200,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1184 | struct sky2_tx_le *le = NULL; | 1200 | struct sky2_tx_le *le = NULL; |
1185 | struct tx_ring_info *re; | 1201 | struct tx_ring_info *re; |
1186 | unsigned i, len; | 1202 | unsigned i, len; |
1187 | int avail; | ||
1188 | dma_addr_t mapping; | 1203 | dma_addr_t mapping; |
1189 | u32 addr64; | 1204 | u32 addr64; |
1190 | u16 mss; | 1205 | u16 mss; |
@@ -1234,25 +1249,18 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1234 | /* Check for TCP Segmentation Offload */ | 1249 | /* Check for TCP Segmentation Offload */ |
1235 | mss = skb_shinfo(skb)->gso_size; | 1250 | mss = skb_shinfo(skb)->gso_size; |
1236 | if (mss != 0) { | 1251 | if (mss != 0) { |
1237 | /* just drop the packet if non-linear expansion fails */ | ||
1238 | if (skb_header_cloned(skb) && | ||
1239 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { | ||
1240 | dev_kfree_skb(skb); | ||
1241 | goto out_unlock; | ||
1242 | } | ||
1243 | |||
1244 | mss += ((skb->h.th->doff - 5) * 4); /* TCP options */ | 1252 | mss += ((skb->h.th->doff - 5) * 4); /* TCP options */ |
1245 | mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); | 1253 | mss += (skb->nh.iph->ihl * 4) + sizeof(struct tcphdr); |
1246 | mss += ETH_HLEN; | 1254 | mss += ETH_HLEN; |
1247 | } | ||
1248 | 1255 | ||
1249 | if (mss != sky2->tx_last_mss) { | 1256 | if (mss != sky2->tx_last_mss) { |
1250 | le = get_tx_le(sky2); | 1257 | le = get_tx_le(sky2); |
1251 | le->tx.tso.size = cpu_to_le16(mss); | 1258 | le->tx.tso.size = cpu_to_le16(mss); |
1252 | le->tx.tso.rsvd = 0; | 1259 | le->tx.tso.rsvd = 0; |
1253 | le->opcode = OP_LRGLEN | HW_OWNER; | 1260 | le->opcode = OP_LRGLEN | HW_OWNER; |
1254 | le->ctrl = 0; | 1261 | le->ctrl = 0; |
1255 | sky2->tx_last_mss = mss; | 1262 | sky2->tx_last_mss = mss; |
1263 | } | ||
1256 | } | 1264 | } |
1257 | 1265 | ||
1258 | ctrl = 0; | 1266 | ctrl = 0; |
@@ -1280,12 +1288,17 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1280 | if (skb->nh.iph->protocol == IPPROTO_UDP) | 1288 | if (skb->nh.iph->protocol == IPPROTO_UDP) |
1281 | ctrl |= UDPTCP; | 1289 | ctrl |= UDPTCP; |
1282 | 1290 | ||
1283 | le = get_tx_le(sky2); | 1291 | if (hdr != sky2->tx_csum_start || offset != sky2->tx_csum_offset) { |
1284 | le->tx.csum.start = cpu_to_le16(hdr); | 1292 | sky2->tx_csum_start = hdr; |
1285 | le->tx.csum.offset = cpu_to_le16(offset); | 1293 | sky2->tx_csum_offset = offset; |
1286 | le->length = 0; /* initial checksum value */ | 1294 | |
1287 | le->ctrl = 1; /* one packet */ | 1295 | le = get_tx_le(sky2); |
1288 | 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 | } | ||
1289 | } | 1302 | } |
1290 | 1303 | ||
1291 | le = get_tx_le(sky2); | 1304 | le = get_tx_le(sky2); |
@@ -1320,23 +1333,18 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
1320 | le->opcode = OP_BUFFER | HW_OWNER; | 1333 | le->opcode = OP_BUFFER | HW_OWNER; |
1321 | 1334 | ||
1322 | fre = sky2->tx_ring | 1335 | fre = sky2->tx_ring |
1323 | + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); | 1336 | + RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); |
1324 | pci_unmap_addr_set(fre, mapaddr, mapping); | 1337 | pci_unmap_addr_set(fre, mapaddr, mapping); |
1325 | } | 1338 | } |
1326 | 1339 | ||
1327 | re->idx = sky2->tx_prod; | 1340 | re->idx = sky2->tx_prod; |
1328 | le->ctrl |= EOP; | 1341 | le->ctrl |= EOP; |
1329 | 1342 | ||
1330 | avail = tx_avail(sky2); | 1343 | if (tx_avail(sky2) <= MAX_SKB_TX_LE) |
1331 | if (mss != 0 || avail < TX_MIN_PENDING) { | 1344 | netif_stop_queue(dev); |
1332 | le->ctrl |= FRC_STAT; | ||
1333 | if (avail <= MAX_SKB_TX_LE) | ||
1334 | netif_stop_queue(dev); | ||
1335 | } | ||
1336 | 1345 | ||
1337 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); | 1346 | sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); |
1338 | 1347 | ||
1339 | out_unlock: | ||
1340 | spin_unlock(&sky2->tx_lock); | 1348 | spin_unlock(&sky2->tx_lock); |
1341 | 1349 | ||
1342 | dev->trans_start = jiffies; | 1350 | dev->trans_start = jiffies; |
@@ -1421,7 +1429,7 @@ static int sky2_down(struct net_device *dev) | |||
1421 | /* Stop more packets from being queued */ | 1429 | /* Stop more packets from being queued */ |
1422 | netif_stop_queue(dev); | 1430 | netif_stop_queue(dev); |
1423 | 1431 | ||
1424 | sky2_phy_reset(hw, port); | 1432 | sky2_gmac_reset(hw, port); |
1425 | 1433 | ||
1426 | /* Stop transmitter */ | 1434 | /* Stop transmitter */ |
1427 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); | 1435 | sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_STOP); |
@@ -1469,6 +1477,8 @@ static int sky2_down(struct net_device *dev) | |||
1469 | imask &= ~portirq_msk[port]; | 1477 | imask &= ~portirq_msk[port]; |
1470 | sky2_write32(hw, B0_IMSK, imask); | 1478 | sky2_write32(hw, B0_IMSK, imask); |
1471 | 1479 | ||
1480 | sky2_phy_power(hw, port, 0); | ||
1481 | |||
1472 | /* turn off LED's */ | 1482 | /* turn off LED's */ |
1473 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); | 1483 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
1474 | 1484 | ||
@@ -1832,15 +1842,16 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
1832 | * For small packets or errors, just reuse existing skb. | 1842 | * For small packets or errors, just reuse existing skb. |
1833 | * For larger packets, get new buffer. | 1843 | * For larger packets, get new buffer. |
1834 | */ | 1844 | */ |
1835 | static struct sk_buff *sky2_receive(struct sky2_port *sky2, | 1845 | static struct sk_buff *sky2_receive(struct net_device *dev, |
1836 | u16 length, u32 status) | 1846 | u16 length, u32 status) |
1837 | { | 1847 | { |
1848 | struct sky2_port *sky2 = netdev_priv(dev); | ||
1838 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; | 1849 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; |
1839 | struct sk_buff *skb = NULL; | 1850 | struct sk_buff *skb = NULL; |
1840 | 1851 | ||
1841 | if (unlikely(netif_msg_rx_status(sky2))) | 1852 | if (unlikely(netif_msg_rx_status(sky2))) |
1842 | 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", |
1843 | sky2->netdev->name, sky2->rx_next, status, length); | 1854 | dev->name, sky2->rx_next, status, length); |
1844 | 1855 | ||
1845 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; | 1856 | sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; |
1846 | prefetch(sky2->rx_ring + sky2->rx_next); | 1857 | prefetch(sky2->rx_ring + sky2->rx_next); |
@@ -1851,11 +1862,11 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1851 | if (!(status & GMR_FS_RX_OK)) | 1862 | if (!(status & GMR_FS_RX_OK)) |
1852 | goto resubmit; | 1863 | goto resubmit; |
1853 | 1864 | ||
1854 | if (length > sky2->netdev->mtu + ETH_HLEN) | 1865 | if (length > dev->mtu + ETH_HLEN) |
1855 | goto oversize; | 1866 | goto oversize; |
1856 | 1867 | ||
1857 | if (length < copybreak) { | 1868 | if (length < copybreak) { |
1858 | skb = alloc_skb(length + 2, GFP_ATOMIC); | 1869 | skb = netdev_alloc_skb(dev, length + 2); |
1859 | if (!skb) | 1870 | if (!skb) |
1860 | goto resubmit; | 1871 | goto resubmit; |
1861 | 1872 | ||
@@ -1870,7 +1881,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2, | |||
1870 | } else { | 1881 | } else { |
1871 | struct sk_buff *nskb; | 1882 | struct sk_buff *nskb; |
1872 | 1883 | ||
1873 | nskb = sky2_alloc_skb(sky2->rx_bufsize, GFP_ATOMIC); | 1884 | nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC); |
1874 | if (!nskb) | 1885 | if (!nskb) |
1875 | goto resubmit; | 1886 | goto resubmit; |
1876 | 1887 | ||
@@ -1900,7 +1911,7 @@ error: | |||
1900 | 1911 | ||
1901 | if (netif_msg_rx_err(sky2) && net_ratelimit()) | 1912 | if (netif_msg_rx_err(sky2) && net_ratelimit()) |
1902 | 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", |
1903 | sky2->netdev->name, status, length); | 1914 | dev->name, status, length); |
1904 | 1915 | ||
1905 | if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE)) | 1916 | if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE)) |
1906 | sky2->net_stats.rx_length_errors++; | 1917 | sky2->net_stats.rx_length_errors++; |
@@ -1926,12 +1937,6 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) | |||
1926 | } | 1937 | } |
1927 | } | 1938 | } |
1928 | 1939 | ||
1929 | /* Is status ring empty or is there more to do? */ | ||
1930 | static inline int sky2_more_work(const struct sky2_hw *hw) | ||
1931 | { | ||
1932 | return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)); | ||
1933 | } | ||
1934 | |||
1935 | /* Process status response ring */ | 1940 | /* Process status response ring */ |
1936 | 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) |
1937 | { | 1942 | { |
@@ -1960,11 +1965,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
1960 | 1965 | ||
1961 | switch (le->opcode & ~HW_OWNER) { | 1966 | switch (le->opcode & ~HW_OWNER) { |
1962 | case OP_RXSTAT: | 1967 | case OP_RXSTAT: |
1963 | skb = sky2_receive(sky2, length, status); | 1968 | skb = sky2_receive(dev, length, status); |
1964 | if (!skb) | 1969 | if (!skb) |
1965 | break; | 1970 | break; |
1966 | 1971 | ||
1967 | skb->dev = dev; | ||
1968 | skb->protocol = eth_type_trans(skb, dev); | 1972 | skb->protocol = eth_type_trans(skb, dev); |
1969 | dev->last_rx = jiffies; | 1973 | dev->last_rx = jiffies; |
1970 | 1974 | ||
@@ -2022,6 +2026,9 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
2022 | } | 2026 | } |
2023 | } | 2027 | } |
2024 | 2028 | ||
2029 | /* Fully processed status ring so clear irq */ | ||
2030 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
2031 | |||
2025 | exit_loop: | 2032 | exit_loop: |
2026 | if (buf_write[0]) { | 2033 | if (buf_write[0]) { |
2027 | sky2 = netdev_priv(hw->dev[0]); | 2034 | sky2 = netdev_priv(hw->dev[0]); |
@@ -2231,19 +2238,16 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2231 | sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); | 2238 | sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); |
2232 | 2239 | ||
2233 | work_done = sky2_status_intr(hw, work_limit); | 2240 | work_done = sky2_status_intr(hw, work_limit); |
2234 | *budget -= work_done; | 2241 | if (work_done < work_limit) { |
2235 | dev0->quota -= work_done; | 2242 | netif_rx_complete(dev0); |
2236 | 2243 | ||
2237 | if (status & Y2_IS_STAT_BMU) | 2244 | sky2_read32(hw, B0_Y2_SP_LISR); |
2238 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2245 | return 0; |
2239 | 2246 | } else { | |
2240 | if (sky2_more_work(hw)) | 2247 | *budget -= work_done; |
2248 | dev0->quota -= work_done; | ||
2241 | return 1; | 2249 | return 1; |
2242 | 2250 | } | |
2243 | netif_rx_complete(dev0); | ||
2244 | |||
2245 | sky2_read32(hw, B0_Y2_SP_LISR); | ||
2246 | return 0; | ||
2247 | } | 2251 | } |
2248 | 2252 | ||
2249 | 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) |
@@ -2409,7 +2413,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2409 | sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); | 2413 | sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK); |
2410 | 2414 | ||
2411 | for (i = 0; i < hw->ports; i++) | 2415 | for (i = 0; i < hw->ports; i++) |
2412 | sky2_phy_reset(hw, i); | 2416 | sky2_gmac_reset(hw, i); |
2413 | 2417 | ||
2414 | memset(hw->st_le, 0, STATUS_LE_BYTES); | 2418 | memset(hw->st_le, 0, STATUS_LE_BYTES); |
2415 | hw->st_idx = 0; | 2419 | hw->st_idx = 0; |
@@ -3200,6 +3204,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3200 | struct pci_dev *pdev = hw->pdev; | 3204 | struct pci_dev *pdev = hw->pdev; |
3201 | int err; | 3205 | int err; |
3202 | 3206 | ||
3207 | init_waitqueue_head (&hw->msi_wait); | ||
3208 | |||
3203 | sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); | 3209 | sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); |
3204 | 3210 | ||
3205 | 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); |
@@ -3209,10 +3215,8 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
3209 | return err; | 3215 | return err; |
3210 | } | 3216 | } |
3211 | 3217 | ||
3212 | init_waitqueue_head (&hw->msi_wait); | ||
3213 | |||
3214 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); | 3218 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); |
3215 | wmb(); | 3219 | sky2_read8(hw, B0_CTST); |
3216 | 3220 | ||
3217 | wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); | 3221 | wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); |
3218 | 3222 | ||