X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fsky2.c;h=f8f50f70bcd2f2175c3ef18b5b0e3582f76b9f11;hb=51c24aaacaea90c8e87f1dec75a2ac7622b593f8;hp=1729ebf5de9c0880dc6a49e7311c27b59215e0eb;hpb=ac958154e9e1548933fe97e4ecbceb30e01e4a6f;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 1729ebf..f8f50f7 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -374,8 +374,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); /* downshift on PHY 88E1112 and 88E1149 is changed */ - if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) - && (hw->flags & SKY2_HW_NEWER_PHY)) { + if ( (sky2->flags & SKY2_FLAG_AUTO_SPEED) && + (hw->flags & SKY2_HW_NEWER_PHY)) { /* set downshift counter to 3x and enable downshift */ ctrl &= ~PHY_M_PC_DSC_MSK; ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; @@ -619,8 +619,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) /* no effect on Yukon-XL */ gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); - if ( !(sky2->flags & SKY2_FLAG_AUTO_SPEED) - || sky2->speed == SPEED_100) { + if (!(sky2->flags & SKY2_FLAG_AUTO_SPEED) || + sky2->speed == SPEED_100) { /* turn on 100 Mbps LED (LED_LINK100) */ ledover |= PHY_M_LED_MO_100(MO_LED_ON); } @@ -644,7 +644,6 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) { u32 reg1; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 &= ~phy_power[port]; @@ -652,7 +651,6 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port) reg1 |= coma_mode[port]; sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); sky2_pci_read32(hw, PCI_DEV_REG1); if (hw->chip_id == CHIP_ID_YUKON_FE) @@ -709,11 +707,9 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_PDOWN); } - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 |= phy_power[port]; /* set PHY to PowerDown/COMA Mode */ sky2_pci_write32(hw, PCI_DEV_REG1, reg1); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } /* Force a renegotiation */ @@ -937,8 +933,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) /* On chips without ram buffer, pause is controled by MAC level */ if (!(hw->flags & SKY2_HW_RAM_BUFFER)) { /* Pause threshold is scaled by 8 in bytes */ - if (hw->chip_id == CHIP_ID_YUKON_FE_P - && hw->chip_rev == CHIP_REV_YU_FE2_A0) + if (hw->chip_id == CHIP_ID_YUKON_FE_P && + hw->chip_rev == CHIP_REV_YU_FE2_A0) reg = 1568 / 8; else reg = 1024 / 8; @@ -1353,8 +1349,8 @@ static int sky2_rx_start(struct sky2_port *sky2) /* These chips have no ram buffer? * MAC Rx RAM Read is controlled by hardware */ if (hw->chip_id == CHIP_ID_YUKON_EC_U && - (hw->chip_rev == CHIP_REV_YU_EC_U_A1 - || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) + (hw->chip_rev == CHIP_REV_YU_EC_U_A1 || + hw->chip_rev == CHIP_REV_YU_EC_U_B0)) sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS); sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); @@ -1560,8 +1556,8 @@ static int sky2_up(struct net_device *dev) sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF); /* Set almost empty threshold */ - if (hw->chip_id == CHIP_ID_YUKON_EC_U - && hw->chip_rev == CHIP_REV_YU_EC_U_A0) + if (hw->chip_id == CHIP_ID_YUKON_EC_U && + hw->chip_rev == CHIP_REV_YU_EC_U_A0) sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV); sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, @@ -1848,7 +1844,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done) sky2->tx_cons = idx; smp_mb(); - if (tx_avail(sky2) > MAX_SKB_TX_LE + 4) + /* Wake unless it's detached, and called e.g. from sky2_down() */ + if (tx_avail(sky2) > MAX_SKB_TX_LE + 4 && netif_device_present(dev)) netif_wake_queue(dev); } @@ -1907,8 +1904,8 @@ static int sky2_down(struct net_device *dev) sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); /* Workaround shared GMAC reset */ - if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 - && port == 0 && hw->dev[1] && netif_running(hw->dev[1]))) + if (!(hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev == 0 && + port == 0 && hw->dev[1] && netif_running(hw->dev[1]))) sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); @@ -2017,7 +2014,7 @@ static void sky2_link_down(struct sky2_port *sky2) netif_carrier_off(sky2->netdev); - /* Turn on link LED */ + /* Turn off link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); if (netif_msg_link(sky2)) @@ -2085,8 +2082,8 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) sky2->flow_status = FC_TX; } - if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 - && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) + if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000 && + !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)) sky2->flow_status = FC_NONE; if (sky2->flow_status & FC_TX) @@ -2643,7 +2640,6 @@ static void sky2_hw_intr(struct sky2_hw *hw) if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { u16 pci_err; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); pci_err = sky2_pci_read16(hw, PCI_STATUS); if (net_ratelimit()) dev_err(&pdev->dev, "PCI hardware error (0x%x)\n", @@ -2651,14 +2647,12 @@ static void sky2_hw_intr(struct sky2_hw *hw) sky2_pci_write16(hw, PCI_STATUS, pci_err | PCI_STATUS_ERROR_BITS); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } if (status & Y2_IS_PCI_EXP) { /* PCI-Express uncorrectable Error occurred */ u32 err; - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, 0xfffffffful); @@ -2666,7 +2660,6 @@ static void sky2_hw_intr(struct sky2_hw *hw) dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } if (status & Y2_HWE_L1_MASK) @@ -2968,8 +2961,13 @@ static int __devinit sky2_init(struct sky2_hw *hw) break; case CHIP_ID_YUKON_UL_2: + hw->flags = SKY2_HW_GIGABIT + | SKY2_HW_ADV_POWER_CTL; + break; + case CHIP_ID_YUKON_OPT: hw->flags = SKY2_HW_GIGABIT + | SKY2_HW_NEW_LE | SKY2_HW_ADV_POWER_CTL; break; @@ -3040,7 +3038,6 @@ static void sky2_reset(struct sky2_hw *hw) } sky2_power_on(hw); - sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); for (i = 0; i < hw->ports; i++) { sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); @@ -3180,7 +3177,9 @@ static void sky2_reset(struct sky2_hw *hw) static void sky2_detach(struct net_device *dev) { if (netif_running(dev)) { + netif_tx_lock(dev); netif_device_detach(dev); /* stop txq */ + netif_tx_unlock(dev); sky2_down(dev); } } @@ -3244,8 +3243,8 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct sky2_port *sky2 = netdev_priv(dev); struct sky2_hw *hw = sky2->hw; - if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) - || !device_can_wakeup(&hw->pdev->dev)) + if ((wol->wolopts & ~sky2_wol_supported(sky2->hw)) || + !device_can_wakeup(&hw->pdev->dev)) return -EOPNOTSUPP; sky2->wol = wol->wolopts; @@ -3841,6 +3840,50 @@ static int sky2_get_regs_len(struct net_device *dev) return 0x4000; } +static int sky2_reg_access_ok(struct sky2_hw *hw, unsigned int b) +{ + /* This complicated switch statement is to make sure and + * only access regions that are unreserved. + * Some blocks are only valid on dual port cards. + */ + switch (b) { + /* second port */ + case 5: /* Tx Arbiter 2 */ + case 9: /* RX2 */ + case 14 ... 15: /* TX2 */ + case 17: case 19: /* Ram Buffer 2 */ + case 22 ... 23: /* Tx Ram Buffer 2 */ + case 25: /* Rx MAC Fifo 1 */ + case 27: /* Tx MAC Fifo 2 */ + case 31: /* GPHY 2 */ + case 40 ... 47: /* Pattern Ram 2 */ + case 52: case 54: /* TCP Segmentation 2 */ + case 112 ... 116: /* GMAC 2 */ + return hw->ports > 1; + + case 0: /* Control */ + case 2: /* Mac address */ + case 4: /* Tx Arbiter 1 */ + case 7: /* PCI express reg */ + case 8: /* RX1 */ + case 12 ... 13: /* TX1 */ + case 16: case 18:/* Rx Ram Buffer 1 */ + case 20 ... 21: /* Tx Ram Buffer 1 */ + case 24: /* Rx MAC Fifo 1 */ + case 26: /* Tx MAC Fifo 1 */ + case 28 ... 29: /* Descriptor and status unit */ + case 30: /* GPHY 1*/ + case 32 ... 39: /* Pattern Ram 1 */ + case 48: case 50: /* TCP Segmentation 1 */ + case 56 ... 60: /* PCI space */ + case 80 ... 84: /* GMAC 1 */ + return 1; + + default: + return 0; + } +} + /* * Returns copy of control register region * Note: ethtool_get_regs always provides full size (16k) buffer @@ -3855,55 +3898,13 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, regs->version = 1; for (b = 0; b < 128; b++) { - /* This complicated switch statement is to make sure and - * only access regions that are unreserved. - * Some blocks are only valid on dual port cards. - * and block 3 has some special diagnostic registers that - * are poison. - */ - switch (b) { - case 3: - /* skip diagnostic ram region */ + /* skip poisonous diagnostic ram region in block 3 */ + if (b == 3) memcpy_fromio(p + 0x10, io + 0x10, 128 - 0x10); - break; - - /* dual port cards only */ - case 5: /* Tx Arbiter 2 */ - case 9: /* RX2 */ - case 14 ... 15: /* TX2 */ - case 17: case 19: /* Ram Buffer 2 */ - case 22 ... 23: /* Tx Ram Buffer 2 */ - case 25: /* Rx MAC Fifo 1 */ - case 27: /* Tx MAC Fifo 2 */ - case 31: /* GPHY 2 */ - case 40 ... 47: /* Pattern Ram 2 */ - case 52: case 54: /* TCP Segmentation 2 */ - case 112 ... 116: /* GMAC 2 */ - if (sky2->hw->ports == 1) - goto reserved; - /* fall through */ - case 0: /* Control */ - case 2: /* Mac address */ - case 4: /* Tx Arbiter 1 */ - case 7: /* PCI express reg */ - case 8: /* RX1 */ - case 12 ... 13: /* TX1 */ - case 16: case 18:/* Rx Ram Buffer 1 */ - case 20 ... 21: /* Tx Ram Buffer 1 */ - case 24: /* Rx MAC Fifo 1 */ - case 26: /* Tx MAC Fifo 1 */ - case 28 ... 29: /* Descriptor and status unit */ - case 30: /* GPHY 1*/ - case 32 ... 39: /* Pattern Ram 1 */ - case 48: case 50: /* TCP Segmentation 1 */ - case 56 ... 60: /* PCI space */ - case 80 ... 84: /* GMAC 1 */ + else if (sky2_reg_access_ok(sky2->hw, b)) memcpy_fromio(p, io, 128); - break; - default: -reserved: + else memset(p, 0, 128); - } p += 128; io += 128; @@ -4521,7 +4522,7 @@ static const char *sky2_name(u8 chipid, char *buf, int sz) "Optima", /* 0xbc */ }; - if (chipid >= CHIP_ID_YUKON_XL && chipid < CHIP_ID_YUKON_OPT) + if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT) strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz); else snprintf(buf, sz, "(chip %#x)", chipid); @@ -4651,6 +4652,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_netdev; } + netif_carrier_off(dev); + netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); err = request_irq(pdev->irq, sky2_intr, @@ -4686,6 +4689,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, INIT_WORK(&hw->restart_work, sky2_restart); pci_set_drvdata(pdev, hw); + pdev->d3_delay = 150; return 0;