Commit 2102a27e authored by Jakub Kicinski's avatar Jakub Kicinski

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 2022-03-01

This series contains updates to iavf driver only.

Mateusz adds support for interrupt moderation for 50G and 100G speeds
as well as support for the driver to specify a request as its primary
MAC address. He also refactors VLAN V2 capability exchange into more
generic extended capabilities to ease the addition of future
capabilities. Finally, he corrects the incorrect return of iavf_status
values and removes non-inclusive language.

Minghao Chi removes unneeded variables, instead returning values
directly.

* '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  iavf: Remove non-inclusive language
  iavf: Fix incorrect use of assigning iavf_status to int
  iavf: stop leaking iavf_status as "errno" values
  iavf: remove redundant ret variable
  iavf: Add usage of new virtchnl format to set default MAC
  iavf: refactor processing of VLAN V2 capability message
  iavf: Add support for 50G/100G in AIM algorithm
====================

Link: https://lore.kernel.org/r/20220301185939.3005116-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 43250901 0a62b209
......@@ -44,6 +44,9 @@
#define DEFAULT_DEBUG_LEVEL_SHIFT 3
#define PFX "iavf: "
int iavf_status_to_errno(enum iavf_status status);
int virtchnl_status_to_errno(enum virtchnl_status_code v_status);
/* VSI state flags shared with common code */
enum iavf_vsi_state_t {
__IAVF_VSI_DOWN,
......@@ -188,7 +191,7 @@ enum iavf_state_t {
__IAVF_REMOVE, /* driver is being unloaded */
__IAVF_INIT_VERSION_CHECK, /* aq msg sent, awaiting reply */
__IAVF_INIT_GET_RESOURCES, /* aq msg sent, awaiting reply */
__IAVF_INIT_GET_OFFLOAD_VLAN_V2_CAPS,
__IAVF_INIT_EXTENDED_CAPS, /* process extended caps which require aq msg exchange */
__IAVF_INIT_CONFIG_ADAPTER,
__IAVF_INIT_SW, /* got resources, setting up structs */
__IAVF_INIT_FAILED, /* init failed, restarting procedure */
......@@ -329,6 +332,21 @@ struct iavf_adapter {
#define IAVF_FLAG_AQ_ENABLE_STAG_VLAN_INSERTION BIT_ULL(37)
#define IAVF_FLAG_AQ_DISABLE_STAG_VLAN_INSERTION BIT_ULL(38)
/* flags for processing extended capability messages during
* __IAVF_INIT_EXTENDED_CAPS. Each capability exchange requires
* both a SEND and a RECV step, which must be processed in sequence.
*
* During the __IAVF_INIT_EXTENDED_CAPS state, the driver will
* process one flag at a time during each state loop.
*/
u64 extended_caps;
#define IAVF_EXTENDED_CAP_SEND_VLAN_V2 BIT_ULL(0)
#define IAVF_EXTENDED_CAP_RECV_VLAN_V2 BIT_ULL(1)
#define IAVF_EXTENDED_CAPS \
(IAVF_EXTENDED_CAP_SEND_VLAN_V2 | \
IAVF_EXTENDED_CAP_RECV_VLAN_V2)
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
......@@ -510,7 +528,7 @@ void iavf_add_vlans(struct iavf_adapter *adapter);
void iavf_del_vlans(struct iavf_adapter *adapter);
void iavf_set_promiscuous(struct iavf_adapter *adapter, int flags);
void iavf_request_stats(struct iavf_adapter *adapter);
void iavf_request_reset(struct iavf_adapter *adapter);
int iavf_request_reset(struct iavf_adapter *adapter);
void iavf_get_hena(struct iavf_adapter *adapter);
void iavf_set_hena(struct iavf_adapter *adapter);
void iavf_set_rss_key(struct iavf_adapter *adapter);
......
......@@ -131,8 +131,8 @@ const char *iavf_stat_str(struct iavf_hw *hw, enum iavf_status stat_err)
return "IAVF_ERR_INVALID_MAC_ADDR";
case IAVF_ERR_DEVICE_NOT_SUPPORTED:
return "IAVF_ERR_DEVICE_NOT_SUPPORTED";
case IAVF_ERR_MASTER_REQUESTS_PENDING:
return "IAVF_ERR_MASTER_REQUESTS_PENDING";
case IAVF_ERR_PRIMARY_REQUESTS_PENDING:
return "IAVF_ERR_PRIMARY_REQUESTS_PENDING";
case IAVF_ERR_INVALID_LINK_SETTINGS:
return "IAVF_ERR_INVALID_LINK_SETTINGS";
case IAVF_ERR_AUTONEG_NOT_COMPLETE:
......
This diff is collapsed.
......@@ -18,7 +18,7 @@ enum iavf_status {
IAVF_ERR_ADAPTER_STOPPED = -9,
IAVF_ERR_INVALID_MAC_ADDR = -10,
IAVF_ERR_DEVICE_NOT_SUPPORTED = -11,
IAVF_ERR_MASTER_REQUESTS_PENDING = -12,
IAVF_ERR_PRIMARY_REQUESTS_PENDING = -12,
IAVF_ERR_INVALID_LINK_SETTINGS = -13,
IAVF_ERR_AUTONEG_NOT_COMPLETE = -14,
IAVF_ERR_RESET_FAILED = -15,
......
......@@ -374,29 +374,60 @@ static inline bool iavf_container_is_rx(struct iavf_q_vector *q_vector,
return &q_vector->rx == rc;
}
static inline unsigned int iavf_itr_divisor(struct iavf_q_vector *q_vector)
#define IAVF_AIM_MULTIPLIER_100G 2560
#define IAVF_AIM_MULTIPLIER_50G 1280
#define IAVF_AIM_MULTIPLIER_40G 1024
#define IAVF_AIM_MULTIPLIER_20G 512
#define IAVF_AIM_MULTIPLIER_10G 256
#define IAVF_AIM_MULTIPLIER_1G 32
static unsigned int iavf_mbps_itr_multiplier(u32 speed_mbps)
{
unsigned int divisor;
switch (speed_mbps) {
case SPEED_100000:
return IAVF_AIM_MULTIPLIER_100G;
case SPEED_50000:
return IAVF_AIM_MULTIPLIER_50G;
case SPEED_40000:
return IAVF_AIM_MULTIPLIER_40G;
case SPEED_25000:
case SPEED_20000:
return IAVF_AIM_MULTIPLIER_20G;
case SPEED_10000:
default:
return IAVF_AIM_MULTIPLIER_10G;
case SPEED_1000:
case SPEED_100:
return IAVF_AIM_MULTIPLIER_1G;
}
}
switch (q_vector->adapter->link_speed) {
static unsigned int
iavf_virtchnl_itr_multiplier(enum virtchnl_link_speed speed_virtchnl)
{
switch (speed_virtchnl) {
case VIRTCHNL_LINK_SPEED_40GB:
divisor = IAVF_ITR_ADAPTIVE_MIN_INC * 1024;
break;
return IAVF_AIM_MULTIPLIER_40G;
case VIRTCHNL_LINK_SPEED_25GB:
case VIRTCHNL_LINK_SPEED_20GB:
divisor = IAVF_ITR_ADAPTIVE_MIN_INC * 512;
break;
default:
return IAVF_AIM_MULTIPLIER_20G;
case VIRTCHNL_LINK_SPEED_10GB:
divisor = IAVF_ITR_ADAPTIVE_MIN_INC * 256;
break;
default:
return IAVF_AIM_MULTIPLIER_10G;
case VIRTCHNL_LINK_SPEED_1GB:
case VIRTCHNL_LINK_SPEED_100MB:
divisor = IAVF_ITR_ADAPTIVE_MIN_INC * 32;
break;
return IAVF_AIM_MULTIPLIER_1G;
}
}
return divisor;
static unsigned int iavf_itr_divisor(struct iavf_adapter *adapter)
{
if (ADV_LINK_SUPPORT(adapter))
return IAVF_ITR_ADAPTIVE_MIN_INC *
iavf_mbps_itr_multiplier(adapter->link_speed_mbps);
else
return IAVF_ITR_ADAPTIVE_MIN_INC *
iavf_virtchnl_itr_multiplier(adapter->link_speed);
}
/**
......@@ -586,8 +617,9 @@ static void iavf_update_itr(struct iavf_q_vector *q_vector,
* Use addition as we have already recorded the new latency flag
* for the ITR value.
*/
itr += DIV_ROUND_UP(avg_wire_size, iavf_itr_divisor(q_vector)) *
IAVF_ITR_ADAPTIVE_MIN_INC;
itr += DIV_ROUND_UP(avg_wire_size,
iavf_itr_divisor(q_vector->adapter)) *
IAVF_ITR_ADAPTIVE_MIN_INC;
if ((itr & IAVF_ITR_MASK) > IAVF_ITR_ADAPTIVE_MAX_USECS) {
itr &= IAVF_ITR_ADAPTIVE_LATENCY;
......
......@@ -22,17 +22,17 @@ static int iavf_send_pf_msg(struct iavf_adapter *adapter,
enum virtchnl_ops op, u8 *msg, u16 len)
{
struct iavf_hw *hw = &adapter->hw;
enum iavf_status err;
enum iavf_status status;
if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
return 0; /* nothing to see here, move along */
err = iavf_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
if (err)
dev_dbg(&adapter->pdev->dev, "Unable to send opcode %d to PF, err %s, aq_err %s\n",
op, iavf_stat_str(hw, err),
status = iavf_aq_send_msg_to_pf(hw, op, 0, msg, len, NULL);
if (status)
dev_dbg(&adapter->pdev->dev, "Unable to send opcode %d to PF, status %s, aq_err %s\n",
op, iavf_stat_str(hw, status),
iavf_aq_str(hw, hw->aq.asq_last_status));
return err;
return iavf_status_to_errno(status);
}
/**
......@@ -54,6 +54,41 @@ int iavf_send_api_ver(struct iavf_adapter *adapter)
sizeof(vvi));
}
/**
* iavf_poll_virtchnl_msg
* @hw: HW configuration structure
* @event: event to populate on success
* @op_to_poll: requested virtchnl op to poll for
*
* Initialize poll for virtchnl msg matching the requested_op. Returns 0
* if a message of the correct opcode is in the queue or an error code
* if no message matching the op code is waiting and other failures.
*/
static int
iavf_poll_virtchnl_msg(struct iavf_hw *hw, struct iavf_arq_event_info *event,
enum virtchnl_ops op_to_poll)
{
enum virtchnl_ops received_op;
enum iavf_status status;
u32 v_retval;
while (1) {
/* When the AQ is empty, iavf_clean_arq_element will return
* nonzero and this loop will terminate.
*/
status = iavf_clean_arq_element(hw, event, NULL);
if (status != IAVF_SUCCESS)
return iavf_status_to_errno(status);
received_op =
(enum virtchnl_ops)le32_to_cpu(event->desc.cookie_high);
if (op_to_poll == received_op)
break;
}
v_retval = le32_to_cpu(event->desc.cookie_low);
return virtchnl_status_to_errno((enum virtchnl_status_code)v_retval);
}
/**
* iavf_verify_api_ver
* @adapter: adapter structure
......@@ -65,55 +100,28 @@ int iavf_send_api_ver(struct iavf_adapter *adapter)
**/
int iavf_verify_api_ver(struct iavf_adapter *adapter)
{
struct virtchnl_version_info *pf_vvi;
struct iavf_hw *hw = &adapter->hw;
struct iavf_arq_event_info event;
enum virtchnl_ops op;
enum iavf_status err;
int err;
event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
if (!event.msg_buf) {
err = -ENOMEM;
goto out;
}
while (1) {
err = iavf_clean_arq_element(hw, &event, NULL);
/* When the AQ is empty, iavf_clean_arq_element will return
* nonzero and this loop will terminate.
*/
if (err)
goto out_alloc;
op =
(enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
if (op == VIRTCHNL_OP_VERSION)
break;
}
event.msg_buf = kzalloc(IAVF_MAX_AQ_BUF_SIZE, GFP_KERNEL);
if (!event.msg_buf)
return -ENOMEM;
err = (enum iavf_status)le32_to_cpu(event.desc.cookie_low);
if (err)
goto out_alloc;
err = iavf_poll_virtchnl_msg(&adapter->hw, &event, VIRTCHNL_OP_VERSION);
if (!err) {
struct virtchnl_version_info *pf_vvi =
(struct virtchnl_version_info *)event.msg_buf;
adapter->pf_version = *pf_vvi;
if (op != VIRTCHNL_OP_VERSION) {
dev_info(&adapter->pdev->dev, "Invalid reply type %d from PF\n",
op);
err = -EIO;
goto out_alloc;
if (pf_vvi->major > VIRTCHNL_VERSION_MAJOR ||
(pf_vvi->major == VIRTCHNL_VERSION_MAJOR &&
pf_vvi->minor > VIRTCHNL_VERSION_MINOR))
err = -EIO;
}
pf_vvi = (struct virtchnl_version_info *)event.msg_buf;
adapter->pf_version = *pf_vvi;
if ((pf_vvi->major > VIRTCHNL_VERSION_MAJOR) ||
((pf_vvi->major == VIRTCHNL_VERSION_MAJOR) &&
(pf_vvi->minor > VIRTCHNL_VERSION_MINOR)))
err = -EIO;
out_alloc:
kfree(event.msg_buf);
out:
return err;
}
......@@ -208,33 +216,17 @@ int iavf_get_vf_config(struct iavf_adapter *adapter)
{
struct iavf_hw *hw = &adapter->hw;
struct iavf_arq_event_info event;
enum virtchnl_ops op;
enum iavf_status err;
u16 len;
int err;
len = sizeof(struct virtchnl_vf_resource) +
len = sizeof(struct virtchnl_vf_resource) +
IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource);
event.buf_len = len;
event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
if (!event.msg_buf) {
err = -ENOMEM;
goto out;
}
while (1) {
/* When the AQ is empty, iavf_clean_arq_element will return
* nonzero and this loop will terminate.
*/
err = iavf_clean_arq_element(hw, &event, NULL);
if (err)
goto out_alloc;
op =
(enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
if (op == VIRTCHNL_OP_GET_VF_RESOURCES)
break;
}
event.msg_buf = kzalloc(len, GFP_KERNEL);
if (!event.msg_buf)
return -ENOMEM;
err = (enum iavf_status)le32_to_cpu(event.desc.cookie_low);
err = iavf_poll_virtchnl_msg(hw, &event, VIRTCHNL_OP_GET_VF_RESOURCES);
memcpy(adapter->vf_res, event.msg_buf, min(event.msg_len, len));
/* some PFs send more queues than we should have so validate that
......@@ -243,48 +235,32 @@ int iavf_get_vf_config(struct iavf_adapter *adapter)
if (!err)
iavf_validate_num_queues(adapter);
iavf_vf_parse_hw_config(hw, adapter->vf_res);
out_alloc:
kfree(event.msg_buf);
out:
return err;
}
int iavf_get_vf_vlan_v2_caps(struct iavf_adapter *adapter)
{
struct iavf_hw *hw = &adapter->hw;
struct iavf_arq_event_info event;
enum virtchnl_ops op;
enum iavf_status err;
int err;
u16 len;
len = sizeof(struct virtchnl_vlan_caps);
len = sizeof(struct virtchnl_vlan_caps);
event.buf_len = len;
event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
if (!event.msg_buf) {
err = -ENOMEM;
goto out;
}
while (1) {
/* When the AQ is empty, iavf_clean_arq_element will return
* nonzero and this loop will terminate.
*/
err = iavf_clean_arq_element(hw, &event, NULL);
if (err)
goto out_alloc;
op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
if (op == VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS)
break;
}
event.msg_buf = kzalloc(len, GFP_KERNEL);
if (!event.msg_buf)
return -ENOMEM;
err = (enum iavf_status)le32_to_cpu(event.desc.cookie_low);
if (err)
goto out_alloc;
err = iavf_poll_virtchnl_msg(&adapter->hw, &event,
VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS);
if (!err)
memcpy(&adapter->vlan_v2_caps, event.msg_buf,
min(event.msg_len, len));
memcpy(&adapter->vlan_v2_caps, event.msg_buf, min(event.msg_len, len));
out_alloc:
kfree(event.msg_buf);
out:
return err;
}
......@@ -453,6 +429,20 @@ void iavf_map_queues(struct iavf_adapter *adapter)
kfree(vimi);
}
/**
* iavf_set_mac_addr_type - Set the correct request type from the filter type
* @virtchnl_ether_addr: pointer to requested list element
* @filter: pointer to requested filter
**/
static void
iavf_set_mac_addr_type(struct virtchnl_ether_addr *virtchnl_ether_addr,
const struct iavf_mac_filter *filter)
{
virtchnl_ether_addr->type = filter->is_primary ?
VIRTCHNL_ETHER_ADDR_PRIMARY :
VIRTCHNL_ETHER_ADDR_EXTRA;
}
/**
* iavf_add_ether_addrs
* @adapter: adapter structure
......@@ -508,6 +498,7 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
list_for_each_entry(f, &adapter->mac_filter_list, list) {
if (f->add) {
ether_addr_copy(veal->list[i].addr, f->macaddr);
iavf_set_mac_addr_type(&veal->list[i], f);
i++;
f->add = false;
if (i == count)
......@@ -577,6 +568,7 @@ void iavf_del_ether_addrs(struct iavf_adapter *adapter)
list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) {
if (f->remove) {
ether_addr_copy(veal->list[i].addr, f->macaddr);
iavf_set_mac_addr_type(&veal->list[i], f);
i++;
list_del(&f->list);
kfree(f);
......@@ -1827,11 +1819,13 @@ void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter)
*
* Request that the PF reset this VF. No response is expected.
**/
void iavf_request_reset(struct iavf_adapter *adapter)
int iavf_request_reset(struct iavf_adapter *adapter)
{
int err;
/* Don't check CURRENT_OP - this is always higher priority */
iavf_send_pf_msg(adapter, VIRTCHNL_OP_RESET_VF, NULL, 0);
err = iavf_send_pf_msg(adapter, VIRTCHNL_OP_RESET_VF, NULL, 0);
adapter->current_op = VIRTCHNL_OP_UNKNOWN;
return err;
}
/**
......
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