Commit b1ce98c7 authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue

Tony Nguyen says:

====================
40GbE Intel Wired LAN Driver Updates 2021-04-23

This series contains updates to i40e and iavf drivers.

Aleksandr adds support for VIRTCHNL_VF_CAP_ADV_LINK_SPEED in i40e which
allows for reporting link speed to VF as a value instead of using an
enum; helper functions are created to remove repeated code.

Coiby Xu reduces memory use of i40e when using kdump by reducing Tx, Rx,
and admin queue to minimum values. Current use causes failure of kdump.

Stefan Assmann removes duplicated free calls in iavf.

Haiyue cleans up a loop to return directly when if the value is found
and changes some magic numbers to defines for better maintainability
in iavf.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cbf2ec50 1f70dfc5
...@@ -66,6 +66,8 @@ ...@@ -66,6 +66,8 @@
#define I40E_FDIR_RING_COUNT 32 #define I40E_FDIR_RING_COUNT 32
#define I40E_MAX_AQ_BUF_SIZE 4096 #define I40E_MAX_AQ_BUF_SIZE 4096
#define I40E_AQ_LEN 256 #define I40E_AQ_LEN 256
#define I40E_MIN_ARQ_LEN 1
#define I40E_MIN_ASQ_LEN 2
#define I40E_AQ_WORK_LIMIT 66 /* max number of VFs + a little */ #define I40E_AQ_WORK_LIMIT 66 /* max number of VFs + a little */
#define I40E_MAX_USER_PRIORITY 8 #define I40E_MAX_USER_PRIORITY 8
#define I40E_DEFAULT_TRAFFIC_CLASS BIT(0) #define I40E_DEFAULT_TRAFFIC_CLASS BIT(0)
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <generated/utsrelease.h> #include <generated/utsrelease.h>
#include <linux/crash_dump.h>
/* Local includes */ /* Local includes */
#include "i40e.h" #include "i40e.h"
...@@ -11039,6 +11040,11 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi) ...@@ -11039,6 +11040,11 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
return -ENODATA; return -ENODATA;
} }
if (is_kdump_kernel()) {
vsi->num_tx_desc = I40E_MIN_NUM_DESCRIPTORS;
vsi->num_rx_desc = I40E_MIN_NUM_DESCRIPTORS;
}
return 0; return 0;
} }
...@@ -15342,8 +15348,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -15342,8 +15348,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_check_recovery_mode(pf); i40e_check_recovery_mode(pf);
hw->aq.num_arq_entries = I40E_AQ_LEN; if (is_kdump_kernel()) {
hw->aq.num_asq_entries = I40E_AQ_LEN; hw->aq.num_arq_entries = I40E_MIN_ARQ_LEN;
hw->aq.num_asq_entries = I40E_MIN_ASQ_LEN;
} else {
hw->aq.num_arq_entries = I40E_AQ_LEN;
hw->aq.num_asq_entries = I40E_AQ_LEN;
}
hw->aq.arq_buf_size = I40E_MAX_AQ_BUF_SIZE; hw->aq.arq_buf_size = I40E_MAX_AQ_BUF_SIZE;
hw->aq.asq_buf_size = I40E_MAX_AQ_BUF_SIZE; hw->aq.asq_buf_size = I40E_MAX_AQ_BUF_SIZE;
pf->adminq_work_limit = I40E_AQ_WORK_LIMIT; pf->adminq_work_limit = I40E_AQ_WORK_LIMIT;
...@@ -15506,6 +15517,14 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -15506,6 +15517,14 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) if (err)
goto err_switch_setup; goto err_switch_setup;
/* Reduce Tx and Rx pairs for kdump
* When MSI-X is enabled, it's not allowed to use more TC queue
* pairs than MSI-X vectors (pf->num_lan_msix) exist. Thus
* vsi->num_queue_pairs will be equal to pf->num_lan_msix, i.e., 1.
*/
if (is_kdump_kernel())
pf->num_lan_msix = 1;
pf->udp_tunnel_nic.set_port = i40e_udp_tunnel_set_port; pf->udp_tunnel_nic.set_port = i40e_udp_tunnel_set_port;
pf->udp_tunnel_nic.unset_port = i40e_udp_tunnel_unset_port; pf->udp_tunnel_nic.unset_port = i40e_udp_tunnel_unset_port;
pf->udp_tunnel_nic.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP; pf->udp_tunnel_nic.flags = UDP_TUNNEL_NIC_INFO_MAY_SLEEP;
......
...@@ -39,6 +39,66 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf, ...@@ -39,6 +39,66 @@ static void i40e_vc_vf_broadcast(struct i40e_pf *pf,
} }
} }
/**
* i40e_vc_link_speed2mbps
* converts i40e_aq_link_speed to integer value of Mbps
* @link_speed: the speed to convert
*
* return the speed as direct value of Mbps.
**/
static u32
i40e_vc_link_speed2mbps(enum i40e_aq_link_speed link_speed)
{
switch (link_speed) {
case I40E_LINK_SPEED_100MB:
return SPEED_100;
case I40E_LINK_SPEED_1GB:
return SPEED_1000;
case I40E_LINK_SPEED_2_5GB:
return SPEED_2500;
case I40E_LINK_SPEED_5GB:
return SPEED_5000;
case I40E_LINK_SPEED_10GB:
return SPEED_10000;
case I40E_LINK_SPEED_20GB:
return SPEED_20000;
case I40E_LINK_SPEED_25GB:
return SPEED_25000;
case I40E_LINK_SPEED_40GB:
return SPEED_40000;
case I40E_LINK_SPEED_UNKNOWN:
return SPEED_UNKNOWN;
}
return SPEED_UNKNOWN;
}
/**
* i40e_set_vf_link_state
* @vf: pointer to the VF structure
* @pfe: pointer to PF event structure
* @ls: pointer to link status structure
*
* set a link state on a single vf
**/
static void i40e_set_vf_link_state(struct i40e_vf *vf,
struct virtchnl_pf_event *pfe, struct i40e_link_status *ls)
{
u8 link_status = ls->link_info & I40E_AQ_LINK_UP;
if (vf->link_forced)
link_status = vf->link_up;
if (vf->driver_caps & VIRTCHNL_VF_CAP_ADV_LINK_SPEED) {
pfe->event_data.link_event_adv.link_speed = link_status ?
i40e_vc_link_speed2mbps(ls->link_speed) : 0;
pfe->event_data.link_event_adv.link_status = link_status;
} else {
pfe->event_data.link_event.link_speed = link_status ?
i40e_virtchnl_link_speed(ls->link_speed) : 0;
pfe->event_data.link_event.link_status = link_status;
}
}
/** /**
* i40e_vc_notify_vf_link_state * i40e_vc_notify_vf_link_state
* @vf: pointer to the VF structure * @vf: pointer to the VF structure
...@@ -55,16 +115,9 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf) ...@@ -55,16 +115,9 @@ static void i40e_vc_notify_vf_link_state(struct i40e_vf *vf)
pfe.event = VIRTCHNL_EVENT_LINK_CHANGE; pfe.event = VIRTCHNL_EVENT_LINK_CHANGE;
pfe.severity = PF_EVENT_SEVERITY_INFO; pfe.severity = PF_EVENT_SEVERITY_INFO;
if (vf->link_forced) {
pfe.event_data.link_event.link_status = vf->link_up; i40e_set_vf_link_state(vf, &pfe, ls);
pfe.event_data.link_event.link_speed =
(vf->link_up ? i40e_virtchnl_link_speed(ls->link_speed) : 0);
} else {
pfe.event_data.link_event.link_status =
ls->link_info & I40E_AQ_LINK_UP;
pfe.event_data.link_event.link_speed =
i40e_virtchnl_link_speed(ls->link_speed);
}
i40e_aq_send_msg_to_vf(hw, abs_vf_id, VIRTCHNL_OP_EVENT, i40e_aq_send_msg_to_vf(hw, abs_vf_id, VIRTCHNL_OP_EVENT,
0, (u8 *)&pfe, sizeof(pfe), NULL); 0, (u8 *)&pfe, sizeof(pfe), NULL);
} }
...@@ -1949,6 +2002,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) ...@@ -1949,6 +2002,7 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
VIRTCHNL_VF_OFFLOAD_VLAN; VIRTCHNL_VF_OFFLOAD_VLAN;
vfres->vf_cap_flags = VIRTCHNL_VF_OFFLOAD_L2; vfres->vf_cap_flags = VIRTCHNL_VF_OFFLOAD_L2;
vfres->vf_cap_flags |= VIRTCHNL_VF_CAP_ADV_LINK_SPEED;
vsi = pf->vsi[vf->lan_vsi_idx]; vsi = pf->vsi[vf->lan_vsi_idx];
if (!vsi->info.pvid) if (!vsi->info.pvid)
vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_VLAN; vfres->vf_cap_flags |= VIRTCHNL_VF_OFFLOAD_VLAN;
...@@ -3696,26 +3750,8 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg) ...@@ -3696,26 +3750,8 @@ static int i40e_vc_add_qch_msg(struct i40e_vf *vf, u8 *msg)
} }
/* get link speed in MB to validate rate limit */ /* get link speed in MB to validate rate limit */
switch (ls->link_speed) { speed = i40e_vc_link_speed2mbps(ls->link_speed);
case VIRTCHNL_LINK_SPEED_100MB: if (speed == SPEED_UNKNOWN) {
speed = SPEED_100;
break;
case VIRTCHNL_LINK_SPEED_1GB:
speed = SPEED_1000;
break;
case VIRTCHNL_LINK_SPEED_10GB:
speed = SPEED_10000;
break;
case VIRTCHNL_LINK_SPEED_20GB:
speed = SPEED_20000;
break;
case VIRTCHNL_LINK_SPEED_25GB:
speed = SPEED_25000;
break;
case VIRTCHNL_LINK_SPEED_40GB:
speed = SPEED_40000;
break;
default:
dev_err(&pf->pdev->dev, dev_err(&pf->pdev->dev,
"Cannot detect link speed\n"); "Cannot detect link speed\n");
aq_ret = I40E_ERR_PARAM; aq_ret = I40E_ERR_PARAM;
...@@ -4464,23 +4500,17 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link) ...@@ -4464,23 +4500,17 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
switch (link) { switch (link) {
case IFLA_VF_LINK_STATE_AUTO: case IFLA_VF_LINK_STATE_AUTO:
vf->link_forced = false; vf->link_forced = false;
pfe.event_data.link_event.link_status = i40e_set_vf_link_state(vf, &pfe, ls);
pf->hw.phy.link_info.link_info & I40E_AQ_LINK_UP;
pfe.event_data.link_event.link_speed =
(enum virtchnl_link_speed)
pf->hw.phy.link_info.link_speed;
break; break;
case IFLA_VF_LINK_STATE_ENABLE: case IFLA_VF_LINK_STATE_ENABLE:
vf->link_forced = true; vf->link_forced = true;
vf->link_up = true; vf->link_up = true;
pfe.event_data.link_event.link_status = true; i40e_set_vf_link_state(vf, &pfe, ls);
pfe.event_data.link_event.link_speed = i40e_virtchnl_link_speed(ls->link_speed);
break; break;
case IFLA_VF_LINK_STATE_DISABLE: case IFLA_VF_LINK_STATE_DISABLE:
vf->link_forced = true; vf->link_forced = true;
vf->link_up = false; vf->link_up = false;
pfe.event_data.link_event.link_status = false; i40e_set_vf_link_state(vf, &pfe, ls);
pfe.event_data.link_event.link_speed = 0;
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
......
...@@ -939,7 +939,7 @@ iavf_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp, ...@@ -939,7 +939,7 @@ iavf_parse_rx_flow_user_data(struct ethtool_rx_flow_spec *fsp,
if (!(fsp->flow_type & FLOW_EXT)) if (!(fsp->flow_type & FLOW_EXT))
return 0; return 0;
for (i = 0; i < 2; i++) { for (i = 0; i < IAVF_FLEX_WORD_NUM; i++) {
#define IAVF_USERDEF_FLEX_WORD_M GENMASK(15, 0) #define IAVF_USERDEF_FLEX_WORD_M GENMASK(15, 0)
#define IAVF_USERDEF_FLEX_OFFS_S 16 #define IAVF_USERDEF_FLEX_OFFS_S 16
#define IAVF_USERDEF_FLEX_OFFS_M GENMASK(31, IAVF_USERDEF_FLEX_OFFS_S) #define IAVF_USERDEF_FLEX_OFFS_M GENMASK(31, IAVF_USERDEF_FLEX_OFFS_S)
......
...@@ -54,8 +54,13 @@ iavf_fill_fdir_gtpu_hdr(struct iavf_fdir_fltr *fltr, ...@@ -54,8 +54,13 @@ iavf_fill_fdir_gtpu_hdr(struct iavf_fdir_fltr *fltr,
#define IAVF_GTPU_HDR_TEID_OFFS0 4 #define IAVF_GTPU_HDR_TEID_OFFS0 4
#define IAVF_GTPU_HDR_TEID_OFFS1 6 #define IAVF_GTPU_HDR_TEID_OFFS1 6
#define IAVF_GTPU_HDR_N_PDU_AND_NEXT_EXTHDR_OFFS 10 #define IAVF_GTPU_HDR_N_PDU_AND_NEXT_EXTHDR_OFFS 10
#define IAVF_GTPU_HDR_NEXT_EXTHDR_TYPE_MASK 0x00FF /* skip N_PDU */
/* PDU Session Container Extension Header (PSC) */
#define IAVF_GTPU_PSC_EXTHDR_TYPE 0x85
#define IAVF_GTPU_HDR_PSC_PDU_TYPE_AND_QFI_OFFS 13 #define IAVF_GTPU_HDR_PSC_PDU_TYPE_AND_QFI_OFFS 13
#define IAVF_GTPU_PSC_EXTHDR_TYPE 0x85 /* PDU Session Container Extension Header */ #define IAVF_GTPU_HDR_PSC_PDU_QFI_MASK 0x3F /* skip Type */
#define IAVF_GTPU_EH_QFI_IDX 1
if (fltr->flex_words[i].offset < adj_offs) if (fltr->flex_words[i].offset < adj_offs)
return -EINVAL; return -EINVAL;
...@@ -71,7 +76,9 @@ iavf_fill_fdir_gtpu_hdr(struct iavf_fdir_fltr *fltr, ...@@ -71,7 +76,9 @@ iavf_fill_fdir_gtpu_hdr(struct iavf_fdir_fltr *fltr,
} }
break; break;
case IAVF_GTPU_HDR_N_PDU_AND_NEXT_EXTHDR_OFFS: case IAVF_GTPU_HDR_N_PDU_AND_NEXT_EXTHDR_OFFS:
if ((fltr->flex_words[i].word & 0xff) != IAVF_GTPU_PSC_EXTHDR_TYPE) if ((fltr->flex_words[i].word &
IAVF_GTPU_HDR_NEXT_EXTHDR_TYPE_MASK) !=
IAVF_GTPU_PSC_EXTHDR_TYPE)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!ehdr) if (!ehdr)
ehdr = &proto_hdrs->proto_hdr[proto_hdrs->count++]; ehdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
...@@ -80,7 +87,9 @@ iavf_fill_fdir_gtpu_hdr(struct iavf_fdir_fltr *fltr, ...@@ -80,7 +87,9 @@ iavf_fill_fdir_gtpu_hdr(struct iavf_fdir_fltr *fltr,
case IAVF_GTPU_HDR_PSC_PDU_TYPE_AND_QFI_OFFS: case IAVF_GTPU_HDR_PSC_PDU_TYPE_AND_QFI_OFFS:
if (!ehdr) if (!ehdr)
return -EINVAL; return -EINVAL;
ehdr->buffer[1] = fltr->flex_words[i].word & 0x3F; ehdr->buffer[IAVF_GTPU_EH_QFI_IDX] =
fltr->flex_words[i].word &
IAVF_GTPU_HDR_PSC_PDU_QFI_MASK;
VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(ehdr, GTPU_EH, QFI); VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(ehdr, GTPU_EH, QFI);
break; break;
default: default:
...@@ -713,7 +722,6 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f ...@@ -713,7 +722,6 @@ void iavf_print_fdir_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *f
bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr) bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *fltr)
{ {
struct iavf_fdir_fltr *tmp; struct iavf_fdir_fltr *tmp;
bool ret = false;
list_for_each_entry(tmp, &adapter->fdir_list_head, list) { list_for_each_entry(tmp, &adapter->fdir_list_head, list) {
if (tmp->flow_type != fltr->flow_type) if (tmp->flow_type != fltr->flow_type)
...@@ -724,13 +732,11 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr * ...@@ -724,13 +732,11 @@ bool iavf_fdir_is_dup_fltr(struct iavf_adapter *adapter, struct iavf_fdir_fltr *
!memcmp(&tmp->ip_data, &fltr->ip_data, !memcmp(&tmp->ip_data, &fltr->ip_data,
sizeof(fltr->ip_data)) && sizeof(fltr->ip_data)) &&
!memcmp(&tmp->ext_data, &fltr->ext_data, !memcmp(&tmp->ext_data, &fltr->ext_data,
sizeof(fltr->ext_data))) { sizeof(fltr->ext_data)))
ret = true; return true;
break;
}
} }
return ret; return false;
} }
/** /**
......
...@@ -35,6 +35,11 @@ enum iavf_fdir_flow_type { ...@@ -35,6 +35,11 @@ enum iavf_fdir_flow_type {
IAVF_FDIR_FLOW_PTYPE_MAX, IAVF_FDIR_FLOW_PTYPE_MAX,
}; };
/* Must not exceed the array element number of '__be32 data[2]' in the ethtool
* 'struct ethtool_rx_flow_spec.m_ext.data[2]' to express the flex-byte (word).
*/
#define IAVF_FLEX_WORD_NUM 2
struct iavf_flex_word { struct iavf_flex_word {
u16 offset; u16 offset;
u16 word; u16 word;
...@@ -71,7 +76,7 @@ struct iavf_fdir_ip { ...@@ -71,7 +76,7 @@ struct iavf_fdir_ip {
}; };
struct iavf_fdir_extra { struct iavf_fdir_extra {
u32 usr_def[2]; u32 usr_def[IAVF_FLEX_WORD_NUM];
}; };
/* bookkeeping of Flow Director filters */ /* bookkeeping of Flow Director filters */
...@@ -95,7 +100,7 @@ struct iavf_fdir_fltr { ...@@ -95,7 +100,7 @@ struct iavf_fdir_fltr {
/* flex byte filter data */ /* flex byte filter data */
u8 ip_ver; /* used to adjust the flex offset, 4 : IPv4, 6 : IPv6 */ u8 ip_ver; /* used to adjust the flex offset, 4 : IPv4, 6 : IPv6 */
u8 flex_cnt; u8 flex_cnt;
struct iavf_flex_word flex_words[2]; struct iavf_flex_word flex_words[IAVF_FLEX_WORD_NUM];
u32 flow_id; u32 flow_id;
......
...@@ -3940,8 +3940,6 @@ static void iavf_remove(struct pci_dev *pdev) ...@@ -3940,8 +3940,6 @@ static void iavf_remove(struct pci_dev *pdev)
iounmap(hw->hw_addr); iounmap(hw->hw_addr);
pci_release_regions(pdev); pci_release_regions(pdev);
iavf_free_all_tx_resources(adapter);
iavf_free_all_rx_resources(adapter);
iavf_free_queues(adapter); iavf_free_queues(adapter);
kfree(adapter->vf_res); kfree(adapter->vf_res);
spin_lock_bh(&adapter->mac_vlan_list_lock); spin_lock_bh(&adapter->mac_vlan_list_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment