mirror of https://gitee.com/openkylin/linux.git
ixgbe: add device support for 82598AT (copper 10GbE) adapters
Intel is currently shipping support for adapters with a phy that does 10GBase-T (copper), which is 10 Gigabit ethernet over standard Category 6 cabling. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
parent
e053b628d3
commit
0befdb3e0a
|
@ -267,6 +267,7 @@ struct ixgbe_adapter {
|
||||||
#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
|
#define IXGBE_FLAG_RSS_CAPABLE (u32)(1 << 17)
|
||||||
#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
|
#define IXGBE_FLAG_VMDQ_CAPABLE (u32)(1 << 18)
|
||||||
#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
|
#define IXGBE_FLAG_VMDQ_ENABLED (u32)(1 << 19)
|
||||||
|
#define IXGBE_FLAG_FAN_FAIL_CAPABLE (u32)(1 << 20)
|
||||||
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
|
#define IXGBE_FLAG_NEED_LINK_UPDATE (u32)(1 << 22)
|
||||||
#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
|
#define IXGBE_FLAG_IN_WATCHDOG_TASK (u32)(1 << 23)
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,11 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
|
||||||
|
|
||||||
/* PHY Init */
|
/* PHY Init */
|
||||||
switch (phy->type) {
|
switch (phy->type) {
|
||||||
|
case ixgbe_phy_tn:
|
||||||
|
phy->ops.check_link = &ixgbe_check_phy_link_tnx;
|
||||||
|
phy->ops.get_firmware_version =
|
||||||
|
&ixgbe_get_phy_firmware_version_tnx;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -189,6 +194,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
|
||||||
case IXGBE_DEV_ID_82598EB_XF_LR:
|
case IXGBE_DEV_ID_82598EB_XF_LR:
|
||||||
media_type = ixgbe_media_type_fiber;
|
media_type = ixgbe_media_type_fiber;
|
||||||
break;
|
break;
|
||||||
|
case IXGBE_DEV_ID_82598AT:
|
||||||
|
media_type = ixgbe_media_type_copper;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
media_type = ixgbe_media_type_unknown;
|
media_type = ixgbe_media_type_unknown;
|
||||||
break;
|
break;
|
||||||
|
@ -872,6 +880,10 @@ s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
|
||||||
case IXGBE_DEV_ID_82598EB_XF_LR:
|
case IXGBE_DEV_ID_82598EB_XF_LR:
|
||||||
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
|
physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
|
||||||
break;
|
break;
|
||||||
|
case IXGBE_DEV_ID_82598AT:
|
||||||
|
physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
|
||||||
|
IXGBE_PHYSICAL_LAYER_1000BASE_T);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
|
physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
|
||||||
|
|
|
@ -149,6 +149,8 @@ static int ixgbe_set_settings(struct net_device *netdev,
|
||||||
{
|
{
|
||||||
struct ixgbe_adapter *adapter = netdev_priv(netdev);
|
struct ixgbe_adapter *adapter = netdev_priv(netdev);
|
||||||
struct ixgbe_hw *hw = &adapter->hw;
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
|
u32 advertised, old;
|
||||||
|
s32 err;
|
||||||
|
|
||||||
switch (hw->phy.media_type) {
|
switch (hw->phy.media_type) {
|
||||||
case ixgbe_media_type_fiber:
|
case ixgbe_media_type_fiber:
|
||||||
|
@ -157,6 +159,31 @@ static int ixgbe_set_settings(struct net_device *netdev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
/* in this case we currently only support 10Gb/FULL */
|
/* in this case we currently only support 10Gb/FULL */
|
||||||
break;
|
break;
|
||||||
|
case ixgbe_media_type_copper:
|
||||||
|
/* 10000/copper and 1000/copper must autoneg
|
||||||
|
* this function does not support any duplex forcing, but can
|
||||||
|
* limit the advertising of the adapter to only 10000 or 1000 */
|
||||||
|
if (ecmd->autoneg == AUTONEG_DISABLE)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
old = hw->phy.autoneg_advertised;
|
||||||
|
advertised = 0;
|
||||||
|
if (ecmd->advertising & ADVERTISED_10000baseT_Full)
|
||||||
|
advertised |= IXGBE_LINK_SPEED_10GB_FULL;
|
||||||
|
|
||||||
|
if (ecmd->advertising & ADVERTISED_1000baseT_Full)
|
||||||
|
advertised |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||||
|
|
||||||
|
if (old == advertised)
|
||||||
|
break;
|
||||||
|
/* this sets the link speed and restarts auto-neg */
|
||||||
|
err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
|
||||||
|
if (err) {
|
||||||
|
DPRINTK(PROBE, INFO,
|
||||||
|
"setup link failed with code %d\n", err);
|
||||||
|
hw->mac.ops.setup_link_speed(hw, old, true, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
|
||||||
board_82598 },
|
board_82598 },
|
||||||
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
|
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT),
|
||||||
board_82598 },
|
board_82598 },
|
||||||
|
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT),
|
||||||
|
board_82598 },
|
||||||
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
|
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
|
||||||
board_82598 },
|
board_82598 },
|
||||||
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
|
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
|
||||||
|
@ -904,6 +906,17 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
|
||||||
|
{
|
||||||
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
|
|
||||||
|
if ((adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) &&
|
||||||
|
(eicr & IXGBE_EICR_GPI_SDP1)) {
|
||||||
|
DPRINTK(PROBE, CRIT, "Fan has stopped, replace the adapter\n");
|
||||||
|
/* write to clear the interrupt */
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
|
static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
|
||||||
{
|
{
|
||||||
|
@ -928,6 +941,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
|
||||||
if (eicr & IXGBE_EICR_LSC)
|
if (eicr & IXGBE_EICR_LSC)
|
||||||
ixgbe_check_lsc(adapter);
|
ixgbe_check_lsc(adapter);
|
||||||
|
|
||||||
|
ixgbe_check_fan_failure(adapter, eicr);
|
||||||
|
|
||||||
if (!test_bit(__IXGBE_DOWN, &adapter->state))
|
if (!test_bit(__IXGBE_DOWN, &adapter->state))
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
|
IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
|
||||||
|
|
||||||
|
@ -1316,6 +1331,8 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
|
||||||
if (eicr & IXGBE_EICR_LSC)
|
if (eicr & IXGBE_EICR_LSC)
|
||||||
ixgbe_check_lsc(adapter);
|
ixgbe_check_lsc(adapter);
|
||||||
|
|
||||||
|
ixgbe_check_fan_failure(adapter, eicr);
|
||||||
|
|
||||||
if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
|
if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
|
||||||
adapter->tx_ring[0].total_packets = 0;
|
adapter->tx_ring[0].total_packets = 0;
|
||||||
adapter->tx_ring[0].total_bytes = 0;
|
adapter->tx_ring[0].total_bytes = 0;
|
||||||
|
@ -1418,6 +1435,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
|
||||||
{
|
{
|
||||||
u32 mask;
|
u32 mask;
|
||||||
mask = IXGBE_EIMS_ENABLE_MASK;
|
mask = IXGBE_EIMS_ENABLE_MASK;
|
||||||
|
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
|
||||||
|
mask |= IXGBE_EIMS_GPI_SDP1;
|
||||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
|
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
|
||||||
IXGBE_WRITE_FLUSH(&adapter->hw);
|
IXGBE_WRITE_FLUSH(&adapter->hw);
|
||||||
}
|
}
|
||||||
|
@ -1927,6 +1946,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
|
IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enable fan failure interrupt if media type is copper */
|
||||||
|
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
|
||||||
|
gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
|
||||||
|
gpie |= IXGBE_SDP1_GPIEN;
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
|
||||||
|
}
|
||||||
|
|
||||||
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
|
mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
|
||||||
if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
|
if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
|
||||||
mhadd &= ~IXGBE_MHADD_MFS_MASK;
|
mhadd &= ~IXGBE_MHADD_MFS_MASK;
|
||||||
|
@ -2564,6 +2590,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
|
||||||
rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
|
rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
|
||||||
adapter->ring_feature[RING_F_RSS].indices = rss;
|
adapter->ring_feature[RING_F_RSS].indices = rss;
|
||||||
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
|
adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
|
||||||
|
if (hw->mac.ops.get_media_type &&
|
||||||
|
(hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper))
|
||||||
|
adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
|
||||||
|
|
||||||
/* default flow control settings */
|
/* default flow control settings */
|
||||||
hw->fc.original_type = ixgbe_fc_none;
|
hw->fc.original_type = ixgbe_fc_none;
|
||||||
|
@ -3691,6 +3720,10 @@ static int ixgbe_link_config(struct ixgbe_hw *hw)
|
||||||
/* must always autoneg for both 1G and 10G link */
|
/* must always autoneg for both 1G and 10G link */
|
||||||
hw->mac.autoneg = true;
|
hw->mac.autoneg = true;
|
||||||
|
|
||||||
|
if ((hw->mac.type == ixgbe_mac_82598EB) &&
|
||||||
|
(hw->phy.media_type == ixgbe_media_type_copper))
|
||||||
|
autoneg = IXGBE_LINK_SPEED_82598_AUTONEG;
|
||||||
|
|
||||||
return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
|
return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,9 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
|
||||||
enum ixgbe_phy_type phy_type;
|
enum ixgbe_phy_type phy_type;
|
||||||
|
|
||||||
switch (phy_id) {
|
switch (phy_id) {
|
||||||
|
case TN1010_PHY_ID:
|
||||||
|
phy_type = ixgbe_phy_tn;
|
||||||
|
break;
|
||||||
case QT2022_PHY_ID:
|
case QT2022_PHY_ID:
|
||||||
phy_type = ixgbe_phy_qt;
|
phy_type = ixgbe_phy_qt;
|
||||||
break;
|
break;
|
||||||
|
@ -426,3 +429,68 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_check_phy_link_tnx - Determine link and speed status
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
*
|
||||||
|
* Reads the VS1 register to determine if link is up and the current speed for
|
||||||
|
* the PHY.
|
||||||
|
**/
|
||||||
|
s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
|
||||||
|
bool *link_up)
|
||||||
|
{
|
||||||
|
s32 status = 0;
|
||||||
|
u32 time_out;
|
||||||
|
u32 max_time_out = 10;
|
||||||
|
u16 phy_link = 0;
|
||||||
|
u16 phy_speed = 0;
|
||||||
|
u16 phy_data = 0;
|
||||||
|
|
||||||
|
/* Initialize speed and link to default case */
|
||||||
|
*link_up = false;
|
||||||
|
*speed = IXGBE_LINK_SPEED_10GB_FULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check current speed and link status of the PHY register.
|
||||||
|
* This is a vendor specific register and may have to
|
||||||
|
* be changed for other copper PHYs.
|
||||||
|
*/
|
||||||
|
for (time_out = 0; time_out < max_time_out; time_out++) {
|
||||||
|
udelay(10);
|
||||||
|
status = hw->phy.ops.read_reg(hw,
|
||||||
|
IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
|
||||||
|
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
|
||||||
|
&phy_data);
|
||||||
|
phy_link = phy_data &
|
||||||
|
IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
|
||||||
|
phy_speed = phy_data &
|
||||||
|
IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
|
||||||
|
if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
|
||||||
|
*link_up = true;
|
||||||
|
if (phy_speed ==
|
||||||
|
IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
|
||||||
|
*speed = IXGBE_LINK_SPEED_1GB_FULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_get_phy_firmware_version_tnx - Gets the PHY Firmware Version
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @firmware_version: pointer to the PHY Firmware Version
|
||||||
|
**/
|
||||||
|
s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
|
||||||
|
u16 *firmware_version)
|
||||||
|
{
|
||||||
|
s32 status = 0;
|
||||||
|
|
||||||
|
status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
|
||||||
|
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
|
||||||
|
firmware_version);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,4 +77,11 @@ s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
|
||||||
bool autoneg,
|
bool autoneg,
|
||||||
bool autoneg_wait_to_complete);
|
bool autoneg_wait_to_complete);
|
||||||
|
|
||||||
|
/* PHY specific */
|
||||||
|
s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw,
|
||||||
|
ixgbe_link_speed *speed,
|
||||||
|
bool *link_up);
|
||||||
|
s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
|
||||||
|
u16 *firmware_version);
|
||||||
|
|
||||||
#endif /* _IXGBE_PHY_H_ */
|
#endif /* _IXGBE_PHY_H_ */
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
/* Device IDs */
|
/* Device IDs */
|
||||||
#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
|
#define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6
|
||||||
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
|
#define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
|
||||||
|
#define IXGBE_DEV_ID_82598AT 0x10C8
|
||||||
#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
|
#define IXGBE_DEV_ID_82598EB_CX4 0x10DD
|
||||||
#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
|
#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
|
||||||
#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
|
#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
|
||||||
|
@ -488,6 +489,8 @@
|
||||||
#define IXGBE_MAX_PHY_ADDR 32
|
#define IXGBE_MAX_PHY_ADDR 32
|
||||||
|
|
||||||
/* PHY IDs*/
|
/* PHY IDs*/
|
||||||
|
#define TN1010_PHY_ID 0x00A19410
|
||||||
|
#define TNX_FW_REV 0xB
|
||||||
#define QT2022_PHY_ID 0x0043A400
|
#define QT2022_PHY_ID 0x0043A400
|
||||||
|
|
||||||
/* PHY Types */
|
/* PHY Types */
|
||||||
|
@ -1202,6 +1205,7 @@ enum ixgbe_mac_type {
|
||||||
|
|
||||||
enum ixgbe_phy_type {
|
enum ixgbe_phy_type {
|
||||||
ixgbe_phy_unknown = 0,
|
ixgbe_phy_unknown = 0,
|
||||||
|
ixgbe_phy_tn,
|
||||||
ixgbe_phy_qt,
|
ixgbe_phy_qt,
|
||||||
ixgbe_phy_xaui,
|
ixgbe_phy_xaui,
|
||||||
ixgbe_phy_tw_tyco,
|
ixgbe_phy_tw_tyco,
|
||||||
|
@ -1396,6 +1400,8 @@ struct ixgbe_phy_operations {
|
||||||
s32 (*setup_link)(struct ixgbe_hw *);
|
s32 (*setup_link)(struct ixgbe_hw *);
|
||||||
s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
|
s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
|
||||||
bool);
|
bool);
|
||||||
|
s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *);
|
||||||
|
s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
|
||||||
s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
|
s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
|
||||||
s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
|
s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
|
||||||
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
|
s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
|
||||||
|
|
Loading…
Reference in New Issue