Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2014-10-23

This series contains updates to i40e and i40evf.

Jesse modifies the i40e driver to only notify the firmware on link up/down
and qualified module events.  Also simplified the job of managing link
state by using the admin queue receive event for link events as a signal
to tell the driver to update link state.

Jeff (me) cleans up the inconsistent use of tabs for indentation in the admin
queue command header file.

Neerav converts the use of udelay() to usleep_range().

Anjali fixes a bug where receive would stop after some stress by adding
a sleep and restart as well as moving the setting of flow control because
it should be done at a PF level and not a VSI level.

Mitch adds code to handle link events when updating the PF switch, which
allows link information to be properly provided to VFS in all cases.

Catherine adds driver support for 10GBaseT and bumps driver version.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 24, 2014
2 parents 74bca13 + e8720db commit 132fb57
Show file tree
Hide file tree
Showing 9 changed files with 2,268 additions and 2,185 deletions.
2,139 changes: 1,069 additions & 1,070 deletions drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_QSFP_A:
case I40E_DEV_ID_QSFP_B:
case I40E_DEV_ID_QSFP_C:
case I40E_DEV_ID_10G_BASE_T:
hw->mac.type = I40E_MAC_XL710;
break;
case I40E_DEV_ID_VF:
Expand Down Expand Up @@ -1419,6 +1420,33 @@ i40e_status i40e_update_link_info(struct i40e_hw *hw, bool enable_lse)
return status;
}

/**
* i40e_aq_set_phy_int_mask
* @hw: pointer to the hw struct
* @mask: interrupt mask to be set
* @cmd_details: pointer to command details structure or NULL
*
* Set link interrupt mask.
**/
i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw,
u16 mask,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_set_phy_int_mask *cmd =
(struct i40e_aqc_set_phy_int_mask *)&desc.params.raw;
i40e_status status;

i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_set_phy_int_mask);

cmd->event_mask = cpu_to_le16(mask);

status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);

return status;
}

/**
* i40e_aq_add_vsi
* @hw: pointer to the hw struct
Expand Down
33 changes: 28 additions & 5 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,14 @@ static int i40e_get_settings(struct net_device *netdev,
ecmd->supported = SUPPORTED_10000baseKR_Full;
ecmd->advertising = ADVERTISED_10000baseKR_Full;
break;
case I40E_DEV_ID_10G_BASE_T:
ecmd->supported = SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_100baseT_Full;
ecmd->advertising = ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full |
ADVERTISED_100baseT_Full;
break;
default:
/* all the rest are 10G/1G */
ecmd->supported = SUPPORTED_10000baseT_Full |
Expand Down Expand Up @@ -322,9 +330,13 @@ static int i40e_get_settings(struct net_device *netdev,
case I40E_PHY_TYPE_10GBASE_CR1:
case I40E_PHY_TYPE_10GBASE_T:
ecmd->supported = SUPPORTED_Autoneg |
SUPPORTED_10000baseT_Full;
SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_100baseT_Full;
ecmd->advertising = ADVERTISED_Autoneg |
ADVERTISED_10000baseT_Full;
ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full |
ADVERTISED_100baseT_Full;
break;
case I40E_PHY_TYPE_XAUI:
case I40E_PHY_TYPE_XFI:
Expand All @@ -335,14 +347,22 @@ static int i40e_get_settings(struct net_device *netdev,
case I40E_PHY_TYPE_1000BASE_KX:
case I40E_PHY_TYPE_1000BASE_T:
ecmd->supported = SUPPORTED_Autoneg |
SUPPORTED_1000baseT_Full;
SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_100baseT_Full;
ecmd->advertising = ADVERTISED_Autoneg |
ADVERTISED_1000baseT_Full;
ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full |
ADVERTISED_100baseT_Full;
break;
case I40E_PHY_TYPE_100BASE_TX:
ecmd->supported = SUPPORTED_Autoneg |
SUPPORTED_10000baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_100baseT_Full;
ecmd->advertising = ADVERTISED_Autoneg |
ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full |
ADVERTISED_100baseT_Full;
break;
case I40E_PHY_TYPE_SGMII:
Expand Down Expand Up @@ -426,6 +446,9 @@ static int i40e_get_settings(struct net_device *netdev,
case I40E_LINK_SPEED_1GB:
ethtool_cmd_speed_set(ecmd, SPEED_1000);
break;
case I40E_LINK_SPEED_100MB:
ethtool_cmd_speed_set(ecmd, SPEED_100);
break;
default:
break;
}
Expand Down Expand Up @@ -528,7 +551,7 @@ static int i40e_set_settings(struct net_device *netdev,
}
/* If autoneg is currently enabled */
if (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) {
config.abilities = abilities.abilities |
config.abilities = abilities.abilities &
~I40E_AQ_PHY_ENABLE_AN;
change = true;
}
Expand Down
108 changes: 73 additions & 35 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static const char i40e_driver_string[] =

#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 0
#define DRV_VERSION_BUILD 11
#define DRV_VERSION_BUILD 21
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
Expand Down Expand Up @@ -74,6 +74,7 @@ static const struct pci_device_id i40e_pci_tbl[] = {
{PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_A), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_B), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_C), 0},
{PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T), 0},
/* required last entry */
{0, }
};
Expand Down Expand Up @@ -812,7 +813,10 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
struct i40e_eth_stats *oes;
struct i40e_eth_stats *es; /* device's eth stats */
u32 tx_restart, tx_busy;
struct i40e_ring *p;
u32 rx_page, rx_buf;
u64 bytes, packets;
unsigned int start;
u64 rx_p, rx_b;
u64 tx_p, tx_b;
u16 q;
Expand All @@ -836,10 +840,6 @@ static void i40e_update_vsi_stats(struct i40e_vsi *vsi)
rx_buf = 0;
rcu_read_lock();
for (q = 0; q < vsi->num_queue_pairs; q++) {
struct i40e_ring *p;
u64 bytes, packets;
unsigned int start;

/* locate Tx ring */
p = ACCESS_ONCE(vsi->tx_rings[q]);

Expand Down Expand Up @@ -3440,7 +3440,7 @@ static int i40e_pf_txq_wait(struct i40e_pf *pf, int pf_q, bool enable)
if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
break;

udelay(10);
usleep_range(10, 20);
}
if (i >= I40E_QUEUE_WAIT_RETRY_LIMIT)
return -ETIMEDOUT;
Expand All @@ -3466,7 +3466,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
/* warn the TX unit of coming changes */
i40e_pre_tx_queue_cfg(&pf->hw, pf_q, enable);
if (!enable)
udelay(10);
usleep_range(10, 20);

for (j = 0; j < 50; j++) {
tx_reg = rd32(hw, I40E_QTX_ENA(pf_q));
Expand Down Expand Up @@ -3526,7 +3526,7 @@ static int i40e_pf_rxq_wait(struct i40e_pf *pf, int pf_q, bool enable)
if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
break;

udelay(10);
usleep_range(10, 20);
}
if (i >= I40E_QUEUE_WAIT_RETRY_LIMIT)
return -ETIMEDOUT;
Expand Down Expand Up @@ -4449,6 +4449,9 @@ static void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
case I40E_LINK_SPEED_1GB:
strlcpy(speed, "1000 Mbps", SPEED_SIZE);
break;
case I40E_LINK_SPEED_100MB:
strncpy(speed, "100 Mbps", SPEED_SIZE);
break;
default:
break;
}
Expand Down Expand Up @@ -4479,12 +4482,8 @@ static void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
static int i40e_up_complete(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;
u8 set_fc_aq_fail = 0;
int err;

/* force flow control off */
i40e_set_fc(&pf->hw, &set_fc_aq_fail, true);

if (pf->flags & I40E_FLAG_MSIX_ENABLED)
i40e_vsi_configure_msix(vsi);
else
Expand Down Expand Up @@ -5354,10 +5353,14 @@ static void i40e_link_event(struct i40e_pf *pf)
{
bool new_link, old_link;

new_link = (pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP);
/* set this to force the get_link_status call to refresh state */
pf->hw.phy.get_link_info = true;

old_link = (pf->hw.phy.link_info_old.link_info & I40E_AQ_LINK_UP);
new_link = i40e_get_link_status(&pf->hw);

if (new_link == old_link)
if (new_link == old_link &&
new_link == netif_carrier_ok(pf->vsi[pf->lan_vsi]->netdev))
return;
if (!test_bit(__I40E_DOWN, &pf->vsi[pf->lan_vsi]->state))
i40e_print_link_message(pf->vsi[pf->lan_vsi], new_link);
Expand Down Expand Up @@ -5525,33 +5528,20 @@ static void i40e_handle_link_event(struct i40e_pf *pf,
memcpy(&pf->hw.phy.link_info_old, hw_link_info,
sizeof(pf->hw.phy.link_info_old));

/* Do a new status request to re-enable LSE reporting
* and load new status information into the hw struct
* This completely ignores any state information
* in the ARQ event info, instead choosing to always
* issue the AQ update link status command.
*/
i40e_link_event(pf);

/* check for unqualified module, if link is down */
if ((status->link_info & I40E_AQ_MEDIA_AVAILABLE) &&
(!(status->an_info & I40E_AQ_QUALIFIED_MODULE)) &&
(!(status->link_info & I40E_AQ_LINK_UP)))
dev_err(&pf->pdev->dev,
"The driver failed to link because an unqualified module was detected.\n");

/* update link status */
hw_link_info->phy_type = (enum i40e_aq_phy_type)status->phy_type;
hw_link_info->link_speed = (enum i40e_aq_link_speed)status->link_speed;
hw_link_info->link_info = status->link_info;
hw_link_info->an_info = status->an_info;
hw_link_info->ext_info = status->ext_info;
hw_link_info->lse_enable =
le16_to_cpu(status->command_flags) &
I40E_AQ_LSE_ENABLE;

/* process the event */
i40e_link_event(pf);

/* Do a new status request to re-enable LSE reporting
* and load new status information into the hw struct,
* then see if the status changed while processing the
* initial event.
*/
i40e_update_link_info(&pf->hw, true);
i40e_link_event(pf);
}

/**
Expand Down Expand Up @@ -5967,6 +5957,7 @@ static void i40e_send_version(struct i40e_pf *pf)
static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
{
struct i40e_hw *hw = &pf->hw;
u8 set_fc_aq_fail = 0;
i40e_status ret;
u32 v;

Expand Down Expand Up @@ -6038,6 +6029,20 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
if (ret)
goto end_core_reset;

/* driver is only interested in link up/down and module qualification
* reports from firmware
*/
ret = i40e_aq_set_phy_int_mask(&pf->hw,
I40E_AQ_EVENT_LINK_UPDOWN |
I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL);
if (ret)
dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", ret);

/* make sure our flow control settings are restored */
ret = i40e_set_fc(&pf->hw, &set_fc_aq_fail, true);
if (ret)
dev_info(&pf->pdev->dev, "set fc fail, aq_err %d\n", ret);

/* Rebuild the VSIs and VEBs that existed before reset.
* They are still in our local switch element arrays, so only
* need to rebuild the switch model in the HW.
Expand Down Expand Up @@ -6092,6 +6097,13 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
}
}

msleep(75);
ret = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
if (ret) {
dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n",
pf->hw.aq.asq_last_status);
}

/* reinit the misc interrupt */
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
ret = i40e_setup_misc_vector(pf);
Expand Down Expand Up @@ -6305,6 +6317,8 @@ static void i40e_service_task(struct work_struct *work)
#endif
i40e_clean_adminq_subtask(pf);

i40e_link_event(pf);

i40e_service_event_complete(pf);

/* If the tasks have taken longer than one timer cycle or there
Expand Down Expand Up @@ -8715,6 +8729,14 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
i40e_update_link_info(&pf->hw, true);
i40e_link_event(pf);

/* Initialize user-specific link properties */
pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info &
I40E_AQ_AN_COMPLETED) ? true : false);

/* fill in link information and enable LSE reporting */
i40e_update_link_info(&pf->hw, true);
i40e_link_event(pf);

/* Initialize user-specific link properties */
pf->fc_autoneg_status = ((pf->hw.phy.link_info.an_info &
I40E_AQ_AN_COMPLETED) ? true : false);
Expand Down Expand Up @@ -9158,6 +9180,22 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}

/* driver is only interested in link up/down and module qualification
* reports from firmware
*/
err = i40e_aq_set_phy_int_mask(&pf->hw,
I40E_AQ_EVENT_LINK_UPDOWN |
I40E_AQ_EVENT_MODULE_QUAL_FAIL, NULL);
if (err)
dev_info(&pf->pdev->dev, "set phy mask fail, aq_err %d\n", err);

msleep(75);
err = i40e_aq_set_link_restart_an(&pf->hw, true, NULL);
if (err) {
dev_info(&pf->pdev->dev, "link restart failed, aq_err=%d\n",
pf->hw.aq.asq_last_status);
}

/* The main driver is (mostly) up and happy. We need to set this state
* before setting up the misc vector or we get a race and the vector
* ends up disabled forever.
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_prototype.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ enum i40e_status_code i40e_aq_set_phy_config(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
bool atomic_reset);
i40e_status i40e_aq_set_phy_int_mask(struct i40e_hw *hw, u16 mask,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_clear_pxe_mode(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_link_restart_an(struct i40e_hw *hw,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define I40E_DEV_ID_QSFP_A 0x1583
#define I40E_DEV_ID_QSFP_B 0x1584
#define I40E_DEV_ID_QSFP_C 0x1585
#define I40E_DEV_ID_10G_BASE_T 0x1586
#define I40E_DEV_ID_VF 0x154C
#define I40E_DEV_ID_VF_HV 0x1571

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
* that the requested op was completed
* successfully
*/
udelay(10);
usleep_range(10, 20);
reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
if (reg & I40E_VPGEN_VFRSTAT_VFRD_MASK) {
rsd = true;
Expand Down
Loading

0 comments on commit 132fb57

Please sign in to comment.