Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net-next-2.6
This commit is contained in:
commit
bf745e88b7
21 changed files with 619 additions and 331 deletions
|
@ -2109,6 +2109,7 @@ config E1000
|
||||||
config E1000E
|
config E1000E
|
||||||
tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
|
tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
|
||||||
depends on PCI && (!SPARC32 || BROKEN)
|
depends on PCI && (!SPARC32 || BROKEN)
|
||||||
|
select CRC32
|
||||||
---help---
|
---help---
|
||||||
This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
|
This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
|
||||||
ethernet family of adapters. For PCI or PCI-X e1000 adapters,
|
ethernet family of adapters. For PCI or PCI-X e1000 adapters,
|
||||||
|
|
|
@ -110,6 +110,7 @@
|
||||||
/* Management Control */
|
/* Management Control */
|
||||||
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
|
#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */
|
||||||
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
|
#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */
|
||||||
|
#define E1000_MANC_EN_BMC2OS 0x10000000 /* OSBMC is Enabled or not */
|
||||||
/* Enable Neighbor Discovery Filtering */
|
/* Enable Neighbor Discovery Filtering */
|
||||||
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
|
#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
|
||||||
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
|
#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
|
||||||
|
|
|
@ -248,6 +248,10 @@ struct e1000_hw_stats {
|
||||||
u64 scvpc;
|
u64 scvpc;
|
||||||
u64 hrmpc;
|
u64 hrmpc;
|
||||||
u64 doosync;
|
u64 doosync;
|
||||||
|
u64 o2bgptc;
|
||||||
|
u64 o2bspc;
|
||||||
|
u64 b2ospc;
|
||||||
|
u64 b2ogprc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct e1000_phy_stats {
|
struct e1000_phy_stats {
|
||||||
|
|
|
@ -328,4 +328,11 @@
|
||||||
|
|
||||||
/* DMA Coalescing registers */
|
/* DMA Coalescing registers */
|
||||||
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
|
#define E1000_PCIEMISC 0x05BB8 /* PCIE misc config register */
|
||||||
|
|
||||||
|
/* OS2BMC Registers */
|
||||||
|
#define E1000_B2OSPC 0x08FE0 /* BMC2OS packets sent by BMC */
|
||||||
|
#define E1000_B2OGPRC 0x04158 /* BMC2OS packets received by host */
|
||||||
|
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
|
||||||
|
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -86,6 +86,10 @@ static const struct igb_stats igb_gstrings_stats[] = {
|
||||||
IGB_STAT("tx_smbus", stats.mgptc),
|
IGB_STAT("tx_smbus", stats.mgptc),
|
||||||
IGB_STAT("rx_smbus", stats.mgprc),
|
IGB_STAT("rx_smbus", stats.mgprc),
|
||||||
IGB_STAT("dropped_smbus", stats.mgpdc),
|
IGB_STAT("dropped_smbus", stats.mgpdc),
|
||||||
|
IGB_STAT("os2bmc_rx_by_bmc", stats.o2bgptc),
|
||||||
|
IGB_STAT("os2bmc_tx_by_bmc", stats.b2ospc),
|
||||||
|
IGB_STAT("os2bmc_tx_by_host", stats.o2bspc),
|
||||||
|
IGB_STAT("os2bmc_rx_by_host", stats.b2ogprc),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IGB_NETDEV_STAT(_net_stat) { \
|
#define IGB_NETDEV_STAT(_net_stat) { \
|
||||||
|
@ -603,7 +607,10 @@ static void igb_get_regs(struct net_device *netdev,
|
||||||
regs_buff[548] = rd32(E1000_TDFT);
|
regs_buff[548] = rd32(E1000_TDFT);
|
||||||
regs_buff[549] = rd32(E1000_TDFHS);
|
regs_buff[549] = rd32(E1000_TDFHS);
|
||||||
regs_buff[550] = rd32(E1000_TDFPC);
|
regs_buff[550] = rd32(E1000_TDFPC);
|
||||||
|
regs_buff[551] = adapter->stats.o2bgptc;
|
||||||
|
regs_buff[552] = adapter->stats.b2ospc;
|
||||||
|
regs_buff[553] = adapter->stats.o2bspc;
|
||||||
|
regs_buff[554] = adapter->stats.b2ogprc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int igb_get_eeprom_len(struct net_device *netdev)
|
static int igb_get_eeprom_len(struct net_device *netdev)
|
||||||
|
|
|
@ -4560,6 +4560,15 @@ void igb_update_stats(struct igb_adapter *adapter,
|
||||||
adapter->stats.mgptc += rd32(E1000_MGTPTC);
|
adapter->stats.mgptc += rd32(E1000_MGTPTC);
|
||||||
adapter->stats.mgprc += rd32(E1000_MGTPRC);
|
adapter->stats.mgprc += rd32(E1000_MGTPRC);
|
||||||
adapter->stats.mgpdc += rd32(E1000_MGTPDC);
|
adapter->stats.mgpdc += rd32(E1000_MGTPDC);
|
||||||
|
|
||||||
|
/* OS2BMC Stats */
|
||||||
|
reg = rd32(E1000_MANC);
|
||||||
|
if (reg & E1000_MANC_EN_BMC2OS) {
|
||||||
|
adapter->stats.o2bgptc += rd32(E1000_O2BGPTC);
|
||||||
|
adapter->stats.o2bspc += rd32(E1000_O2BSPC);
|
||||||
|
adapter->stats.b2ospc += rd32(E1000_B2OSPC);
|
||||||
|
adapter->stats.b2ogprc += rd32(E1000_B2OGPRC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t igb_msix_other(int irq, void *data)
|
static irqreturn_t igb_msix_other(int irq, void *data)
|
||||||
|
|
|
@ -552,6 +552,8 @@ extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
|
||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
||||||
struct scatterlist *sgl, unsigned int sgc);
|
struct scatterlist *sgl, unsigned int sgc);
|
||||||
|
extern int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
|
||||||
|
struct scatterlist *sgl, unsigned int sgc);
|
||||||
extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
|
extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
|
||||||
extern int ixgbe_fcoe_enable(struct net_device *netdev);
|
extern int ixgbe_fcoe_enable(struct net_device *netdev);
|
||||||
extern int ixgbe_fcoe_disable(struct net_device *netdev);
|
extern int ixgbe_fcoe_disable(struct net_device *netdev);
|
||||||
|
|
|
@ -280,10 +280,22 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
enum ixgbe_media_type media_type;
|
enum ixgbe_media_type media_type;
|
||||||
|
|
||||||
|
/* Detect if there is a copper PHY attached. */
|
||||||
|
switch (hw->phy.type) {
|
||||||
|
case ixgbe_phy_cu_unknown:
|
||||||
|
case ixgbe_phy_tn:
|
||||||
|
case ixgbe_phy_aq:
|
||||||
|
media_type = ixgbe_media_type_copper;
|
||||||
|
goto out;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Media type for I82598 is based on device ID */
|
/* Media type for I82598 is based on device ID */
|
||||||
switch (hw->device_id) {
|
switch (hw->device_id) {
|
||||||
case IXGBE_DEV_ID_82598:
|
case IXGBE_DEV_ID_82598:
|
||||||
case IXGBE_DEV_ID_82598_BX:
|
case IXGBE_DEV_ID_82598_BX:
|
||||||
|
/* Default device ID is mezzanine card KX/KX4 */
|
||||||
media_type = ixgbe_media_type_backplane;
|
media_type = ixgbe_media_type_backplane;
|
||||||
break;
|
break;
|
||||||
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
|
case IXGBE_DEV_ID_82598AF_DUAL_PORT:
|
||||||
|
@ -306,7 +318,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
|
||||||
media_type = ixgbe_media_type_unknown;
|
media_type = ixgbe_media_type_unknown;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
return media_type;
|
return media_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +366,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
|
|
||||||
/* Negotiate the fc mode to use */
|
/* Negotiate the fc mode to use */
|
||||||
ret_val = ixgbe_fc_autoneg(hw);
|
ret_val = ixgbe_fc_autoneg(hw);
|
||||||
if (ret_val)
|
if (ret_val == IXGBE_ERR_FLOW_CONTROL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Disable any previous flow control settings */
|
/* Disable any previous flow control settings */
|
||||||
|
@ -372,10 +384,10 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
* 2: Tx flow control is enabled (we can send pause frames but
|
* 2: Tx flow control is enabled (we can send pause frames but
|
||||||
* we do not support receiving pause frames).
|
* we do not support receiving pause frames).
|
||||||
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
||||||
* other: Invalid.
|
|
||||||
#ifdef CONFIG_DCB
|
#ifdef CONFIG_DCB
|
||||||
* 4: Priority Flow Control is enabled.
|
* 4: Priority Flow Control is enabled.
|
||||||
#endif
|
#endif
|
||||||
|
* other: Invalid.
|
||||||
*/
|
*/
|
||||||
switch (hw->fc.current_mode) {
|
switch (hw->fc.current_mode) {
|
||||||
case ixgbe_fc_none:
|
case ixgbe_fc_none:
|
||||||
|
@ -432,9 +444,10 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
reg = (rx_pba_size - hw->fc.low_water) << 6;
|
reg = (rx_pba_size - hw->fc.low_water) << 6;
|
||||||
if (hw->fc.send_xon)
|
if (hw->fc.send_xon)
|
||||||
reg |= IXGBE_FCRTL_XONE;
|
reg |= IXGBE_FCRTL_XONE;
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg);
|
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), reg);
|
||||||
|
|
||||||
reg = (rx_pba_size - hw->fc.high_water) << 10;
|
reg = (rx_pba_size - hw->fc.high_water) << 6;
|
||||||
reg |= IXGBE_FCRTH_FCEN;
|
reg |= IXGBE_FCRTH_FCEN;
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg);
|
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), reg);
|
||||||
|
@ -632,7 +645,7 @@ out:
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @speed: new link speed
|
* @speed: new link speed
|
||||||
* @autoneg: true if auto-negotiation enabled
|
* @autoneg: true if auto-negotiation enabled
|
||||||
* @autoneg_wait_to_complete: true if waiting is needed to complete
|
* @autoneg_wait_to_complete: true when waiting for completion is needed
|
||||||
*
|
*
|
||||||
* Set the link speed in the AUTOC register and restarts link.
|
* Set the link speed in the AUTOC register and restarts link.
|
||||||
**/
|
**/
|
||||||
|
@ -671,7 +684,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
|
||||||
* ixgbe_hw This will write the AUTOC register based on the new
|
* ixgbe_hw This will write the AUTOC register based on the new
|
||||||
* stored values
|
* stored values
|
||||||
*/
|
*/
|
||||||
status = ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
|
status = ixgbe_start_mac_link_82598(hw,
|
||||||
|
autoneg_wait_to_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -1090,10 +1104,12 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
|
||||||
|
|
||||||
/* Copper PHY must be checked before AUTOC LMS to determine correct
|
/* Copper PHY must be checked before AUTOC LMS to determine correct
|
||||||
* physical layer because 10GBase-T PHYs use LMS = KX4/KX */
|
* physical layer because 10GBase-T PHYs use LMS = KX4/KX */
|
||||||
if (hw->phy.type == ixgbe_phy_tn ||
|
switch (hw->phy.type) {
|
||||||
hw->phy.type == ixgbe_phy_cu_unknown) {
|
case ixgbe_phy_tn:
|
||||||
hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
|
case ixgbe_phy_aq:
|
||||||
&ext_ability);
|
case ixgbe_phy_cu_unknown:
|
||||||
|
hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE,
|
||||||
|
MDIO_MMD_PMAPMD, &ext_ability);
|
||||||
if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
|
if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
|
||||||
physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
|
physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
|
||||||
if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
|
if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
|
||||||
|
@ -1101,6 +1117,8 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
|
||||||
if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
|
if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
|
||||||
physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
|
physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
|
||||||
goto out;
|
goto out;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (autoc & IXGBE_AUTOC_LMS_MASK) {
|
switch (autoc & IXGBE_AUTOC_LMS_MASK) {
|
||||||
|
|
|
@ -470,8 +470,6 @@ static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
|
||||||
**/
|
**/
|
||||||
static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
|
static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
|
|
||||||
|
|
||||||
if (hw->mac.autotry_restart) {
|
if (hw->mac.autotry_restart) {
|
||||||
ixgbe_disable_tx_laser_multispeed_fiber(hw);
|
ixgbe_disable_tx_laser_multispeed_fiber(hw);
|
||||||
ixgbe_enable_tx_laser_multispeed_fiber(hw);
|
ixgbe_enable_tx_laser_multispeed_fiber(hw);
|
||||||
|
@ -494,17 +492,21 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
bool autoneg_wait_to_complete)
|
bool autoneg_wait_to_complete)
|
||||||
{
|
{
|
||||||
s32 status = 0;
|
s32 status = 0;
|
||||||
ixgbe_link_speed phy_link_speed;
|
ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
|
||||||
ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
|
ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
|
||||||
u32 speedcnt = 0;
|
u32 speedcnt = 0;
|
||||||
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
|
u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
|
||||||
|
u32 i = 0;
|
||||||
bool link_up = false;
|
bool link_up = false;
|
||||||
bool negotiation;
|
bool negotiation;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Mask off requested but non-supported speeds */
|
/* Mask off requested but non-supported speeds */
|
||||||
hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
|
status = hw->mac.ops.get_link_capabilities(hw, &link_speed,
|
||||||
speed &= phy_link_speed;
|
&negotiation);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
speed &= link_speed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try each speed one by one, highest priority first. We do this in
|
* Try each speed one by one, highest priority first. We do this in
|
||||||
|
@ -515,9 +517,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
|
highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
|
||||||
|
|
||||||
/* If we already have link at this speed, just jump out */
|
/* If we already have link at this speed, just jump out */
|
||||||
hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
|
status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
|
||||||
|
false);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
|
if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Set the module link speed */
|
/* Set the module link speed */
|
||||||
|
@ -529,9 +534,9 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
msleep(40);
|
msleep(40);
|
||||||
|
|
||||||
status = ixgbe_setup_mac_link_82599(hw,
|
status = ixgbe_setup_mac_link_82599(hw,
|
||||||
IXGBE_LINK_SPEED_10GB_FULL,
|
IXGBE_LINK_SPEED_10GB_FULL,
|
||||||
autoneg,
|
autoneg,
|
||||||
autoneg_wait_to_complete);
|
autoneg_wait_to_complete);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -548,8 +553,11 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
|
||||||
/* If we have link, just jump out */
|
/* If we have link, just jump out */
|
||||||
hw->mac.ops.check_link(hw, &phy_link_speed,
|
status = hw->mac.ops.check_link(hw, &link_speed,
|
||||||
&link_up, false);
|
&link_up, false);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (link_up)
|
if (link_up)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -561,9 +569,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
|
highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
|
||||||
|
|
||||||
/* If we already have link at this speed, just jump out */
|
/* If we already have link at this speed, just jump out */
|
||||||
hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
|
status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
|
||||||
|
false);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
|
if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Set the module link speed */
|
/* Set the module link speed */
|
||||||
|
@ -576,9 +587,9 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
msleep(40);
|
msleep(40);
|
||||||
|
|
||||||
status = ixgbe_setup_mac_link_82599(hw,
|
status = ixgbe_setup_mac_link_82599(hw,
|
||||||
IXGBE_LINK_SPEED_1GB_FULL,
|
IXGBE_LINK_SPEED_1GB_FULL,
|
||||||
autoneg,
|
autoneg,
|
||||||
autoneg_wait_to_complete);
|
autoneg_wait_to_complete);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
@ -589,7 +600,11 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
|
||||||
/* If we have link, just jump out */
|
/* If we have link, just jump out */
|
||||||
hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
|
status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
|
||||||
|
false);
|
||||||
|
if (status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
if (link_up)
|
if (link_up)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -632,13 +647,10 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
|
||||||
bool autoneg_wait_to_complete)
|
bool autoneg_wait_to_complete)
|
||||||
{
|
{
|
||||||
s32 status = 0;
|
s32 status = 0;
|
||||||
ixgbe_link_speed link_speed;
|
ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
|
||||||
s32 i, j;
|
s32 i, j;
|
||||||
bool link_up = false;
|
bool link_up = false;
|
||||||
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||||
struct ixgbe_adapter *adapter = hw->back;
|
|
||||||
|
|
||||||
hw_dbg(hw, "ixgbe_setup_mac_link_smartspeed.\n");
|
|
||||||
|
|
||||||
/* Set autoneg_advertised value based on input link speed */
|
/* Set autoneg_advertised value based on input link speed */
|
||||||
hw->phy.autoneg_advertised = 0;
|
hw->phy.autoneg_advertised = 0;
|
||||||
|
@ -664,7 +676,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
|
||||||
for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
|
for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
|
||||||
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
|
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
|
||||||
autoneg_wait_to_complete);
|
autoneg_wait_to_complete);
|
||||||
if (status)
|
if (status != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -677,8 +689,11 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
|
||||||
mdelay(100);
|
mdelay(100);
|
||||||
|
|
||||||
/* If we have link, just jump out */
|
/* If we have link, just jump out */
|
||||||
hw->mac.ops.check_link(hw, &link_speed,
|
status = hw->mac.ops.check_link(hw, &link_speed,
|
||||||
&link_up, false);
|
&link_up, false);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (link_up)
|
if (link_up)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -696,7 +711,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
|
||||||
hw->phy.smart_speed_active = true;
|
hw->phy.smart_speed_active = true;
|
||||||
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
|
status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
|
||||||
autoneg_wait_to_complete);
|
autoneg_wait_to_complete);
|
||||||
if (status)
|
if (status != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -709,8 +724,11 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
|
||||||
mdelay(100);
|
mdelay(100);
|
||||||
|
|
||||||
/* If we have link, just jump out */
|
/* If we have link, just jump out */
|
||||||
hw->mac.ops.check_link(hw, &link_speed,
|
status = hw->mac.ops.check_link(hw, &link_speed,
|
||||||
&link_up, false);
|
&link_up, false);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (link_up)
|
if (link_up)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -722,7 +740,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
|
if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
|
||||||
e_info(hw, "Smartspeed has downgraded the link speed from "
|
hw_dbg(hw, "Smartspeed has downgraded the link speed from "
|
||||||
"the maximum advertised\n");
|
"the maximum advertised\n");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -754,6 +772,9 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
|
||||||
|
|
||||||
/* Check to see if speed passed in is supported. */
|
/* Check to see if speed passed in is supported. */
|
||||||
hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
|
hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
|
||||||
|
if (status != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
speed &= link_capabilities;
|
speed &= link_capabilities;
|
||||||
|
|
||||||
if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
|
if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
|
||||||
|
@ -883,7 +904,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
|
||||||
|
|
||||||
/* PHY ops must be identified and initialized prior to reset */
|
/* PHY ops must be identified and initialized prior to reset */
|
||||||
|
|
||||||
/* Init PHY and function pointers, perform SFP setup */
|
/* Identify PHY and related function pointers */
|
||||||
status = hw->phy.ops.init(hw);
|
status = hw->phy.ops.init(hw);
|
||||||
|
|
||||||
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
|
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
|
||||||
|
@ -895,6 +916,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
|
||||||
hw->phy.sfp_setup_needed = false;
|
hw->phy.sfp_setup_needed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
|
||||||
|
goto reset_hw_out;
|
||||||
|
|
||||||
/* Reset PHY */
|
/* Reset PHY */
|
||||||
if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
|
if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
|
||||||
hw->phy.ops.reset(hw);
|
hw->phy.ops.reset(hw);
|
||||||
|
@ -2051,28 +2075,28 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
|
static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
|
||||||
.init_params = &ixgbe_init_eeprom_params_generic,
|
.init_params = &ixgbe_init_eeprom_params_generic,
|
||||||
.read = &ixgbe_read_eerd_generic,
|
.read = &ixgbe_read_eerd_generic,
|
||||||
.write = &ixgbe_write_eeprom_generic,
|
.write = &ixgbe_write_eeprom_generic,
|
||||||
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
|
.calc_checksum = &ixgbe_calc_eeprom_checksum_generic,
|
||||||
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
|
.validate_checksum = &ixgbe_validate_eeprom_checksum_generic,
|
||||||
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
|
.update_checksum = &ixgbe_update_eeprom_checksum_generic,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ixgbe_phy_operations phy_ops_82599 = {
|
static struct ixgbe_phy_operations phy_ops_82599 = {
|
||||||
.identify = &ixgbe_identify_phy_82599,
|
.identify = &ixgbe_identify_phy_82599,
|
||||||
.identify_sfp = &ixgbe_identify_sfp_module_generic,
|
.identify_sfp = &ixgbe_identify_sfp_module_generic,
|
||||||
.init = &ixgbe_init_phy_ops_82599,
|
.init = &ixgbe_init_phy_ops_82599,
|
||||||
.reset = &ixgbe_reset_phy_generic,
|
.reset = &ixgbe_reset_phy_generic,
|
||||||
.read_reg = &ixgbe_read_phy_reg_generic,
|
.read_reg = &ixgbe_read_phy_reg_generic,
|
||||||
.write_reg = &ixgbe_write_phy_reg_generic,
|
.write_reg = &ixgbe_write_phy_reg_generic,
|
||||||
.setup_link = &ixgbe_setup_phy_link_generic,
|
.setup_link = &ixgbe_setup_phy_link_generic,
|
||||||
.setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
|
.setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
|
||||||
.read_i2c_byte = &ixgbe_read_i2c_byte_generic,
|
.read_i2c_byte = &ixgbe_read_i2c_byte_generic,
|
||||||
.write_i2c_byte = &ixgbe_write_i2c_byte_generic,
|
.write_i2c_byte = &ixgbe_write_i2c_byte_generic,
|
||||||
.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
|
.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
|
||||||
.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
|
.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
|
||||||
.check_overtemp = &ixgbe_tn_check_overtemp,
|
.check_overtemp = &ixgbe_tn_check_overtemp,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ixgbe_info ixgbe_82599_info = {
|
struct ixgbe_info ixgbe_82599_info = {
|
||||||
|
|
|
@ -47,6 +47,12 @@ static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
|
||||||
static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
|
static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
|
||||||
|
|
||||||
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
|
static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
|
||||||
|
static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw);
|
||||||
|
static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw);
|
||||||
|
static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw);
|
||||||
|
static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
|
||||||
|
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
|
||||||
|
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
|
||||||
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,17 +142,29 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
|
||||||
IXGBE_READ_REG(hw, IXGBE_MRFC);
|
IXGBE_READ_REG(hw, IXGBE_MRFC);
|
||||||
IXGBE_READ_REG(hw, IXGBE_RLEC);
|
IXGBE_READ_REG(hw, IXGBE_RLEC);
|
||||||
IXGBE_READ_REG(hw, IXGBE_LXONTXC);
|
IXGBE_READ_REG(hw, IXGBE_LXONTXC);
|
||||||
IXGBE_READ_REG(hw, IXGBE_LXONRXC);
|
|
||||||
IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
|
IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
|
||||||
IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
|
if (hw->mac.type >= ixgbe_mac_82599EB) {
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
|
||||||
|
} else {
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_LXONRXC);
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
|
IXGBE_READ_REG(hw, IXGBE_PXONTXC(i));
|
||||||
IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
|
|
||||||
IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
|
IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i));
|
||||||
IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
|
if (hw->mac.type >= ixgbe_mac_82599EB) {
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i));
|
||||||
|
} else {
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_PXONRXC(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (hw->mac.type >= ixgbe_mac_82599EB)
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_PXON2OFFCNT(i));
|
||||||
IXGBE_READ_REG(hw, IXGBE_PRC64);
|
IXGBE_READ_REG(hw, IXGBE_PRC64);
|
||||||
IXGBE_READ_REG(hw, IXGBE_PRC127);
|
IXGBE_READ_REG(hw, IXGBE_PRC127);
|
||||||
IXGBE_READ_REG(hw, IXGBE_PRC255);
|
IXGBE_READ_REG(hw, IXGBE_PRC255);
|
||||||
|
@ -184,9 +202,26 @@ s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
|
||||||
IXGBE_READ_REG(hw, IXGBE_BPTC);
|
IXGBE_READ_REG(hw, IXGBE_BPTC);
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
IXGBE_READ_REG(hw, IXGBE_QPRC(i));
|
IXGBE_READ_REG(hw, IXGBE_QPRC(i));
|
||||||
IXGBE_READ_REG(hw, IXGBE_QBRC(i));
|
|
||||||
IXGBE_READ_REG(hw, IXGBE_QPTC(i));
|
IXGBE_READ_REG(hw, IXGBE_QPTC(i));
|
||||||
IXGBE_READ_REG(hw, IXGBE_QBTC(i));
|
if (hw->mac.type >= ixgbe_mac_82599EB) {
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QBRC_L(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QBRC_H(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QBTC_L(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QBTC_H(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
|
||||||
|
} else {
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QBRC(i));
|
||||||
|
IXGBE_READ_REG(hw, IXGBE_QBTC(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hw->mac.type == ixgbe_mac_X540) {
|
||||||
|
if (hw->phy.id == 0)
|
||||||
|
hw->phy.ops.identify(hw);
|
||||||
|
hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECL, &i);
|
||||||
|
hw->phy.ops.read_reg(hw, 0x3, IXGBE_PCRC8ECH, &i);
|
||||||
|
hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECL, &i);
|
||||||
|
hw->phy.ops.read_reg(hw, 0x3, IXGBE_LDPCECH, &i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1075,7 +1110,7 @@ static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
|
||||||
eec &= ~IXGBE_EEC_REQ;
|
eec &= ~IXGBE_EEC_REQ;
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
|
IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
|
||||||
|
|
||||||
ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
|
||||||
|
|
||||||
/* Delay before attempt to obtain semaphore again to allow FW access */
|
/* Delay before attempt to obtain semaphore again to allow FW access */
|
||||||
msleep(hw->eeprom.semaphore_delay);
|
msleep(hw->eeprom.semaphore_delay);
|
||||||
|
@ -1537,7 +1572,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
#endif /* CONFIG_DCB */
|
#endif /* CONFIG_DCB */
|
||||||
/* Negotiate the fc mode to use */
|
/* Negotiate the fc mode to use */
|
||||||
ret_val = ixgbe_fc_autoneg(hw);
|
ret_val = ixgbe_fc_autoneg(hw);
|
||||||
if (ret_val)
|
if (ret_val == IXGBE_ERR_FLOW_CONTROL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Disable any previous flow control settings */
|
/* Disable any previous flow control settings */
|
||||||
|
@ -1645,12 +1680,13 @@ out:
|
||||||
**/
|
**/
|
||||||
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
s32 ret_val = 0;
|
s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
|
||||||
ixgbe_link_speed speed;
|
ixgbe_link_speed speed;
|
||||||
u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
|
|
||||||
u32 links2, anlp1_reg, autoc_reg, links;
|
|
||||||
bool link_up;
|
bool link_up;
|
||||||
|
|
||||||
|
if (hw->fc.disable_fc_autoneg)
|
||||||
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AN should have completed when the cable was plugged in.
|
* AN should have completed when the cable was plugged in.
|
||||||
* Look for reasons to bail out. Bail out if:
|
* Look for reasons to bail out. Bail out if:
|
||||||
|
@ -1661,155 +1697,201 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
|
||||||
* So use link_up_wait_to_complete=false.
|
* So use link_up_wait_to_complete=false.
|
||||||
*/
|
*/
|
||||||
hw->mac.ops.check_link(hw, &speed, &link_up, false);
|
hw->mac.ops.check_link(hw, &speed, &link_up, false);
|
||||||
|
if (!link_up) {
|
||||||
if (hw->fc.disable_fc_autoneg || (!link_up)) {
|
ret_val = IXGBE_ERR_FLOW_CONTROL;
|
||||||
hw->fc.fc_was_autonegged = false;
|
|
||||||
hw->fc.current_mode = hw->fc.requested_mode;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
switch (hw->phy.media_type) {
|
||||||
* On backplane, bail out if
|
/* Autoneg flow control on fiber adapters */
|
||||||
* - backplane autoneg was not completed, or if
|
case ixgbe_media_type_fiber:
|
||||||
* - we are 82599 and link partner is not AN enabled
|
if (speed == IXGBE_LINK_SPEED_1GB_FULL)
|
||||||
*/
|
ret_val = ixgbe_fc_autoneg_fiber(hw);
|
||||||
if (hw->phy.media_type == ixgbe_media_type_backplane) {
|
break;
|
||||||
links = IXGBE_READ_REG(hw, IXGBE_LINKS);
|
|
||||||
if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) {
|
|
||||||
hw->fc.fc_was_autonegged = false;
|
|
||||||
hw->fc.current_mode = hw->fc.requested_mode;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hw->mac.type == ixgbe_mac_82599EB) {
|
/* Autoneg flow control on backplane adapters */
|
||||||
links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
|
case ixgbe_media_type_backplane:
|
||||||
if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) {
|
ret_val = ixgbe_fc_autoneg_backplane(hw);
|
||||||
hw->fc.fc_was_autonegged = false;
|
break;
|
||||||
hw->fc.current_mode = hw->fc.requested_mode;
|
|
||||||
goto out;
|
/* Autoneg flow control on copper adapters */
|
||||||
}
|
case ixgbe_media_type_copper:
|
||||||
}
|
if (ixgbe_device_supports_autoneg_fc(hw) == 0)
|
||||||
|
ret_val = ixgbe_fc_autoneg_copper(hw);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (ret_val == 0) {
|
||||||
|
hw->fc.fc_was_autonegged = true;
|
||||||
|
} else {
|
||||||
|
hw->fc.fc_was_autonegged = false;
|
||||||
|
hw->fc.current_mode = hw->fc.requested_mode;
|
||||||
|
}
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_fc_autoneg_fiber - Enable flow control on 1 gig fiber
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
*
|
||||||
|
* Enable flow control according on 1 gig fiber.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_fc_autoneg_fiber(struct ixgbe_hw *hw)
|
||||||
|
{
|
||||||
|
u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
|
||||||
|
s32 ret_val;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On multispeed fiber at 1g, bail out if
|
* On multispeed fiber at 1g, bail out if
|
||||||
* - link is up but AN did not complete, or if
|
* - link is up but AN did not complete, or if
|
||||||
* - link is up and AN completed but timed out
|
* - link is up and AN completed but timed out
|
||||||
*/
|
*/
|
||||||
if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) {
|
|
||||||
linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
|
|
||||||
if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
|
|
||||||
((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
|
|
||||||
hw->fc.fc_was_autonegged = false;
|
|
||||||
hw->fc.current_mode = hw->fc.requested_mode;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
|
||||||
* Bail out on
|
if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
|
||||||
* - copper or CX4 adapters
|
((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
|
||||||
* - fiber adapters running at 10gig
|
ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
|
||||||
*/
|
|
||||||
if ((hw->phy.media_type == ixgbe_media_type_copper) ||
|
|
||||||
(hw->phy.media_type == ixgbe_media_type_cx4) ||
|
|
||||||
((hw->phy.media_type == ixgbe_media_type_fiber) &&
|
|
||||||
(speed == IXGBE_LINK_SPEED_10GB_FULL))) {
|
|
||||||
hw->fc.fc_was_autonegged = false;
|
|
||||||
hw->fc.current_mode = hw->fc.requested_mode;
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
|
||||||
* Read the AN advertisement and LP ability registers and resolve
|
pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
|
||||||
* local flow control settings accordingly
|
|
||||||
*/
|
|
||||||
if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
|
|
||||||
(hw->phy.media_type != ixgbe_media_type_backplane)) {
|
|
||||||
pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
|
|
||||||
pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
|
|
||||||
if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
|
|
||||||
(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
|
|
||||||
/*
|
|
||||||
* Now we need to check if the user selected Rx ONLY
|
|
||||||
* of pause frames. In this case, we had to advertise
|
|
||||||
* FULL flow control because we could not advertise RX
|
|
||||||
* ONLY. Hence, we must now check to see if we need to
|
|
||||||
* turn OFF the TRANSMISSION of PAUSE frames.
|
|
||||||
*/
|
|
||||||
if (hw->fc.requested_mode == ixgbe_fc_full) {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_full;
|
|
||||||
hw_dbg(hw, "Flow Control = FULL.\n");
|
|
||||||
} else {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_rx_pause;
|
|
||||||
hw_dbg(hw, "Flow Control=RX PAUSE only\n");
|
|
||||||
}
|
|
||||||
} else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
|
|
||||||
(pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
|
|
||||||
(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
|
|
||||||
(pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_tx_pause;
|
|
||||||
hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
|
|
||||||
} else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
|
|
||||||
(pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
|
|
||||||
!(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
|
|
||||||
(pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_rx_pause;
|
|
||||||
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
|
|
||||||
} else {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_none;
|
|
||||||
hw_dbg(hw, "Flow Control = NONE.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hw->phy.media_type == ixgbe_media_type_backplane) {
|
ret_val = ixgbe_negotiate_fc(hw, pcs_anadv_reg,
|
||||||
/*
|
pcs_lpab_reg, IXGBE_PCS1GANA_SYM_PAUSE,
|
||||||
* Read the 10g AN autoc and LP ability registers and resolve
|
IXGBE_PCS1GANA_ASM_PAUSE,
|
||||||
* local flow control settings accordingly
|
IXGBE_PCS1GANA_SYM_PAUSE,
|
||||||
*/
|
IXGBE_PCS1GANA_ASM_PAUSE);
|
||||||
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
|
||||||
anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
|
|
||||||
|
|
||||||
if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
|
|
||||||
(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) {
|
|
||||||
/*
|
|
||||||
* Now we need to check if the user selected Rx ONLY
|
|
||||||
* of pause frames. In this case, we had to advertise
|
|
||||||
* FULL flow control because we could not advertise RX
|
|
||||||
* ONLY. Hence, we must now check to see if we need to
|
|
||||||
* turn OFF the TRANSMISSION of PAUSE frames.
|
|
||||||
*/
|
|
||||||
if (hw->fc.requested_mode == ixgbe_fc_full) {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_full;
|
|
||||||
hw_dbg(hw, "Flow Control = FULL.\n");
|
|
||||||
} else {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_rx_pause;
|
|
||||||
hw_dbg(hw, "Flow Control=RX PAUSE only\n");
|
|
||||||
}
|
|
||||||
} else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
|
|
||||||
(autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
|
|
||||||
(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
|
|
||||||
(anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_tx_pause;
|
|
||||||
hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
|
|
||||||
} else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
|
|
||||||
(autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
|
|
||||||
!(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
|
|
||||||
(anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_rx_pause;
|
|
||||||
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
|
|
||||||
} else {
|
|
||||||
hw->fc.current_mode = ixgbe_fc_none;
|
|
||||||
hw_dbg(hw, "Flow Control = NONE.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Record that current_mode is the result of a successful autoneg */
|
|
||||||
hw->fc.fc_was_autonegged = true;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_fc_autoneg_backplane - Enable flow control IEEE clause 37
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
*
|
||||||
|
* Enable flow control according to IEEE clause 37.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_fc_autoneg_backplane(struct ixgbe_hw *hw)
|
||||||
|
{
|
||||||
|
u32 links2, anlp1_reg, autoc_reg, links;
|
||||||
|
s32 ret_val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On backplane, bail out if
|
||||||
|
* - backplane autoneg was not completed, or if
|
||||||
|
* - we are 82599 and link partner is not AN enabled
|
||||||
|
*/
|
||||||
|
links = IXGBE_READ_REG(hw, IXGBE_LINKS);
|
||||||
|
if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) {
|
||||||
|
hw->fc.fc_was_autonegged = false;
|
||||||
|
hw->fc.current_mode = hw->fc.requested_mode;
|
||||||
|
ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hw->mac.type == ixgbe_mac_82599EB) {
|
||||||
|
links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
|
||||||
|
if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) {
|
||||||
|
hw->fc.fc_was_autonegged = false;
|
||||||
|
hw->fc.current_mode = hw->fc.requested_mode;
|
||||||
|
ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Read the 10g AN autoc and LP ability registers and resolve
|
||||||
|
* local flow control settings accordingly
|
||||||
|
*/
|
||||||
|
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||||
|
anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
|
||||||
|
|
||||||
|
ret_val = ixgbe_negotiate_fc(hw, autoc_reg,
|
||||||
|
anlp1_reg, IXGBE_AUTOC_SYM_PAUSE, IXGBE_AUTOC_ASM_PAUSE,
|
||||||
|
IXGBE_ANLP1_SYM_PAUSE, IXGBE_ANLP1_ASM_PAUSE);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_fc_autoneg_copper - Enable flow control IEEE clause 37
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
*
|
||||||
|
* Enable flow control according to IEEE clause 37.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_fc_autoneg_copper(struct ixgbe_hw *hw)
|
||||||
|
{
|
||||||
|
u16 technology_ability_reg = 0;
|
||||||
|
u16 lp_technology_ability_reg = 0;
|
||||||
|
|
||||||
|
hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
|
||||||
|
MDIO_MMD_AN,
|
||||||
|
&technology_ability_reg);
|
||||||
|
hw->phy.ops.read_reg(hw, MDIO_AN_LPA,
|
||||||
|
MDIO_MMD_AN,
|
||||||
|
&lp_technology_ability_reg);
|
||||||
|
|
||||||
|
return ixgbe_negotiate_fc(hw, (u32)technology_ability_reg,
|
||||||
|
(u32)lp_technology_ability_reg,
|
||||||
|
IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE,
|
||||||
|
IXGBE_TAF_SYM_PAUSE, IXGBE_TAF_ASM_PAUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_negotiate_fc - Negotiate flow control
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
* @adv_reg: flow control advertised settings
|
||||||
|
* @lp_reg: link partner's flow control settings
|
||||||
|
* @adv_sym: symmetric pause bit in advertisement
|
||||||
|
* @adv_asm: asymmetric pause bit in advertisement
|
||||||
|
* @lp_sym: symmetric pause bit in link partner advertisement
|
||||||
|
* @lp_asm: asymmetric pause bit in link partner advertisement
|
||||||
|
*
|
||||||
|
* Find the intersection between advertised settings and link partner's
|
||||||
|
* advertised settings
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
|
||||||
|
u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm)
|
||||||
|
{
|
||||||
|
if ((!(adv_reg)) || (!(lp_reg)))
|
||||||
|
return IXGBE_ERR_FC_NOT_NEGOTIATED;
|
||||||
|
|
||||||
|
if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) {
|
||||||
|
/*
|
||||||
|
* Now we need to check if the user selected Rx ONLY
|
||||||
|
* of pause frames. In this case, we had to advertise
|
||||||
|
* FULL flow control because we could not advertise RX
|
||||||
|
* ONLY. Hence, we must now check to see if we need to
|
||||||
|
* turn OFF the TRANSMISSION of PAUSE frames.
|
||||||
|
*/
|
||||||
|
if (hw->fc.requested_mode == ixgbe_fc_full) {
|
||||||
|
hw->fc.current_mode = ixgbe_fc_full;
|
||||||
|
hw_dbg(hw, "Flow Control = FULL.\n");
|
||||||
|
} else {
|
||||||
|
hw->fc.current_mode = ixgbe_fc_rx_pause;
|
||||||
|
hw_dbg(hw, "Flow Control=RX PAUSE frames only\n");
|
||||||
|
}
|
||||||
|
} else if (!(adv_reg & adv_sym) && (adv_reg & adv_asm) &&
|
||||||
|
(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
|
||||||
|
hw->fc.current_mode = ixgbe_fc_tx_pause;
|
||||||
|
hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
|
||||||
|
} else if ((adv_reg & adv_sym) && (adv_reg & adv_asm) &&
|
||||||
|
!(lp_reg & lp_sym) && (lp_reg & lp_asm)) {
|
||||||
|
hw->fc.current_mode = ixgbe_fc_rx_pause;
|
||||||
|
hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
|
||||||
|
} else {
|
||||||
|
hw->fc.current_mode = ixgbe_fc_none;
|
||||||
|
hw_dbg(hw, "Flow Control = NONE.\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_setup_fc - Set up flow control
|
* ixgbe_setup_fc - Set up flow control
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
|
@ -1819,7 +1901,8 @@ out:
|
||||||
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
{
|
{
|
||||||
s32 ret_val = 0;
|
s32 ret_val = 0;
|
||||||
u32 reg;
|
u32 reg = 0, reg_bp = 0;
|
||||||
|
u16 reg_cu = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_DCB
|
#ifdef CONFIG_DCB
|
||||||
if (hw->fc.requested_mode == ixgbe_fc_pfc) {
|
if (hw->fc.requested_mode == ixgbe_fc_pfc) {
|
||||||
|
@ -1827,7 +1910,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif /* CONFIG_DCB */
|
||||||
/* Validate the packetbuf configuration */
|
/* Validate the packetbuf configuration */
|
||||||
if (packetbuf_num < 0 || packetbuf_num > 7) {
|
if (packetbuf_num < 0 || packetbuf_num > 7) {
|
||||||
hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
|
hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
|
||||||
|
@ -1865,11 +1948,26 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
hw->fc.requested_mode = ixgbe_fc_full;
|
hw->fc.requested_mode = ixgbe_fc_full;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up the 1G flow control advertisement registers so the HW will be
|
* Set up the 1G and 10G flow control advertisement registers so the
|
||||||
* able to do fc autoneg once the cable is plugged in. If we end up
|
* HW will be able to do fc autoneg once the cable is plugged in. If
|
||||||
* using 10g instead, this is harmless.
|
* we link at 10G, the 1G advertisement is harmless and vice versa.
|
||||||
*/
|
*/
|
||||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
|
|
||||||
|
switch (hw->phy.media_type) {
|
||||||
|
case ixgbe_media_type_fiber:
|
||||||
|
case ixgbe_media_type_backplane:
|
||||||
|
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
|
||||||
|
reg_bp = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ixgbe_media_type_copper:
|
||||||
|
hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE,
|
||||||
|
MDIO_MMD_AN, ®_cu);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The possible values of fc.requested_mode are:
|
* The possible values of fc.requested_mode are:
|
||||||
|
@ -1888,6 +1986,11 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
case ixgbe_fc_none:
|
case ixgbe_fc_none:
|
||||||
/* Flow control completely disabled by software override. */
|
/* Flow control completely disabled by software override. */
|
||||||
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||||
|
if (hw->phy.media_type == ixgbe_media_type_backplane)
|
||||||
|
reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE |
|
||||||
|
IXGBE_AUTOC_ASM_PAUSE);
|
||||||
|
else if (hw->phy.media_type == ixgbe_media_type_copper)
|
||||||
|
reg_cu &= ~(IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
|
||||||
break;
|
break;
|
||||||
case ixgbe_fc_rx_pause:
|
case ixgbe_fc_rx_pause:
|
||||||
/*
|
/*
|
||||||
|
@ -1899,6 +2002,11 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
* disable the adapter's ability to send PAUSE frames.
|
* disable the adapter's ability to send PAUSE frames.
|
||||||
*/
|
*/
|
||||||
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||||
|
if (hw->phy.media_type == ixgbe_media_type_backplane)
|
||||||
|
reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
|
||||||
|
IXGBE_AUTOC_ASM_PAUSE);
|
||||||
|
else if (hw->phy.media_type == ixgbe_media_type_copper)
|
||||||
|
reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
|
||||||
break;
|
break;
|
||||||
case ixgbe_fc_tx_pause:
|
case ixgbe_fc_tx_pause:
|
||||||
/*
|
/*
|
||||||
|
@ -1907,10 +2015,22 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
*/
|
*/
|
||||||
reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
|
reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
|
||||||
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
|
reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
|
||||||
|
if (hw->phy.media_type == ixgbe_media_type_backplane) {
|
||||||
|
reg_bp |= (IXGBE_AUTOC_ASM_PAUSE);
|
||||||
|
reg_bp &= ~(IXGBE_AUTOC_SYM_PAUSE);
|
||||||
|
} else if (hw->phy.media_type == ixgbe_media_type_copper) {
|
||||||
|
reg_cu |= (IXGBE_TAF_ASM_PAUSE);
|
||||||
|
reg_cu &= ~(IXGBE_TAF_SYM_PAUSE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ixgbe_fc_full:
|
case ixgbe_fc_full:
|
||||||
/* Flow control (both Rx and Tx) is enabled by SW override. */
|
/* Flow control (both Rx and Tx) is enabled by SW override. */
|
||||||
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
|
||||||
|
if (hw->phy.media_type == ixgbe_media_type_backplane)
|
||||||
|
reg_bp |= (IXGBE_AUTOC_SYM_PAUSE |
|
||||||
|
IXGBE_AUTOC_ASM_PAUSE);
|
||||||
|
else if (hw->phy.media_type == ixgbe_media_type_copper)
|
||||||
|
reg_cu |= (IXGBE_TAF_SYM_PAUSE | IXGBE_TAF_ASM_PAUSE);
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_DCB
|
#ifdef CONFIG_DCB
|
||||||
case ixgbe_fc_pfc:
|
case ixgbe_fc_pfc:
|
||||||
|
@ -1924,80 +2044,37 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
|
if (hw->mac.type != ixgbe_mac_X540) {
|
||||||
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
|
|
||||||
|
|
||||||
/* Disable AN timeout */
|
|
||||||
if (hw->fc.strict_ieee)
|
|
||||||
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
|
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
|
|
||||||
hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the 10G flow control advertisement registers so the HW
|
|
||||||
* can do fc autoneg once the cable is plugged in. If we end up
|
|
||||||
* using 1g instead, this is harmless.
|
|
||||||
*/
|
|
||||||
reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The possible values of fc.requested_mode are:
|
|
||||||
* 0: Flow control is completely disabled
|
|
||||||
* 1: Rx flow control is enabled (we can receive pause frames,
|
|
||||||
* but not send pause frames).
|
|
||||||
* 2: Tx flow control is enabled (we can send pause frames but
|
|
||||||
* we do not support receiving pause frames).
|
|
||||||
* 3: Both Rx and Tx flow control (symmetric) are enabled.
|
|
||||||
* other: Invalid.
|
|
||||||
*/
|
|
||||||
switch (hw->fc.requested_mode) {
|
|
||||||
case ixgbe_fc_none:
|
|
||||||
/* Flow control completely disabled by software override. */
|
|
||||||
reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
|
|
||||||
break;
|
|
||||||
case ixgbe_fc_rx_pause:
|
|
||||||
/*
|
/*
|
||||||
* Rx Flow control is enabled and Tx Flow control is
|
* Enable auto-negotiation between the MAC & PHY;
|
||||||
* disabled by software override. Since there really
|
* the MAC will advertise clause 37 flow control.
|
||||||
* isn't a way to advertise that we are capable of RX
|
|
||||||
* Pause ONLY, we will advertise that we support both
|
|
||||||
* symmetric and asymmetric Rx PAUSE. Later, we will
|
|
||||||
* disable the adapter's ability to send PAUSE frames.
|
|
||||||
*/
|
*/
|
||||||
reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
|
IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
|
||||||
break;
|
reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
|
||||||
case ixgbe_fc_tx_pause:
|
|
||||||
/*
|
/* Disable AN timeout */
|
||||||
* Tx Flow control is enabled, and Rx Flow control is
|
if (hw->fc.strict_ieee)
|
||||||
* disabled by software override.
|
reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
|
||||||
*/
|
|
||||||
reg |= (IXGBE_AUTOC_ASM_PAUSE);
|
IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
|
||||||
reg &= ~(IXGBE_AUTOC_SYM_PAUSE);
|
hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
|
||||||
break;
|
|
||||||
case ixgbe_fc_full:
|
|
||||||
/* Flow control (both Rx and Tx) is enabled by SW override. */
|
|
||||||
reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
|
|
||||||
break;
|
|
||||||
#ifdef CONFIG_DCB
|
|
||||||
case ixgbe_fc_pfc:
|
|
||||||
goto out;
|
|
||||||
break;
|
|
||||||
#endif /* CONFIG_DCB */
|
|
||||||
default:
|
|
||||||
hw_dbg(hw, "Flow control param set incorrectly\n");
|
|
||||||
ret_val = IXGBE_ERR_CONFIG;
|
|
||||||
goto out;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AUTOC restart handles negotiation of 1G and 10G. There is
|
* AUTOC restart handles negotiation of 1G and 10G on backplane
|
||||||
* no need to set the PCS1GCTL register.
|
* and copper. There is no need to set the PCS1GCTL register.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
reg |= IXGBE_AUTOC_AN_RESTART;
|
if (hw->phy.media_type == ixgbe_media_type_backplane) {
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg);
|
reg_bp |= IXGBE_AUTOC_AN_RESTART;
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
|
||||||
|
} else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
|
||||||
|
(ixgbe_device_supports_autoneg_fc(hw) == 0)) {
|
||||||
|
hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
|
||||||
|
MDIO_MMD_AN, reg_cu);
|
||||||
|
}
|
||||||
|
|
||||||
hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
|
hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
@ -2085,7 +2162,7 @@ out:
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @mask: Mask to specify which semaphore to acquire
|
* @mask: Mask to specify which semaphore to acquire
|
||||||
*
|
*
|
||||||
* Acquires the SWFW semaphore thought the GSSR register for the specified
|
* Acquires the SWFW semaphore through the GSSR register for the specified
|
||||||
* function (CSR, PHY0, PHY1, EEPROM, Flash)
|
* function (CSR, PHY0, PHY1, EEPROM, Flash)
|
||||||
**/
|
**/
|
||||||
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
||||||
|
@ -2133,7 +2210,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
* @mask: Mask to specify which semaphore to release
|
* @mask: Mask to specify which semaphore to release
|
||||||
*
|
*
|
||||||
* Releases the SWFW semaphore thought the GSSR register for the specified
|
* Releases the SWFW semaphore through the GSSR register for the specified
|
||||||
* function (CSR, PHY0, PHY1, EEPROM, Flash)
|
* function (CSR, PHY0, PHY1, EEPROM, Flash)
|
||||||
**/
|
**/
|
||||||
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
|
||||||
|
@ -2721,6 +2798,28 @@ wwn_prefix_out:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_device_supports_autoneg_fc - Check if phy supports autoneg flow
|
||||||
|
* control
|
||||||
|
* @hw: pointer to hardware structure
|
||||||
|
*
|
||||||
|
* There are several phys that do not support autoneg flow control. This
|
||||||
|
* function check the device id to see if the associated phy supports
|
||||||
|
* autoneg flow control.
|
||||||
|
**/
|
||||||
|
static s32 ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (hw->device_id) {
|
||||||
|
case IXGBE_DEV_ID_X540T:
|
||||||
|
return 0;
|
||||||
|
case IXGBE_DEV_ID_82599_T3_LOM:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return IXGBE_ERR_FC_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
|
* ixgbe_set_mac_anti_spoofing - Enable/Disable MAC anti-spoofing
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
|
|
|
@ -161,29 +161,25 @@ static int ixgbe_get_settings(struct net_device *netdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
ecmd->advertising = ADVERTISED_Autoneg;
|
ecmd->advertising = ADVERTISED_Autoneg;
|
||||||
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
|
if (hw->phy.autoneg_advertised) {
|
||||||
ecmd->advertising |= ADVERTISED_100baseT_Full;
|
if (hw->phy.autoneg_advertised &
|
||||||
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
|
IXGBE_LINK_SPEED_100_FULL)
|
||||||
ecmd->advertising |= ADVERTISED_10000baseT_Full;
|
ecmd->advertising |= ADVERTISED_100baseT_Full;
|
||||||
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
|
if (hw->phy.autoneg_advertised &
|
||||||
ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
IXGBE_LINK_SPEED_10GB_FULL)
|
||||||
/*
|
ecmd->advertising |= ADVERTISED_10000baseT_Full;
|
||||||
* It's possible that phy.autoneg_advertised may not be
|
if (hw->phy.autoneg_advertised &
|
||||||
* set yet. If so display what the default would be -
|
IXGBE_LINK_SPEED_1GB_FULL)
|
||||||
* both 1G and 10G supported.
|
ecmd->advertising |= ADVERTISED_1000baseT_Full;
|
||||||
*/
|
} else {
|
||||||
if (!(ecmd->advertising & (ADVERTISED_1000baseT_Full |
|
/*
|
||||||
ADVERTISED_10000baseT_Full)))
|
* Default advertised modes in case
|
||||||
|
* phy.autoneg_advertised isn't set.
|
||||||
|
*/
|
||||||
ecmd->advertising |= (ADVERTISED_10000baseT_Full |
|
ecmd->advertising |= (ADVERTISED_10000baseT_Full |
|
||||||
ADVERTISED_1000baseT_Full);
|
ADVERTISED_1000baseT_Full);
|
||||||
|
if (hw->mac.type == ixgbe_mac_X540)
|
||||||
switch (hw->mac.type) {
|
ecmd->advertising |= ADVERTISED_100baseT_Full;
|
||||||
case ixgbe_mac_X540:
|
|
||||||
if (!(ecmd->advertising & ADVERTISED_100baseT_Full))
|
|
||||||
ecmd->advertising |= (ADVERTISED_100baseT_Full);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hw->phy.media_type == ixgbe_media_type_copper) {
|
if (hw->phy.media_type == ixgbe_media_type_copper) {
|
||||||
|
@ -336,6 +332,9 @@ static int ixgbe_set_settings(struct net_device *netdev,
|
||||||
if (ecmd->advertising & ADVERTISED_1000baseT_Full)
|
if (ecmd->advertising & ADVERTISED_1000baseT_Full)
|
||||||
advertised |= IXGBE_LINK_SPEED_1GB_FULL;
|
advertised |= IXGBE_LINK_SPEED_1GB_FULL;
|
||||||
|
|
||||||
|
if (ecmd->advertising & ADVERTISED_100baseT_Full)
|
||||||
|
advertised |= IXGBE_LINK_SPEED_100_FULL;
|
||||||
|
|
||||||
if (old == advertised)
|
if (old == advertised)
|
||||||
return err;
|
return err;
|
||||||
/* this sets the link speed and restarts auto-neg */
|
/* this sets the link speed and restarts auto-neg */
|
||||||
|
|
|
@ -135,22 +135,19 @@ out_ddp_put:
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_fcoe_ddp_get - called to set up ddp context
|
* ixgbe_fcoe_ddp_setup - called to set up ddp context
|
||||||
* @netdev: the corresponding net_device
|
* @netdev: the corresponding net_device
|
||||||
* @xid: the exchange id requesting ddp
|
* @xid: the exchange id requesting ddp
|
||||||
* @sgl: the scatter-gather list for this request
|
* @sgl: the scatter-gather list for this request
|
||||||
* @sgc: the number of scatter-gather items
|
* @sgc: the number of scatter-gather items
|
||||||
*
|
*
|
||||||
* This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
|
|
||||||
* and is expected to be called from ULD, e.g., FCP layer of libfc
|
|
||||||
* to set up ddp for the corresponding xid of the given sglist for
|
|
||||||
* the corresponding I/O.
|
|
||||||
*
|
|
||||||
* Returns : 1 for success and 0 for no ddp
|
* Returns : 1 for success and 0 for no ddp
|
||||||
*/
|
*/
|
||||||
int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
|
||||||
struct scatterlist *sgl, unsigned int sgc)
|
struct scatterlist *sgl, unsigned int sgc,
|
||||||
|
int target_mode)
|
||||||
{
|
{
|
||||||
struct ixgbe_adapter *adapter;
|
struct ixgbe_adapter *adapter;
|
||||||
struct ixgbe_hw *hw;
|
struct ixgbe_hw *hw;
|
||||||
|
@ -164,7 +161,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
||||||
unsigned int lastsize;
|
unsigned int lastsize;
|
||||||
unsigned int thisoff = 0;
|
unsigned int thisoff = 0;
|
||||||
unsigned int thislen = 0;
|
unsigned int thislen = 0;
|
||||||
u32 fcbuff, fcdmarw, fcfltrw;
|
u32 fcbuff, fcdmarw, fcfltrw, fcrxctl;
|
||||||
dma_addr_t addr = 0;
|
dma_addr_t addr = 0;
|
||||||
|
|
||||||
if (!netdev || !sgl)
|
if (!netdev || !sgl)
|
||||||
|
@ -275,6 +272,9 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
||||||
fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
|
fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
|
||||||
fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
|
fcbuff |= ((j & 0xff) << IXGBE_FCBUFF_BUFFCNT_SHIFT);
|
||||||
fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
|
fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
|
||||||
|
/* Set WRCONTX bit to allow DDP for target */
|
||||||
|
if (target_mode)
|
||||||
|
fcbuff |= (IXGBE_FCBUFF_WRCONTX);
|
||||||
fcbuff |= (IXGBE_FCBUFF_VALID);
|
fcbuff |= (IXGBE_FCBUFF_VALID);
|
||||||
|
|
||||||
fcdmarw = xid;
|
fcdmarw = xid;
|
||||||
|
@ -287,6 +287,16 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
||||||
/* program DMA context */
|
/* program DMA context */
|
||||||
hw = &adapter->hw;
|
hw = &adapter->hw;
|
||||||
spin_lock_bh(&fcoe->lock);
|
spin_lock_bh(&fcoe->lock);
|
||||||
|
|
||||||
|
/* turn on last frame indication for target mode as FCP_RSPtarget is
|
||||||
|
* supposed to send FCP_RSP when it is done. */
|
||||||
|
if (target_mode && !test_bit(__IXGBE_FCOE_TARGET, &fcoe->mode)) {
|
||||||
|
set_bit(__IXGBE_FCOE_TARGET, &fcoe->mode);
|
||||||
|
fcrxctl = IXGBE_READ_REG(hw, IXGBE_FCRXCTRL);
|
||||||
|
fcrxctl |= IXGBE_FCRXCTRL_LASTSEQH;
|
||||||
|
IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL, fcrxctl);
|
||||||
|
}
|
||||||
|
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32));
|
IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_BIT_MASK(32));
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32);
|
IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32);
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff);
|
IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff);
|
||||||
|
@ -295,6 +305,7 @@ int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0);
|
IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0);
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID);
|
IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID);
|
||||||
IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw);
|
IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw);
|
||||||
|
|
||||||
spin_unlock_bh(&fcoe->lock);
|
spin_unlock_bh(&fcoe->lock);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -308,6 +319,47 @@ out_noddp_unmap:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_fcoe_ddp_get - called to set up ddp context in initiator mode
|
||||||
|
* @netdev: the corresponding net_device
|
||||||
|
* @xid: the exchange id requesting ddp
|
||||||
|
* @sgl: the scatter-gather list for this request
|
||||||
|
* @sgc: the number of scatter-gather items
|
||||||
|
*
|
||||||
|
* This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
|
||||||
|
* and is expected to be called from ULD, e.g., FCP layer of libfc
|
||||||
|
* to set up ddp for the corresponding xid of the given sglist for
|
||||||
|
* the corresponding I/O.
|
||||||
|
*
|
||||||
|
* Returns : 1 for success and 0 for no ddp
|
||||||
|
*/
|
||||||
|
int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
|
||||||
|
struct scatterlist *sgl, unsigned int sgc)
|
||||||
|
{
|
||||||
|
return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_fcoe_ddp_target - called to set up ddp context in target mode
|
||||||
|
* @netdev: the corresponding net_device
|
||||||
|
* @xid: the exchange id requesting ddp
|
||||||
|
* @sgl: the scatter-gather list for this request
|
||||||
|
* @sgc: the number of scatter-gather items
|
||||||
|
*
|
||||||
|
* This is the implementation of net_device_ops.ndo_fcoe_ddp_target
|
||||||
|
* and is expected to be called from ULD, e.g., FCP layer of libfc
|
||||||
|
* to set up ddp for the corresponding xid of the given sglist for
|
||||||
|
* the corresponding I/O. The DDP in target mode is a write I/O request
|
||||||
|
* from the initiator.
|
||||||
|
*
|
||||||
|
* Returns : 1 for success and 0 for no ddp
|
||||||
|
*/
|
||||||
|
int ixgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid,
|
||||||
|
struct scatterlist *sgl, unsigned int sgc)
|
||||||
|
{
|
||||||
|
return ixgbe_fcoe_ddp_setup(netdev, xid, sgl, sgc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_fcoe_ddp - check ddp status and mark it done
|
* ixgbe_fcoe_ddp - check ddp status and mark it done
|
||||||
* @adapter: ixgbe adapter
|
* @adapter: ixgbe adapter
|
||||||
|
@ -331,6 +383,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
|
||||||
struct ixgbe_fcoe *fcoe;
|
struct ixgbe_fcoe *fcoe;
|
||||||
struct ixgbe_fcoe_ddp *ddp;
|
struct ixgbe_fcoe_ddp *ddp;
|
||||||
struct fc_frame_header *fh;
|
struct fc_frame_header *fh;
|
||||||
|
struct fcoe_crc_eof *crc;
|
||||||
|
|
||||||
if (!ixgbe_rx_is_fcoe(rx_desc))
|
if (!ixgbe_rx_is_fcoe(rx_desc))
|
||||||
goto ddp_out;
|
goto ddp_out;
|
||||||
|
@ -384,7 +437,18 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
|
||||||
else if (ddp->len)
|
else if (ddp->len)
|
||||||
rc = ddp->len;
|
rc = ddp->len;
|
||||||
}
|
}
|
||||||
|
/* In target mode, check the last data frame of the sequence.
|
||||||
|
* For DDP in target mode, data is already DDPed but the header
|
||||||
|
* indication of the last data frame ould allow is to tell if we
|
||||||
|
* got all the data and the ULP can send FCP_RSP back, as this is
|
||||||
|
* not a full fcoe frame, we fill the trailer here so it won't be
|
||||||
|
* dropped by the ULP stack.
|
||||||
|
*/
|
||||||
|
if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) &&
|
||||||
|
(fctl & FC_FC_END_SEQ)) {
|
||||||
|
crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc));
|
||||||
|
crc->fcoe_eof = FC_EOF_T;
|
||||||
|
}
|
||||||
ddp_out:
|
ddp_out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -840,5 +904,3 @@ int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type)
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,9 @@
|
||||||
/* fcerr */
|
/* fcerr */
|
||||||
#define IXGBE_FCERR_BADCRC 0x00100000
|
#define IXGBE_FCERR_BADCRC 0x00100000
|
||||||
|
|
||||||
|
/* FCoE DDP for target mode */
|
||||||
|
#define __IXGBE_FCOE_TARGET 1
|
||||||
|
|
||||||
struct ixgbe_fcoe_ddp {
|
struct ixgbe_fcoe_ddp {
|
||||||
int len;
|
int len;
|
||||||
u32 err;
|
u32 err;
|
||||||
|
@ -66,6 +69,7 @@ struct ixgbe_fcoe {
|
||||||
u8 tc;
|
u8 tc;
|
||||||
u8 up;
|
u8 up;
|
||||||
#endif
|
#endif
|
||||||
|
unsigned long mode;
|
||||||
atomic_t refcnt;
|
atomic_t refcnt;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct pci_pool *pool;
|
struct pci_pool *pool;
|
||||||
|
|
|
@ -3775,7 +3775,8 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto link_cfg_out;
|
goto link_cfg_out;
|
||||||
|
|
||||||
if (hw->mac.ops.get_link_capabilities)
|
autoneg = hw->phy.autoneg_advertised;
|
||||||
|
if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
|
||||||
ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
|
ret = hw->mac.ops.get_link_capabilities(hw, &autoneg,
|
||||||
&negotiation);
|
&negotiation);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -7019,6 +7020,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef IXGBE_FCOE
|
#ifdef IXGBE_FCOE
|
||||||
.ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
|
.ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
|
||||||
|
.ndo_fcoe_ddp_target = ixgbe_fcoe_ddp_target,
|
||||||
.ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
|
.ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
|
||||||
.ndo_fcoe_enable = ixgbe_fcoe_enable,
|
.ndo_fcoe_enable = ixgbe_fcoe_enable,
|
||||||
.ndo_fcoe_disable = ixgbe_fcoe_disable,
|
.ndo_fcoe_disable = ixgbe_fcoe_disable,
|
||||||
|
|
|
@ -448,23 +448,20 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
struct ixgbe_mbx_info *mbx = &hw->mbx;
|
struct ixgbe_mbx_info *mbx = &hw->mbx;
|
||||||
|
|
||||||
switch (hw->mac.type) {
|
if (hw->mac.type != ixgbe_mac_82599EB &&
|
||||||
case ixgbe_mac_82599EB:
|
hw->mac.type != ixgbe_mac_X540)
|
||||||
case ixgbe_mac_X540:
|
return;
|
||||||
mbx->timeout = 0;
|
|
||||||
mbx->usec_delay = 0;
|
|
||||||
|
|
||||||
mbx->size = IXGBE_VFMAILBOX_SIZE;
|
mbx->timeout = 0;
|
||||||
|
mbx->udelay = 0;
|
||||||
|
|
||||||
mbx->stats.msgs_tx = 0;
|
mbx->stats.msgs_tx = 0;
|
||||||
mbx->stats.msgs_rx = 0;
|
mbx->stats.msgs_rx = 0;
|
||||||
mbx->stats.reqs = 0;
|
mbx->stats.reqs = 0;
|
||||||
mbx->stats.acks = 0;
|
mbx->stats.acks = 0;
|
||||||
mbx->stats.rsts = 0;
|
mbx->stats.rsts = 0;
|
||||||
break;
|
|
||||||
default:
|
mbx->size = IXGBE_VFMAILBOX_SIZE;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PCI_IOV */
|
#endif /* CONFIG_PCI_IOV */
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
|
s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
|
||||||
u32 phy_addr;
|
u32 phy_addr;
|
||||||
|
u16 ext_ability = 0;
|
||||||
|
|
||||||
if (hw->phy.type == ixgbe_phy_unknown) {
|
if (hw->phy.type == ixgbe_phy_unknown) {
|
||||||
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
|
for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
|
||||||
|
@ -65,12 +66,29 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
|
||||||
ixgbe_get_phy_id(hw);
|
ixgbe_get_phy_id(hw);
|
||||||
hw->phy.type =
|
hw->phy.type =
|
||||||
ixgbe_get_phy_type_from_id(hw->phy.id);
|
ixgbe_get_phy_type_from_id(hw->phy.id);
|
||||||
|
|
||||||
|
if (hw->phy.type == ixgbe_phy_unknown) {
|
||||||
|
hw->phy.ops.read_reg(hw,
|
||||||
|
MDIO_PMA_EXTABLE,
|
||||||
|
MDIO_MMD_PMAPMD,
|
||||||
|
&ext_ability);
|
||||||
|
if (ext_ability &
|
||||||
|
(MDIO_PMA_EXTABLE_10GBT |
|
||||||
|
MDIO_PMA_EXTABLE_1000BT))
|
||||||
|
hw->phy.type =
|
||||||
|
ixgbe_phy_cu_unknown;
|
||||||
|
else
|
||||||
|
hw->phy.type =
|
||||||
|
ixgbe_phy_generic;
|
||||||
|
}
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* clear value if nothing found */
|
/* clear value if nothing found */
|
||||||
hw->phy.mdio.prtad = 0;
|
if (status != 0)
|
||||||
|
hw->phy.mdio.prtad = 0;
|
||||||
} else {
|
} else {
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
|
@ -823,7 +841,6 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is guaranteed to be 82599, no need to check for NULL */
|
|
||||||
hw->mac.ops.get_device_caps(hw, &enforce_sfp);
|
hw->mac.ops.get_device_caps(hw, &enforce_sfp);
|
||||||
if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
|
if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
|
||||||
!((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) ||
|
!((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) ||
|
||||||
|
|
|
@ -58,6 +58,10 @@
|
||||||
#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2
|
#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2
|
||||||
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
|
#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3
|
||||||
|
|
||||||
|
/* Flow control defines */
|
||||||
|
#define IXGBE_TAF_SYM_PAUSE 0x400
|
||||||
|
#define IXGBE_TAF_ASM_PAUSE 0x800
|
||||||
|
|
||||||
/* Bit-shift macros */
|
/* Bit-shift macros */
|
||||||
#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24
|
#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 24
|
||||||
#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16
|
#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 16
|
||||||
|
|
|
@ -659,6 +659,8 @@
|
||||||
#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
|
#define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
|
||||||
#define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
|
#define IXGBE_QBRC(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
|
||||||
#define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */
|
#define IXGBE_QBTC(_i) (0x06034 + ((_i) * 0x40)) /* 16 of these */
|
||||||
|
#define IXGBE_QBRC_L(_i) (0x01034 + ((_i) * 0x40)) /* 16 of these */
|
||||||
|
#define IXGBE_QBRC_H(_i) (0x01038 + ((_i) * 0x40)) /* 16 of these */
|
||||||
#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
|
#define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
|
||||||
#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
|
#define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
|
||||||
#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
|
#define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
|
||||||
|
@ -669,6 +671,11 @@
|
||||||
#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */
|
#define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */
|
||||||
#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */
|
#define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */
|
||||||
#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */
|
#define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */
|
||||||
|
#define IXGBE_PCRC8ECL 0x0E810
|
||||||
|
#define IXGBE_PCRC8ECH 0x0E811
|
||||||
|
#define IXGBE_PCRC8ECH_MASK 0x1F
|
||||||
|
#define IXGBE_LDPCECL 0x0E820
|
||||||
|
#define IXGBE_LDPCECH 0x0E821
|
||||||
|
|
||||||
/* Management */
|
/* Management */
|
||||||
#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
|
#define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
|
||||||
|
@ -2691,6 +2698,9 @@ struct ixgbe_info {
|
||||||
#define IXGBE_ERR_EEPROM_VERSION -24
|
#define IXGBE_ERR_EEPROM_VERSION -24
|
||||||
#define IXGBE_ERR_NO_SPACE -25
|
#define IXGBE_ERR_NO_SPACE -25
|
||||||
#define IXGBE_ERR_OVERTEMP -26
|
#define IXGBE_ERR_OVERTEMP -26
|
||||||
|
#define IXGBE_ERR_FC_NOT_NEGOTIATED -27
|
||||||
|
#define IXGBE_ERR_FC_NOT_SUPPORTED -28
|
||||||
|
#define IXGBE_ERR_FLOW_CONTROL -29
|
||||||
#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30
|
#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30
|
||||||
#define IXGBE_ERR_PBA_SECTION -31
|
#define IXGBE_ERR_PBA_SECTION -31
|
||||||
#define IXGBE_ERR_INVALID_ARGUMENT -32
|
#define IXGBE_ERR_INVALID_ARGUMENT -32
|
||||||
|
|
|
@ -251,8 +251,11 @@ static u32 ixgbe_get_supported_physical_layer_X540(struct ixgbe_hw *hw)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
|
* ixgbe_init_eeprom_params_X540 - Initialize EEPROM params
|
||||||
* @hw: pointer to hardware structure
|
* @hw: pointer to hardware structure
|
||||||
|
*
|
||||||
|
* Initializes the EEPROM parameters ixgbe_eeprom_info within the
|
||||||
|
* ixgbe_hw struct in order to set up EEPROM access.
|
||||||
**/
|
**/
|
||||||
static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
|
static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
|
||||||
{
|
{
|
||||||
|
@ -271,7 +274,7 @@ static s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw)
|
||||||
IXGBE_EEPROM_WORD_SIZE_SHIFT);
|
IXGBE_EEPROM_WORD_SIZE_SHIFT);
|
||||||
|
|
||||||
hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
|
hw_dbg(hw, "Eeprom params: type = %d, size = %d\n",
|
||||||
eeprom->type, eeprom->word_size);
|
eeprom->type, eeprom->word_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -871,6 +871,10 @@ struct net_device_ops {
|
||||||
unsigned int sgc);
|
unsigned int sgc);
|
||||||
int (*ndo_fcoe_ddp_done)(struct net_device *dev,
|
int (*ndo_fcoe_ddp_done)(struct net_device *dev,
|
||||||
u16 xid);
|
u16 xid);
|
||||||
|
int (*ndo_fcoe_ddp_target)(struct net_device *dev,
|
||||||
|
u16 xid,
|
||||||
|
struct scatterlist *sgl,
|
||||||
|
unsigned int sgc);
|
||||||
#define NETDEV_FCOE_WWNN 0
|
#define NETDEV_FCOE_WWNN 0
|
||||||
#define NETDEV_FCOE_WWPN 1
|
#define NETDEV_FCOE_WWPN 1
|
||||||
int (*ndo_fcoe_get_wwn)(struct net_device *dev,
|
int (*ndo_fcoe_get_wwn)(struct net_device *dev,
|
||||||
|
|
|
@ -625,6 +625,19 @@ static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type)
|
||||||
rc = ops->ndo_fcoe_get_wwn(real_dev, wwn, type);
|
rc = ops->ndo_fcoe_get_wwn(real_dev, wwn, type);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid,
|
||||||
|
struct scatterlist *sgl, unsigned int sgc)
|
||||||
|
{
|
||||||
|
struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
|
||||||
|
const struct net_device_ops *ops = real_dev->netdev_ops;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (ops->ndo_fcoe_ddp_target)
|
||||||
|
rc = ops->ndo_fcoe_ddp_target(real_dev, xid, sgl, sgc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
|
static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
|
||||||
|
@ -858,6 +871,7 @@ static const struct net_device_ops vlan_netdev_ops = {
|
||||||
.ndo_fcoe_enable = vlan_dev_fcoe_enable,
|
.ndo_fcoe_enable = vlan_dev_fcoe_enable,
|
||||||
.ndo_fcoe_disable = vlan_dev_fcoe_disable,
|
.ndo_fcoe_disable = vlan_dev_fcoe_disable,
|
||||||
.ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
|
.ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn,
|
||||||
|
.ndo_fcoe_ddp_target = vlan_dev_fcoe_ddp_target,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue