diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 139 |
1 files changed, 61 insertions, 78 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index a2070db725c..52ec89b82f6 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -31,7 +31,6 @@ #include <linux/etherdevice.h> #include <linux/ethtool.h> #include <linux/pci.h> -#include <linux/aer.h> #include <linux/ip.h> #include <net/ip.h> #include <linux/tcp.h> @@ -240,22 +239,21 @@ static void sky2_power_on(struct sky2_hw *hw) sky2_write8(hw, B2_Y2_CLK_GATE, 0); if (hw->flags & SKY2_HW_ADV_POWER_CTL) { - struct pci_dev *pdev = hw->pdev; u32 reg; - pci_write_config_dword(pdev, PCI_DEV_REG3, 0); + sky2_pci_write32(hw, PCI_DEV_REG3, 0); - pci_read_config_dword(pdev, PCI_DEV_REG4, ®); + reg = sky2_pci_read32(hw, PCI_DEV_REG4); /* set all bits to 0 except bits 15..12 and 8 */ reg &= P_ASPM_CONTROL_MSK; - pci_write_config_dword(pdev, PCI_DEV_REG4, reg); + sky2_pci_write32(hw, PCI_DEV_REG4, reg); - pci_read_config_dword(pdev, PCI_DEV_REG5, ®); + reg = sky2_pci_read32(hw, PCI_DEV_REG5); /* set all bits to 0 except bits 28 & 27 */ reg &= P_CTL_TIM_VMAIN_AV_MSK; - pci_write_config_dword(pdev, PCI_DEV_REG5, reg); + sky2_pci_write32(hw, PCI_DEV_REG5, reg); - pci_write_config_dword(pdev, PCI_CFG_REG_1, 0); + sky2_pci_write32(hw, PCI_CFG_REG_1, 0); /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */ reg = sky2_read32(hw, B2_GP_IO); @@ -619,12 +617,11 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) { - struct pci_dev *pdev = hw->pdev; u32 reg1; static const u32 phy_power[] = { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD }; static const u32 coma_mode[] = { PCI_Y2_PHY1_COMA, PCI_Y2_PHY2_COMA }; - pci_read_config_dword(pdev, PCI_DEV_REG1, ®1); + reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); /* Turn on/off phy power saving */ if (onoff) reg1 &= ~phy_power[port]; @@ -634,8 +631,8 @@ static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff) if (onoff && hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1) reg1 |= coma_mode[port]; - pci_write_config_dword(pdev, PCI_DEV_REG1, reg1); - pci_read_config_dword(pdev, PCI_DEV_REG1, ®1); + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); + reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); udelay(100); } @@ -704,9 +701,9 @@ static void sky2_wol_init(struct sky2_port *sky2) sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl); /* Turn on legacy PCI-Express PME mode */ - pci_read_config_dword(hw->pdev, PCI_DEV_REG1, ®1); + reg1 = sky2_pci_read32(hw, PCI_DEV_REG1); reg1 |= PCI_Y2_PME_LEGACY; - pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1); + sky2_pci_write32(hw, PCI_DEV_REG1, reg1); /* block receiver */ sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); @@ -825,8 +822,13 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); - /* Flush Rx MAC FIFO on any flow control or error */ - sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); + if (hw->chip_id == CHIP_ID_YUKON_XL) { + /* Hardware errata - clear flush mask */ + sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), 0); + } else { + /* Flush Rx MAC FIFO on any flow control or error */ + sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); + } /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */ reg = RX_GMF_FL_THR_DEF + 1; @@ -848,6 +850,13 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) sky2_set_tx_stfwd(hw, port); } + if (hw->chip_id == CHIP_ID_YUKON_FE_P && + hw->chip_rev == CHIP_REV_YU_FE2_A0) { + /* disable dynamic watermark */ + reg = sky2_read16(hw, SK_REG(port, TX_GMF_EA)); + reg &= ~TX_DYN_WM_ENA; + sky2_write16(hw, SK_REG(port, TX_GMF_EA), reg); + } } /* Assign Ram Buffer allocation to queue */ @@ -1159,6 +1168,7 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp TX_VLAN_TAG_OFF); } + sky2_read32(hw, B0_Y2_SP_LISR); napi_enable(&hw->napi); netif_tx_unlock_bh(dev); } @@ -1320,15 +1330,12 @@ static int sky2_up(struct net_device *dev) */ if (otherdev && netif_running(otherdev) && (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) { - struct sky2_port *osky2 = netdev_priv(otherdev); u16 cmd; - pci_read_config_word(hw->pdev, cap + PCI_X_CMD, &cmd); + cmd = sky2_pci_read16(hw, cap + PCI_X_CMD); cmd &= ~PCI_X_CMD_MAX_SPLIT; - pci_write_config_word(hw->pdev, cap + PCI_X_CMD, cmd); + sky2_pci_write16(hw, cap + PCI_X_CMD, cmd); - sky2->rx_csum = 0; - osky2->rx_csum = 0; } if (netif_msg_ifup(sky2)) @@ -2037,6 +2044,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) err = sky2_rx_start(sky2); sky2_write32(hw, B0_IMSK, imask); + sky2_read32(hw, B0_Y2_SP_LISR); napi_enable(&hw->napi); if (err) @@ -2426,37 +2434,26 @@ static void sky2_hw_intr(struct sky2_hw *hw) if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) { u16 pci_err; - pci_read_config_word(pdev, PCI_STATUS, &pci_err); + pci_err = sky2_pci_read16(hw, PCI_STATUS); if (net_ratelimit()) dev_err(&pdev->dev, "PCI hardware error (0x%x)\n", pci_err); - pci_write_config_word(pdev, PCI_STATUS, + sky2_pci_write16(hw, PCI_STATUS, pci_err | PCI_STATUS_ERROR_BITS); } if (status & Y2_IS_PCI_EXP) { /* PCI-Express uncorrectable Error occurred */ - int aer = pci_find_aer_capability(hw->pdev); u32 err; - if (aer) { - pci_read_config_dword(pdev, aer + PCI_ERR_UNCOR_STATUS, - &err); - pci_cleanup_aer_uncorrect_error_status(pdev); - } else { - /* Either AER not configured, or not working - * because of bad MMCONFIG, so just do recover - * manually. - */ - err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); - sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, - 0xfffffffful); - } - + err = sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); + sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, + 0xfffffffful); if (net_ratelimit()) dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err); + sky2_read32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS); } if (status & Y2_HWE_L1_MASK) @@ -2703,13 +2700,10 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) static int __devinit sky2_init(struct sky2_hw *hw) { - int rc; u8 t8; /* Enable all clocks and check for bad PCI access */ - rc = pci_write_config_dword(hw->pdev, PCI_DEV_REG3, 0); - if (rc) - return rc; + sky2_pci_write32(hw, PCI_DEV_REG3, 0); sky2_write8(hw, B0_CTST, CS_RST_CLR); @@ -2806,32 +2800,21 @@ static void sky2_reset(struct sky2_hw *hw) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); /* clear PCI errors, if any */ - pci_read_config_word(pdev, PCI_STATUS, &status); + status = sky2_pci_read16(hw, PCI_STATUS); status |= PCI_STATUS_ERROR_BITS; - pci_write_config_word(pdev, PCI_STATUS, status); + sky2_pci_write16(hw, PCI_STATUS, status); sky2_write8(hw, B0_CTST, CS_MRST_CLR); cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); if (cap) { - if (pci_find_aer_capability(pdev)) { - /* Check for advanced error reporting */ - pci_cleanup_aer_uncorrect_error_status(pdev); - pci_cleanup_aer_correct_error_status(pdev); - } else { - dev_warn(&pdev->dev, - "PCI Express Advanced Error Reporting" - " not configured or MMCONFIG problem?\n"); - - sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, - 0xfffffffful); - } + sky2_write32(hw, Y2_CFG_AER + PCI_ERR_UNCOR_STATUS, + 0xfffffffful); /* If error bit is stuck on ignore it */ if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP) dev_info(&pdev->dev, "ignoring stuck error report bit\n"); - - else if (pci_enable_pcie_error_reporting(pdev)) + else hwe_mask |= Y2_IS_PCI_EXP; } @@ -2930,16 +2913,14 @@ static void sky2_restart(struct work_struct *work) int i, err; rtnl_lock(); - sky2_write32(hw, B0_IMSK, 0); - sky2_read32(hw, B0_IMSK); - napi_disable(&hw->napi); - for (i = 0; i < hw->ports; i++) { dev = hw->dev[i]; if (netif_running(dev)) sky2_down(dev); } + napi_disable(&hw->napi); + sky2_write32(hw, B0_IMSK, 0); sky2_reset(hw); sky2_write32(hw, B0_IMSK, Y2_IS_BASE); napi_enable(&hw->napi); @@ -3672,32 +3653,33 @@ static int sky2_set_tso(struct net_device *dev, u32 data) static int sky2_get_eeprom_len(struct net_device *dev) { struct sky2_port *sky2 = netdev_priv(dev); + struct sky2_hw *hw = sky2->hw; u16 reg2; - pci_read_config_word(sky2->hw->pdev, PCI_DEV_REG2, ®2); + reg2 = sky2_pci_read16(hw, PCI_DEV_REG2); return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8); } -static u32 sky2_vpd_read(struct pci_dev *pdev, int cap, u16 offset) +static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset) { u32 val; - pci_write_config_word(pdev, cap + PCI_VPD_ADDR, offset); + sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset); do { - pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset); + offset = sky2_pci_read16(hw, cap + PCI_VPD_ADDR); } while (!(offset & PCI_VPD_ADDR_F)); - pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &val); + val = sky2_pci_read32(hw, cap + PCI_VPD_DATA); return val; } -static void sky2_vpd_write(struct pci_dev *pdev, int cap, u16 offset, u32 val) +static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val) { - pci_write_config_word(pdev, cap + PCI_VPD_DATA, val); - pci_write_config_dword(pdev, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F); + sky2_pci_write16(hw, cap + PCI_VPD_DATA, val); + sky2_pci_write32(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F); do { - pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset); + offset = sky2_pci_read16(hw, cap + PCI_VPD_ADDR); } while (offset & PCI_VPD_ADDR_F); } @@ -3715,7 +3697,7 @@ static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom eeprom->magic = SKY2_EEPROM_MAGIC; while (length > 0) { - u32 val = sky2_vpd_read(sky2->hw->pdev, cap, offset); + u32 val = sky2_vpd_read(sky2->hw, cap, offset); int n = min_t(int, length, sizeof(val)); memcpy(data, &val, n); @@ -3745,10 +3727,10 @@ static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom int n = min_t(int, length, sizeof(val)); if (n < sizeof(val)) - val = sky2_vpd_read(sky2->hw->pdev, cap, offset); + val = sky2_vpd_read(sky2->hw, cap, offset); memcpy(&val, data, n); - sky2_vpd_write(sky2->hw->pdev, cap, offset, val); + sky2_vpd_write(sky2->hw, cap, offset, val); length -= n; data += n; @@ -3881,6 +3863,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); + sky2_read32(hw, B0_Y2_SP_LISR); napi_enable(&hw->napi); return 0; } @@ -4013,7 +3996,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->duplex = -1; sky2->speed = -1; sky2->advertising = sky2_supported_modes(hw); - sky2->rx_csum = 1; + sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL); sky2->wol = wol; spin_lock_init(&sky2->phy_lock); @@ -4184,9 +4167,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, */ { u32 reg; - pci_read_config_dword(pdev,PCI_DEV_REG2, ®); + reg = sky2_pci_read32(hw, PCI_DEV_REG2); reg &= ~PCI_REV_DESC; - pci_write_config_dword(pdev, PCI_DEV_REG2, reg); + sky2_pci_write32(hw, PCI_DEV_REG2, reg); } #endif @@ -4377,7 +4360,7 @@ static int sky2_resume(struct pci_dev *pdev) if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_FE_P) - pci_write_config_dword(pdev, PCI_DEV_REG3, 0); + sky2_pci_write32(hw, PCI_DEV_REG3, 0); sky2_reset(hw); sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |