Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue
Anthony Nguyen says: ==================== Intel Wired LAN Driver Updates 2021-01-26 This series contains updates to the ice, i40e, and igc driver. Henry corrects setting an unspecified protocol to IPPROTO_NONE instead of 0 for IPv6 flexbytes filters for ice. Nick fixes the IPv6 extension header being processed incorrectly and updates the netdev->dev_addr if it exists in hardware as it may have been modified outside the ice driver. Brett ensures a user cannot request more channels than available LAN MSI-X and fixes the minimum allocation logic as it was incorrectly trying to use more MSI-X than allocated for ice. Stefan Assmann minimizes the delay between getting and using the VSI pointer to prevent a possible crash for i40e. Corinna Vinschen fixes link speed advertising for igc. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/net-queue: igc: fix link speed advertising i40e: acquire VSI pointer only after VF is initialized ice: Fix MSI-X vector fallback logic ice: Don't allow more channels than LAN MSI-X available ice: update dev_addr in ice_set_mac_address even if HW filter exists ice: Implement flow for IPv6 next header (extension header) ice: fix FDir IPv6 flexbyte ==================== Link: https://lore.kernel.org/r/20210126221035.658124-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
5ae3a25b32
@ -4046,20 +4046,16 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
|
|||||||
goto error_param;
|
goto error_param;
|
||||||
|
|
||||||
vf = &pf->vf[vf_id];
|
vf = &pf->vf[vf_id];
|
||||||
vsi = pf->vsi[vf->lan_vsi_idx];
|
|
||||||
|
|
||||||
/* When the VF is resetting wait until it is done.
|
/* When the VF is resetting wait until it is done.
|
||||||
* It can take up to 200 milliseconds,
|
* It can take up to 200 milliseconds,
|
||||||
* but wait for up to 300 milliseconds to be safe.
|
* but wait for up to 300 milliseconds to be safe.
|
||||||
* If the VF is indeed in reset, the vsi pointer has
|
* Acquire the VSI pointer only after the VF has been
|
||||||
* to show on the newly loaded vsi under pf->vsi[id].
|
* properly initialized.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 15; i++) {
|
for (i = 0; i < 15; i++) {
|
||||||
if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
|
if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states))
|
||||||
if (i > 0)
|
|
||||||
vsi = pf->vsi[vf->lan_vsi_idx];
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
msleep(20);
|
msleep(20);
|
||||||
}
|
}
|
||||||
if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
|
if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) {
|
||||||
@ -4068,6 +4064,7 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
|
|||||||
ret = -EAGAIN;
|
ret = -EAGAIN;
|
||||||
goto error_param;
|
goto error_param;
|
||||||
}
|
}
|
||||||
|
vsi = pf->vsi[vf->lan_vsi_idx];
|
||||||
|
|
||||||
if (is_multicast_ether_addr(mac)) {
|
if (is_multicast_ether_addr(mac)) {
|
||||||
dev_err(&pf->pdev->dev,
|
dev_err(&pf->pdev->dev,
|
||||||
|
@ -68,7 +68,9 @@
|
|||||||
#define ICE_INT_NAME_STR_LEN (IFNAMSIZ + 16)
|
#define ICE_INT_NAME_STR_LEN (IFNAMSIZ + 16)
|
||||||
#define ICE_AQ_LEN 64
|
#define ICE_AQ_LEN 64
|
||||||
#define ICE_MBXSQ_LEN 64
|
#define ICE_MBXSQ_LEN 64
|
||||||
#define ICE_MIN_MSIX 2
|
#define ICE_MIN_LAN_TXRX_MSIX 1
|
||||||
|
#define ICE_MIN_LAN_OICR_MSIX 1
|
||||||
|
#define ICE_MIN_MSIX (ICE_MIN_LAN_TXRX_MSIX + ICE_MIN_LAN_OICR_MSIX)
|
||||||
#define ICE_FDIR_MSIX 1
|
#define ICE_FDIR_MSIX 1
|
||||||
#define ICE_NO_VSI 0xffff
|
#define ICE_NO_VSI 0xffff
|
||||||
#define ICE_VSI_MAP_CONTIG 0
|
#define ICE_VSI_MAP_CONTIG 0
|
||||||
|
@ -3258,8 +3258,8 @@ ice_set_rxfh(struct net_device *netdev, const u32 *indir, const u8 *key,
|
|||||||
*/
|
*/
|
||||||
static int ice_get_max_txq(struct ice_pf *pf)
|
static int ice_get_max_txq(struct ice_pf *pf)
|
||||||
{
|
{
|
||||||
return min_t(int, num_online_cpus(),
|
return min3(pf->num_lan_msix, (u16)num_online_cpus(),
|
||||||
pf->hw.func_caps.common_cap.num_txq);
|
(u16)pf->hw.func_caps.common_cap.num_txq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3268,8 +3268,8 @@ static int ice_get_max_txq(struct ice_pf *pf)
|
|||||||
*/
|
*/
|
||||||
static int ice_get_max_rxq(struct ice_pf *pf)
|
static int ice_get_max_rxq(struct ice_pf *pf)
|
||||||
{
|
{
|
||||||
return min_t(int, num_online_cpus(),
|
return min3(pf->num_lan_msix, (u16)num_online_cpus(),
|
||||||
pf->hw.func_caps.common_cap.num_rxq);
|
(u16)pf->hw.func_caps.common_cap.num_rxq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1576,7 +1576,13 @@ ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp,
|
|||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
input->ip.v6.l4_header = fsp->h_u.usr_ip6_spec.l4_4_bytes;
|
input->ip.v6.l4_header = fsp->h_u.usr_ip6_spec.l4_4_bytes;
|
||||||
input->ip.v6.tc = fsp->h_u.usr_ip6_spec.tclass;
|
input->ip.v6.tc = fsp->h_u.usr_ip6_spec.tclass;
|
||||||
input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto;
|
|
||||||
|
/* if no protocol requested, use IPPROTO_NONE */
|
||||||
|
if (!fsp->m_u.usr_ip6_spec.l4_proto)
|
||||||
|
input->ip.v6.proto = IPPROTO_NONE;
|
||||||
|
else
|
||||||
|
input->ip.v6.proto = fsp->h_u.usr_ip6_spec.l4_proto;
|
||||||
|
|
||||||
memcpy(input->mask.v6.dst_ip, fsp->m_u.usr_ip6_spec.ip6dst,
|
memcpy(input->mask.v6.dst_ip, fsp->m_u.usr_ip6_spec.ip6dst,
|
||||||
sizeof(struct in6_addr));
|
sizeof(struct in6_addr));
|
||||||
memcpy(input->mask.v6.src_ip, fsp->m_u.usr_ip6_spec.ip6src,
|
memcpy(input->mask.v6.src_ip, fsp->m_u.usr_ip6_spec.ip6src,
|
||||||
|
@ -161,8 +161,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
|
|||||||
|
|
||||||
switch (vsi->type) {
|
switch (vsi->type) {
|
||||||
case ICE_VSI_PF:
|
case ICE_VSI_PF:
|
||||||
vsi->alloc_txq = min_t(int, ice_get_avail_txq_count(pf),
|
vsi->alloc_txq = min3(pf->num_lan_msix,
|
||||||
num_online_cpus());
|
ice_get_avail_txq_count(pf),
|
||||||
|
(u16)num_online_cpus());
|
||||||
if (vsi->req_txq) {
|
if (vsi->req_txq) {
|
||||||
vsi->alloc_txq = vsi->req_txq;
|
vsi->alloc_txq = vsi->req_txq;
|
||||||
vsi->num_txq = vsi->req_txq;
|
vsi->num_txq = vsi->req_txq;
|
||||||
@ -174,8 +175,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
|
|||||||
if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
|
if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) {
|
||||||
vsi->alloc_rxq = 1;
|
vsi->alloc_rxq = 1;
|
||||||
} else {
|
} else {
|
||||||
vsi->alloc_rxq = min_t(int, ice_get_avail_rxq_count(pf),
|
vsi->alloc_rxq = min3(pf->num_lan_msix,
|
||||||
num_online_cpus());
|
ice_get_avail_rxq_count(pf),
|
||||||
|
(u16)num_online_cpus());
|
||||||
if (vsi->req_rxq) {
|
if (vsi->req_rxq) {
|
||||||
vsi->alloc_rxq = vsi->req_rxq;
|
vsi->alloc_rxq = vsi->req_rxq;
|
||||||
vsi->num_rxq = vsi->req_rxq;
|
vsi->num_rxq = vsi->req_rxq;
|
||||||
@ -184,7 +186,9 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi, u16 vf_id)
|
|||||||
|
|
||||||
pf->num_lan_rx = vsi->alloc_rxq;
|
pf->num_lan_rx = vsi->alloc_rxq;
|
||||||
|
|
||||||
vsi->num_q_vectors = max_t(int, vsi->alloc_rxq, vsi->alloc_txq);
|
vsi->num_q_vectors = min_t(int, pf->num_lan_msix,
|
||||||
|
max_t(int, vsi->alloc_rxq,
|
||||||
|
vsi->alloc_txq));
|
||||||
break;
|
break;
|
||||||
case ICE_VSI_VF:
|
case ICE_VSI_VF:
|
||||||
vf = &pf->vf[vsi->vf_id];
|
vf = &pf->vf[vsi->vf_id];
|
||||||
|
@ -3430,18 +3430,14 @@ static int ice_ena_msix_range(struct ice_pf *pf)
|
|||||||
if (v_actual < v_budget) {
|
if (v_actual < v_budget) {
|
||||||
dev_warn(dev, "not enough OS MSI-X vectors. requested = %d, obtained = %d\n",
|
dev_warn(dev, "not enough OS MSI-X vectors. requested = %d, obtained = %d\n",
|
||||||
v_budget, v_actual);
|
v_budget, v_actual);
|
||||||
/* 2 vectors each for LAN and RDMA (traffic + OICR), one for flow director */
|
|
||||||
#define ICE_MIN_LAN_VECS 2
|
|
||||||
#define ICE_MIN_RDMA_VECS 2
|
|
||||||
#define ICE_MIN_VECS (ICE_MIN_LAN_VECS + ICE_MIN_RDMA_VECS + 1)
|
|
||||||
|
|
||||||
if (v_actual < ICE_MIN_LAN_VECS) {
|
if (v_actual < ICE_MIN_MSIX) {
|
||||||
/* error if we can't get minimum vectors */
|
/* error if we can't get minimum vectors */
|
||||||
pci_disable_msix(pf->pdev);
|
pci_disable_msix(pf->pdev);
|
||||||
err = -ERANGE;
|
err = -ERANGE;
|
||||||
goto msix_err;
|
goto msix_err;
|
||||||
} else {
|
} else {
|
||||||
pf->num_lan_msix = ICE_MIN_LAN_VECS;
|
pf->num_lan_msix = ICE_MIN_LAN_TXRX_MSIX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4884,9 +4880,15 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi)
|
|||||||
goto err_update_filters;
|
goto err_update_filters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add filter for new MAC. If filter exists, just return success */
|
/* Add filter for new MAC. If filter exists, return success */
|
||||||
status = ice_fltr_add_mac(vsi, mac, ICE_FWD_TO_VSI);
|
status = ice_fltr_add_mac(vsi, mac, ICE_FWD_TO_VSI);
|
||||||
if (status == ICE_ERR_ALREADY_EXISTS) {
|
if (status == ICE_ERR_ALREADY_EXISTS) {
|
||||||
|
/* Although this MAC filter is already present in hardware it's
|
||||||
|
* possible in some cases (e.g. bonding) that dev_addr was
|
||||||
|
* modified outside of the driver and needs to be restored back
|
||||||
|
* to this value.
|
||||||
|
*/
|
||||||
|
memcpy(netdev->dev_addr, mac, netdev->addr_len);
|
||||||
netdev_dbg(netdev, "filter for MAC %pM already exists\n", mac);
|
netdev_dbg(netdev, "filter for MAC %pM already exists\n", mac);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1923,12 +1923,15 @@ int ice_tx_csum(struct ice_tx_buf *first, struct ice_tx_offload_params *off)
|
|||||||
ICE_TX_CTX_EIPT_IPV4_NO_CSUM;
|
ICE_TX_CTX_EIPT_IPV4_NO_CSUM;
|
||||||
l4_proto = ip.v4->protocol;
|
l4_proto = ip.v4->protocol;
|
||||||
} else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
|
} else if (first->tx_flags & ICE_TX_FLAGS_IPV6) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
tunnel |= ICE_TX_CTX_EIPT_IPV6;
|
tunnel |= ICE_TX_CTX_EIPT_IPV6;
|
||||||
exthdr = ip.hdr + sizeof(*ip.v6);
|
exthdr = ip.hdr + sizeof(*ip.v6);
|
||||||
l4_proto = ip.v6->nexthdr;
|
l4_proto = ip.v6->nexthdr;
|
||||||
if (l4.hdr != exthdr)
|
ret = ipv6_skip_exthdr(skb, exthdr - skb->data,
|
||||||
ipv6_skip_exthdr(skb, exthdr - skb->data,
|
&l4_proto, &frag_off);
|
||||||
&l4_proto, &frag_off);
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define outer transport */
|
/* define outer transport */
|
||||||
|
@ -1675,12 +1675,18 @@ static int igc_ethtool_get_link_ksettings(struct net_device *netdev,
|
|||||||
cmd->base.phy_address = hw->phy.addr;
|
cmd->base.phy_address = hw->phy.addr;
|
||||||
|
|
||||||
/* advertising link modes */
|
/* advertising link modes */
|
||||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half);
|
if (hw->phy.autoneg_advertised & ADVERTISE_10_HALF)
|
||||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full);
|
ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half);
|
||||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half);
|
if (hw->phy.autoneg_advertised & ADVERTISE_10_FULL)
|
||||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full);
|
ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Full);
|
||||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);
|
if (hw->phy.autoneg_advertised & ADVERTISE_100_HALF)
|
||||||
ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full);
|
ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Half);
|
||||||
|
if (hw->phy.autoneg_advertised & ADVERTISE_100_FULL)
|
||||||
|
ethtool_link_ksettings_add_link_mode(cmd, advertising, 100baseT_Full);
|
||||||
|
if (hw->phy.autoneg_advertised & ADVERTISE_1000_FULL)
|
||||||
|
ethtool_link_ksettings_add_link_mode(cmd, advertising, 1000baseT_Full);
|
||||||
|
if (hw->phy.autoneg_advertised & ADVERTISE_2500_FULL)
|
||||||
|
ethtool_link_ksettings_add_link_mode(cmd, advertising, 2500baseT_Full);
|
||||||
|
|
||||||
/* set autoneg settings */
|
/* set autoneg settings */
|
||||||
if (hw->mac.autoneg == 1) {
|
if (hw->mac.autoneg == 1) {
|
||||||
@ -1792,6 +1798,12 @@ igc_ethtool_set_link_ksettings(struct net_device *netdev,
|
|||||||
|
|
||||||
ethtool_convert_link_mode_to_legacy_u32(&advertising,
|
ethtool_convert_link_mode_to_legacy_u32(&advertising,
|
||||||
cmd->link_modes.advertising);
|
cmd->link_modes.advertising);
|
||||||
|
/* Converting to legacy u32 drops ETHTOOL_LINK_MODE_2500baseT_Full_BIT.
|
||||||
|
* We have to check this and convert it to ADVERTISE_2500_FULL
|
||||||
|
* (aka ETHTOOL_LINK_MODE_2500baseX_Full_BIT) explicitly.
|
||||||
|
*/
|
||||||
|
if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 2500baseT_Full))
|
||||||
|
advertising |= ADVERTISE_2500_FULL;
|
||||||
|
|
||||||
if (cmd->base.autoneg == AUTONEG_ENABLE) {
|
if (cmd->base.autoneg == AUTONEG_ENABLE) {
|
||||||
hw->mac.autoneg = 1;
|
hw->mac.autoneg = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user