Lines 23-34
Link Here
|
23 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 |
*/ |
24 |
*/ |
25 |
|
25 |
|
26 |
/* |
|
|
27 |
* TOTEST |
28 |
* - speed setting |
29 |
* - suspend/resume |
30 |
*/ |
31 |
|
32 |
#include <linux/config.h> |
26 |
#include <linux/config.h> |
33 |
#include <linux/crc32.h> |
27 |
#include <linux/crc32.h> |
34 |
#include <linux/kernel.h> |
28 |
#include <linux/kernel.h> |
Lines 57-63
Link Here
|
57 |
#include "sky2.h" |
51 |
#include "sky2.h" |
58 |
|
52 |
|
59 |
#define DRV_NAME "sky2" |
53 |
#define DRV_NAME "sky2" |
60 |
#define DRV_VERSION "0.12" |
54 |
#define DRV_VERSION "1.3-rc1" |
61 |
#define PFX DRV_NAME " " |
55 |
#define PFX DRV_NAME " " |
62 |
|
56 |
|
63 |
/* |
57 |
/* |
Lines 67-76
Link Here
|
67 |
* a receive requires one (or two if using 64 bit dma). |
61 |
* a receive requires one (or two if using 64 bit dma). |
68 |
*/ |
62 |
*/ |
69 |
|
63 |
|
70 |
#define is_ec_a1(hw) \ |
|
|
71 |
unlikely((hw)->chip_id == CHIP_ID_YUKON_EC && \ |
72 |
(hw)->chip_rev == CHIP_REV_YU_EC_A1) |
73 |
|
74 |
#define RX_LE_SIZE 512 |
64 |
#define RX_LE_SIZE 512 |
75 |
#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)) |
76 |
#define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) |
66 |
#define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) |
Lines 80-86
Link Here
|
80 |
#define TX_RING_SIZE 512 |
70 |
#define TX_RING_SIZE 512 |
81 |
#define TX_DEF_PENDING (TX_RING_SIZE - 1) |
71 |
#define TX_DEF_PENDING (TX_RING_SIZE - 1) |
82 |
#define TX_MIN_PENDING 64 |
72 |
#define TX_MIN_PENDING 64 |
83 |
#define MAX_SKB_TX_LE (4 + 2*MAX_SKB_FRAGS) |
73 |
#define MAX_SKB_TX_LE (4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS) |
84 |
|
74 |
|
85 |
#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
75 |
#define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
86 |
#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
76 |
#define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
Lines 89-98
Link Here
|
89 |
#define NAPI_WEIGHT 64 |
79 |
#define NAPI_WEIGHT 64 |
90 |
#define PHY_RETRIES 1000 |
80 |
#define PHY_RETRIES 1000 |
91 |
|
81 |
|
|
|
82 |
#define RING_NEXT(x,s) (((x)+1) & ((s)-1)) |
83 |
|
92 |
static const u32 default_msg = |
84 |
static const u32 default_msg = |
93 |
NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK |
85 |
NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK |
94 |
| NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR |
86 |
| NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR |
95 |
| NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_INTR; |
87 |
| NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; |
96 |
|
88 |
|
97 |
static int debug = -1; /* defaults above */ |
89 |
static int debug = -1; /* defaults above */ |
98 |
module_param(debug, int, 0); |
90 |
module_param(debug, int, 0); |
Lines 102-112
static int copybreak __read_mostly = 256
Link Here
|
102 |
module_param(copybreak, int, 0); |
94 |
module_param(copybreak, int, 0); |
103 |
MODULE_PARM_DESC(copybreak, "Receive copy threshold"); |
95 |
MODULE_PARM_DESC(copybreak, "Receive copy threshold"); |
104 |
|
96 |
|
|
|
97 |
static int disable_msi = 0; |
98 |
module_param(disable_msi, int, 0); |
99 |
MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); |
100 |
|
101 |
static int idle_timeout = 100; |
102 |
module_param(idle_timeout, int, 0); |
103 |
MODULE_PARM_DESC(idle_timeout, "Idle timeout workaround for lost interrupts (ms)"); |
104 |
|
105 |
static const struct pci_device_id sky2_id_table[] = { |
105 |
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) }, |
|
|
109 |
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) }, |
110 |
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, |
108 |
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, |
111 |
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, |
109 |
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) }, |
112 |
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, |
110 |
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) }, |
Lines 197-207
static int sky2_set_power_state(struct s
Link Here
|
197 |
pr_debug("sky2_set_power_state %d\n", state); |
195 |
pr_debug("sky2_set_power_state %d\n", state); |
198 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
196 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
199 |
|
197 |
|
200 |
pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); |
198 |
power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_PMC); |
201 |
vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) && |
199 |
vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && |
202 |
(power_control & PCI_PM_CAP_PME_D3cold); |
200 |
(power_control & PCI_PM_CAP_PME_D3cold); |
203 |
|
201 |
|
204 |
pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); |
202 |
power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL); |
205 |
|
203 |
|
206 |
power_control |= PCI_PM_CTRL_PME_STATUS; |
204 |
power_control |= PCI_PM_CTRL_PME_STATUS; |
207 |
power_control &= ~(PCI_PM_CTRL_STATE_MASK); |
205 |
power_control &= ~(PCI_PM_CTRL_STATE_MASK); |
Lines 225-231
static int sky2_set_power_state(struct s
Link Here
|
225 |
sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
223 |
sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
226 |
|
224 |
|
227 |
/* Turn off phy power saving */ |
225 |
/* Turn off phy power saving */ |
228 |
pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); |
226 |
reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
229 |
reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
227 |
reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
230 |
|
228 |
|
231 |
/* looks like this XL is back asswards .. */ |
229 |
/* looks like this XL is back asswards .. */ |
Lines 234-251
static int sky2_set_power_state(struct s
Link Here
|
234 |
if (hw->ports > 1) |
232 |
if (hw->ports > 1) |
235 |
reg1 |= PCI_Y2_PHY2_COMA; |
233 |
reg1 |= PCI_Y2_PHY2_COMA; |
236 |
} |
234 |
} |
237 |
pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); |
235 |
|
|
|
236 |
if (hw->chip_id == CHIP_ID_YUKON_EC_U) { |
237 |
sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
238 |
reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); |
239 |
reg1 &= P_ASPM_CONTROL_MSK; |
240 |
sky2_pci_write32(hw, PCI_DEV_REG4, reg1); |
241 |
sky2_pci_write32(hw, PCI_DEV_REG5, 0); |
242 |
} |
243 |
|
244 |
sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
245 |
|
238 |
break; |
246 |
break; |
239 |
|
247 |
|
240 |
case PCI_D3hot: |
248 |
case PCI_D3hot: |
241 |
case PCI_D3cold: |
249 |
case PCI_D3cold: |
242 |
/* Turn on phy power saving */ |
250 |
/* Turn on phy power saving */ |
243 |
pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); |
251 |
reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); |
244 |
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
252 |
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
245 |
reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
253 |
reg1 &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
246 |
else |
254 |
else |
247 |
reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
255 |
reg1 |= (PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); |
248 |
pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); |
256 |
sky2_pci_write32(hw, PCI_DEV_REG1, reg1); |
249 |
|
257 |
|
250 |
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
258 |
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) |
251 |
sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
259 |
sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
Lines 267-273
static int sky2_set_power_state(struct s
Link Here
|
267 |
ret = -1; |
275 |
ret = -1; |
268 |
} |
276 |
} |
269 |
|
277 |
|
270 |
pci_write_config_byte(hw->pdev, hw->pm_cap + PCI_PM_CTRL, power_control); |
278 |
sky2_pci_write16(hw, hw->pm_cap + PCI_PM_CTRL, power_control); |
271 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
279 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
272 |
return ret; |
280 |
return ret; |
273 |
} |
281 |
} |
Lines 296-302
static void sky2_phy_init(struct sky2_hw
Link Here
|
296 |
struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
304 |
struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
297 |
u16 ctrl, ct1000, adv, pg, ledctrl, ledover; |
305 |
u16 ctrl, ct1000, adv, pg, ledctrl, ledover; |
298 |
|
306 |
|
299 |
if (sky2->autoneg == AUTONEG_ENABLE && hw->chip_id != CHIP_ID_YUKON_XL) { |
307 |
if (sky2->autoneg == AUTONEG_ENABLE && |
|
|
308 |
(hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { |
300 |
u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
309 |
u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); |
301 |
|
310 |
|
302 |
ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | |
311 |
ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | |
Lines 324-330
static void sky2_phy_init(struct sky2_hw
Link Here
|
324 |
ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); |
333 |
ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); |
325 |
|
334 |
|
326 |
if (sky2->autoneg == AUTONEG_ENABLE && |
335 |
if (sky2->autoneg == AUTONEG_ENABLE && |
327 |
hw->chip_id == CHIP_ID_YUKON_XL) { |
336 |
(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) { |
328 |
ctrl &= ~PHY_M_PC_DSC_MSK; |
337 |
ctrl &= ~PHY_M_PC_DSC_MSK; |
329 |
ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; |
338 |
ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; |
330 |
} |
339 |
} |
Lines 440-449
static void sky2_phy_init(struct sky2_hw
Link Here
|
440 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
449 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
441 |
|
450 |
|
442 |
/* set LED Function Control register */ |
451 |
/* set LED Function Control register */ |
443 |
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ |
452 |
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, |
444 |
PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ |
453 |
(PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ |
445 |
PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ |
454 |
PHY_M_LEDC_INIT_CTRL(7) | /* 10 Mbps */ |
446 |
PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ |
455 |
PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ |
|
|
456 |
PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ |
447 |
|
457 |
|
448 |
/* set Polarity Control register */ |
458 |
/* set Polarity Control register */ |
449 |
gm_phy_write(hw, port, PHY_MARV_PHY_STAT, |
459 |
gm_phy_write(hw, port, PHY_MARV_PHY_STAT, |
Lines 457-462
static void sky2_phy_init(struct sky2_hw
Link Here
|
457 |
/* restore page register */ |
467 |
/* restore page register */ |
458 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
468 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
459 |
break; |
469 |
break; |
|
|
470 |
case CHIP_ID_YUKON_EC_U: |
471 |
pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
472 |
|
473 |
/* select page 3 to access LED control register */ |
474 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
475 |
|
476 |
/* set LED Function Control register */ |
477 |
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, |
478 |
(PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ |
479 |
PHY_M_LEDC_INIT_CTRL(8) | /* 10 Mbps */ |
480 |
PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ |
481 |
PHY_M_LEDC_STA0_CTRL(7)));/* 1000 Mbps */ |
482 |
|
483 |
/* set Blink Rate in LED Timer Control Register */ |
484 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, |
485 |
ledctrl | PHY_M_LED_BLINK_RT(BLINK_84MS)); |
486 |
/* restore page register */ |
487 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
488 |
break; |
460 |
|
489 |
|
461 |
default: |
490 |
default: |
462 |
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ |
491 |
/* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ |
Lines 465-480
static void sky2_phy_init(struct sky2_hw
Link Here
|
465 |
ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
494 |
ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); |
466 |
} |
495 |
} |
467 |
|
496 |
|
468 |
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
497 |
if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == CHIP_REV_YU_EC_A1) { |
|
|
498 |
/* apply fixes in PHY AFE */ |
499 |
pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
500 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 255); |
469 |
|
501 |
|
470 |
if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { |
502 |
/* increase differential signal amplitude in 10BASE-T */ |
471 |
/* turn on 100 Mbps LED (LED_LINK100) */ |
503 |
gm_phy_write(hw, port, 0x18, 0xaa99); |
472 |
ledover |= PHY_M_LED_MO_100(MO_LED_ON); |
504 |
gm_phy_write(hw, port, 0x17, 0x2011); |
473 |
} |
|
|
474 |
|
505 |
|
475 |
if (ledover) |
506 |
/* fix for IEEE A/B Symmetry failure in 1000BASE-T */ |
476 |
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
507 |
gm_phy_write(hw, port, 0x18, 0xa204); |
|
|
508 |
gm_phy_write(hw, port, 0x17, 0x2002); |
509 |
|
510 |
/* set page register to 0 */ |
511 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
512 |
} else { |
513 |
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
514 |
|
515 |
if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { |
516 |
/* turn on 100 Mbps LED (LED_LINK100) */ |
517 |
ledover |= PHY_M_LED_MO_100(MO_LED_ON); |
518 |
} |
519 |
|
520 |
if (ledover) |
521 |
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
477 |
|
522 |
|
|
|
523 |
} |
478 |
/* Enable phy interrupt on auto-negotiation complete (or link up) */ |
524 |
/* Enable phy interrupt on auto-negotiation complete (or link up) */ |
479 |
if (sky2->autoneg == AUTONEG_ENABLE) |
525 |
if (sky2->autoneg == AUTONEG_ENABLE) |
480 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
526 |
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); |
Lines 485-493
static void sky2_phy_init(struct sky2_hw
Link Here
|
485 |
/* Force a renegotiation */ |
531 |
/* Force a renegotiation */ |
486 |
static void sky2_phy_reinit(struct sky2_port *sky2) |
532 |
static void sky2_phy_reinit(struct sky2_port *sky2) |
487 |
{ |
533 |
{ |
488 |
down(&sky2->phy_sema); |
534 |
spin_lock_bh(&sky2->phy_lock); |
489 |
sky2_phy_init(sky2->hw, sky2->port); |
535 |
sky2_phy_init(sky2->hw, sky2->port); |
490 |
up(&sky2->phy_sema); |
536 |
spin_unlock_bh(&sky2->phy_lock); |
491 |
} |
537 |
} |
492 |
|
538 |
|
493 |
static void sky2_mac_init(struct sky2_hw *hw, unsigned port) |
539 |
static void sky2_mac_init(struct sky2_hw *hw, unsigned port) |
Lines 522-535
static void sky2_mac_init(struct sky2_hw
Link Here
|
522 |
|
568 |
|
523 |
switch (sky2->speed) { |
569 |
switch (sky2->speed) { |
524 |
case SPEED_1000: |
570 |
case SPEED_1000: |
|
|
571 |
reg &= ~GM_GPCR_SPEED_100; |
525 |
reg |= GM_GPCR_SPEED_1000; |
572 |
reg |= GM_GPCR_SPEED_1000; |
526 |
/* fallthru */ |
573 |
break; |
527 |
case SPEED_100: |
574 |
case SPEED_100: |
|
|
575 |
reg &= ~GM_GPCR_SPEED_1000; |
528 |
reg |= GM_GPCR_SPEED_100; |
576 |
reg |= GM_GPCR_SPEED_100; |
|
|
577 |
break; |
578 |
case SPEED_10: |
579 |
reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); |
580 |
break; |
529 |
} |
581 |
} |
530 |
|
582 |
|
531 |
if (sky2->duplex == DUPLEX_FULL) |
583 |
if (sky2->duplex == DUPLEX_FULL) |
532 |
reg |= GM_GPCR_DUP_FULL; |
584 |
reg |= GM_GPCR_DUP_FULL; |
|
|
585 |
|
586 |
/* turn off pause in 10/100mbps half duplex */ |
587 |
else if (sky2->speed != SPEED_1000 && |
588 |
hw->chip_id != CHIP_ID_YUKON_EC_U) |
589 |
sky2->tx_pause = sky2->rx_pause = 0; |
533 |
} else |
590 |
} else |
534 |
reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; |
591 |
reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; |
535 |
|
592 |
|
Lines 546-561
static void sky2_mac_init(struct sky2_hw
Link Here
|
546 |
|
603 |
|
547 |
sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); |
604 |
sky2_read16(hw, SK_REG(port, GMAC_IRQ_SRC)); |
548 |
|
605 |
|
549 |
down(&sky2->phy_sema); |
606 |
spin_lock_bh(&sky2->phy_lock); |
550 |
sky2_phy_init(hw, port); |
607 |
sky2_phy_init(hw, port); |
551 |
up(&sky2->phy_sema); |
608 |
spin_unlock_bh(&sky2->phy_lock); |
552 |
|
609 |
|
553 |
/* MIB clear */ |
610 |
/* MIB clear */ |
554 |
reg = gma_read16(hw, port, GM_PHY_ADDR); |
611 |
reg = gma_read16(hw, port, GM_PHY_ADDR); |
555 |
gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); |
612 |
gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); |
556 |
|
613 |
|
557 |
for (i = 0; i < GM_MIB_CNT_SIZE; i++) |
614 |
for (i = GM_MIB_CNT_BASE; i <= GM_MIB_CNT_END; i += 4) |
558 |
gma_read16(hw, port, GM_MIB_CNT_BASE + 8 * i); |
615 |
gma_read16(hw, port, i); |
559 |
gma_write16(hw, port, GM_PHY_ADDR, reg); |
616 |
gma_write16(hw, port, GM_PHY_ADDR, reg); |
560 |
|
617 |
|
561 |
/* transmit control */ |
618 |
/* transmit control */ |
Lines 597-604
static void sky2_mac_init(struct sky2_hw
Link Here
|
597 |
|
654 |
|
598 |
/* Configure Rx MAC FIFO */ |
655 |
/* Configure Rx MAC FIFO */ |
599 |
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
656 |
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
600 |
sky2_write16(hw, SK_REG(port, RX_GMF_CTRL_T), |
657 |
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), |
601 |
GMF_RX_CTRL_DEF); |
658 |
GMF_OPER_ON | GMF_RX_F_FL_ON); |
602 |
|
659 |
|
603 |
/* Flush Rx MAC FIFO on any flow control or error */ |
660 |
/* Flush Rx MAC FIFO on any flow control or error */ |
604 |
sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
661 |
sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
Lines 625-637
static void sky2_mac_init(struct sky2_hw
Link Here
|
625 |
|
682 |
|
626 |
} |
683 |
} |
627 |
|
684 |
|
628 |
static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len) |
685 |
/* Assign Ram Buffer allocation. |
|
|
686 |
* start and end are in units of 4k bytes |
687 |
* ram registers are in units of 64bit words |
688 |
*/ |
689 |
static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk) |
629 |
{ |
690 |
{ |
630 |
u32 end; |
691 |
u32 start, end; |
631 |
|
692 |
|
632 |
start /= 8; |
693 |
start = startk * 4096/8; |
633 |
len /= 8; |
694 |
end = (endk * 4096/8) - 1; |
634 |
end = start + len - 1; |
|
|
635 |
|
695 |
|
636 |
sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); |
696 |
sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); |
637 |
sky2_write32(hw, RB_ADDR(q, RB_START), start); |
697 |
sky2_write32(hw, RB_ADDR(q, RB_START), start); |
Lines 640-653
static void sky2_ramset(struct sky2_hw *
Link Here
|
640 |
sky2_write32(hw, RB_ADDR(q, RB_RP), start); |
700 |
sky2_write32(hw, RB_ADDR(q, RB_RP), start); |
641 |
|
701 |
|
642 |
if (q == Q_R1 || q == Q_R2) { |
702 |
if (q == Q_R1 || q == Q_R2) { |
643 |
u32 rxup, rxlo; |
703 |
u32 space = (endk - startk) * 4096/8; |
|
|
704 |
u32 tp = space - space/4; |
644 |
|
705 |
|
645 |
rxlo = len/2; |
706 |
/* On receive queue's set the thresholds |
646 |
rxup = rxlo + len/4; |
707 |
* give receiver priority when > 3/4 full |
|
|
708 |
* send pause when down to 2K |
709 |
*/ |
710 |
sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp); |
711 |
sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); |
647 |
|
712 |
|
648 |
/* Set thresholds on receive queue's */ |
713 |
tp = space - 2048/8; |
649 |
sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup); |
714 |
sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); |
650 |
sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), rxlo); |
715 |
sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); |
651 |
} else { |
716 |
} else { |
652 |
/* Enable store & forward on Tx queue's because |
717 |
/* Enable store & forward on Tx queue's because |
653 |
* Tx FIFO is only 1K on Yukon |
718 |
* Tx FIFO is only 1K on Yukon |
Lines 688-745
static inline struct sky2_tx_le *get_tx_
Link Here
|
688 |
{ |
753 |
{ |
689 |
struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; |
754 |
struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod; |
690 |
|
755 |
|
691 |
sky2->tx_prod = (sky2->tx_prod + 1) % TX_RING_SIZE; |
756 |
sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE); |
692 |
return le; |
757 |
return le; |
693 |
} |
758 |
} |
694 |
|
759 |
|
695 |
/* |
760 |
/* Update chip's next pointer */ |
696 |
* This is a workaround code taken from SysKonnect sk98lin driver |
761 |
static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx) |
697 |
* to deal with chip bug on Yukon EC rev 0 in the wraparound case. |
|
|
698 |
*/ |
699 |
static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, |
700 |
u16 idx, u16 *last, u16 size) |
701 |
{ |
762 |
{ |
702 |
if (is_ec_a1(hw) && idx < *last) { |
763 |
wmb(); |
703 |
u16 hwget = sky2_read16(hw, Y2_QADDR(q, PREF_UNIT_GET_IDX)); |
764 |
sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); |
704 |
|
765 |
mmiowb(); |
705 |
if (hwget == 0) { |
|
|
706 |
/* Start prefetching again */ |
707 |
sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 0xe0); |
708 |
goto setnew; |
709 |
} |
710 |
|
711 |
if (hwget == size - 1) { |
712 |
/* set watermark to one list element */ |
713 |
sky2_write8(hw, Y2_QADDR(q, PREF_UNIT_FIFO_WM), 8); |
714 |
|
715 |
/* set put index to first list element */ |
716 |
sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), 0); |
717 |
} else /* have hardware go to end of list */ |
718 |
sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), |
719 |
size - 1); |
720 |
} else { |
721 |
setnew: |
722 |
sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx); |
723 |
} |
724 |
*last = idx; |
725 |
} |
766 |
} |
726 |
|
767 |
|
727 |
|
768 |
|
728 |
static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) |
769 |
static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2) |
729 |
{ |
770 |
{ |
730 |
struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put; |
771 |
struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put; |
731 |
sky2->rx_put = (sky2->rx_put + 1) % RX_LE_SIZE; |
772 |
sky2->rx_put = RING_NEXT(sky2->rx_put, RX_LE_SIZE); |
732 |
return le; |
773 |
return le; |
733 |
} |
774 |
} |
734 |
|
775 |
|
735 |
/* Return high part of DMA address (could be 32 or 64 bit) */ |
776 |
/* Return high part of DMA address (could be 32 or 64 bit) */ |
736 |
static inline u32 high32(dma_addr_t a) |
777 |
static inline u32 high32(dma_addr_t a) |
737 |
{ |
778 |
{ |
738 |
return (a >> 16) >> 16; |
779 |
return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0; |
739 |
} |
780 |
} |
740 |
|
781 |
|
741 |
/* Build description to hardware about buffer */ |
782 |
/* Build description to hardware about buffer */ |
742 |
static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map) |
783 |
static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map) |
743 |
{ |
784 |
{ |
744 |
struct sky2_rx_le *le; |
785 |
struct sky2_rx_le *le; |
745 |
u32 hi = high32(map); |
786 |
u32 hi = high32(map); |
Lines 756-762
static inline void sky2_rx_add(struct sk
Link Here
|
756 |
le = sky2_next_rx(sky2); |
797 |
le = sky2_next_rx(sky2); |
757 |
le->addr = cpu_to_le32((u32) map); |
798 |
le->addr = cpu_to_le32((u32) map); |
758 |
le->length = cpu_to_le16(len); |
799 |
le->length = cpu_to_le16(len); |
759 |
le->ctrl = 0; |
800 |
le->ctrl = sky2->rx_csum ? CALSUM : 0; |
760 |
le->opcode = OP_PACKET | HW_OWNER; |
801 |
le->opcode = OP_PACKET | HW_OWNER; |
761 |
} |
802 |
} |
762 |
|
803 |
|
Lines 843-849
static int sky2_ioctl(struct net_device
Link Here
|
843 |
if (!netif_running(dev)) |
884 |
if (!netif_running(dev)) |
844 |
return -ENODEV; /* Phy still in reset */ |
885 |
return -ENODEV; /* Phy still in reset */ |
845 |
|
886 |
|
846 |
switch(cmd) { |
887 |
switch (cmd) { |
847 |
case SIOCGMIIPHY: |
888 |
case SIOCGMIIPHY: |
848 |
data->phy_id = PHY_ADDR_MARV; |
889 |
data->phy_id = PHY_ADDR_MARV; |
849 |
|
890 |
|
Lines 851-859
static int sky2_ioctl(struct net_device
Link Here
|
851 |
case SIOCGMIIREG: { |
892 |
case SIOCGMIIREG: { |
852 |
u16 val = 0; |
893 |
u16 val = 0; |
853 |
|
894 |
|
854 |
down(&sky2->phy_sema); |
895 |
spin_lock_bh(&sky2->phy_lock); |
855 |
err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val); |
896 |
err = __gm_phy_read(hw, sky2->port, data->reg_num & 0x1f, &val); |
856 |
up(&sky2->phy_sema); |
897 |
spin_unlock_bh(&sky2->phy_lock); |
857 |
|
898 |
|
858 |
data->val_out = val; |
899 |
data->val_out = val; |
859 |
break; |
900 |
break; |
Lines 863-872
static int sky2_ioctl(struct net_device
Link Here
|
863 |
if (!capable(CAP_NET_ADMIN)) |
904 |
if (!capable(CAP_NET_ADMIN)) |
864 |
return -EPERM; |
905 |
return -EPERM; |
865 |
|
906 |
|
866 |
down(&sky2->phy_sema); |
907 |
spin_lock_bh(&sky2->phy_lock); |
867 |
err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f, |
908 |
err = gm_phy_write(hw, sky2->port, data->reg_num & 0x1f, |
868 |
data->val_in); |
909 |
data->val_in); |
869 |
up(&sky2->phy_sema); |
910 |
spin_unlock_bh(&sky2->phy_lock); |
870 |
break; |
911 |
break; |
871 |
} |
912 |
} |
872 |
return err; |
913 |
return err; |
Lines 879-891
static void sky2_vlan_rx_register(struct
Link Here
|
879 |
struct sky2_hw *hw = sky2->hw; |
920 |
struct sky2_hw *hw = sky2->hw; |
880 |
u16 port = sky2->port; |
921 |
u16 port = sky2->port; |
881 |
|
922 |
|
882 |
spin_lock(&sky2->tx_lock); |
923 |
spin_lock_bh(&sky2->tx_lock); |
883 |
|
924 |
|
884 |
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON); |
925 |
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_ON); |
885 |
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON); |
926 |
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_ON); |
886 |
sky2->vlgrp = grp; |
927 |
sky2->vlgrp = grp; |
887 |
|
928 |
|
888 |
spin_unlock(&sky2->tx_lock); |
929 |
spin_unlock_bh(&sky2->tx_lock); |
889 |
} |
930 |
} |
890 |
|
931 |
|
891 |
static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) |
932 |
static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) |
Lines 894-907
static void sky2_vlan_rx_kill_vid(struct
Link Here
|
894 |
struct sky2_hw *hw = sky2->hw; |
935 |
struct sky2_hw *hw = sky2->hw; |
895 |
u16 port = sky2->port; |
936 |
u16 port = sky2->port; |
896 |
|
937 |
|
897 |
spin_lock(&sky2->tx_lock); |
938 |
spin_lock_bh(&sky2->tx_lock); |
898 |
|
939 |
|
899 |
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF); |
940 |
sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF); |
900 |
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF); |
941 |
sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF); |
901 |
if (sky2->vlgrp) |
942 |
if (sky2->vlgrp) |
902 |
sky2->vlgrp->vlan_devices[vid] = NULL; |
943 |
sky2->vlgrp->vlan_devices[vid] = NULL; |
903 |
|
944 |
|
904 |
spin_unlock(&sky2->tx_lock); |
945 |
spin_unlock_bh(&sky2->tx_lock); |
905 |
} |
946 |
} |
906 |
#endif |
947 |
#endif |
907 |
|
948 |
|
Lines 918-925
static inline struct sk_buff *sky2_alloc
Link Here
|
918 |
skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); |
959 |
skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); |
919 |
if (likely(skb)) { |
960 |
if (likely(skb)) { |
920 |
unsigned long p = (unsigned long) skb->data; |
961 |
unsigned long p = (unsigned long) skb->data; |
921 |
skb_reserve(skb, |
962 |
skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); |
922 |
((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p); |
|
|
923 |
} |
963 |
} |
924 |
|
964 |
|
925 |
return skb; |
965 |
return skb; |
Lines 939-944
static int sky2_rx_start(struct sky2_por
Link Here
|
939 |
|
979 |
|
940 |
sky2->rx_put = sky2->rx_next = 0; |
980 |
sky2->rx_put = sky2->rx_next = 0; |
941 |
sky2_qset(hw, rxq); |
981 |
sky2_qset(hw, rxq); |
|
|
982 |
|
983 |
if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev >= 2) { |
984 |
/* MAC Rx RAM Read is controlled by hardware */ |
985 |
sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); |
986 |
} |
987 |
|
942 |
sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
988 |
sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
943 |
|
989 |
|
944 |
rx_set_checksum(sky2); |
990 |
rx_set_checksum(sky2); |
Lines 954-962
static int sky2_rx_start(struct sky2_por
Link Here
|
954 |
sky2_rx_add(sky2, re->mapaddr); |
1000 |
sky2_rx_add(sky2, re->mapaddr); |
955 |
} |
1001 |
} |
956 |
|
1002 |
|
|
|
1003 |
/* Truncate oversize frames */ |
1004 |
sky2_write16(hw, SK_REG(sky2->port, RX_GMF_TR_THR), sky2->rx_bufsize - 8); |
1005 |
sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); |
1006 |
|
957 |
/* Tell chip about available buffers */ |
1007 |
/* Tell chip about available buffers */ |
958 |
sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
1008 |
sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
959 |
sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); |
|
|
960 |
return 0; |
1009 |
return 0; |
961 |
nomem: |
1010 |
nomem: |
962 |
sky2_rx_clean(sky2); |
1011 |
sky2_rx_clean(sky2); |
Lines 969-975
static int sky2_up(struct net_device *de
Link Here
|
969 |
struct sky2_port *sky2 = netdev_priv(dev); |
1018 |
struct sky2_port *sky2 = netdev_priv(dev); |
970 |
struct sky2_hw *hw = sky2->hw; |
1019 |
struct sky2_hw *hw = sky2->hw; |
971 |
unsigned port = sky2->port; |
1020 |
unsigned port = sky2->port; |
972 |
u32 ramsize, rxspace; |
1021 |
u32 ramsize, rxspace, imask; |
973 |
int err = -ENOMEM; |
1022 |
int err = -ENOMEM; |
974 |
|
1023 |
|
975 |
if (netif_msg_ifup(sky2)) |
1024 |
if (netif_msg_ifup(sky2)) |
Lines 1002-1029
static int sky2_up(struct net_device *de
Link Here
|
1002 |
|
1051 |
|
1003 |
sky2_mac_init(hw, port); |
1052 |
sky2_mac_init(hw, port); |
1004 |
|
1053 |
|
1005 |
/* Configure RAM buffers */ |
1054 |
/* Determine available ram buffer space (in 4K blocks). |
1006 |
if (hw->chip_id == CHIP_ID_YUKON_FE || |
1055 |
* Note: not sure about the FE setting below yet |
1007 |
(hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == 2)) |
1056 |
*/ |
1008 |
ramsize = 4096; |
1057 |
if (hw->chip_id == CHIP_ID_YUKON_FE) |
1009 |
else { |
1058 |
ramsize = 4; |
1010 |
u8 e0 = sky2_read8(hw, B2_E_0); |
1059 |
else |
1011 |
ramsize = (e0 == 0) ? (128 * 1024) : (e0 * 4096); |
1060 |
ramsize = sky2_read8(hw, B2_E_0); |
1012 |
} |
1061 |
|
|
|
1062 |
/* Give transmitter one third (rounded up) */ |
1063 |
rxspace = ramsize - (ramsize + 2) / 3; |
1013 |
|
1064 |
|
1014 |
/* 2/3 for Rx */ |
|
|
1015 |
rxspace = (2 * ramsize) / 3; |
1016 |
sky2_ramset(hw, rxqaddr[port], 0, rxspace); |
1065 |
sky2_ramset(hw, rxqaddr[port], 0, rxspace); |
1017 |
sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace); |
1066 |
sky2_ramset(hw, txqaddr[port], rxspace, ramsize); |
1018 |
|
1067 |
|
1019 |
/* Make sure SyncQ is disabled */ |
1068 |
/* Make sure SyncQ is disabled */ |
1020 |
sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), |
1069 |
sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), |
1021 |
RB_RST_SET); |
1070 |
RB_RST_SET); |
1022 |
|
1071 |
|
1023 |
sky2_qset(hw, txqaddr[port]); |
1072 |
sky2_qset(hw, txqaddr[port]); |
1024 |
if (hw->chip_id == CHIP_ID_YUKON_EC_U) |
|
|
1025 |
sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); |
1026 |
|
1073 |
|
|
|
1074 |
/* Set almost empty threshold */ |
1075 |
if (hw->chip_id == CHIP_ID_YUKON_EC_U && hw->chip_rev == 1) |
1076 |
sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), 0x1a0); |
1027 |
|
1077 |
|
1028 |
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1078 |
sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1029 |
TX_RING_SIZE - 1); |
1079 |
TX_RING_SIZE - 1); |
Lines 1033-1040
static int sky2_up(struct net_device *de
Link Here
|
1033 |
goto err_out; |
1083 |
goto err_out; |
1034 |
|
1084 |
|
1035 |
/* Enable interrupts from phy/mac for port */ |
1085 |
/* Enable interrupts from phy/mac for port */ |
1036 |
hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; |
1086 |
imask = sky2_read32(hw, B0_IMSK); |
1037 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1087 |
imask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; |
|
|
1088 |
sky2_write32(hw, B0_IMSK, imask); |
1089 |
|
1038 |
return 0; |
1090 |
return 0; |
1039 |
|
1091 |
|
1040 |
err_out: |
1092 |
err_out: |
Lines 1060-1066
err_out:
Link Here
|
1060 |
/* Modular subtraction in ring */ |
1112 |
/* Modular subtraction in ring */ |
1061 |
static inline int tx_dist(unsigned tail, unsigned head) |
1113 |
static inline int tx_dist(unsigned tail, unsigned head) |
1062 |
{ |
1114 |
{ |
1063 |
return (head - tail) % TX_RING_SIZE; |
1115 |
return (head - tail) & (TX_RING_SIZE - 1); |
1064 |
} |
1116 |
} |
1065 |
|
1117 |
|
1066 |
/* Number of list elements available for next tx */ |
1118 |
/* Number of list elements available for next tx */ |
Lines 1070-1076
static inline int tx_avail(const struct
Link Here
|
1070 |
} |
1122 |
} |
1071 |
|
1123 |
|
1072 |
/* Estimate of number of transmit list elements required */ |
1124 |
/* Estimate of number of transmit list elements required */ |
1073 |
static inline unsigned tx_le_req(const struct sk_buff *skb) |
1125 |
static unsigned tx_le_req(const struct sk_buff *skb) |
1074 |
{ |
1126 |
{ |
1075 |
unsigned count; |
1127 |
unsigned count; |
1076 |
|
1128 |
|
Lines 1101-1111
static int sky2_xmit_frame(struct sk_buf
Link Here
|
1101 |
struct sky2_tx_le *le = NULL; |
1153 |
struct sky2_tx_le *le = NULL; |
1102 |
struct tx_ring_info *re; |
1154 |
struct tx_ring_info *re; |
1103 |
unsigned i, len; |
1155 |
unsigned i, len; |
|
|
1156 |
int avail; |
1104 |
dma_addr_t mapping; |
1157 |
dma_addr_t mapping; |
1105 |
u32 addr64; |
1158 |
u32 addr64; |
1106 |
u16 mss; |
1159 |
u16 mss; |
1107 |
u8 ctrl; |
1160 |
u8 ctrl; |
1108 |
|
1161 |
|
|
|
1162 |
/* No BH disabling for tx_lock here. We are running in BH disabled |
1163 |
* context and TX reclaim runs via poll inside of a software |
1164 |
* interrupt, and no related locks in IRQ processing. |
1165 |
*/ |
1109 |
if (!spin_trylock(&sky2->tx_lock)) |
1166 |
if (!spin_trylock(&sky2->tx_lock)) |
1110 |
return NETDEV_TX_LOCKED; |
1167 |
return NETDEV_TX_LOCKED; |
1111 |
|
1168 |
|
Lines 1115-1122
static int sky2_xmit_frame(struct sk_buf
Link Here
|
1115 |
*/ |
1172 |
*/ |
1116 |
if (!netif_queue_stopped(dev)) { |
1173 |
if (!netif_queue_stopped(dev)) { |
1117 |
netif_stop_queue(dev); |
1174 |
netif_stop_queue(dev); |
1118 |
printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", |
1175 |
if (net_ratelimit()) |
1119 |
dev->name); |
1176 |
printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", |
|
|
1177 |
dev->name); |
1120 |
} |
1178 |
} |
1121 |
spin_unlock(&sky2->tx_lock); |
1179 |
spin_unlock(&sky2->tx_lock); |
1122 |
|
1180 |
|
Lines 1148-1154
static int sky2_xmit_frame(struct sk_buf
Link Here
|
1148 |
/* just drop the packet if non-linear expansion fails */ |
1206 |
/* just drop the packet if non-linear expansion fails */ |
1149 |
if (skb_header_cloned(skb) && |
1207 |
if (skb_header_cloned(skb) && |
1150 |
pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { |
1208 |
pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { |
1151 |
dev_kfree_skb_any(skb); |
1209 |
dev_kfree_skb(skb); |
1152 |
goto out_unlock; |
1210 |
goto out_unlock; |
1153 |
} |
1211 |
} |
1154 |
|
1212 |
|
Lines 1215-1221
static int sky2_xmit_frame(struct sk_buf
Link Here
|
1215 |
|
1273 |
|
1216 |
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, |
1274 |
mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, |
1217 |
frag->size, PCI_DMA_TODEVICE); |
1275 |
frag->size, PCI_DMA_TODEVICE); |
1218 |
addr64 = (mapping >> 16) >> 16; |
1276 |
addr64 = high32(mapping); |
1219 |
if (addr64 != sky2->tx_addr64) { |
1277 |
if (addr64 != sky2->tx_addr64) { |
1220 |
le = get_tx_le(sky2); |
1278 |
le = get_tx_le(sky2); |
1221 |
le->tx.addr = cpu_to_le32(addr64); |
1279 |
le->tx.addr = cpu_to_le32(addr64); |
Lines 1231-1251
static int sky2_xmit_frame(struct sk_buf
Link Here
|
1231 |
le->opcode = OP_BUFFER | HW_OWNER; |
1289 |
le->opcode = OP_BUFFER | HW_OWNER; |
1232 |
|
1290 |
|
1233 |
fre = sky2->tx_ring |
1291 |
fre = sky2->tx_ring |
1234 |
+ ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; |
1292 |
+ RING_NEXT((re - sky2->tx_ring) + i, TX_RING_SIZE); |
1235 |
pci_unmap_addr_set(fre, mapaddr, mapping); |
1293 |
pci_unmap_addr_set(fre, mapaddr, mapping); |
1236 |
} |
1294 |
} |
1237 |
|
1295 |
|
1238 |
re->idx = sky2->tx_prod; |
1296 |
re->idx = sky2->tx_prod; |
1239 |
le->ctrl |= EOP; |
1297 |
le->ctrl |= EOP; |
1240 |
|
1298 |
|
1241 |
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod, |
1299 |
avail = tx_avail(sky2); |
1242 |
&sky2->tx_last_put, TX_RING_SIZE); |
1300 |
if (mss != 0 || avail < TX_MIN_PENDING) { |
|
|
1301 |
le->ctrl |= FRC_STAT; |
1302 |
if (avail <= MAX_SKB_TX_LE) |
1303 |
netif_stop_queue(dev); |
1304 |
} |
1243 |
|
1305 |
|
1244 |
if (tx_avail(sky2) <= MAX_SKB_TX_LE) |
1306 |
sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod); |
1245 |
netif_stop_queue(dev); |
|
|
1246 |
|
1307 |
|
1247 |
out_unlock: |
1308 |
out_unlock: |
1248 |
mmiowb(); |
|
|
1249 |
spin_unlock(&sky2->tx_lock); |
1309 |
spin_unlock(&sky2->tx_lock); |
1250 |
|
1310 |
|
1251 |
dev->trans_start = jiffies; |
1311 |
dev->trans_start = jiffies; |
Lines 1275-1281
static void sky2_tx_complete(struct sky2
Link Here
|
1275 |
struct tx_ring_info *re = sky2->tx_ring + put; |
1335 |
struct tx_ring_info *re = sky2->tx_ring + put; |
1276 |
struct sk_buff *skb = re->skb; |
1336 |
struct sk_buff *skb = re->skb; |
1277 |
|
1337 |
|
1278 |
nxt = re->idx; |
1338 |
nxt = re->idx; |
1279 |
BUG_ON(nxt >= TX_RING_SIZE); |
1339 |
BUG_ON(nxt >= TX_RING_SIZE); |
1280 |
prefetch(sky2->tx_ring + nxt); |
1340 |
prefetch(sky2->tx_ring + nxt); |
1281 |
|
1341 |
|
Lines 1289-1314
static void sky2_tx_complete(struct sky2
Link Here
|
1289 |
|
1349 |
|
1290 |
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
1350 |
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
1291 |
struct tx_ring_info *fre; |
1351 |
struct tx_ring_info *fre; |
1292 |
fre = sky2->tx_ring + (put + i + 1) % TX_RING_SIZE; |
1352 |
fre = sky2->tx_ring + RING_NEXT(put + i, TX_RING_SIZE); |
1293 |
pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr), |
1353 |
pci_unmap_page(pdev, pci_unmap_addr(fre, mapaddr), |
1294 |
skb_shinfo(skb)->frags[i].size, |
1354 |
skb_shinfo(skb)->frags[i].size, |
1295 |
PCI_DMA_TODEVICE); |
1355 |
PCI_DMA_TODEVICE); |
1296 |
} |
1356 |
} |
1297 |
|
1357 |
|
1298 |
dev_kfree_skb_any(skb); |
1358 |
dev_kfree_skb(skb); |
1299 |
} |
1359 |
} |
1300 |
|
1360 |
|
1301 |
spin_lock(&sky2->tx_lock); |
|
|
1302 |
sky2->tx_cons = put; |
1361 |
sky2->tx_cons = put; |
1303 |
if (netif_queue_stopped(dev) && tx_avail(sky2) > MAX_SKB_TX_LE) |
1362 |
if (tx_avail(sky2) > MAX_SKB_TX_LE) |
1304 |
netif_wake_queue(dev); |
1363 |
netif_wake_queue(dev); |
1305 |
spin_unlock(&sky2->tx_lock); |
|
|
1306 |
} |
1364 |
} |
1307 |
|
1365 |
|
1308 |
/* Cleanup all untransmitted buffers, assume transmitter not running */ |
1366 |
/* Cleanup all untransmitted buffers, assume transmitter not running */ |
1309 |
static void sky2_tx_clean(struct sky2_port *sky2) |
1367 |
static void sky2_tx_clean(struct sky2_port *sky2) |
1310 |
{ |
1368 |
{ |
|
|
1369 |
spin_lock_bh(&sky2->tx_lock); |
1311 |
sky2_tx_complete(sky2, sky2->tx_prod); |
1370 |
sky2_tx_complete(sky2, sky2->tx_prod); |
|
|
1371 |
spin_unlock_bh(&sky2->tx_lock); |
1312 |
} |
1372 |
} |
1313 |
|
1373 |
|
1314 |
/* Network shutdown */ |
1374 |
/* Network shutdown */ |
Lines 1318-1323
static int sky2_down(struct net_device *
Link Here
|
1318 |
struct sky2_hw *hw = sky2->hw; |
1378 |
struct sky2_hw *hw = sky2->hw; |
1319 |
unsigned port = sky2->port; |
1379 |
unsigned port = sky2->port; |
1320 |
u16 ctrl; |
1380 |
u16 ctrl; |
|
|
1381 |
u32 imask; |
1321 |
|
1382 |
|
1322 |
/* Never really got started! */ |
1383 |
/* Never really got started! */ |
1323 |
if (!sky2->tx_le) |
1384 |
if (!sky2->tx_le) |
Lines 1329-1342
static int sky2_down(struct net_device *
Link Here
|
1329 |
/* Stop more packets from being queued */ |
1390 |
/* Stop more packets from being queued */ |
1330 |
netif_stop_queue(dev); |
1391 |
netif_stop_queue(dev); |
1331 |
|
1392 |
|
1332 |
/* Disable port IRQ */ |
|
|
1333 |
local_irq_disable(); |
1334 |
hw->intr_mask &= ~((sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); |
1335 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1336 |
local_irq_enable(); |
1337 |
|
1338 |
flush_scheduled_work(); |
1339 |
|
1340 |
sky2_phy_reset(hw, port); |
1393 |
sky2_phy_reset(hw, port); |
1341 |
|
1394 |
|
1342 |
/* Stop transmitter */ |
1395 |
/* Stop transmitter */ |
Lines 1380-1385
static int sky2_down(struct net_device *
Link Here
|
1380 |
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1433 |
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1381 |
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1434 |
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
1382 |
|
1435 |
|
|
|
1436 |
/* Disable port IRQ */ |
1437 |
imask = sky2_read32(hw, B0_IMSK); |
1438 |
imask &= ~(sky2->port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; |
1439 |
sky2_write32(hw, B0_IMSK, imask); |
1440 |
|
1383 |
/* turn off LED's */ |
1441 |
/* turn off LED's */ |
1384 |
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
1442 |
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
1385 |
|
1443 |
|
Lines 1434-1439
static void sky2_link_up(struct sky2_por
Link Here
|
1434 |
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
1492 |
sky2_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK); |
1435 |
|
1493 |
|
1436 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
1494 |
reg = gma_read16(hw, port, GM_GP_CTRL); |
|
|
1495 |
if (sky2->autoneg == AUTONEG_DISABLE) { |
1496 |
reg |= GM_GPCR_AU_ALL_DIS; |
1497 |
|
1498 |
/* Is write/read necessary? Copied from sky2_mac_init */ |
1499 |
gma_write16(hw, port, GM_GP_CTRL, reg); |
1500 |
gma_read16(hw, port, GM_GP_CTRL); |
1501 |
|
1502 |
switch (sky2->speed) { |
1503 |
case SPEED_1000: |
1504 |
reg &= ~GM_GPCR_SPEED_100; |
1505 |
reg |= GM_GPCR_SPEED_1000; |
1506 |
break; |
1507 |
case SPEED_100: |
1508 |
reg &= ~GM_GPCR_SPEED_1000; |
1509 |
reg |= GM_GPCR_SPEED_100; |
1510 |
break; |
1511 |
case SPEED_10: |
1512 |
reg &= ~(GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100); |
1513 |
break; |
1514 |
} |
1515 |
} else |
1516 |
reg &= ~GM_GPCR_AU_ALL_DIS; |
1517 |
|
1437 |
if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) |
1518 |
if (sky2->duplex == DUPLEX_FULL || sky2->autoneg == AUTONEG_ENABLE) |
1438 |
reg |= GM_GPCR_DUP_FULL; |
1519 |
reg |= GM_GPCR_DUP_FULL; |
1439 |
|
1520 |
|
Lines 1451-1467
static void sky2_link_up(struct sky2_por
Link Here
|
1451 |
sky2_write8(hw, SK_REG(port, LNK_LED_REG), |
1532 |
sky2_write8(hw, SK_REG(port, LNK_LED_REG), |
1452 |
LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); |
1533 |
LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); |
1453 |
|
1534 |
|
1454 |
if (hw->chip_id == CHIP_ID_YUKON_XL) { |
1535 |
if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) { |
1455 |
u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
1536 |
u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
|
|
1537 |
u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ |
1538 |
|
1539 |
switch(sky2->speed) { |
1540 |
case SPEED_10: |
1541 |
led |= PHY_M_LEDC_INIT_CTRL(7); |
1542 |
break; |
1543 |
|
1544 |
case SPEED_100: |
1545 |
led |= PHY_M_LEDC_STA1_CTRL(7); |
1546 |
break; |
1547 |
|
1548 |
case SPEED_1000: |
1549 |
led |= PHY_M_LEDC_STA0_CTRL(7); |
1550 |
break; |
1551 |
} |
1456 |
|
1552 |
|
1457 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
1553 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
1458 |
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ |
1554 |
gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, led); |
1459 |
PHY_M_LEDC_INIT_CTRL(sky2->speed == |
|
|
1460 |
SPEED_10 ? 7 : 0) | |
1461 |
PHY_M_LEDC_STA1_CTRL(sky2->speed == |
1462 |
SPEED_100 ? 7 : 0) | |
1463 |
PHY_M_LEDC_STA0_CTRL(sky2->speed == |
1464 |
SPEED_1000 ? 7 : 0)); |
1465 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
1555 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg); |
1466 |
} |
1556 |
} |
1467 |
|
1557 |
|
Lines 1536-1542
static int sky2_autoneg_done(struct sky2
Link Here
|
1536 |
sky2->speed = sky2_phy_speed(hw, aux); |
1626 |
sky2->speed = sky2_phy_speed(hw, aux); |
1537 |
|
1627 |
|
1538 |
/* Pause bits are offset (9..8) */ |
1628 |
/* Pause bits are offset (9..8) */ |
1539 |
if (hw->chip_id == CHIP_ID_YUKON_XL) |
1629 |
if (hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U) |
1540 |
aux >>= 6; |
1630 |
aux >>= 6; |
1541 |
|
1631 |
|
1542 |
sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; |
1632 |
sky2->rx_pause = (aux & PHY_M_PS_RX_P_EN) != 0; |
Lines 1551-1570
static int sky2_autoneg_done(struct sky2
Link Here
|
1551 |
return 0; |
1641 |
return 0; |
1552 |
} |
1642 |
} |
1553 |
|
1643 |
|
1554 |
/* |
1644 |
/* Interrupt from PHY */ |
1555 |
* Interrupt from PHY are handled outside of interrupt context |
1645 |
static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) |
1556 |
* because accessing phy registers requires spin wait which might |
|
|
1557 |
* cause excess interrupt latency. |
1558 |
*/ |
1559 |
static void sky2_phy_task(void *arg) |
1560 |
{ |
1646 |
{ |
1561 |
struct sky2_port *sky2 = arg; |
1647 |
struct net_device *dev = hw->dev[port]; |
1562 |
struct sky2_hw *hw = sky2->hw; |
1648 |
struct sky2_port *sky2 = netdev_priv(dev); |
1563 |
u16 istatus, phystat; |
1649 |
u16 istatus, phystat; |
1564 |
|
1650 |
|
1565 |
down(&sky2->phy_sema); |
1651 |
spin_lock(&sky2->phy_lock); |
1566 |
istatus = gm_phy_read(hw, sky2->port, PHY_MARV_INT_STAT); |
1652 |
istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); |
1567 |
phystat = gm_phy_read(hw, sky2->port, PHY_MARV_PHY_STAT); |
1653 |
phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); |
|
|
1654 |
|
1655 |
if (!netif_running(dev)) |
1656 |
goto out; |
1568 |
|
1657 |
|
1569 |
if (netif_msg_intr(sky2)) |
1658 |
if (netif_msg_intr(sky2)) |
1570 |
printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", |
1659 |
printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n", |
Lines 1590-1633
static void sky2_phy_task(void *arg)
Link Here
|
1590 |
sky2_link_down(sky2); |
1679 |
sky2_link_down(sky2); |
1591 |
} |
1680 |
} |
1592 |
out: |
1681 |
out: |
1593 |
up(&sky2->phy_sema); |
1682 |
spin_unlock(&sky2->phy_lock); |
1594 |
|
|
|
1595 |
local_irq_disable(); |
1596 |
hw->intr_mask |= (sky2->port == 0) ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2; |
1597 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1598 |
local_irq_enable(); |
1599 |
} |
1683 |
} |
1600 |
|
1684 |
|
|
|
1685 |
|
1686 |
/* Transmit timeout is only called if we are running, carries is up |
1687 |
* and tx queue is full (stopped). |
1688 |
*/ |
1601 |
static void sky2_tx_timeout(struct net_device *dev) |
1689 |
static void sky2_tx_timeout(struct net_device *dev) |
1602 |
{ |
1690 |
{ |
1603 |
struct sky2_port *sky2 = netdev_priv(dev); |
1691 |
struct sky2_port *sky2 = netdev_priv(dev); |
1604 |
struct sky2_hw *hw = sky2->hw; |
1692 |
struct sky2_hw *hw = sky2->hw; |
1605 |
unsigned txq = txqaddr[sky2->port]; |
1693 |
unsigned txq = txqaddr[sky2->port]; |
|
|
1694 |
u16 report, done; |
1606 |
|
1695 |
|
1607 |
if (netif_msg_timer(sky2)) |
1696 |
if (netif_msg_timer(sky2)) |
1608 |
printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); |
1697 |
printk(KERN_ERR PFX "%s: tx timeout\n", dev->name); |
1609 |
|
1698 |
|
1610 |
netif_stop_queue(dev); |
1699 |
report = sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX); |
|
|
1700 |
done = sky2_read16(hw, Q_ADDR(txq, Q_DONE)); |
1611 |
|
1701 |
|
1612 |
sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); |
1702 |
printk(KERN_DEBUG PFX "%s: transmit ring %u .. %u report=%u done=%u\n", |
1613 |
sky2_read32(hw, Q_ADDR(txq, Q_CSR)); |
1703 |
dev->name, |
|
|
1704 |
sky2->tx_cons, sky2->tx_prod, report, done); |
1614 |
|
1705 |
|
1615 |
sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); |
1706 |
if (report != done) { |
|
|
1707 |
printk(KERN_INFO PFX "status burst pending (irq moderation?)\n"); |
1616 |
|
1708 |
|
1617 |
sky2_tx_clean(sky2); |
1709 |
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); |
|
|
1710 |
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); |
1711 |
} else if (report != sky2->tx_cons) { |
1712 |
printk(KERN_INFO PFX "status report lost?\n"); |
1713 |
|
1714 |
spin_lock_bh(&sky2->tx_lock); |
1715 |
sky2_tx_complete(sky2, report); |
1716 |
spin_unlock_bh(&sky2->tx_lock); |
1717 |
} else { |
1718 |
printk(KERN_INFO PFX "hardware hung? flushing\n"); |
1618 |
|
1719 |
|
1619 |
sky2_qset(hw, txq); |
1720 |
sky2_write32(hw, Q_ADDR(txq, Q_CSR), BMU_STOP); |
1620 |
sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1); |
1721 |
sky2_write32(hw, Y2_QADDR(txq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); |
1621 |
|
1722 |
|
1622 |
netif_wake_queue(dev); |
1723 |
sky2_tx_clean(sky2); |
|
|
1724 |
|
1725 |
sky2_qset(hw, txq); |
1726 |
sky2_prefetch_init(hw, txq, sky2->tx_le_map, TX_RING_SIZE - 1); |
1727 |
} |
1623 |
} |
1728 |
} |
1624 |
|
1729 |
|
1625 |
|
1730 |
|
1626 |
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
1731 |
/* Want receive buffer size to be multiple of 64 bits |
1627 |
/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */ |
1732 |
* and incl room for vlan and truncation |
|
|
1733 |
*/ |
1628 |
static inline unsigned sky2_buf_size(int mtu) |
1734 |
static inline unsigned sky2_buf_size(int mtu) |
1629 |
{ |
1735 |
{ |
1630 |
return roundup(mtu + ETH_HLEN + 4, 8); |
1736 |
return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; |
1631 |
} |
1737 |
} |
1632 |
|
1738 |
|
1633 |
static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
1739 |
static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
Lines 1636-1641
static int sky2_change_mtu(struct net_de
Link Here
|
1636 |
struct sky2_hw *hw = sky2->hw; |
1742 |
struct sky2_hw *hw = sky2->hw; |
1637 |
int err; |
1743 |
int err; |
1638 |
u16 ctl, mode; |
1744 |
u16 ctl, mode; |
|
|
1745 |
u32 imask; |
1639 |
|
1746 |
|
1640 |
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
1747 |
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
1641 |
return -EINVAL; |
1748 |
return -EINVAL; |
Lines 1648-1659
static int sky2_change_mtu(struct net_de
Link Here
|
1648 |
return 0; |
1755 |
return 0; |
1649 |
} |
1756 |
} |
1650 |
|
1757 |
|
|
|
1758 |
imask = sky2_read32(hw, B0_IMSK); |
1651 |
sky2_write32(hw, B0_IMSK, 0); |
1759 |
sky2_write32(hw, B0_IMSK, 0); |
1652 |
|
1760 |
|
1653 |
dev->trans_start = jiffies; /* prevent tx timeout */ |
1761 |
dev->trans_start = jiffies; /* prevent tx timeout */ |
1654 |
netif_stop_queue(dev); |
1762 |
netif_stop_queue(dev); |
1655 |
netif_poll_disable(hw->dev[0]); |
1763 |
netif_poll_disable(hw->dev[0]); |
1656 |
|
1764 |
|
|
|
1765 |
synchronize_irq(hw->pdev->irq); |
1766 |
|
1657 |
ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); |
1767 |
ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); |
1658 |
gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); |
1768 |
gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); |
1659 |
sky2_rx_stop(sky2); |
1769 |
sky2_rx_stop(sky2); |
Lines 1672-1678
static int sky2_change_mtu(struct net_de
Link Here
|
1672 |
sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); |
1782 |
sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); |
1673 |
|
1783 |
|
1674 |
err = sky2_rx_start(sky2); |
1784 |
err = sky2_rx_start(sky2); |
1675 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1785 |
sky2_write32(hw, B0_IMSK, imask); |
1676 |
|
1786 |
|
1677 |
if (err) |
1787 |
if (err) |
1678 |
dev_close(dev); |
1788 |
dev_close(dev); |
Lines 1710-1716
static struct sk_buff *sky2_receive(stru
Link Here
|
1710 |
if (!(status & GMR_FS_RX_OK)) |
1820 |
if (!(status & GMR_FS_RX_OK)) |
1711 |
goto resubmit; |
1821 |
goto resubmit; |
1712 |
|
1822 |
|
1713 |
if ((status >> 16) != length || length > sky2->rx_bufsize) |
1823 |
if (length > sky2->netdev->mtu + ETH_HLEN) |
1714 |
goto oversize; |
1824 |
goto oversize; |
1715 |
|
1825 |
|
1716 |
if (length < copybreak) { |
1826 |
if (length < copybreak) { |
Lines 1749-1756
resubmit:
Link Here
|
1749 |
sky2_rx_add(sky2, re->mapaddr); |
1859 |
sky2_rx_add(sky2, re->mapaddr); |
1750 |
|
1860 |
|
1751 |
/* Tell receiver about new buffers. */ |
1861 |
/* Tell receiver about new buffers. */ |
1752 |
sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put, |
1862 |
sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put); |
1753 |
&sky2->rx_last_put, RX_LE_SIZE); |
|
|
1754 |
|
1863 |
|
1755 |
return skb; |
1864 |
return skb; |
1756 |
|
1865 |
|
Lines 1761-1767
oversize:
Link Here
|
1761 |
error: |
1870 |
error: |
1762 |
++sky2->net_stats.rx_errors; |
1871 |
++sky2->net_stats.rx_errors; |
1763 |
|
1872 |
|
1764 |
if (netif_msg_rx_err(sky2)) |
1873 |
if (netif_msg_rx_err(sky2) && net_ratelimit()) |
1765 |
printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", |
1874 |
printk(KERN_INFO PFX "%s: rx error, status 0x%x length %d\n", |
1766 |
sky2->netdev->name, status, length); |
1875 |
sky2->netdev->name, status, length); |
1767 |
|
1876 |
|
Lines 1777-1839
error:
Link Here
|
1777 |
goto resubmit; |
1886 |
goto resubmit; |
1778 |
} |
1887 |
} |
1779 |
|
1888 |
|
1780 |
/* |
1889 |
/* Transmit complete */ |
1781 |
* Check for transmit complete |
1890 |
static inline void sky2_tx_done(struct net_device *dev, u16 last) |
1782 |
*/ |
|
|
1783 |
#define TX_NO_STATUS 0xffff |
1784 |
|
1785 |
static inline void sky2_tx_check(struct sky2_hw *hw, int port, u16 last) |
1786 |
{ |
1891 |
{ |
1787 |
if (last != TX_NO_STATUS) { |
1892 |
struct sky2_port *sky2 = netdev_priv(dev); |
1788 |
struct net_device *dev = hw->dev[port]; |
1893 |
|
1789 |
if (dev && netif_running(dev)) { |
1894 |
if (netif_running(dev)) { |
1790 |
struct sky2_port *sky2 = netdev_priv(dev); |
1895 |
spin_lock(&sky2->tx_lock); |
1791 |
sky2_tx_complete(sky2, last); |
1896 |
sky2_tx_complete(sky2, last); |
1792 |
} |
1897 |
spin_unlock(&sky2->tx_lock); |
1793 |
} |
1898 |
} |
1794 |
} |
1899 |
} |
1795 |
|
1900 |
|
1796 |
/* |
1901 |
/* Process status response ring */ |
1797 |
* Both ports share the same status interrupt, therefore there is only |
1902 |
static int sky2_status_intr(struct sky2_hw *hw, int to_do) |
1798 |
* one poll routine. |
|
|
1799 |
*/ |
1800 |
static int sky2_poll(struct net_device *dev0, int *budget) |
1801 |
{ |
1903 |
{ |
1802 |
struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; |
1904 |
int work_done = 0; |
1803 |
unsigned int to_do = min(dev0->quota, *budget); |
1905 |
u16 hwidx = sky2_read16(hw, STAT_PUT_IDX); |
1804 |
unsigned int work_done = 0; |
|
|
1805 |
u16 hwidx; |
1806 |
u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; |
1807 |
|
1906 |
|
1808 |
hwidx = sky2_read16(hw, STAT_PUT_IDX); |
|
|
1809 |
BUG_ON(hwidx >= STATUS_RING_SIZE); |
1810 |
rmb(); |
1907 |
rmb(); |
1811 |
|
1908 |
|
1812 |
while (hwidx != hw->st_idx) { |
1909 |
while (hw->st_idx != hwidx) { |
1813 |
struct sky2_status_le *le = hw->st_le + hw->st_idx; |
1910 |
struct sky2_status_le *le = hw->st_le + hw->st_idx; |
1814 |
struct net_device *dev; |
1911 |
struct net_device *dev; |
1815 |
struct sky2_port *sky2; |
1912 |
struct sky2_port *sky2; |
1816 |
struct sk_buff *skb; |
1913 |
struct sk_buff *skb; |
1817 |
u32 status; |
1914 |
u32 status; |
1818 |
u16 length; |
1915 |
u16 length; |
1819 |
u8 op; |
|
|
1820 |
|
1916 |
|
1821 |
le = hw->st_le + hw->st_idx; |
1917 |
hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); |
1822 |
hw->st_idx = (hw->st_idx + 1) % STATUS_RING_SIZE; |
|
|
1823 |
prefetch(hw->st_le + hw->st_idx); |
1824 |
|
1918 |
|
1825 |
BUG_ON(le->link >= 2); |
1919 |
BUG_ON(le->link >= 2); |
1826 |
dev = hw->dev[le->link]; |
1920 |
dev = hw->dev[le->link]; |
1827 |
if (dev == NULL || !netif_running(dev)) |
|
|
1828 |
continue; |
1829 |
|
1921 |
|
1830 |
sky2 = netdev_priv(dev); |
1922 |
sky2 = netdev_priv(dev); |
1831 |
status = le32_to_cpu(le->status); |
1923 |
length = le->length; |
1832 |
length = le16_to_cpu(le->length); |
1924 |
status = le->status; |
1833 |
op = le->opcode & ~HW_OWNER; |
|
|
1834 |
le->opcode = 0; |
1835 |
|
1925 |
|
1836 |
switch (op) { |
1926 |
switch (le->opcode & ~HW_OWNER) { |
1837 |
case OP_RXSTAT: |
1927 |
case OP_RXSTAT: |
1838 |
skb = sky2_receive(sky2, length, status); |
1928 |
skb = sky2_receive(sky2, length, status); |
1839 |
if (!skb) |
1929 |
if (!skb) |
Lines 1873-1950
static int sky2_poll(struct net_device *
Link Here
|
1873 |
|
1963 |
|
1874 |
case OP_TXINDEXLE: |
1964 |
case OP_TXINDEXLE: |
1875 |
/* TX index reports status for both ports */ |
1965 |
/* TX index reports status for both ports */ |
1876 |
tx_done[0] = status & 0xffff; |
1966 |
BUILD_BUG_ON(TX_RING_SIZE > 0x1000); |
1877 |
tx_done[1] = ((status >> 24) & 0xff) |
1967 |
sky2_tx_done(hw->dev[0], status & 0xfff); |
1878 |
| (u16)(length & 0xf) << 8; |
1968 |
if (hw->dev[1]) |
|
|
1969 |
sky2_tx_done(hw->dev[1], |
1970 |
((status >> 24) & 0xff) |
1971 |
| (u16)(length & 0xf) << 8); |
1879 |
break; |
1972 |
break; |
1880 |
|
1973 |
|
1881 |
default: |
1974 |
default: |
1882 |
if (net_ratelimit()) |
1975 |
if (net_ratelimit()) |
1883 |
printk(KERN_WARNING PFX |
1976 |
printk(KERN_WARNING PFX |
1884 |
"unknown status opcode 0x%x\n", op); |
1977 |
"unknown status opcode 0x%x\n", le->opcode); |
1885 |
break; |
1978 |
goto exit_loop; |
1886 |
} |
1979 |
} |
1887 |
} |
1980 |
} |
1888 |
|
1981 |
|
1889 |
exit_loop: |
1982 |
exit_loop: |
1890 |
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
1983 |
return work_done; |
1891 |
mmiowb(); |
|
|
1892 |
|
1893 |
sky2_tx_check(hw, 0, tx_done[0]); |
1894 |
sky2_tx_check(hw, 1, tx_done[1]); |
1895 |
|
1896 |
if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) { |
1897 |
/* need to restart TX timer */ |
1898 |
if (is_ec_a1(hw)) { |
1899 |
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); |
1900 |
sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); |
1901 |
} |
1902 |
|
1903 |
netif_rx_complete(dev0); |
1904 |
hw->intr_mask |= Y2_IS_STAT_BMU; |
1905 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
1906 |
mmiowb(); |
1907 |
return 0; |
1908 |
} else { |
1909 |
*budget -= work_done; |
1910 |
dev0->quota -= work_done; |
1911 |
return 1; |
1912 |
} |
1913 |
} |
1984 |
} |
1914 |
|
1985 |
|
1915 |
static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status) |
1986 |
static void sky2_hw_error(struct sky2_hw *hw, unsigned port, u32 status) |
1916 |
{ |
1987 |
{ |
1917 |
struct net_device *dev = hw->dev[port]; |
1988 |
struct net_device *dev = hw->dev[port]; |
1918 |
|
1989 |
|
1919 |
printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n", |
1990 |
if (net_ratelimit()) |
1920 |
dev->name, status); |
1991 |
printk(KERN_INFO PFX "%s: hw error interrupt status 0x%x\n", |
|
|
1992 |
dev->name, status); |
1921 |
|
1993 |
|
1922 |
if (status & Y2_IS_PAR_RD1) { |
1994 |
if (status & Y2_IS_PAR_RD1) { |
1923 |
printk(KERN_ERR PFX "%s: ram data read parity error\n", |
1995 |
if (net_ratelimit()) |
1924 |
dev->name); |
1996 |
printk(KERN_ERR PFX "%s: ram data read parity error\n", |
|
|
1997 |
dev->name); |
1925 |
/* Clear IRQ */ |
1998 |
/* Clear IRQ */ |
1926 |
sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR); |
1999 |
sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_RD_PERR); |
1927 |
} |
2000 |
} |
1928 |
|
2001 |
|
1929 |
if (status & Y2_IS_PAR_WR1) { |
2002 |
if (status & Y2_IS_PAR_WR1) { |
1930 |
printk(KERN_ERR PFX "%s: ram data write parity error\n", |
2003 |
if (net_ratelimit()) |
1931 |
dev->name); |
2004 |
printk(KERN_ERR PFX "%s: ram data write parity error\n", |
|
|
2005 |
dev->name); |
1932 |
|
2006 |
|
1933 |
sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR); |
2007 |
sky2_write16(hw, RAM_BUFFER(port, B3_RI_CTRL), RI_CLR_WR_PERR); |
1934 |
} |
2008 |
} |
1935 |
|
2009 |
|
1936 |
if (status & Y2_IS_PAR_MAC1) { |
2010 |
if (status & Y2_IS_PAR_MAC1) { |
1937 |
printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name); |
2011 |
if (net_ratelimit()) |
|
|
2012 |
printk(KERN_ERR PFX "%s: MAC parity error\n", dev->name); |
1938 |
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE); |
2013 |
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_PE); |
1939 |
} |
2014 |
} |
1940 |
|
2015 |
|
1941 |
if (status & Y2_IS_PAR_RX1) { |
2016 |
if (status & Y2_IS_PAR_RX1) { |
1942 |
printk(KERN_ERR PFX "%s: RX parity error\n", dev->name); |
2017 |
if (net_ratelimit()) |
|
|
2018 |
printk(KERN_ERR PFX "%s: RX parity error\n", dev->name); |
1943 |
sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR); |
2019 |
sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), BMU_CLR_IRQ_PAR); |
1944 |
} |
2020 |
} |
1945 |
|
2021 |
|
1946 |
if (status & Y2_IS_TCP_TXA1) { |
2022 |
if (status & Y2_IS_TCP_TXA1) { |
1947 |
printk(KERN_ERR PFX "%s: TCP segmentation error\n", dev->name); |
2023 |
if (net_ratelimit()) |
|
|
2024 |
printk(KERN_ERR PFX "%s: TCP segmentation error\n", |
2025 |
dev->name); |
1948 |
sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP); |
2026 |
sky2_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), BMU_CLR_IRQ_TCP); |
1949 |
} |
2027 |
} |
1950 |
} |
2028 |
} |
Lines 1959-1970
static void sky2_hw_intr(struct sky2_hw
Link Here
|
1959 |
if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { |
2037 |
if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { |
1960 |
u16 pci_err; |
2038 |
u16 pci_err; |
1961 |
|
2039 |
|
1962 |
pci_read_config_word(hw->pdev, PCI_STATUS, &pci_err); |
2040 |
pci_err = sky2_pci_read16(hw, PCI_STATUS); |
1963 |
printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", |
2041 |
if (net_ratelimit()) |
1964 |
pci_name(hw->pdev), pci_err); |
2042 |
printk(KERN_ERR PFX "%s: pci hw error (0x%x)\n", |
|
|
2043 |
pci_name(hw->pdev), pci_err); |
1965 |
|
2044 |
|
1966 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2045 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
1967 |
pci_write_config_word(hw->pdev, PCI_STATUS, |
2046 |
sky2_pci_write16(hw, PCI_STATUS, |
1968 |
pci_err | PCI_STATUS_ERROR_BITS); |
2047 |
pci_err | PCI_STATUS_ERROR_BITS); |
1969 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2048 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
1970 |
} |
2049 |
} |
Lines 1973-1986
static void sky2_hw_intr(struct sky2_hw
Link Here
|
1973 |
/* PCI-Express uncorrectable Error occurred */ |
2052 |
/* PCI-Express uncorrectable Error occurred */ |
1974 |
u32 pex_err; |
2053 |
u32 pex_err; |
1975 |
|
2054 |
|
1976 |
pci_read_config_dword(hw->pdev, PEX_UNC_ERR_STAT, &pex_err); |
2055 |
pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT); |
1977 |
|
2056 |
|
1978 |
printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", |
2057 |
if (net_ratelimit()) |
1979 |
pci_name(hw->pdev), pex_err); |
2058 |
printk(KERN_ERR PFX "%s: pci express error (0x%x)\n", |
|
|
2059 |
pci_name(hw->pdev), pex_err); |
1980 |
|
2060 |
|
1981 |
/* clear the interrupt */ |
2061 |
/* clear the interrupt */ |
1982 |
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2062 |
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
1983 |
pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, |
2063 |
sky2_pci_write32(hw, PEX_UNC_ERR_STAT, |
1984 |
0xffffffffUL); |
2064 |
0xffffffffUL); |
1985 |
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
2065 |
sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
1986 |
|
2066 |
|
Lines 2019-2058
static void sky2_mac_intr(struct sky2_hw
Link Here
|
2019 |
} |
2099 |
} |
2020 |
} |
2100 |
} |
2021 |
|
2101 |
|
2022 |
static void sky2_phy_intr(struct sky2_hw *hw, unsigned port) |
2102 |
/* This should never happen it is a fatal situation */ |
|
|
2103 |
static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, |
2104 |
const char *rxtx, u32 mask) |
2023 |
{ |
2105 |
{ |
2024 |
struct net_device *dev = hw->dev[port]; |
2106 |
struct net_device *dev = hw->dev[port]; |
2025 |
struct sky2_port *sky2 = netdev_priv(dev); |
2107 |
struct sky2_port *sky2 = netdev_priv(dev); |
|
|
2108 |
u32 imask; |
2109 |
|
2110 |
printk(KERN_ERR PFX "%s: %s descriptor error (hardware problem)\n", |
2111 |
dev ? dev->name : "<not registered>", rxtx); |
2026 |
|
2112 |
|
2027 |
hw->intr_mask &= ~(port == 0 ? Y2_IS_IRQ_PHY1 : Y2_IS_IRQ_PHY2); |
2113 |
imask = sky2_read32(hw, B0_IMSK); |
2028 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
2114 |
imask &= ~mask; |
2029 |
schedule_work(&sky2->phy_task); |
2115 |
sky2_write32(hw, B0_IMSK, imask); |
|
|
2116 |
|
2117 |
if (dev) { |
2118 |
spin_lock(&sky2->phy_lock); |
2119 |
sky2_link_down(sky2); |
2120 |
spin_unlock(&sky2->phy_lock); |
2121 |
} |
2030 |
} |
2122 |
} |
2031 |
|
2123 |
|
2032 |
static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) |
2124 |
/* If idle then force a fake soft NAPI poll once a second |
|
|
2125 |
* to work around cases where sharing an edge triggered interrupt. |
2126 |
*/ |
2127 |
static void sky2_idle(unsigned long arg) |
2033 |
{ |
2128 |
{ |
2034 |
struct sky2_hw *hw = dev_id; |
2129 |
struct sky2_hw *hw = (struct sky2_hw *) arg; |
2035 |
struct net_device *dev0 = hw->dev[0]; |
2130 |
struct net_device *dev = hw->dev[0]; |
2036 |
u32 status; |
|
|
2037 |
|
2131 |
|
2038 |
status = sky2_read32(hw, B0_Y2_SP_ISRC2); |
2132 |
if (__netif_rx_schedule_prep(dev)) |
2039 |
if (status == 0 || status == ~0) |
2133 |
__netif_rx_schedule(dev); |
2040 |
return IRQ_NONE; |
2134 |
|
|
|
2135 |
mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout)); |
2136 |
} |
2137 |
|
2138 |
|
2139 |
static int sky2_poll(struct net_device *dev0, int *budget) |
2140 |
{ |
2141 |
struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; |
2142 |
int work_limit = min(dev0->quota, *budget); |
2143 |
int work_done = 0; |
2144 |
u32 status = sky2_read32(hw, B0_Y2_SP_EISR); |
2041 |
|
2145 |
|
2042 |
if (status & Y2_IS_HW_ERR) |
2146 |
if (status & Y2_IS_HW_ERR) |
2043 |
sky2_hw_intr(hw); |
2147 |
sky2_hw_intr(hw); |
2044 |
|
2148 |
|
2045 |
/* Do NAPI for Rx and Tx status */ |
|
|
2046 |
if (status & Y2_IS_STAT_BMU) { |
2047 |
hw->intr_mask &= ~Y2_IS_STAT_BMU; |
2048 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
2049 |
|
2050 |
if (likely(__netif_rx_schedule_prep(dev0))) { |
2051 |
prefetch(&hw->st_le[hw->st_idx]); |
2052 |
__netif_rx_schedule(dev0); |
2053 |
} |
2054 |
} |
2055 |
|
2056 |
if (status & Y2_IS_IRQ_PHY1) |
2149 |
if (status & Y2_IS_IRQ_PHY1) |
2057 |
sky2_phy_intr(hw, 0); |
2150 |
sky2_phy_intr(hw, 0); |
2058 |
|
2151 |
|
Lines 2065-2073
static irqreturn_t sky2_intr(int irq, vo
Link Here
|
2065 |
if (status & Y2_IS_IRQ_MAC2) |
2158 |
if (status & Y2_IS_IRQ_MAC2) |
2066 |
sky2_mac_intr(hw, 1); |
2159 |
sky2_mac_intr(hw, 1); |
2067 |
|
2160 |
|
2068 |
sky2_write32(hw, B0_Y2_SP_ICR, 2); |
2161 |
if (status & Y2_IS_CHK_RX1) |
|
|
2162 |
sky2_descriptor_error(hw, 0, "receive", Y2_IS_CHK_RX1); |
2163 |
|
2164 |
if (status & Y2_IS_CHK_RX2) |
2165 |
sky2_descriptor_error(hw, 1, "receive", Y2_IS_CHK_RX2); |
2166 |
|
2167 |
if (status & Y2_IS_CHK_TXA1) |
2168 |
sky2_descriptor_error(hw, 0, "transmit", Y2_IS_CHK_TXA1); |
2169 |
|
2170 |
if (status & Y2_IS_CHK_TXA2) |
2171 |
sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2); |
2172 |
|
2173 |
if (status & Y2_IS_STAT_BMU) |
2174 |
sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
2175 |
|
2176 |
work_done = sky2_status_intr(hw, work_limit); |
2177 |
*budget -= work_done; |
2178 |
dev0->quota -= work_done; |
2179 |
|
2180 |
if (work_done >= work_limit) |
2181 |
return 1; |
2182 |
|
2183 |
netif_rx_complete(dev0); |
2184 |
|
2185 |
status = sky2_read32(hw, B0_Y2_SP_LISR); |
2186 |
return 0; |
2187 |
} |
2188 |
|
2189 |
static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) |
2190 |
{ |
2191 |
struct sky2_hw *hw = dev_id; |
2192 |
struct net_device *dev0 = hw->dev[0]; |
2193 |
u32 status; |
2069 |
|
2194 |
|
2070 |
sky2_read32(hw, B0_IMSK); |
2195 |
/* Reading this mask interrupts as side effect */ |
|
|
2196 |
status = sky2_read32(hw, B0_Y2_SP_ISRC2); |
2197 |
if (status == 0 || status == ~0) |
2198 |
return IRQ_NONE; |
2199 |
|
2200 |
prefetch(&hw->st_le[hw->st_idx]); |
2201 |
if (likely(__netif_rx_schedule_prep(dev0))) |
2202 |
__netif_rx_schedule(dev0); |
2071 |
|
2203 |
|
2072 |
return IRQ_HANDLED; |
2204 |
return IRQ_HANDLED; |
2073 |
} |
2205 |
} |
Lines 2106-2121
static inline u32 sky2_clk2us(const stru
Link Here
|
2106 |
} |
2238 |
} |
2107 |
|
2239 |
|
2108 |
|
2240 |
|
2109 |
static int sky2_reset(struct sky2_hw *hw) |
2241 |
static int __devinit sky2_reset(struct sky2_hw *hw) |
2110 |
{ |
2242 |
{ |
2111 |
u32 ctst; |
|
|
2112 |
u16 status; |
2243 |
u16 status; |
2113 |
u8 t8, pmd_type; |
2244 |
u8 t8, pmd_type; |
2114 |
int i; |
2245 |
int i; |
2115 |
|
2246 |
|
2116 |
ctst = sky2_read32(hw, B0_CTST); |
|
|
2117 |
|
2118 |
sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2247 |
sky2_write8(hw, B0_CTST, CS_RST_CLR); |
|
|
2248 |
|
2119 |
hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
2249 |
hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
2120 |
if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { |
2250 |
if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { |
2121 |
printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", |
2251 |
printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", |
Lines 2123-2133
static int sky2_reset(struct sky2_hw *hw
Link Here
|
2123 |
return -EOPNOTSUPP; |
2253 |
return -EOPNOTSUPP; |
2124 |
} |
2254 |
} |
2125 |
|
2255 |
|
2126 |
/* ring for status responses */ |
2256 |
hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; |
2127 |
hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, |
2257 |
|
2128 |
&hw->st_dma); |
2258 |
/* This rev is really old, and requires untested workarounds */ |
2129 |
if (!hw->st_le) |
2259 |
if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) { |
2130 |
return -ENOMEM; |
2260 |
printk(KERN_ERR PFX "%s: unsupported revision Yukon-%s (0x%x) rev %d\n", |
|
|
2261 |
pci_name(hw->pdev), yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], |
2262 |
hw->chip_id, hw->chip_rev); |
2263 |
return -EOPNOTSUPP; |
2264 |
} |
2131 |
|
2265 |
|
2132 |
/* disable ASF */ |
2266 |
/* disable ASF */ |
2133 |
if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
2267 |
if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
Lines 2140-2159
static int sky2_reset(struct sky2_hw *hw
Link Here
|
2140 |
sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2274 |
sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2141 |
|
2275 |
|
2142 |
/* clear PCI errors, if any */ |
2276 |
/* clear PCI errors, if any */ |
2143 |
pci_read_config_word(hw->pdev, PCI_STATUS, &status); |
2277 |
status = sky2_pci_read16(hw, PCI_STATUS); |
|
|
2278 |
|
2144 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2279 |
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2145 |
pci_write_config_word(hw->pdev, PCI_STATUS, |
2280 |
sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS); |
2146 |
status | PCI_STATUS_ERROR_BITS); |
2281 |
|
2147 |
|
2282 |
|
2148 |
sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
2283 |
sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
2149 |
|
2284 |
|
2150 |
/* clear any PEX errors */ |
2285 |
/* clear any PEX errors */ |
2151 |
if (is_pciex(hw)) { |
2286 |
if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) |
2152 |
u16 lstat; |
2287 |
sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL); |
2153 |
pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, |
2288 |
|
2154 |
0xffffffffUL); |
|
|
2155 |
pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat); |
2156 |
} |
2157 |
|
2289 |
|
2158 |
pmd_type = sky2_read8(hw, B2_PMD_TYP); |
2290 |
pmd_type = sky2_read8(hw, B2_PMD_TYP); |
2159 |
hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); |
2291 |
hw->copper = !(pmd_type == 'L' || pmd_type == 'S'); |
Lines 2164-2170
static int sky2_reset(struct sky2_hw *hw
Link Here
|
2164 |
if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) |
2296 |
if (!(sky2_read8(hw, B2_Y2_CLK_GATE) & Y2_STATUS_LNK2_INAC)) |
2165 |
++hw->ports; |
2297 |
++hw->ports; |
2166 |
} |
2298 |
} |
2167 |
hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; |
|
|
2168 |
|
2299 |
|
2169 |
sky2_set_power_state(hw, PCI_D0); |
2300 |
sky2_set_power_state(hw, PCI_D0); |
2170 |
|
2301 |
|
Lines 2230-2260
static int sky2_reset(struct sky2_hw *hw
Link Here
|
2230 |
/* Set the list last index */ |
2361 |
/* Set the list last index */ |
2231 |
sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); |
2362 |
sky2_write16(hw, STAT_LAST_IDX, STATUS_RING_SIZE - 1); |
2232 |
|
2363 |
|
2233 |
/* These status setup values are copied from SysKonnect's driver */ |
2364 |
sky2_write16(hw, STAT_TX_IDX_TH, 10); |
2234 |
if (is_ec_a1(hw)) { |
2365 |
sky2_write8(hw, STAT_FIFO_WM, 16); |
2235 |
/* WA for dev. #4.3 */ |
|
|
2236 |
sky2_write16(hw, STAT_TX_IDX_TH, 0xfff); /* Tx Threshold */ |
2237 |
|
2238 |
/* set Status-FIFO watermark */ |
2239 |
sky2_write8(hw, STAT_FIFO_WM, 0x21); /* WA for dev. #4.18 */ |
2240 |
|
2241 |
/* set Status-FIFO ISR watermark */ |
2242 |
sky2_write8(hw, STAT_FIFO_ISR_WM, 0x07); /* WA for dev. #4.18 */ |
2243 |
sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 10000)); |
2244 |
} else { |
2245 |
sky2_write16(hw, STAT_TX_IDX_TH, 10); |
2246 |
sky2_write8(hw, STAT_FIFO_WM, 16); |
2247 |
|
2366 |
|
2248 |
/* set Status-FIFO ISR watermark */ |
2367 |
/* set Status-FIFO ISR watermark */ |
2249 |
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0) |
2368 |
if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0) |
2250 |
sky2_write8(hw, STAT_FIFO_ISR_WM, 4); |
2369 |
sky2_write8(hw, STAT_FIFO_ISR_WM, 4); |
2251 |
else |
2370 |
else |
2252 |
sky2_write8(hw, STAT_FIFO_ISR_WM, 16); |
2371 |
sky2_write8(hw, STAT_FIFO_ISR_WM, 16); |
2253 |
|
2372 |
|
2254 |
sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); |
2373 |
sky2_write32(hw, STAT_TX_TIMER_INI, sky2_us2clk(hw, 1000)); |
2255 |
sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100)); |
2374 |
sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20)); |
2256 |
sky2_write32(hw, STAT_ISR_TIMER_INI, sky2_us2clk(hw, 20)); |
2375 |
sky2_write32(hw, STAT_LEV_TIMER_INI, sky2_us2clk(hw, 100)); |
2257 |
} |
|
|
2258 |
|
2376 |
|
2259 |
/* enable status unit */ |
2377 |
/* enable status unit */ |
2260 |
sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON); |
2378 |
sky2_write32(hw, STAT_CTRL, SC_STAT_OP_ON); |
Lines 2266-2272
static int sky2_reset(struct sky2_hw *hw
Link Here
|
2266 |
return 0; |
2384 |
return 0; |
2267 |
} |
2385 |
} |
2268 |
|
2386 |
|
2269 |
static inline u32 sky2_supported_modes(const struct sky2_hw *hw) |
2387 |
static u32 sky2_supported_modes(const struct sky2_hw *hw) |
2270 |
{ |
2388 |
{ |
2271 |
u32 modes; |
2389 |
u32 modes; |
2272 |
if (hw->copper) { |
2390 |
if (hw->copper) { |
Lines 2396-2412
static const struct sky2_stat {
Link Here
|
2396 |
{ "rx_unicast", GM_RXF_UC_OK }, |
2514 |
{ "rx_unicast", GM_RXF_UC_OK }, |
2397 |
{ "tx_mac_pause", GM_TXF_MPAUSE }, |
2515 |
{ "tx_mac_pause", GM_TXF_MPAUSE }, |
2398 |
{ "rx_mac_pause", GM_RXF_MPAUSE }, |
2516 |
{ "rx_mac_pause", GM_RXF_MPAUSE }, |
2399 |
{ "collisions", GM_TXF_SNG_COL }, |
2517 |
{ "collisions", GM_TXF_COL }, |
2400 |
{ "late_collision",GM_TXF_LAT_COL }, |
2518 |
{ "late_collision",GM_TXF_LAT_COL }, |
2401 |
{ "aborted", GM_TXF_ABO_COL }, |
2519 |
{ "aborted", GM_TXF_ABO_COL }, |
|
|
2520 |
{ "single_collisions", GM_TXF_SNG_COL }, |
2402 |
{ "multi_collisions", GM_TXF_MUL_COL }, |
2521 |
{ "multi_collisions", GM_TXF_MUL_COL }, |
2403 |
{ "fifo_underrun", GM_TXE_FIFO_UR }, |
2522 |
|
2404 |
{ "fifo_overflow", GM_RXE_FIFO_OV }, |
2523 |
{ "rx_short", GM_RXF_SHT }, |
2405 |
{ "rx_toolong", GM_RXF_LNG_ERR }, |
|
|
2406 |
{ "rx_jabber", GM_RXF_JAB_PKT }, |
2407 |
{ "rx_runt", GM_RXE_FRAG }, |
2524 |
{ "rx_runt", GM_RXE_FRAG }, |
|
|
2525 |
{ "rx_64_byte_packets", GM_RXF_64B }, |
2526 |
{ "rx_65_to_127_byte_packets", GM_RXF_127B }, |
2527 |
{ "rx_128_to_255_byte_packets", GM_RXF_255B }, |
2528 |
{ "rx_256_to_511_byte_packets", GM_RXF_511B }, |
2529 |
{ "rx_512_to_1023_byte_packets", GM_RXF_1023B }, |
2530 |
{ "rx_1024_to_1518_byte_packets", GM_RXF_1518B }, |
2531 |
{ "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ }, |
2408 |
{ "rx_too_long", GM_RXF_LNG_ERR }, |
2532 |
{ "rx_too_long", GM_RXF_LNG_ERR }, |
|
|
2533 |
{ "rx_fifo_overflow", GM_RXE_FIFO_OV }, |
2534 |
{ "rx_jabber", GM_RXF_JAB_PKT }, |
2409 |
{ "rx_fcs_error", GM_RXF_FCS_ERR }, |
2535 |
{ "rx_fcs_error", GM_RXF_FCS_ERR }, |
|
|
2536 |
|
2537 |
{ "tx_64_byte_packets", GM_TXF_64B }, |
2538 |
{ "tx_65_to_127_byte_packets", GM_TXF_127B }, |
2539 |
{ "tx_128_to_255_byte_packets", GM_TXF_255B }, |
2540 |
{ "tx_256_to_511_byte_packets", GM_TXF_511B }, |
2541 |
{ "tx_512_to_1023_byte_packets", GM_TXF_1023B }, |
2542 |
{ "tx_1024_to_1518_byte_packets", GM_TXF_1518B }, |
2543 |
{ "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ }, |
2544 |
{ "tx_fifo_underrun", GM_TXE_FIFO_UR }, |
2410 |
}; |
2545 |
}; |
2411 |
|
2546 |
|
2412 |
static u32 sky2_get_rx_csum(struct net_device *dev) |
2547 |
static u32 sky2_get_rx_csum(struct net_device *dev) |
Lines 2508-2514
static struct net_device_stats *sky2_get
Link Here
|
2508 |
sky2->net_stats.rx_bytes = data[1]; |
2643 |
sky2->net_stats.rx_bytes = data[1]; |
2509 |
sky2->net_stats.tx_packets = data[2] + data[4] + data[6]; |
2644 |
sky2->net_stats.tx_packets = data[2] + data[4] + data[6]; |
2510 |
sky2->net_stats.rx_packets = data[3] + data[5] + data[7]; |
2645 |
sky2->net_stats.rx_packets = data[3] + data[5] + data[7]; |
2511 |
sky2->net_stats.multicast = data[5] + data[7]; |
2646 |
sky2->net_stats.multicast = data[3] + data[5]; |
2512 |
sky2->net_stats.collisions = data[10]; |
2647 |
sky2->net_stats.collisions = data[10]; |
2513 |
sky2->net_stats.tx_aborted_errors = data[12]; |
2648 |
sky2->net_stats.tx_aborted_errors = data[12]; |
2514 |
|
2649 |
|
Lines 2518-2536
static struct net_device_stats *sky2_get
Link Here
|
2518 |
static int sky2_set_mac_address(struct net_device *dev, void *p) |
2653 |
static int sky2_set_mac_address(struct net_device *dev, void *p) |
2519 |
{ |
2654 |
{ |
2520 |
struct sky2_port *sky2 = netdev_priv(dev); |
2655 |
struct sky2_port *sky2 = netdev_priv(dev); |
2521 |
struct sockaddr *addr = p; |
2656 |
struct sky2_hw *hw = sky2->hw; |
|
|
2657 |
unsigned port = sky2->port; |
2658 |
const struct sockaddr *addr = p; |
2522 |
|
2659 |
|
2523 |
if (!is_valid_ether_addr(addr->sa_data)) |
2660 |
if (!is_valid_ether_addr(addr->sa_data)) |
2524 |
return -EADDRNOTAVAIL; |
2661 |
return -EADDRNOTAVAIL; |
2525 |
|
2662 |
|
2526 |
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
2663 |
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
2527 |
memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8, |
2664 |
memcpy_toio(hw->regs + B2_MAC_1 + port * 8, |
2528 |
dev->dev_addr, ETH_ALEN); |
2665 |
dev->dev_addr, ETH_ALEN); |
2529 |
memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8, |
2666 |
memcpy_toio(hw->regs + B2_MAC_2 + port * 8, |
2530 |
dev->dev_addr, ETH_ALEN); |
2667 |
dev->dev_addr, ETH_ALEN); |
2531 |
|
2668 |
|
2532 |
if (netif_running(dev)) |
2669 |
/* virtual address for data */ |
2533 |
sky2_phy_reinit(sky2); |
2670 |
gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); |
|
|
2671 |
|
2672 |
/* physical address: used for pause frames */ |
2673 |
gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); |
2534 |
|
2674 |
|
2535 |
return 0; |
2675 |
return 0; |
2536 |
} |
2676 |
} |
Lines 2632-2638
static int sky2_phys_id(struct net_devic
Link Here
|
2632 |
ms = data * 1000; |
2772 |
ms = data * 1000; |
2633 |
|
2773 |
|
2634 |
/* save initial values */ |
2774 |
/* save initial values */ |
2635 |
down(&sky2->phy_sema); |
2775 |
spin_lock_bh(&sky2->phy_lock); |
2636 |
if (hw->chip_id == CHIP_ID_YUKON_XL) { |
2776 |
if (hw->chip_id == CHIP_ID_YUKON_XL) { |
2637 |
u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
2777 |
u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
2638 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
2778 |
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 3); |
Lines 2648-2656
static int sky2_phys_id(struct net_devic
Link Here
|
2648 |
sky2_led(hw, port, onoff); |
2788 |
sky2_led(hw, port, onoff); |
2649 |
onoff = !onoff; |
2789 |
onoff = !onoff; |
2650 |
|
2790 |
|
2651 |
up(&sky2->phy_sema); |
2791 |
spin_unlock_bh(&sky2->phy_lock); |
2652 |
interrupted = msleep_interruptible(250); |
2792 |
interrupted = msleep_interruptible(250); |
2653 |
down(&sky2->phy_sema); |
2793 |
spin_lock_bh(&sky2->phy_lock); |
2654 |
|
2794 |
|
2655 |
ms -= 250; |
2795 |
ms -= 250; |
2656 |
} |
2796 |
} |
Lines 2665-2671
static int sky2_phys_id(struct net_devic
Link Here
|
2665 |
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
2805 |
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
2666 |
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
2806 |
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); |
2667 |
} |
2807 |
} |
2668 |
up(&sky2->phy_sema); |
2808 |
spin_unlock_bh(&sky2->phy_lock); |
2669 |
|
2809 |
|
2670 |
return 0; |
2810 |
return 0; |
2671 |
} |
2811 |
} |
Lines 2695-2732
static int sky2_set_pauseparam(struct ne
Link Here
|
2695 |
return err; |
2835 |
return err; |
2696 |
} |
2836 |
} |
2697 |
|
2837 |
|
2698 |
#ifdef CONFIG_PM |
|
|
2699 |
static void sky2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2700 |
{ |
2701 |
struct sky2_port *sky2 = netdev_priv(dev); |
2702 |
|
2703 |
wol->supported = WAKE_MAGIC; |
2704 |
wol->wolopts = sky2->wol ? WAKE_MAGIC : 0; |
2705 |
} |
2706 |
|
2707 |
static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
2708 |
{ |
2709 |
struct sky2_port *sky2 = netdev_priv(dev); |
2710 |
struct sky2_hw *hw = sky2->hw; |
2711 |
|
2712 |
if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) |
2713 |
return -EOPNOTSUPP; |
2714 |
|
2715 |
sky2->wol = wol->wolopts == WAKE_MAGIC; |
2716 |
|
2717 |
if (sky2->wol) { |
2718 |
memcpy_toio(hw->regs + WOL_MAC_ADDR, dev->dev_addr, ETH_ALEN); |
2719 |
|
2720 |
sky2_write16(hw, WOL_CTRL_STAT, |
2721 |
WOL_CTL_ENA_PME_ON_MAGIC_PKT | |
2722 |
WOL_CTL_ENA_MAGIC_PKT_UNIT); |
2723 |
} else |
2724 |
sky2_write16(hw, WOL_CTRL_STAT, WOL_CTL_DEFAULT); |
2725 |
|
2726 |
return 0; |
2727 |
} |
2728 |
#endif |
2729 |
|
2730 |
static int sky2_get_coalesce(struct net_device *dev, |
2838 |
static int sky2_get_coalesce(struct net_device *dev, |
2731 |
struct ethtool_coalesce *ecmd) |
2839 |
struct ethtool_coalesce *ecmd) |
2732 |
{ |
2840 |
{ |
Lines 2767-2792
static int sky2_set_coalesce(struct net_
Link Here
|
2767 |
{ |
2875 |
{ |
2768 |
struct sky2_port *sky2 = netdev_priv(dev); |
2876 |
struct sky2_port *sky2 = netdev_priv(dev); |
2769 |
struct sky2_hw *hw = sky2->hw; |
2877 |
struct sky2_hw *hw = sky2->hw; |
2770 |
const u32 tmin = sky2_clk2us(hw, 1); |
2878 |
const u32 tmax = sky2_clk2us(hw, 0x0ffffff); |
2771 |
const u32 tmax = 5000; |
|
|
2772 |
|
2773 |
if (ecmd->tx_coalesce_usecs != 0 && |
2774 |
(ecmd->tx_coalesce_usecs < tmin || ecmd->tx_coalesce_usecs > tmax)) |
2775 |
return -EINVAL; |
2776 |
|
2879 |
|
2777 |
if (ecmd->rx_coalesce_usecs != 0 && |
2880 |
if (ecmd->tx_coalesce_usecs > tmax || |
2778 |
(ecmd->rx_coalesce_usecs < tmin || ecmd->rx_coalesce_usecs > tmax)) |
2881 |
ecmd->rx_coalesce_usecs > tmax || |
|
|
2882 |
ecmd->rx_coalesce_usecs_irq > tmax) |
2779 |
return -EINVAL; |
2883 |
return -EINVAL; |
2780 |
|
2884 |
|
2781 |
if (ecmd->rx_coalesce_usecs_irq != 0 && |
2885 |
if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1) |
2782 |
(ecmd->rx_coalesce_usecs_irq < tmin || ecmd->rx_coalesce_usecs_irq > tmax)) |
|
|
2783 |
return -EINVAL; |
2886 |
return -EINVAL; |
2784 |
|
2887 |
if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING) |
2785 |
if (ecmd->tx_max_coalesced_frames > 0xffff) |
|
|
2786 |
return -EINVAL; |
2787 |
if (ecmd->rx_max_coalesced_frames > 0xff) |
2788 |
return -EINVAL; |
2888 |
return -EINVAL; |
2789 |
if (ecmd->rx_max_coalesced_frames_irq > 0xff) |
2889 |
if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING) |
2790 |
return -EINVAL; |
2890 |
return -EINVAL; |
2791 |
|
2891 |
|
2792 |
if (ecmd->tx_coalesce_usecs == 0) |
2892 |
if (ecmd->tx_coalesce_usecs == 0) |
Lines 2810-2816
static int sky2_set_coalesce(struct net_
Link Here
|
2810 |
if (ecmd->rx_coalesce_usecs_irq == 0) |
2910 |
if (ecmd->rx_coalesce_usecs_irq == 0) |
2811 |
sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); |
2911 |
sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); |
2812 |
else { |
2912 |
else { |
2813 |
sky2_write32(hw, STAT_TX_TIMER_INI, |
2913 |
sky2_write32(hw, STAT_ISR_TIMER_INI, |
2814 |
sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); |
2914 |
sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); |
2815 |
sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
2915 |
sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
2816 |
} |
2916 |
} |
Lines 2914-2923
static struct ethtool_ops sky2_ethtool_o
Link Here
|
2914 |
.set_ringparam = sky2_set_ringparam, |
3014 |
.set_ringparam = sky2_set_ringparam, |
2915 |
.get_pauseparam = sky2_get_pauseparam, |
3015 |
.get_pauseparam = sky2_get_pauseparam, |
2916 |
.set_pauseparam = sky2_set_pauseparam, |
3016 |
.set_pauseparam = sky2_set_pauseparam, |
2917 |
#ifdef CONFIG_PM |
|
|
2918 |
.get_wol = sky2_get_wol, |
2919 |
.set_wol = sky2_set_wol, |
2920 |
#endif |
2921 |
.phys_id = sky2_phys_id, |
3017 |
.phys_id = sky2_phys_id, |
2922 |
.get_stats_count = sky2_get_stats_count, |
3018 |
.get_stats_count = sky2_get_stats_count, |
2923 |
.get_ethtool_stats = sky2_get_ethtool_stats, |
3019 |
.get_ethtool_stats = sky2_get_ethtool_stats, |
Lines 2971-2986
static __devinit struct net_device *sky2
Link Here
|
2971 |
sky2->speed = -1; |
3067 |
sky2->speed = -1; |
2972 |
sky2->advertising = sky2_supported_modes(hw); |
3068 |
sky2->advertising = sky2_supported_modes(hw); |
2973 |
|
3069 |
|
2974 |
/* Receive checksum disabled for Yukon XL |
3070 |
/* Receive checksum disabled for Yukon XL |
2975 |
* because of observed problems with incorrect |
3071 |
* because of observed problems with incorrect |
2976 |
* values when multiple packets are received in one interrupt |
3072 |
* values when multiple packets are received in one interrupt |
2977 |
*/ |
3073 |
*/ |
2978 |
sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); |
3074 |
sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); |
2979 |
|
3075 |
|
2980 |
INIT_WORK(&sky2->phy_task, sky2_phy_task, sky2); |
3076 |
spin_lock_init(&sky2->phy_lock); |
2981 |
init_MUTEX(&sky2->phy_sema); |
|
|
2982 |
sky2->tx_pending = TX_DEF_PENDING; |
3077 |
sky2->tx_pending = TX_DEF_PENDING; |
2983 |
sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING; |
3078 |
sky2->rx_pending = RX_DEF_PENDING; |
2984 |
sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); |
3079 |
sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); |
2985 |
|
3080 |
|
2986 |
hw->dev[port] = dev; |
3081 |
hw->dev[port] = dev; |
Lines 3011-3017
static __devinit struct net_device *sky2
Link Here
|
3011 |
return dev; |
3106 |
return dev; |
3012 |
} |
3107 |
} |
3013 |
|
3108 |
|
3014 |
static inline void sky2_show_addr(struct net_device *dev) |
3109 |
static void __devinit sky2_show_addr(struct net_device *dev) |
3015 |
{ |
3110 |
{ |
3016 |
const struct sky2_port *sky2 = netdev_priv(dev); |
3111 |
const struct sky2_port *sky2 = netdev_priv(dev); |
3017 |
|
3112 |
|
Lines 3022-3027
static inline void sky2_show_addr(struct
Link Here
|
3022 |
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); |
3117 |
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); |
3023 |
} |
3118 |
} |
3024 |
|
3119 |
|
|
|
3120 |
/* Handle software interrupt used during MSI test */ |
3121 |
static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id, |
3122 |
struct pt_regs *regs) |
3123 |
{ |
3124 |
struct sky2_hw *hw = dev_id; |
3125 |
u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2); |
3126 |
|
3127 |
if (status == 0) |
3128 |
return IRQ_NONE; |
3129 |
|
3130 |
if (status & Y2_IS_IRQ_SW) { |
3131 |
hw->msi_detected = 1; |
3132 |
wake_up(&hw->msi_wait); |
3133 |
sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); |
3134 |
} |
3135 |
sky2_write32(hw, B0_Y2_SP_ICR, 2); |
3136 |
|
3137 |
return IRQ_HANDLED; |
3138 |
} |
3139 |
|
3140 |
/* Test interrupt path by forcing a a software IRQ */ |
3141 |
static int __devinit sky2_test_msi(struct sky2_hw *hw) |
3142 |
{ |
3143 |
struct pci_dev *pdev = hw->pdev; |
3144 |
int err; |
3145 |
|
3146 |
sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); |
3147 |
|
3148 |
err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw); |
3149 |
if (err) { |
3150 |
printk(KERN_ERR PFX "%s: cannot assign irq %d\n", |
3151 |
pci_name(pdev), pdev->irq); |
3152 |
return err; |
3153 |
} |
3154 |
|
3155 |
init_waitqueue_head (&hw->msi_wait); |
3156 |
|
3157 |
sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); |
3158 |
wmb(); |
3159 |
|
3160 |
wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10); |
3161 |
|
3162 |
if (!hw->msi_detected) { |
3163 |
/* MSI test failed, go back to INTx mode */ |
3164 |
printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " |
3165 |
"switching to INTx mode. Please report this failure to " |
3166 |
"the PCI maintainer and include system chipset information.\n", |
3167 |
pci_name(pdev)); |
3168 |
|
3169 |
err = -EOPNOTSUPP; |
3170 |
sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); |
3171 |
} |
3172 |
|
3173 |
sky2_write32(hw, B0_IMSK, 0); |
3174 |
|
3175 |
free_irq(pdev->irq, hw); |
3176 |
|
3177 |
return err; |
3178 |
} |
3179 |
|
3025 |
static int __devinit sky2_probe(struct pci_dev *pdev, |
3180 |
static int __devinit sky2_probe(struct pci_dev *pdev, |
3026 |
const struct pci_device_id *ent) |
3181 |
const struct pci_device_id *ent) |
3027 |
{ |
3182 |
{ |
Lines 3073-3098
static int __devinit sky2_probe(struct p
Link Here
|
3073 |
} |
3228 |
} |
3074 |
} |
3229 |
} |
3075 |
|
3230 |
|
3076 |
#ifdef __BIG_ENDIAN |
|
|
3077 |
/* byte swap descriptors in hardware */ |
3078 |
{ |
3079 |
u32 reg; |
3080 |
|
3081 |
pci_read_config_dword(pdev, PCI_DEV_REG2, ®); |
3082 |
reg |= PCI_REV_DESC; |
3083 |
pci_write_config_dword(pdev, PCI_DEV_REG2, reg); |
3084 |
} |
3085 |
#endif |
3086 |
|
3087 |
err = -ENOMEM; |
3231 |
err = -ENOMEM; |
3088 |
hw = kmalloc(sizeof(*hw), GFP_KERNEL); |
3232 |
hw = kzalloc(sizeof(*hw), GFP_KERNEL); |
3089 |
if (!hw) { |
3233 |
if (!hw) { |
3090 |
printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", |
3234 |
printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n", |
3091 |
pci_name(pdev)); |
3235 |
pci_name(pdev)); |
3092 |
goto err_out_free_regions; |
3236 |
goto err_out_free_regions; |
3093 |
} |
3237 |
} |
3094 |
|
3238 |
|
3095 |
memset(hw, 0, sizeof(*hw)); |
|
|
3096 |
hw->pdev = pdev; |
3239 |
hw->pdev = pdev; |
3097 |
|
3240 |
|
3098 |
hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); |
3241 |
hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); |
Lines 3103-3108
static int __devinit sky2_probe(struct p
Link Here
|
3103 |
} |
3246 |
} |
3104 |
hw->pm_cap = pm_cap; |
3247 |
hw->pm_cap = pm_cap; |
3105 |
|
3248 |
|
|
|
3249 |
#ifdef __BIG_ENDIAN |
3250 |
/* byte swap descriptors in hardware */ |
3251 |
{ |
3252 |
u32 reg; |
3253 |
|
3254 |
reg = sky2_pci_read32(hw, PCI_DEV_REG2); |
3255 |
reg |= PCI_REV_DESC; |
3256 |
sky2_pci_write32(hw, PCI_DEV_REG2, reg); |
3257 |
} |
3258 |
#endif |
3259 |
|
3260 |
/* ring for status responses */ |
3261 |
hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, |
3262 |
&hw->st_dma); |
3263 |
if (!hw->st_le) |
3264 |
goto err_out_iounmap; |
3265 |
|
3106 |
err = sky2_reset(hw); |
3266 |
err = sky2_reset(hw); |
3107 |
if (err) |
3267 |
if (err) |
3108 |
goto err_out_iounmap; |
3268 |
goto err_out_iounmap; |
Lines 3137-3157
static int __devinit sky2_probe(struct p
Link Here
|
3137 |
} |
3297 |
} |
3138 |
} |
3298 |
} |
3139 |
|
3299 |
|
3140 |
err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); |
3300 |
if (!disable_msi && pci_enable_msi(pdev) == 0) { |
|
|
3301 |
err = sky2_test_msi(hw); |
3302 |
if (err == -EOPNOTSUPP) |
3303 |
pci_disable_msi(pdev); |
3304 |
else if (err) |
3305 |
goto err_out_unregister; |
3306 |
} |
3307 |
|
3308 |
err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); |
3141 |
if (err) { |
3309 |
if (err) { |
3142 |
printk(KERN_ERR PFX "%s: cannot assign irq %d\n", |
3310 |
printk(KERN_ERR PFX "%s: cannot assign irq %d\n", |
3143 |
pci_name(pdev), pdev->irq); |
3311 |
pci_name(pdev), pdev->irq); |
3144 |
goto err_out_unregister; |
3312 |
goto err_out_unregister; |
3145 |
} |
3313 |
} |
3146 |
|
3314 |
|
3147 |
hw->intr_mask = Y2_IS_BASE; |
3315 |
sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
3148 |
sky2_write32(hw, B0_IMSK, hw->intr_mask); |
3316 |
|
|
|
3317 |
setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); |
3318 |
if (idle_timeout > 0) |
3319 |
mod_timer(&hw->idle_timer, |
3320 |
jiffies + msecs_to_jiffies(idle_timeout)); |
3149 |
|
3321 |
|
3150 |
pci_set_drvdata(pdev, hw); |
3322 |
pci_set_drvdata(pdev, hw); |
3151 |
|
3323 |
|
3152 |
return 0; |
3324 |
return 0; |
3153 |
|
3325 |
|
3154 |
err_out_unregister: |
3326 |
err_out_unregister: |
|
|
3327 |
pci_disable_msi(pdev); |
3155 |
if (dev1) { |
3328 |
if (dev1) { |
3156 |
unregister_netdev(dev1); |
3329 |
unregister_netdev(dev1); |
3157 |
free_netdev(dev1); |
3330 |
free_netdev(dev1); |
Lines 3181-3199
static void __devexit sky2_remove(struct
Link Here
|
3181 |
if (!hw) |
3354 |
if (!hw) |
3182 |
return; |
3355 |
return; |
3183 |
|
3356 |
|
|
|
3357 |
del_timer_sync(&hw->idle_timer); |
3358 |
|
3359 |
sky2_write32(hw, B0_IMSK, 0); |
3360 |
synchronize_irq(hw->pdev->irq); |
3361 |
|
3184 |
dev0 = hw->dev[0]; |
3362 |
dev0 = hw->dev[0]; |
3185 |
dev1 = hw->dev[1]; |
3363 |
dev1 = hw->dev[1]; |
3186 |
if (dev1) |
3364 |
if (dev1) |
3187 |
unregister_netdev(dev1); |
3365 |
unregister_netdev(dev1); |
3188 |
unregister_netdev(dev0); |
3366 |
unregister_netdev(dev0); |
3189 |
|
3367 |
|
3190 |
sky2_write32(hw, B0_IMSK, 0); |
|
|
3191 |
sky2_set_power_state(hw, PCI_D3hot); |
3368 |
sky2_set_power_state(hw, PCI_D3hot); |
3192 |
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
3369 |
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
3193 |
sky2_write8(hw, B0_CTST, CS_RST_SET); |
3370 |
sky2_write8(hw, B0_CTST, CS_RST_SET); |
3194 |
sky2_read8(hw, B0_CTST); |
3371 |
sky2_read8(hw, B0_CTST); |
3195 |
|
3372 |
|
3196 |
free_irq(pdev->irq, hw); |
3373 |
free_irq(pdev->irq, hw); |
|
|
3374 |
pci_disable_msi(pdev); |
3197 |
pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); |
3375 |
pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); |
3198 |
pci_release_regions(pdev); |
3376 |
pci_release_regions(pdev); |
3199 |
pci_disable_device(pdev); |
3377 |
pci_disable_device(pdev); |
Lines 3231-3255
static int sky2_suspend(struct pci_dev *
Link Here
|
3231 |
static int sky2_resume(struct pci_dev *pdev) |
3409 |
static int sky2_resume(struct pci_dev *pdev) |
3232 |
{ |
3410 |
{ |
3233 |
struct sky2_hw *hw = pci_get_drvdata(pdev); |
3411 |
struct sky2_hw *hw = pci_get_drvdata(pdev); |
3234 |
int i; |
3412 |
int i, err; |
3235 |
|
3413 |
|
3236 |
pci_restore_state(pdev); |
3414 |
pci_restore_state(pdev); |
3237 |
pci_enable_wake(pdev, PCI_D0, 0); |
3415 |
pci_enable_wake(pdev, PCI_D0, 0); |
3238 |
sky2_set_power_state(hw, PCI_D0); |
3416 |
err = sky2_set_power_state(hw, PCI_D0); |
|
|
3417 |
if (err) |
3418 |
goto out; |
3239 |
|
3419 |
|
3240 |
sky2_reset(hw); |
3420 |
err = sky2_reset(hw); |
|
|
3421 |
if (err) |
3422 |
goto out; |
3241 |
|
3423 |
|
3242 |
for (i = 0; i < 2; i++) { |
3424 |
for (i = 0; i < 2; i++) { |
3243 |
struct net_device *dev = hw->dev[i]; |
3425 |
struct net_device *dev = hw->dev[i]; |
3244 |
if (dev) { |
3426 |
if (dev && netif_running(dev)) { |
3245 |
if (netif_running(dev)) { |
3427 |
netif_device_attach(dev); |
3246 |
netif_device_attach(dev); |
3428 |
err = sky2_up(dev); |
3247 |
if (sky2_up(dev)) |
3429 |
if (err) { |
3248 |
dev_close(dev); |
3430 |
printk(KERN_ERR PFX "%s: could not up: %d\n", |
|
|
3431 |
dev->name, err); |
3432 |
dev_close(dev); |
3433 |
break; |
3249 |
} |
3434 |
} |
3250 |
} |
3435 |
} |
3251 |
} |
3436 |
} |
3252 |
return 0; |
3437 |
out: |
|
|
3438 |
return err; |
3253 |
} |
3439 |
} |
3254 |
#endif |
3440 |
#endif |
3255 |
|
3441 |
|