/[linux-patches]/genpatches-2.6/trunk/2.6.16/2400_sky2-1.2.patch
Gentoo

Contents of /genpatches-2.6/trunk/2.6.16/2400_sky2-1.2.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 443 - (show annotations) (download) (as text)
Thu Apr 27 11:56:31 2006 UTC (14 years, 7 months ago) by dsd
File MIME type: text/x-diff
File size: 41578 byte(s)
sky2 v1.2
1 --- linux-2.6.16.11/drivers/net/sky2.c 2006-04-27 13:08:30.000000000 +0100
2 +++ linux-2.6.17-rc3/drivers/net/sky2.c 2006-04-27 12:43:22.000000000 +0100
3 @@ -51,7 +51,7 @@
4 #include "sky2.h"
5
6 #define DRV_NAME "sky2"
7 -#define DRV_VERSION "0.15"
8 +#define DRV_VERSION "1.2"
9 #define PFX DRV_NAME " "
10
11 /*
12 @@ -61,10 +61,6 @@
13 * a receive requires one (or two if using 64 bit dma).
14 */
15
16 -#define is_ec_a1(hw) \
17 - unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \
18 - (hw)->chip_rev == CHIP_REV_YU_EC_A1)
19 -
20 #define RX_LE_SIZE 512
21 #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
22 #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2)
23 @@ -96,11 +92,13 @@ static int copybreak __read_mostly = 256
24 module_param(copybreak, int, 0);
25 MODULE_PARM_DESC(copybreak, "Receive copy threshold");
26
27 +static int disable_msi = 0;
28 +module_param(disable_msi, int, 0);
29 +MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
30 +
31 static const struct pci_device_id sky2_id_table[] = {
32 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
33 { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
34 - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
35 - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
36 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
37 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
38 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
39 @@ -504,9 +502,9 @@ static void sky2_phy_init(struct sky2_hw
40 /* Force a renegotiation */
41 static void sky2_phy_reinit(struct sky2_port *sky2)
42 {
43 - down(&sky2->phy_sema);
44 + spin_lock_bh(&sky2->phy_lock);
45 sky2_phy_init(sky2->hw, sky2->port);
46 - up(&sky2->phy_sema);
47 + spin_unlock_bh(&sky2->phy_lock);
48 }
49
50 static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
51 @@ -571,9 +569,9 @@ static void sky2_mac_init(struct sky2_hw
52
53 sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
54
55 - down(&sky2->phy_sema);
56 + spin_lock_bh(&sky2->phy_lock);
57 sky2_phy_init(hw, port);
58 - up(&sky2->phy_sema);
59 + spin_unlock_bh(&sky2->phy_lock);
60
61 /* MIB clear */
62 reg = gma_read16(hw, port, GM_PHY_ADDR);
63 @@ -725,37 +723,11 @@ static inline struct sky2_tx_le *get_tx_
64 return le;
65 }
66
67 -/*
68 - * This is a workaround code taken from SysKonnect sk98lin driver
69 - * to deal with chip bug on Yukon EC rev 0 in the wraparound case.
70 - */
71 -static void sky2_put_idx(struct sky2_hw *hw, unsigned q,
72 - u16 idx, u16 *last, u16 size)
73 +/* Update chip's next pointer */
74 +static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
75 {
76 wmb();
77 - if (is_ec_a1(hw) && idx < *last) {
78 - u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX));
79 -
80 - if (hwget == 0) {
81 - /* Start prefetching again */
82 - sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0);
83 - goto setnew;
84 - }
85 -
86 - if (hwget == size - 1) {
87 - /* set watermark to one list element */
88 - sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8);
89 -
90 - /* set put index to first list element */
91 - sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0);
92 - } else /* have hardware go to end of list */
93 - sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX),
94 - size - 1);
95 - } else {
96 -setnew:
97 - sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
98 - }
99 - *last = idx;
100 + sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
101 mmiowb();
102 }
103
104 @@ -878,7 +850,7 @@ static int sky2_ioctl(struct net_device
105 if (!netif_running(dev))
106 return -ENODEV; /* Phy still in reset */
107
108 - switch(cmd) {
109 + switch (cmd) {
110 case SIOCGMIIPHY:
111 data->phy_id = PHY_ADDR_MARV;
112
113 @@ -886,9 +858,9 @@ static int sky2_ioctl(struct net_device
114 case SIOCGMIIREG: {
115 u16 val = 0;
116
117 - down(&sky2->phy_sema);
118 + spin_lock_bh(&sky2->phy_lock);
119 err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val);
120 - up(&sky2->phy_sema);
121 + spin_unlock_bh(&sky2->phy_lock);
122
123 data->val_out = val;
124 break;
125 @@ -898,10 +870,10 @@ static int sky2_ioctl(struct net_device
126 if (!capable(CAP_NET_ADMIN))
127 return -EPERM;
128
129 - down(&sky2->phy_sema);
130 + spin_lock_bh(&sky2->phy_lock);
131 err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f,
132 data->val_in);
133 - up(&sky2->phy_sema);
134 + spin_unlock_bh(&sky2->phy_lock);
135 break;
136 }
137 return err;
138 @@ -953,8 +925,7 @@ static inline struct sk_buff *sky2_alloc
139 skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
140 if (likely(skb)) {
141 unsigned long p = (unsigned long) skb->data;
142 - skb_reserve(skb,
143 - ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p);
144 + skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
145 }
146
147 return skb;
148 @@ -1001,7 +972,6 @@ static int sky2_rx_start(struct sky2_por
149
150 /* Tell chip about available buffers */
151 sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
152 - sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX));
153 return 0;
154 nomem:
155 sky2_rx_clean(sky2);
156 @@ -1014,7 +984,7 @@ static int sky2_up(struct net_device *de
157 struct sky2_port *sky2 = netdev_priv(dev);
158 struct sky2_hw *hw = sky2->hw;
159 unsigned port = sky2->port;
160 - u32 ramsize, rxspace;
161 + u32 ramsize, rxspace, imask;
162 int err = -ENOMEM;
163
164 if (netif_msg_ifup(sky2))
165 @@ -1079,10 +1049,10 @@ static int sky2_up(struct net_device *de
166 goto err_out;
167
168 /* Enable interrupts from phy/mac for port */
169 - spin_lock_irq(&hw->hw_lock);
170 - hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
171 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
172 - spin_unlock_irq(&hw->hw_lock);
173 + imask = sky2_read32(hw, B0_IMSK);
174 + imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
175 + sky2_write32(hw, B0_IMSK, imask);
176 +
177 return 0;
178
179 err_out:
180 @@ -1202,7 +1172,7 @@ static int sky2_xmit_frame(struct sk_buf
181 /* just drop the packet if non-linear expansion fails */
182 if (skb_header_cloned(skb) &&
183 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
184 - dev_kfree_skb_any(skb);
185 + dev_kfree_skb(skb);
186 goto out_unlock;
187 }
188
189 @@ -1299,8 +1269,7 @@ static int sky2_xmit_frame(struct sk_buf
190 netif_stop_queue(dev);
191 }
192
193 - sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod,
194 - &sky2->tx_last_put, TX_RING_SIZE);
195 + sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
196
197 out_unlock:
198 spin_unlock(&sky2->tx_lock);
199 @@ -1332,7 +1301,7 @@ static void sky2_tx_complete(struct sky2
200 struct tx_ring_info *re = sky2->tx_ring + put;
201 struct sk_buff *skb = re->skb;
202
203 - nxt = re->idx;
204 + nxt = re->idx;
205 BUG_ON(nxt >= TX_RING_SIZE);
206 prefetch(sky2->tx_ring + nxt);
207
208 @@ -1348,15 +1317,15 @@ static void sky2_tx_complete(struct sky2
209 struct tx_ring_info *fre;
210 fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE;
211 pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr),
212 - skb_shinfo(skb)->frags[i].size,
213 + skb_shinfo(skb)->frags[i].size,
214 PCI_DMA_TODEVICE);
215 }
216
217 - dev_kfree_skb_any(skb);
218 + dev_kfree_skb(skb);
219 }
220
221 sky2->tx_cons = put;
222 - if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE)
223 + if (tx_avail(sky2) > MAX_SKB_TX_LE)
224 netif_wake_queue(dev);
225 }
226
227 @@ -1375,6 +1344,7 @@ static int sky2_down(struct net_device *
228 struct sky2_hw *hw = sky2->hw;
229 unsigned port = sky2->port;
230 u16 ctrl;
231 + u32 imask;
232
233 /* Never really got started! */
234 if (!sky2->tx_le)
235 @@ -1386,14 +1356,6 @@ static int sky2_down(struct net_device *
236 /* Stop more packets from being queued */
237 netif_stop_queue(dev);
238
239 - /* Disable port IRQ */
240 - spin_lock_irq(&hw->hw_lock);
241 - hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
242 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
243 - spin_unlock_irq(&hw->hw_lock);
244 -
245 - flush_scheduled_work();
246 -
247 sky2_phy_reset(hw, port);
248
249 /* Stop transmitter */
250 @@ -1437,6 +1399,11 @@ static int sky2_down(struct net_device *
251 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
252 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
253
254 + /* Disable port IRQ */
255 + imask = sky2_read32(hw, B0_IMSK);
256 + imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2;
257 + sky2_write32(hw, B0_IMSK, imask);
258 +
259 /* turn off LED's */
260 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
261
262 @@ -1631,20 +1598,19 @@ static int sky2_autoneg_done(struct sky2
263 return 0;
264 }
265
266 -/*
267 - * Interrupt from PHY are handled outside of interrupt context
268 - * because accessing phy registers requires spin wait which might
269 - * cause excess interrupt latency.
270 - */
271 -static void sky2_phy_task(void *arg)
272 +/* Interrupt from PHY */
273 +static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
274 {
275 - struct sky2_port *sky2 = arg;
276 - struct sky2_hw *hw = sky2->hw;
277 + struct net_device *dev = hw->dev[port];
278 + struct sky2_port *sky2 = netdev_priv(dev);
279 u16 istatus, phystat;
280
281 - down(&sky2->phy_sema);
282 - istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT);
283 - phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT);
284 + spin_lock(&sky2->phy_lock);
285 + istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
286 + phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
287 +
288 + if (!netif_running(dev))
289 + goto out;
290
291 if (netif_msg_intr(sky2))
292 printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
293 @@ -1670,12 +1636,7 @@ static void sky2_phy_task(void *arg)
294 sky2_link_down(sky2);
295 }
296 out:
297 - up(&sky2->phy_sema);
298 -
299 - spin_lock_irq(&hw->hw_lock);
300 - hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2;
301 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
302 - spin_unlock_irq(&hw->hw_lock);
303 + spin_unlock(&sky2->phy_lock);
304 }
305
306
307 @@ -1687,41 +1648,49 @@ static void sky2_tx_timeout(struct net_d
308 struct sky2_port *sky2 = netdev_priv(dev);
309 struct sky2_hw *hw = sky2->hw;
310 unsigned txq = txqaddr[sky2->port];
311 - u16 ridx;
312 -
313 - /* Maybe we just missed an status interrupt */
314 - spin_lock(&sky2->tx_lock);
315 - ridx = sky2_read16(hw,
316 - sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
317 - sky2_tx_complete(sky2, ridx);
318 - spin_unlock(&sky2->tx_lock);
319 -
320 - if (!netif_queue_stopped(dev)) {
321 - if (net_ratelimit())
322 - pr_info(PFX "transmit interrupt missed? recovered\n");
323 - return;
324 - }
325 + u16 report, done;
326
327 if (netif_msg_timer(sky2))
328 printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
329
330 - sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
331 - sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
332 + report = sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX);
333 + done = sky2_read16(hw, Q_ADDR(txq, Q_DONE));
334
335 - sky2_tx_clean(sky2);
336 + printk(KERN_DEBUG PFX "%s: transmit ring %u .. %u report=%u done=%u\n",
337 + dev->name,
338 + sky2->tx_cons, sky2->tx_prod, report, done);
339 +
340 + if (report != done) {
341 + printk(KERN_INFO PFX "status burst pending (irq moderation?)\n");
342 +
343 + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
344 + sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
345 + } else if (report != sky2->tx_cons) {
346 + printk(KERN_INFO PFX "status report lost?\n");
347 +
348 + spin_lock_bh(&sky2->tx_lock);
349 + sky2_tx_complete(sky2, report);
350 + spin_unlock_bh(&sky2->tx_lock);
351 + } else {
352 + printk(KERN_INFO PFX "hardware hung? flushing\n");
353 +
354 + sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP);
355 + sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
356 +
357 + sky2_tx_clean(sky2);
358
359 - sky2_qset(hw, txq);
360 - sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
361 + sky2_qset(hw, txq);
362 + sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1);
363 + }
364 }
365
366
367 -#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
368 /* Want receive buffer size to be multiple of 64 bits
369 * and incl room for vlan and truncation
370 */
371 static inline unsigned sky2_buf_size(int mtu)
372 {
373 - return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
374 + return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8;
375 }
376
377 static int sky2_change_mtu(struct net_device *dev, int new_mtu)
378 @@ -1730,6 +1699,7 @@ static int sky2_change_mtu(struct net_de
379 struct sky2_hw *hw = sky2->hw;
380 int err;
381 u16 ctl, mode;
382 + u32 imask;
383
384 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
385 return -EINVAL;
386 @@ -1742,12 +1712,15 @@ static int sky2_change_mtu(struct net_de
387 return 0;
388 }
389
390 + imask = sky2_read32(hw, B0_IMSK);
391 sky2_write32(hw, B0_IMSK, 0);
392
393 dev->trans_start = jiffies; /* prevent tx timeout */
394 netif_stop_queue(dev);
395 netif_poll_disable(hw->dev[0]);
396
397 + synchronize_irq(hw->pdev->irq);
398 +
399 ctl = gma_read16(hw, sky2->port, GM_GP_CTRL);
400 gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
401 sky2_rx_stop(sky2);
402 @@ -1766,7 +1739,7 @@ static int sky2_change_mtu(struct net_de
403 sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD);
404
405 err = sky2_rx_start(sky2);
406 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
407 + sky2_write32(hw, B0_IMSK, imask);
408
409 if (err)
410 dev_close(dev);
411 @@ -1843,8 +1816,7 @@ resubmit:
412 sky2_rx_add(sky2, re->mapaddr);
413
414 /* Tell receiver about new buffers. */
415 - sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
416 - &sky2->rx_last_put, RX_LE_SIZE);
417 + sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put);
418
419 return skb;
420
421 @@ -1871,76 +1843,51 @@ error:
422 goto resubmit;
423 }
424
425 -/*
426 - * Check for transmit complete
427 - */
428 -#define TX_NO_STATUS 0xffff
429 -
430 -static void sky2_tx_check(struct sky2_hw *hw, int port, u16 last)
431 +/* Transmit complete */
432 +static inline void sky2_tx_done(struct net_device *dev, u16 last)
433 {
434 - if (last != TX_NO_STATUS) {
435 - struct net_device *dev = hw->dev[port];
436 - if (dev && netif_running(dev)) {
437 - struct sky2_port *sky2 = netdev_priv(dev);
438 + struct sky2_port *sky2 = netdev_priv(dev);
439
440 - spin_lock(&sky2->tx_lock);
441 - sky2_tx_complete(sky2, last);
442 - spin_unlock(&sky2->tx_lock);
443 - }
444 + if (netif_running(dev)) {
445 + spin_lock(&sky2->tx_lock);
446 + sky2_tx_complete(sky2, last);
447 + spin_unlock(&sky2->tx_lock);
448 }
449 }
450
451 -/*
452 - * Both ports share the same status interrupt, therefore there is only
453 - * one poll routine.
454 - */
455 -static int sky2_poll(struct net_device *dev0, int *budget)
456 +/* Process status response ring */
457 +static int sky2_status_intr(struct sky2_hw *hw, int to_do)
458 {
459 - struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
460 - unsigned int to_do = min(dev0->quota, *budget);
461 - unsigned int work_done = 0;
462 - u16 hwidx;
463 - u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS };
464 -
465 - sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
466 -
467 - /*
468 - * Kick the STAT_LEV_TIMER_CTRL timer.
469 - * This fixes my hangs on Yukon-EC (0xb6) rev 1.
470 - * The if clause is there to start the timer only if it has been
471 - * configured correctly and not been disabled via ethtool.
472 - */
473 - if (sky2_read8(hw, STAT_LEV_TIMER_CTRL) == TIM_START) {
474 - sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_STOP);
475 - sky2_write8(hw, STAT_LEV_TIMER_CTRL, TIM_START);
476 - }
477 + int work_done = 0;
478
479 - hwidx = sky2_read16(hw, STAT_PUT_IDX);
480 - BUG_ON(hwidx >= STATUS_RING_SIZE);
481 rmb();
482
483 - while (hwidx != hw->st_idx) {
484 + for(;;) {
485 struct sky2_status_le *le = hw->st_le + hw->st_idx;
486 struct net_device *dev;
487 struct sky2_port *sky2;
488 struct sk_buff *skb;
489 u32 status;
490 u16 length;
491 + u8 link, opcode;
492 +
493 + opcode = le->opcode;
494 + if (!opcode)
495 + break;
496 + opcode &= ~HW_OWNER;
497
498 - le = hw->st_le + hw->st_idx;
499 hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE;
500 - prefetch(hw->st_le + hw->st_idx);
501 + le->opcode = 0;
502
503 - BUG_ON(le->link >= 2);
504 - dev = hw->dev[le->link];
505 - if (dev == NULL || !netif_running(dev))
506 - continue;
507 + link = le->link;
508 + BUG_ON(link >= 2);
509 + dev = hw->dev[link];
510
511 sky2 = netdev_priv(dev);
512 - status = le32_to_cpu(le->status);
513 - length = le16_to_cpu(le->length);
514 + length = le->length;
515 + status = le->status;
516
517 - switch (le->opcode & ~HW_OWNER) {
518 + switch (opcode) {
519 case OP_RXSTAT:
520 skb = sky2_receive(sky2, length, status);
521 if (!skb)
522 @@ -1980,42 +1927,23 @@ static int sky2_poll(struct net_device *
523
524 case OP_TXINDEXLE:
525 /* TX index reports status for both ports */
526 - tx_done[0] = status & 0xffff;
527 - tx_done[1] = ((status >> 24) & 0xff)
528 - | (u16)(length & 0xf) << 8;
529 + sky2_tx_done(hw->dev[0], status & 0xffff);
530 + if (hw->dev[1])
531 + sky2_tx_done(hw->dev[1],
532 + ((status >> 24) & 0xff)
533 + | (u16)(length & 0xf) << 8);
534 break;
535
536 default:
537 if (net_ratelimit())
538 printk(KERN_WARNING PFX
539 - "unknown status opcode 0x%x\n", le->opcode);
540 + "unknown status opcode 0x%x\n", opcode);
541 break;
542 }
543 }
544
545 exit_loop:
546 - sky2_tx_check(hw, 0, tx_done[0]);
547 - sky2_tx_check(hw, 1, tx_done[1]);
548 -
549 - if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
550 - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
551 - sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
552 - }
553 -
554 - if (likely(work_done < to_do)) {
555 - spin_lock_irq(&hw->hw_lock);
556 - __netif_rx_complete(dev0);
557 -
558 - hw->intr_mask |= Y2_IS_STAT_BMU;
559 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
560 - spin_unlock_irq(&hw->hw_lock);
561 -
562 - return 0;
563 - } else {
564 - *budget -= work_done;
565 - dev0->quota -= work_done;
566 - return 1;
567 - }
568 + return work_done;
569 }
570
571 static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status)
572 @@ -2134,57 +2062,125 @@ static void sky2_mac_intr(struct sky2_hw
573 }
574 }
575
576 -static void sky2_phy_intr(struct sky2_hw *hw, unsigned port)
577 +/* This should never happen it is a fatal situation */
578 +static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port,
579 + const char *rxtx, u32 mask)
580 {
581 struct net_device *dev = hw->dev[port];
582 struct sky2_port *sky2 = netdev_priv(dev);
583 + u32 imask;
584 +
585 + printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n",
586 + dev ? dev->name : "<not registered>", rxtx);
587
588 - hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2);
589 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
590 + imask = sky2_read32(hw, B0_IMSK);
591 + imask &= ~mask;
592 + sky2_write32(hw, B0_IMSK, imask);
593
594 - schedule_work(&sky2->phy_task);
595 + if (dev) {
596 + spin_lock(&sky2->phy_lock);
597 + sky2_link_down(sky2);
598 + spin_unlock(&sky2->phy_lock);
599 + }
600 }
601
602 -static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
603 +/* If idle then force a fake soft NAPI poll once a second
604 + * to work around cases where sharing an edge triggered interrupt.
605 + */
606 +static void sky2_idle(unsigned long arg)
607 {
608 - struct sky2_hw *hw = dev_id;
609 - struct net_device *dev0 = hw->dev[0];
610 - u32 status;
611 + struct net_device *dev = (struct net_device *) arg;
612
613 - status = sky2_read32(hw, B0_Y2_SP_ISRC2);
614 - if (status == 0 || status == ~0)
615 - return IRQ_NONE;
616 + local_irq_disable();
617 + if (__netif_rx_schedule_prep(dev))
618 + __netif_rx_schedule(dev);
619 + local_irq_enable();
620 +}
621 +
622 +
623 +static int sky2_poll(struct net_device *dev0, int *budget)
624 +{
625 + struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
626 + int work_limit = min(dev0->quota, *budget);
627 + int work_done = 0;
628 + u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
629
630 - spin_lock(&hw->hw_lock);
631 - if (status & Y2_IS_HW_ERR)
632 - sky2_hw_intr(hw);
633 + restart_poll:
634 + if (unlikely(status & ~Y2_IS_STAT_BMU)) {
635 + if (status & Y2_IS_HW_ERR)
636 + sky2_hw_intr(hw);
637 +
638 + if (status & Y2_IS_IRQ_PHY1)
639 + sky2_phy_intr(hw, 0);
640 +
641 + if (status & Y2_IS_IRQ_PHY2)
642 + sky2_phy_intr(hw, 1);
643 +
644 + if (status & Y2_IS_IRQ_MAC1)
645 + sky2_mac_intr(hw, 0);
646 +
647 + if (status & Y2_IS_IRQ_MAC2)
648 + sky2_mac_intr(hw, 1);
649 +
650 + if (status & Y2_IS_CHK_RX1)
651 + sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1);
652 +
653 + if (status & Y2_IS_CHK_RX2)
654 + sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2);
655 +
656 + if (status & Y2_IS_CHK_TXA1)
657 + sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1);
658 +
659 + if (status & Y2_IS_CHK_TXA2)
660 + sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
661 + }
662
663 - /* Do NAPI for Rx and Tx status */
664 if (status & Y2_IS_STAT_BMU) {
665 - hw->intr_mask &= ~Y2_IS_STAT_BMU;
666 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
667 + work_done += sky2_status_intr(hw, work_limit - work_done);
668 + *budget -= work_done;
669 + dev0->quota -= work_done;
670
671 - if (likely(__netif_rx_schedule_prep(dev0))) {
672 - prefetch(&hw->st_le[hw->st_idx]);
673 - __netif_rx_schedule(dev0);
674 - }
675 + if (work_done >= work_limit)
676 + return 1;
677 +
678 + sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
679 }
680
681 - if (status & Y2_IS_IRQ_PHY1)
682 - sky2_phy_intr(hw, 0);
683 + mod_timer(&hw->idle_timer, jiffies + HZ);
684
685 - if (status & Y2_IS_IRQ_PHY2)
686 - sky2_phy_intr(hw, 1);
687 + local_irq_disable();
688 + __netif_rx_complete(dev0);
689
690 - if (status & Y2_IS_IRQ_MAC1)
691 - sky2_mac_intr(hw, 0);
692 + status = sky2_read32(hw, B0_Y2_SP_LISR);
693
694 - if (status & Y2_IS_IRQ_MAC2)
695 - sky2_mac_intr(hw, 1);
696 + if (unlikely(status)) {
697 + /* More work pending, try and keep going */
698 + if (__netif_rx_schedule_prep(dev0)) {
699 + __netif_rx_reschedule(dev0, work_done);
700 + status = sky2_read32(hw, B0_Y2_SP_EISR);
701 + local_irq_enable();
702 + goto restart_poll;
703 + }
704 + }
705
706 - sky2_write32(hw, B0_Y2_SP_ICR, 2);
707 + local_irq_enable();
708 + return 0;
709 +}
710
711 - spin_unlock(&hw->hw_lock);
712 +static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs)
713 +{
714 + struct sky2_hw *hw = dev_id;
715 + struct net_device *dev0 = hw->dev[0];
716 + u32 status;
717 +
718 + /* Reading this mask interrupts as side effect */
719 + status = sky2_read32(hw, B0_Y2_SP_ISRC2);
720 + if (status == 0 || status == ~0)
721 + return IRQ_NONE;
722 +
723 + prefetch(&hw->st_le[hw->st_idx]);
724 + if (likely(__netif_rx_schedule_prep(dev0)))
725 + __netif_rx_schedule(dev0);
726
727 return IRQ_HANDLED;
728 }
729 @@ -2223,7 +2219,7 @@ static inline u32 sky2_clk2us(const stru
730 }
731
732
733 -static int sky2_reset(struct sky2_hw *hw)
734 +static int __devinit sky2_reset(struct sky2_hw *hw)
735 {
736 u16 status;
737 u8 t8, pmd_type;
738 @@ -2238,6 +2234,23 @@ static int sky2_reset(struct sky2_hw *hw
739 return -EOPNOTSUPP;
740 }
741
742 + hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
743 +
744 + /* This rev is really old, and requires untested workarounds */
745 + if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) {
746 + printk(KERN_ERR PFX "%s: unsupported revision Yukon-%s (0x%x) rev %d\n",
747 + pci_name(hw->pdev), yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
748 + hw->chip_id, hw->chip_rev);
749 + return -EOPNOTSUPP;
750 + }
751 +
752 + /* This chip is new and not tested yet */
753 + if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
754 + pr_info(PFX "%s: is a version of Yukon 2 chipset that has not been tested yet.\n",
755 + pci_name(hw->pdev));
756 + pr_info("Please report success/failure to maintainer <shemminger@osdl.org>\n");
757 + }
758 +
759 /* disable ASF */
760 if (hw->chip_id <= CHIP_ID_YUKON_EC) {
761 sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET);
762 @@ -2258,7 +2271,7 @@ static int sky2_reset(struct sky2_hw *hw
763 sky2_write8(hw, B0_CTST, CS_MRST_CLR);
764
765 /* clear any PEX errors */
766 - if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
767 + if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
768 sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
769
770
771 @@ -2271,7 +2284,6 @@ static int sky2_reset(struct sky2_hw *hw
772 if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC))
773 ++hw->ports;
774 }
775 - hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
776
777 sky2_set_power_state(hw, PCI_D0);
778
779 @@ -2337,30 +2349,18 @@ static int sky2_reset(struct sky2_hw *hw
780 /* Set the list last index */
781 sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1);
782
783 - /* These status setup values are copied from SysKonnect's driver */
784 - if (is_ec_a1(hw)) {
785 - /* WA for dev. #4.3 */
786 - sky2_write16(hw, STAT_TX_IDX_TH, 0xfff); /* Tx Threshold */
787 -
788 - /* set Status-FIFO watermark */
789 - sky2_write8(hw, STAT_FIFO_WM, 0x21); /* WA for dev. #4.18 */
790 -
791 - /* set Status-FIFO ISR watermark */
792 - sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07); /* WA for dev. #4.18 */
793 - sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000));
794 - } else {
795 - sky2_write16(hw, STAT_TX_IDX_TH, 10);
796 - sky2_write8(hw, STAT_FIFO_WM, 16);
797 + sky2_write16(hw, STAT_TX_IDX_TH, 10);
798 + sky2_write8(hw, STAT_FIFO_WM, 16);
799
800 - /* set Status-FIFO ISR watermark */
801 - if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
802 - sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
803 - else
804 - sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
805 + /* set Status-FIFO ISR watermark */
806 + if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0)
807 + sky2_write8(hw, STAT_FIFO_ISR_WM, 4);
808 + else
809 + sky2_write8(hw, STAT_FIFO_ISR_WM, 16);
810
811 - sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
812 - sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 7));
813 - }
814 + sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000));
815 + sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20));
816 + sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100));
817
818 /* enable status unit */
819 sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON);
820 @@ -2502,17 +2502,34 @@ static const struct sky2_stat {
821 { "rx_unicast", GM_RXF_UC_OK },
822 { "tx_mac_pause", GM_TXF_MPAUSE },
823 { "rx_mac_pause", GM_RXF_MPAUSE },
824 - { "collisions", GM_TXF_SNG_COL },
825 + { "collisions", GM_TXF_COL },
826 { "late_collision",GM_TXF_LAT_COL },
827 { "aborted", GM_TXF_ABO_COL },
828 + { "single_collisions", GM_TXF_SNG_COL },
829 { "multi_collisions", GM_TXF_MUL_COL },
830 - { "fifo_underrun", GM_TXE_FIFO_UR },
831 - { "fifo_overflow", GM_RXE_FIFO_OV },
832 - { "rx_toolong", GM_RXF_LNG_ERR },
833 - { "rx_jabber", GM_RXF_JAB_PKT },
834 +
835 + { "rx_short", GM_RXF_SHT },
836 { "rx_runt", GM_RXE_FRAG },
837 + { "rx_64_byte_packets", GM_RXF_64B },
838 + { "rx_65_to_127_byte_packets", GM_RXF_127B },
839 + { "rx_128_to_255_byte_packets", GM_RXF_255B },
840 + { "rx_256_to_511_byte_packets", GM_RXF_511B },
841 + { "rx_512_to_1023_byte_packets", GM_RXF_1023B },
842 + { "rx_1024_to_1518_byte_packets", GM_RXF_1518B },
843 + { "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ },
844 { "rx_too_long", GM_RXF_LNG_ERR },
845 + { "rx_fifo_overflow", GM_RXE_FIFO_OV },
846 + { "rx_jabber", GM_RXF_JAB_PKT },
847 { "rx_fcs_error", GM_RXF_FCS_ERR },
848 +
849 + { "tx_64_byte_packets", GM_TXF_64B },
850 + { "tx_65_to_127_byte_packets", GM_TXF_127B },
851 + { "tx_128_to_255_byte_packets", GM_TXF_255B },
852 + { "tx_256_to_511_byte_packets", GM_TXF_511B },
853 + { "tx_512_to_1023_byte_packets", GM_TXF_1023B },
854 + { "tx_1024_to_1518_byte_packets", GM_TXF_1518B },
855 + { "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ },
856 + { "tx_fifo_underrun", GM_TXE_FIFO_UR },
857 };
858
859 static u32 sky2_get_rx_csum(struct net_device *dev)
860 @@ -2614,7 +2631,7 @@ static struct net_device_stats *sky2_get
861 sky2->net_stats.rx_bytes = data[1];
862 sky2->net_stats.tx_packets = data[2] + data[4] + data[6];
863 sky2->net_stats.rx_packets = data[3] + data[5] + data[7];
864 - sky2->net_stats.multicast = data[5] + data[7];
865 + sky2->net_stats.multicast = data[3] + data[5];
866 sky2->net_stats.collisions = data[10];
867 sky2->net_stats.tx_aborted_errors = data[12];
868
869 @@ -2743,7 +2760,7 @@ static int sky2_phys_id(struct net_devic
870 ms = data * 1000;
871
872 /* save initial values */
873 - down(&sky2->phy_sema);
874 + spin_lock_bh(&sky2->phy_lock);
875 if (hw->chip_id == CHIP_ID_YUKON_XL) {
876 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
877 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3);
878 @@ -2759,9 +2776,9 @@ static int sky2_phys_id(struct net_devic
879 sky2_led(hw, port, onoff);
880 onoff = !onoff;
881
882 - up(&sky2->phy_sema);
883 + spin_unlock_bh(&sky2->phy_lock);
884 interrupted = msleep_interruptible(250);
885 - down(&sky2->phy_sema);
886 + spin_lock_bh(&sky2->phy_lock);
887
888 ms -= 250;
889 }
890 @@ -2776,7 +2793,7 @@ static int sky2_phys_id(struct net_devic
891 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
892 gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
893 }
894 - up(&sky2->phy_sema);
895 + spin_unlock_bh(&sky2->phy_lock);
896
897 return 0;
898 }
899 @@ -2806,38 +2823,6 @@ static int sky2_set_pauseparam(struct ne
900 return err;
901 }
902
903 -#ifdef CONFIG_PM
904 -static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
905 -{
906 - struct sky2_port *sky2 = netdev_priv(dev);
907 -
908 - wol->supported = WAKE_MAGIC;
909 - wol->wolopts = sky2->wol ? WAKE_MAGIC : 0;
910 -}
911 -
912 -static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
913 -{
914 - struct sky2_port *sky2 = netdev_priv(dev);
915 - struct sky2_hw *hw = sky2->hw;
916 -
917 - if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
918 - return -EOPNOTSUPP;
919 -
920 - sky2->wol = wol->wolopts == WAKE_MAGIC;
921 -
922 - if (sky2->wol) {
923 - memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN);
924 -
925 - sky2_write16(hw, WOL_CTRL_STAT,
926 - WOL_CTL_ENA_PME_ON_MAGIC_PKT |
927 - WOL_CTL_ENA_MAGIC_PKT_UNIT);
928 - } else
929 - sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT);
930 -
931 - return 0;
932 -}
933 -#endif
934 -
935 static int sky2_get_coalesce(struct net_device *dev,
936 struct ethtool_coalesce *ecmd)
937 {
938 @@ -2878,19 +2863,11 @@ static int sky2_set_coalesce(struct net_
939 {
940 struct sky2_port *sky2 = netdev_priv(dev);
941 struct sky2_hw *hw = sky2->hw;
942 - const u32 tmin = sky2_clk2us(hw, 1);
943 - const u32 tmax = 5000;
944 -
945 - if (ecmd->tx_coalesce_usecs != 0 &&
946 - (ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax))
947 - return -EINVAL;
948 -
949 - if (ecmd->rx_coalesce_usecs != 0 &&
950 - (ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax))
951 - return -EINVAL;
952 + const u32 tmax = sky2_clk2us(hw, 0x0ffffff);
953
954 - if (ecmd->rx_coalesce_usecs_irq != 0 &&
955 - (ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax))
956 + if (ecmd->tx_coalesce_usecs > tmax ||
957 + ecmd->rx_coalesce_usecs > tmax ||
958 + ecmd->rx_coalesce_usecs_irq > tmax)
959 return -EINVAL;
960
961 if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1)
962 @@ -3025,10 +3002,6 @@ static struct ethtool_ops sky2_ethtool_o
963 .set_ringparam = sky2_set_ringparam,
964 .get_pauseparam = sky2_get_pauseparam,
965 .set_pauseparam = sky2_set_pauseparam,
966 -#ifdef CONFIG_PM
967 - .get_wol = sky2_get_wol,
968 - .set_wol = sky2_set_wol,
969 -#endif
970 .phys_id = sky2_phys_id,
971 .get_stats_count = sky2_get_stats_count,
972 .get_ethtool_stats = sky2_get_ethtool_stats,
973 @@ -3082,16 +3055,15 @@ static __devinit struct net_device *sky2
974 sky2->speed = -1;
975 sky2->advertising = sky2_supported_modes(hw);
976
977 - /* Receive checksum disabled for Yukon XL
978 + /* Receive checksum disabled for Yukon XL
979 * because of observed problems with incorrect
980 * values when multiple packets are received in one interrupt
981 */
982 sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
983
984 - INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2);
985 - init_MUTEX(&sky2->phy_sema);
986 + spin_lock_init(&sky2->phy_lock);
987 sky2->tx_pending = TX_DEF_PENDING;
988 - sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
989 + sky2->rx_pending = RX_DEF_PENDING;
990 sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
991
992 hw->dev[port] = dev;
993 @@ -3133,6 +3105,66 @@ static void __devinit sky2_show_addr(str
994 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
995 }
996
997 +/* Handle software interrupt used during MSI test */
998 +static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id,
999 + struct pt_regs *regs)
1000 +{
1001 + struct sky2_hw *hw = dev_id;
1002 + u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2);
1003 +
1004 + if (status == 0)
1005 + return IRQ_NONE;
1006 +
1007 + if (status & Y2_IS_IRQ_SW) {
1008 + hw->msi_detected = 1;
1009 + wake_up(&hw->msi_wait);
1010 + sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
1011 + }
1012 + sky2_write32(hw, B0_Y2_SP_ICR, 2);
1013 +
1014 + return IRQ_HANDLED;
1015 +}
1016 +
1017 +/* Test interrupt path by forcing a a software IRQ */
1018 +static int __devinit sky2_test_msi(struct sky2_hw *hw)
1019 +{
1020 + struct pci_dev *pdev = hw->pdev;
1021 + int err;
1022 +
1023 + sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
1024 +
1025 + err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw);
1026 + if (err) {
1027 + printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
1028 + pci_name(pdev), pdev->irq);
1029 + return err;
1030 + }
1031 +
1032 + init_waitqueue_head (&hw->msi_wait);
1033 +
1034 + sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
1035 + wmb();
1036 +
1037 + wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
1038 +
1039 + if (!hw->msi_detected) {
1040 + /* MSI test failed, go back to INTx mode */
1041 + printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, "
1042 + "switching to INTx mode. Please report this failure to "
1043 + "the PCI maintainer and include system chipset information.\n",
1044 + pci_name(pdev));
1045 +
1046 + err = -EOPNOTSUPP;
1047 + sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
1048 + }
1049 +
1050 + sky2_write32(hw, B0_IMSK, 0);
1051 +
1052 + free_irq(pdev->irq, hw);
1053 +
1054 + return err;
1055 +}
1056 +
1057 static int __devinit sky2_probe(struct pci_dev *pdev,
1058 const struct pci_device_id *ent)
1059 {
1060 @@ -3201,7 +3233,6 @@ static int __devinit sky2_probe(struct p
1061 goto err_out_free_hw;
1062 }
1063 hw->pm_cap = pm_cap;
1064 - spin_lock_init(&hw->hw_lock);
1065
1066 #ifdef __BIG_ENDIAN
1067 /* byte swap descriptors in hardware */
1068 @@ -3254,21 +3285,31 @@ static int __devinit sky2_probe(struct p
1069 }
1070 }
1071
1072 - err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
1073 + if (!disable_msi && pci_enable_msi(pdev) == 0) {
1074 + err = sky2_test_msi(hw);
1075 + if (err == -EOPNOTSUPP)
1076 + pci_disable_msi(pdev);
1077 + else if (err)
1078 + goto err_out_unregister;
1079 + }
1080 +
1081 + err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw);
1082 if (err) {
1083 printk(KERN_ERR PFX "%s: cannot assign irq %d\n",
1084 pci_name(pdev), pdev->irq);
1085 goto err_out_unregister;
1086 }
1087
1088 - hw->intr_mask = Y2_IS_BASE;
1089 - sky2_write32(hw, B0_IMSK, hw->intr_mask);
1090 + sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
1091 +
1092 + setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev);
1093
1094 pci_set_drvdata(pdev, hw);
1095
1096 return 0;
1097
1098 err_out_unregister:
1099 + pci_disable_msi(pdev);
1100 if (dev1) {
1101 unregister_netdev(dev1);
1102 free_netdev(dev1);
1103 @@ -3298,19 +3339,22 @@ static void __devexit sky2_remove(struct
1104 if (!hw)
1105 return;
1106
1107 + del_timer_sync(&hw->idle_timer);
1108 +
1109 + sky2_write32(hw, B0_IMSK, 0);
1110 dev0 = hw->dev[0];
1111 dev1 = hw->dev[1];
1112 if (dev1)
1113 unregister_netdev(dev1);
1114 unregister_netdev(dev0);
1115
1116 - sky2_write32(hw, B0_IMSK, 0);
1117 sky2_set_power_state(hw, PCI_D3hot);
1118 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
1119 sky2_write8(hw, B0_CTST, CS_RST_SET);
1120 sky2_read8(hw, B0_CTST);
1121
1122 free_irq(pdev->irq, hw);
1123 + pci_disable_msi(pdev);
1124 pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
1125 pci_release_regions(pdev);
1126 pci_disable_device(pdev);
1127 --- linux-2.6.16.11/drivers/net/sky2.h 2006-04-27 13:08:30.000000000 +0100
1128 +++ linux-2.6.17-rc3/drivers/net/sky2.h 2006-04-27 12:43:22.000000000 +0100
1129 @@ -278,13 +278,11 @@ enum {
1130 Y2_IS_CHK_TXS1 = 1<<1, /* Descriptor error TXS 1 */
1131 Y2_IS_CHK_TXA1 = 1<<0, /* Descriptor error TXA 1 */
1132
1133 - Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU |
1134 - Y2_IS_POLL_CHK | Y2_IS_TWSI_RDY |
1135 - Y2_IS_IRQ_SW | Y2_IS_TIMINT,
1136 - Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1 |
1137 - Y2_IS_CHK_RX1 | Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXS1,
1138 - Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2 |
1139 - Y2_IS_CHK_RX2 | Y2_IS_CHK_TXA2 | Y2_IS_CHK_TXS2,
1140 + Y2_IS_BASE = Y2_IS_HW_ERR | Y2_IS_STAT_BMU,
1141 + Y2_IS_PORT_1 = Y2_IS_IRQ_PHY1 | Y2_IS_IRQ_MAC1
1142 + | Y2_IS_CHK_TXA1 | Y2_IS_CHK_RX1,
1143 + Y2_IS_PORT_2 = Y2_IS_IRQ_PHY2 | Y2_IS_IRQ_MAC2
1144 + | Y2_IS_CHK_TXA2 | Y2_IS_CHK_RX2,
1145 };
1146
1147 /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */
1148 @@ -1375,24 +1373,23 @@ enum {
1149 GM_SMI_CTRL = 0x0080, /* 16 bit r/w SMI Control Register */
1150 GM_SMI_DATA = 0x0084, /* 16 bit r/w SMI Data Register */
1151 GM_PHY_ADDR = 0x0088, /* 16 bit r/w GPHY Address Register */
1152 +/* MIB Counters */
1153 + GM_MIB_CNT_BASE = 0x0100, /* Base Address of MIB Counters */
1154 + GM_MIB_CNT_END = 0x025C, /* Last MIB counter */
1155 };
1156
1157 -/* MIB Counters */
1158 -#define GM_MIB_CNT_BASE 0x0100 /* Base Address of MIB Counters */
1159 -#define GM_MIB_CNT_SIZE 44 /* Number of MIB Counters */
1160 -#define GM_MIB_CNT_END 0x025C /* Last MIB counter */
1161
1162 /*
1163 * MIB Counters base address definitions (low word) -
1164 * use offset 4 for access to high word (32 bit r/o)
1165 */
1166 enum {
1167 - GM_RXF_UC_OK = GM_MIB_CNT_BASE + 0, /* Unicast Frames Received OK */
1168 + GM_RXF_UC_OK = GM_MIB_CNT_BASE + 0, /* Unicast Frames Received OK */
1169 GM_RXF_BC_OK = GM_MIB_CNT_BASE + 8, /* Broadcast Frames Received OK */
1170 GM_RXF_MPAUSE = GM_MIB_CNT_BASE + 16, /* Pause MAC Ctrl Frames Received */
1171 GM_RXF_MC_OK = GM_MIB_CNT_BASE + 24, /* Multicast Frames Received OK */
1172 GM_RXF_FCS_ERR = GM_MIB_CNT_BASE + 32, /* Rx Frame Check Seq. Error */
1173 - /* GM_MIB_CNT_BASE + 40: reserved */
1174 +
1175 GM_RXO_OK_LO = GM_MIB_CNT_BASE + 48, /* Octets Received OK Low */
1176 GM_RXO_OK_HI = GM_MIB_CNT_BASE + 56, /* Octets Received OK High */
1177 GM_RXO_ERR_LO = GM_MIB_CNT_BASE + 64, /* Octets Received Invalid Low */
1178 @@ -1400,37 +1397,36 @@ enum {
1179 GM_RXF_SHT = GM_MIB_CNT_BASE + 80, /* Frames <64 Byte Received OK */
1180 GM_RXE_FRAG = GM_MIB_CNT_BASE + 88, /* Frames <64 Byte Received with FCS Err */
1181 GM_RXF_64B = GM_MIB_CNT_BASE + 96, /* 64 Byte Rx Frame */
1182 - GM_RXF_127B = GM_MIB_CNT_BASE + 104, /* 65-127 Byte Rx Frame */
1183 - GM_RXF_255B = GM_MIB_CNT_BASE + 112, /* 128-255 Byte Rx Frame */
1184 - GM_RXF_511B = GM_MIB_CNT_BASE + 120, /* 256-511 Byte Rx Frame */
1185 - GM_RXF_1023B = GM_MIB_CNT_BASE + 128, /* 512-1023 Byte Rx Frame */
1186 - GM_RXF_1518B = GM_MIB_CNT_BASE + 136, /* 1024-1518 Byte Rx Frame */
1187 - GM_RXF_MAX_SZ = GM_MIB_CNT_BASE + 144, /* 1519-MaxSize Byte Rx Frame */
1188 - GM_RXF_LNG_ERR = GM_MIB_CNT_BASE + 152, /* Rx Frame too Long Error */
1189 - GM_RXF_JAB_PKT = GM_MIB_CNT_BASE + 160, /* Rx Jabber Packet Frame */
1190 - /* GM_MIB_CNT_BASE + 168: reserved */
1191 - GM_RXE_FIFO_OV = GM_MIB_CNT_BASE + 176, /* Rx FIFO overflow Event */
1192 - /* GM_MIB_CNT_BASE + 184: reserved */
1193 - GM_TXF_UC_OK = GM_MIB_CNT_BASE + 192, /* Unicast Frames Xmitted OK */
1194 - GM_TXF_BC_OK = GM_MIB_CNT_BASE + 200, /* Broadcast Frames Xmitted OK */
1195 - GM_TXF_MPAUSE = GM_MIB_CNT_BASE + 208, /* Pause MAC Ctrl Frames Xmitted */
1196 - GM_TXF_MC_OK = GM_MIB_CNT_BASE + 216, /* Multicast Frames Xmitted OK */
1197 - GM_TXO_OK_LO = GM_MIB_CNT_BASE + 224, /* Octets Transmitted OK Low */
1198 - GM_TXO_OK_HI = GM_MIB_CNT_BASE + 232, /* Octets Transmitted OK High */
1199 - GM_TXF_64B = GM_MIB_CNT_BASE + 240, /* 64 Byte Tx Frame */
1200 - GM_TXF_127B = GM_MIB_CNT_BASE + 248, /* 65-127 Byte Tx Frame */
1201 - GM_TXF_255B = GM_MIB_CNT_BASE + 256, /* 128-255 Byte Tx Frame */
1202 - GM_TXF_511B = GM_MIB_CNT_BASE + 264, /* 256-511 Byte Tx Frame */
1203 - GM_TXF_1023B = GM_MIB_CNT_BASE + 272, /* 512-1023 Byte Tx Frame */
1204 - GM_TXF_1518B = GM_MIB_CNT_BASE + 280, /* 1024-1518 Byte Tx Frame */
1205 - GM_TXF_MAX_SZ = GM_MIB_CNT_BASE + 288, /* 1519-MaxSize Byte Tx Frame */
1206 -
1207 - GM_TXF_COL = GM_MIB_CNT_BASE + 304, /* Tx Collision */
1208 - GM_TXF_LAT_COL = GM_MIB_CNT_BASE + 312, /* Tx Late Collision */
1209 - GM_TXF_ABO_COL = GM_MIB_CNT_BASE + 320, /* Tx aborted due to Exces. Col. */
1210 - GM_TXF_MUL_COL = GM_MIB_CNT_BASE + 328, /* Tx Multiple Collision */
1211 - GM_TXF_SNG_COL = GM_MIB_CNT_BASE + 336, /* Tx Single Collision */
1212 - GM_TXE_FIFO_UR = GM_MIB_CNT_BASE + 344, /* Tx FIFO Underrun Event */
1213 + GM_RXF_127B = GM_MIB_CNT_BASE + 104,/* 65-127 Byte Rx Frame */
1214 + GM_RXF_255B = GM_MIB_CNT_BASE + 112,/* 128-255 Byte Rx Frame */
1215 + GM_RXF_511B = GM_MIB_CNT_BASE + 120,/* 256-511 Byte Rx Frame */
1216 + GM_RXF_1023B = GM_MIB_CNT_BASE + 128,/* 512-1023 Byte Rx Frame */
1217 + GM_RXF_1518B = GM_MIB_CNT_BASE + 136,/* 1024-1518 Byte Rx Frame */
1218 + GM_RXF_MAX_SZ = GM_MIB_CNT_BASE + 144,/* 1519-MaxSize Byte Rx Frame */
1219 + GM_RXF_LNG_ERR = GM_MIB_CNT_BASE + 152,/* Rx Frame too Long Error */
1220 + GM_RXF_JAB_PKT = GM_MIB_CNT_BASE + 160,/* Rx Jabber Packet Frame */
1221 +
1222 + GM_RXE_FIFO_OV = GM_MIB_CNT_BASE + 176,/* Rx FIFO overflow Event */
1223 + GM_TXF_UC_OK = GM_MIB_CNT_BASE + 192,/* Unicast Frames Xmitted OK */
1224 + GM_TXF_BC_OK = GM_MIB_CNT_BASE + 200,/* Broadcast Frames Xmitted OK */
1225 + GM_TXF_MPAUSE = GM_MIB_CNT_BASE + 208,/* Pause MAC Ctrl Frames Xmitted */
1226 + GM_TXF_MC_OK = GM_MIB_CNT_BASE + 216,/* Multicast Frames Xmitted OK */
1227 + GM_TXO_OK_LO = GM_MIB_CNT_BASE + 224,/* Octets Transmitted OK Low */
1228 + GM_TXO_OK_HI = GM_MIB_CNT_BASE + 232,/* Octets Transmitted OK High */
1229 + GM_TXF_64B = GM_MIB_CNT_BASE + 240,/* 64 Byte Tx Frame */
1230 + GM_TXF_127B = GM_MIB_CNT_BASE + 248,/* 65-127 Byte Tx Frame */
1231 + GM_TXF_255B = GM_MIB_CNT_BASE + 256,/* 128-255 Byte Tx Frame */
1232 + GM_TXF_511B = GM_MIB_CNT_BASE + 264,/* 256-511 Byte Tx Frame */
1233 + GM_TXF_1023B = GM_MIB_CNT_BASE + 272,/* 512-1023 Byte Tx Frame */
1234 + GM_TXF_1518B = GM_MIB_CNT_BASE + 280,/* 1024-1518 Byte Tx Frame */
1235 + GM_TXF_MAX_SZ = GM_MIB_CNT_BASE + 288,/* 1519-MaxSize Byte Tx Frame */
1236 +
1237 + GM_TXF_COL = GM_MIB_CNT_BASE + 304,/* Tx Collision */
1238 + GM_TXF_LAT_COL = GM_MIB_CNT_BASE + 312,/* Tx Late Collision */
1239 + GM_TXF_ABO_COL = GM_MIB_CNT_BASE + 320,/* Tx aborted due to Exces. Col. */
1240 + GM_TXF_MUL_COL = GM_MIB_CNT_BASE + 328,/* Tx Multiple Collision */
1241 + GM_TXF_SNG_COL = GM_MIB_CNT_BASE + 336,/* Tx Single Collision */
1242 + GM_TXE_FIFO_UR = GM_MIB_CNT_BASE + 344,/* Tx FIFO Underrun Event */
1243 };
1244
1245 /* GMAC Bit Definitions */
1246 @@ -1808,7 +1804,7 @@ struct sky2_rx_le {
1247 __le16 length;
1248 u8 ctrl;
1249 u8 opcode;
1250 -} __attribute((packed));;
1251 +} __attribute((packed));
1252
1253 struct sky2_status_le {
1254 __le32 status; /* also checksum */
1255 @@ -1833,6 +1829,7 @@ struct sky2_port {
1256 struct net_device *netdev;
1257 unsigned port;
1258 u32 msg_enable;
1259 + spinlock_t phy_lock;
1260
1261 spinlock_t tx_lock ____cacheline_aligned_in_smp;
1262 struct tx_ring_info *tx_ring;
1263 @@ -1841,7 +1838,6 @@ struct sky2_port {
1264 u16 tx_prod; /* next le to use */
1265 u32 tx_addr64;
1266 u16 tx_pending;
1267 - u16 tx_last_put;
1268 u16 tx_last_mss;
1269
1270 struct ring_info *rx_ring ____cacheline_aligned_in_smp;
1271 @@ -1850,7 +1846,6 @@ struct sky2_port {
1272 u16 rx_next; /* next re to check */
1273 u16 rx_put; /* next le index to use */
1274 u16 rx_pending;
1275 - u16 rx_last_put;
1276 u16 rx_bufsize;
1277 #ifdef SKY2_VLAN_TAG_USED
1278 u16 rx_tag;
1279 @@ -1866,20 +1861,15 @@ struct sky2_port {
1280 u8 rx_pause;
1281 u8 tx_pause;
1282 u8 rx_csum;
1283 - u8 wol;
1284
1285 struct net_device_stats net_stats;
1286
1287 - struct work_struct phy_task;
1288 - struct semaphore phy_sema;
1289 };
1290
1291 struct sky2_hw {
1292 void __iomem *regs;
1293 struct pci_dev *pdev;
1294 struct net_device *dev[2];
1295 - spinlock_t hw_lock;
1296 - u32 intr_mask;
1297
1298 int pm_cap;
1299 u8 chip_id;
1300 @@ -1890,6 +1880,10 @@ struct sky2_hw {
1301 struct sky2_status_le *st_le;
1302 u32 st_idx;
1303 dma_addr_t st_dma;
1304 +
1305 + struct timer_list idle_timer;
1306 + int msi_detected;
1307 + wait_queue_head_t msi_wait;
1308 };
1309
1310 /* Register accessor for memory mapped device */

  ViewVC Help
Powered by ViewVC 1.1.20