Loading drivers/net/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -2519,6 +2519,7 @@ config ENIC config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI && INET select MDIO ---help--- This driver supports Intel(R) 10GbE PCI Express family of adapters. For more information on how to identify your adapter, go Loading drivers/net/ixgbe/ixgbe_82598.c +16 −17 Original line number Diff line number Diff line Loading @@ -229,14 +229,13 @@ static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, &speed_ability); if (status == 0) { if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) if (speed_ability & MDIO_SPEED_10G) *speed |= IXGBE_LINK_SPEED_10GB_FULL; if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) if (speed_ability & MDIO_PMA_SPEED_1000) *speed |= IXGBE_LINK_SPEED_1GB_FULL; } Loading Loading @@ -526,9 +525,9 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, * clear indicates active; set indicates inactive. */ if (hw->phy.type == ixgbe_phy_nl) { hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD, &adapt_comp_reg); if (link_up_wait_to_complete) { for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { Loading @@ -541,10 +540,10 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, } msleep(100); hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, MDIO_MMD_PMAPMD, &adapt_comp_reg); } } else { Loading Loading @@ -990,14 +989,14 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK); hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, IXGBE_MDIO_PMA_PMD_DEV_TYPE, MDIO_MMD_PMAPMD, sfp_addr); /* Poll status */ for (i = 0; i < 100; i++) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT, IXGBE_MDIO_PMA_PMD_DEV_TYPE, MDIO_MMD_PMAPMD, &sfp_stat); sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) Loading @@ -1013,7 +1012,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, /* Read data */ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data); MDIO_MMD_PMAPMD, &sfp_data); *eeprom_data = (u8)(sfp_data >> 8); } else { Loading Loading @@ -1045,13 +1044,13 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ if (hw->phy.type == ixgbe_phy_tn || hw->phy.type == ixgbe_phy_cu_unknown) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, &ext_ability); if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_1000BT) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; } Loading drivers/net/ixgbe/ixgbe_82599.c +8 −9 Original line number Diff line number Diff line Loading @@ -314,14 +314,13 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, &speed_ability); if (status == 0) { if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) if (speed_ability & MDIO_SPEED_10G) *speed |= IXGBE_LINK_SPEED_10GB_FULL; if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) if (speed_ability & MDIO_PMA_SPEED_1000) *speed |= IXGBE_LINK_SPEED_1GB_FULL; } Loading Loading @@ -1153,13 +1152,13 @@ u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_tn || hw->phy.type == ixgbe_phy_cu_unknown) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, &ext_ability); if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_1000BT) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; } Loading drivers/net/ixgbe/ixgbe_main.c +42 −0 Original line number Diff line number Diff line Loading @@ -4642,6 +4642,40 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p) return 0; } static int ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; u16 value; int rc; if (prtad != hw->phy.mdio.prtad) return -EINVAL; rc = hw->phy.ops.read_reg(hw, addr, devad, &value); if (!rc) rc = value; return rc; } static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad, u16 addr, u16 value) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; if (prtad != hw->phy.mdio.prtad) return -EINVAL; return hw->phy.ops.write_reg(hw, addr, devad, value); } static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) { struct ixgbe_adapter *adapter = netdev_priv(netdev); return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); } #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs Loading Loading @@ -4675,6 +4709,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_vlan_rx_register = ixgbe_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, .ndo_do_ioctl = ixgbe_ioctl, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif Loading Loading @@ -4789,6 +4824,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* PHY */ memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops)); hw->phy.sfp_type = ixgbe_sfp_type_unknown; /* ixgbe_identify_phy_generic will set prtad and mmds properly */ hw->phy.mdio.prtad = MDIO_PRTAD_NONE; hw->phy.mdio.mmds = 0; hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; hw->phy.mdio.dev = netdev; hw->phy.mdio.mdio_read = ixgbe_mdio_read; hw->phy.mdio.mdio_write = ixgbe_mdio_write; /* set up this timer and work struct before calling get_invariants * which might start the timer Loading drivers/net/ixgbe/ixgbe_phy.c +32 −63 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); static bool ixgbe_get_i2c_data(u32 *i2cctl); static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); Loading @@ -61,8 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { if (ixgbe_validate_phy_addr(hw, phy_addr)) { hw->phy.addr = phy_addr; if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { ixgbe_get_phy_id(hw); hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); Loading @@ -77,26 +75,6 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) return status; } /** * ixgbe_validate_phy_addr - Determines phy address is valid * @hw: pointer to hardware structure * **/ static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) { u16 phy_id = 0; bool valid = false; hw->phy.addr = phy_addr; hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); if (phy_id != 0xFFFF && phy_id != 0x0) valid = true; return valid; } /** * ixgbe_get_phy_id - Get the phy type * @hw: pointer to hardware structure Loading @@ -108,14 +86,12 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) u16 phy_id_high = 0; u16 phy_id_low = 0; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD, &phy_id_high); if (status == 0) { hw->phy.id = (u32)(phy_id_high << 16); status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD, &phy_id_low); hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); Loading Loading @@ -160,9 +136,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, IXGBE_MDIO_PHY_XS_RESET); return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, MDIO_CTRL1_RESET); } /** Loading Loading @@ -192,7 +167,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -223,7 +198,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -292,7 +268,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -323,7 +299,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -365,7 +342,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) s32 status = IXGBE_NOT_IMPLEMENTED; u32 time_out; u32 max_time_out = 10; u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; u16 autoneg_reg; /* * Set advertisement settings in PHY based on autoneg_advertised Loading @@ -373,36 +350,31 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) * tnx devices cannot be "forced" to a autoneg 10G and fail. But can * for a 1G. */ hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg); if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */ autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; else autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg); /* Restart PHY autonegotiation and wait for completion */ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg); autoneg_reg |= IXGBE_MII_RESTART; autoneg_reg |= MDIO_AN_CTRL1_RESTART; hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg); /* Wait for autonegotiation to finish */ for (time_out = 0; time_out < max_time_out; time_out++) { udelay(10); /* Restart PHY autonegotiation and wait for completion */ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, &autoneg_reg); autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE; if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) { autoneg_reg &= MDIO_AN_STAT1_COMPLETE; if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) { status = 0; break; } Loading Loading @@ -457,23 +429,21 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) s32 ret_val = 0; u32 i; hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data); /* reset the PHY and poll for completion */ hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, (phy_data | IXGBE_MDIO_PHY_XS_RESET)); hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, (phy_data | MDIO_CTRL1_RESET)); for (i = 0; i < 100; i++) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0) hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data); if ((phy_data & MDIO_CTRL1_RESET) == 0) break; msleep(10); } if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) { if ((phy_data & MDIO_CTRL1_RESET) != 0) { hw_dbg(hw, "PHY reset did not complete.\n"); ret_val = IXGBE_ERR_PHY; goto out; Loading Loading @@ -509,7 +479,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) for (i = 0; i < edata; i++) { hw->eeprom.ops.read(hw, data_offset, &eword); hw->phy.ops.write_reg(hw, phy_offset, IXGBE_TWINAX_DEV, eword); MDIO_MMD_PMAPMD, eword); hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword, phy_offset); data_offset++; Loading Loading @@ -1302,7 +1272,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, udelay(10); status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, MDIO_MMD_VEND1, &phy_data); phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; Loading Loading @@ -1330,8 +1300,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, { s32 status = 0; status = hw->phy.ops.read_reg(hw, TNX_FW_REV, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1, firmware_version); return status; Loading Loading
drivers/net/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -2519,6 +2519,7 @@ config ENIC config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI && INET select MDIO ---help--- This driver supports Intel(R) 10GbE PCI Express family of adapters. For more information on how to identify your adapter, go Loading
drivers/net/ixgbe/ixgbe_82598.c +16 −17 Original line number Diff line number Diff line Loading @@ -229,14 +229,13 @@ static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, &speed_ability); if (status == 0) { if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) if (speed_ability & MDIO_SPEED_10G) *speed |= IXGBE_LINK_SPEED_10GB_FULL; if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) if (speed_ability & MDIO_PMA_SPEED_1000) *speed |= IXGBE_LINK_SPEED_1GB_FULL; } Loading Loading @@ -526,9 +525,9 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, * clear indicates active; set indicates inactive. */ if (hw->phy.type == ixgbe_phy_nl) { hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD, &adapt_comp_reg); if (link_up_wait_to_complete) { for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { Loading @@ -541,10 +540,10 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, } msleep(100); hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, MDIO_MMD_PMAPMD, &link_reg); hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV, MDIO_MMD_PMAPMD, &adapt_comp_reg); } } else { Loading Loading @@ -990,14 +989,14 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK); hw->phy.ops.write_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, IXGBE_MDIO_PMA_PMD_DEV_TYPE, MDIO_MMD_PMAPMD, sfp_addr); /* Poll status */ for (i = 0; i < 100; i++) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT, IXGBE_MDIO_PMA_PMD_DEV_TYPE, MDIO_MMD_PMAPMD, &sfp_stat); sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK; if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS) Loading @@ -1013,7 +1012,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, /* Read data */ hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data); MDIO_MMD_PMAPMD, &sfp_data); *eeprom_data = (u8)(sfp_data >> 8); } else { Loading Loading @@ -1045,13 +1044,13 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) * physical layer because 10GBase-T PHYs use LMS = KX4/KX */ if (hw->phy.type == ixgbe_phy_tn || hw->phy.type == ixgbe_phy_cu_unknown) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, &ext_ability); if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_1000BT) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; } Loading
drivers/net/ixgbe/ixgbe_82599.c +8 −9 Original line number Diff line number Diff line Loading @@ -314,14 +314,13 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD, &speed_ability); if (status == 0) { if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) if (speed_ability & MDIO_SPEED_10G) *speed |= IXGBE_LINK_SPEED_10GB_FULL; if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G) if (speed_ability & MDIO_PMA_SPEED_1000) *speed |= IXGBE_LINK_SPEED_1GB_FULL; } Loading Loading @@ -1153,13 +1152,13 @@ u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_tn || hw->phy.type == ixgbe_phy_cu_unknown) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_EXT_ABILITY, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &ext_ability); if (ext_ability & IXGBE_MDIO_PHY_10GBASET_ABILITY) hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD, &ext_ability); if (ext_ability & MDIO_PMA_EXTABLE_10GBT) physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T; if (ext_ability & IXGBE_MDIO_PHY_1000BASET_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_1000BT) physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T; if (ext_ability & IXGBE_MDIO_PHY_100BASETX_ABILITY) if (ext_ability & MDIO_PMA_EXTABLE_100BTX) physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX; goto out; } Loading
drivers/net/ixgbe/ixgbe_main.c +42 −0 Original line number Diff line number Diff line Loading @@ -4642,6 +4642,40 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p) return 0; } static int ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; u16 value; int rc; if (prtad != hw->phy.mdio.prtad) return -EINVAL; rc = hw->phy.ops.read_reg(hw, addr, devad, &value); if (!rc) rc = value; return rc; } static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad, u16 addr, u16 value) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; if (prtad != hw->phy.mdio.prtad) return -EINVAL; return hw->phy.ops.write_reg(hw, addr, devad, value); } static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) { struct ixgbe_adapter *adapter = netdev_priv(netdev); return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); } #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs Loading Loading @@ -4675,6 +4709,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_vlan_rx_register = ixgbe_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, .ndo_do_ioctl = ixgbe_ioctl, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif Loading Loading @@ -4789,6 +4824,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* PHY */ memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops)); hw->phy.sfp_type = ixgbe_sfp_type_unknown; /* ixgbe_identify_phy_generic will set prtad and mmds properly */ hw->phy.mdio.prtad = MDIO_PRTAD_NONE; hw->phy.mdio.mmds = 0; hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; hw->phy.mdio.dev = netdev; hw->phy.mdio.mdio_read = ixgbe_mdio_read; hw->phy.mdio.mdio_write = ixgbe_mdio_write; /* set up this timer and work struct before calling get_invariants * which might start the timer Loading
drivers/net/ixgbe/ixgbe_phy.c +32 −63 Original line number Diff line number Diff line Loading @@ -44,7 +44,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl); static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data); static bool ixgbe_get_i2c_data(u32 *i2cctl); static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw); static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); Loading @@ -61,8 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { if (ixgbe_validate_phy_addr(hw, phy_addr)) { hw->phy.addr = phy_addr; if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) { ixgbe_get_phy_id(hw); hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); Loading @@ -77,26 +75,6 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) return status; } /** * ixgbe_validate_phy_addr - Determines phy address is valid * @hw: pointer to hardware structure * **/ static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) { u16 phy_id = 0; bool valid = false; hw->phy.addr = phy_addr; hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); if (phy_id != 0xFFFF && phy_id != 0x0) valid = true; return valid; } /** * ixgbe_get_phy_id - Get the phy type * @hw: pointer to hardware structure Loading @@ -108,14 +86,12 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) u16 phy_id_high = 0; u16 phy_id_low = 0; status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD, &phy_id_high); if (status == 0) { hw->phy.id = (u32)(phy_id_high << 16); status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, IXGBE_MDIO_PMA_PMD_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD, &phy_id_low); hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); Loading Loading @@ -160,9 +136,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, IXGBE_MDIO_PHY_XS_RESET); return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, MDIO_CTRL1_RESET); } /** Loading Loading @@ -192,7 +167,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -223,7 +198,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -292,7 +268,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -323,7 +299,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) | (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); Loading Loading @@ -365,7 +342,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) s32 status = IXGBE_NOT_IMPLEMENTED; u32 time_out; u32 max_time_out = 10; u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; u16 autoneg_reg; /* * Set advertisement settings in PHY based on autoneg_advertised Loading @@ -373,36 +350,31 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) * tnx devices cannot be "forced" to a autoneg 10G and fail. But can * for a 1G. */ hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg); if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */ autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G; else autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */ autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G; hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg); /* Restart PHY autonegotiation and wait for completion */ hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg); autoneg_reg |= IXGBE_MII_RESTART; autoneg_reg |= MDIO_AN_CTRL1_RESTART; hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg); /* Wait for autonegotiation to finish */ for (time_out = 0; time_out < max_time_out; time_out++) { udelay(10); /* Restart PHY autonegotiation and wait for completion */ status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, IXGBE_MDIO_AUTO_NEG_DEV_TYPE, status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN, &autoneg_reg); autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE; if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) { autoneg_reg &= MDIO_AN_STAT1_COMPLETE; if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) { status = 0; break; } Loading Loading @@ -457,23 +429,21 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) s32 ret_val = 0; u32 i; hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data); /* reset the PHY and poll for completion */ hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, (phy_data | IXGBE_MDIO_PHY_XS_RESET)); hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, (phy_data | MDIO_CTRL1_RESET)); for (i = 0; i < 100; i++) { hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data); if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0) hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data); if ((phy_data & MDIO_CTRL1_RESET) == 0) break; msleep(10); } if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) { if ((phy_data & MDIO_CTRL1_RESET) != 0) { hw_dbg(hw, "PHY reset did not complete.\n"); ret_val = IXGBE_ERR_PHY; goto out; Loading Loading @@ -509,7 +479,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw) for (i = 0; i < edata; i++) { hw->eeprom.ops.read(hw, data_offset, &eword); hw->phy.ops.write_reg(hw, phy_offset, IXGBE_TWINAX_DEV, eword); MDIO_MMD_PMAPMD, eword); hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword, phy_offset); data_offset++; Loading Loading @@ -1302,7 +1272,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed, udelay(10); status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, MDIO_MMD_VEND1, &phy_data); phy_link = phy_data & IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; Loading Loading @@ -1330,8 +1300,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw, { s32 status = 0; status = hw->phy.ops.read_reg(hw, TNX_FW_REV, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1, firmware_version); return status; Loading