Commit 4825a4e4 authored by David S. Miller's avatar David S. Miller

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

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-08-19

This series contains updates to i40e and i40evf only.

Jake provides several patches, first just moves a function to co-locate
the two functions related to configuring RSS via the admin queue, which
should help in spotting bugs when comparing the two functions.  Fixed
an issue where commit e69ff813 ("i40e: rework the functions to
configure RSS with similar parameters") missed checking whether the seed
is NULL before using it and did not use the passed in *lut parameter.
Fixed an issue where a previous refactor missed i40e_vsi_config_rss()
and the values were being ignored, so checked for the fields and used
them instead of default values.  Lastly replaced calls to
create_singlethread_workqueue() with alloc_workqueue() to provide more
control over workqueue creation and allows explicit setting of the
desired mode of operation.

Mitch adds link speed to log messages and reports speed through ethtool.

Carolyn refactors tail bump check and fixes byte ordering problems found
when enabling this feature support.  Adds support for HMC resources and
profile commands for x722 firmware.

Heinrich Schuchardt fixes format identifiers from %u to %d since the
variable is defined as an integer.

Catherine fixes an issue where there was a race condition between the
completion of the client open and calls to the client ops, so ensured
that client ops are not called until we are sure client is open.

Harshitha makes sure that i40e_client_release() does not try to use
an adapter pointer which may not be initialized, so make sure it is.

Joe Perches fixes the use of the local macro XSTRINGIFY() to use
__stringify() instead.

Avinash corrects the mutex usage in client_subtask().  Fixed the RDMA
client to open again after reset since it is closed during a PF reset.

Jeff (me) clean up whitespace issues, where indentation was done
inconsistently and with spaces versus tabs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6afb1e28 bf3a178c
...@@ -120,10 +120,6 @@ ...@@ -120,10 +120,6 @@
#define I40E_CURRENT_NVM_VERSION_HI 0x2 #define I40E_CURRENT_NVM_VERSION_HI 0x2
#define I40E_CURRENT_NVM_VERSION_LO 0x40 #define I40E_CURRENT_NVM_VERSION_LO 0x40
/* magic for getting defines into strings */
#define STRINGIFY(foo) #foo
#define XSTRINGIFY(bar) STRINGIFY(bar)
#define I40E_RX_DESC(R, i) \ #define I40E_RX_DESC(R, i) \
(&(((union i40e_32byte_rx_desc *)((R)->desc))[i])) (&(((union i40e_32byte_rx_desc *)((R)->desc))[i]))
#define I40E_TX_DESC(R, i) \ #define I40E_TX_DESC(R, i) \
...@@ -541,6 +537,7 @@ struct i40e_vsi { ...@@ -541,6 +537,7 @@ struct i40e_vsi {
u8 *rss_hkey_user; /* User configured hash keys */ u8 *rss_hkey_user; /* User configured hash keys */
u8 *rss_lut_user; /* User configured lookup table entries */ u8 *rss_lut_user; /* User configured lookup table entries */
u16 max_frame; u16 max_frame;
u16 rx_buf_len; u16 rx_buf_len;
......
...@@ -204,6 +204,9 @@ enum i40e_admin_queue_opc { ...@@ -204,6 +204,9 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_suspend_port_tx = 0x041B, i40e_aqc_opc_suspend_port_tx = 0x041B,
i40e_aqc_opc_resume_port_tx = 0x041C, i40e_aqc_opc_resume_port_tx = 0x041C,
i40e_aqc_opc_configure_partition_bw = 0x041D, i40e_aqc_opc_configure_partition_bw = 0x041D,
/* hmc */
i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
i40e_aqc_opc_set_hmc_resource_profile = 0x0501,
/* phy commands*/ /* phy commands*/
i40e_aqc_opc_get_phy_abilities = 0x0600, i40e_aqc_opc_get_phy_abilities = 0x0600,
...@@ -450,13 +453,15 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration); ...@@ -450,13 +453,15 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration);
/* Set ARP Proxy command / response (indirect 0x0104) */ /* Set ARP Proxy command / response (indirect 0x0104) */
struct i40e_aqc_arp_proxy_data { struct i40e_aqc_arp_proxy_data {
__le16 command_flags; __le16 command_flags;
#define I40E_AQ_ARP_INIT_IPV4 0x0008 #define I40E_AQ_ARP_INIT_IPV4 0x0800
#define I40E_AQ_ARP_UNSUP_CTL 0x0010 #define I40E_AQ_ARP_UNSUP_CTL 0x1000
#define I40E_AQ_ARP_ENA 0x0020 #define I40E_AQ_ARP_ENA 0x2000
#define I40E_AQ_ARP_ADD_IPV4 0x0040 #define I40E_AQ_ARP_ADD_IPV4 0x4000
#define I40E_AQ_ARP_DEL_IPV4 0x0080 #define I40E_AQ_ARP_DEL_IPV4 0x8000
__le16 table_id; __le16 table_id;
__le32 pfpm_proxyfc; __le32 enabled_offloads;
#define I40E_AQ_ARP_DIRECTED_OFFLOAD_ENABLE 0x00000020
#define I40E_AQ_ARP_OFFLOAD_ENABLE 0x00000800
__le32 ip_addr; __le32 ip_addr;
u8 mac_addr[6]; u8 mac_addr[6];
u8 reserved[2]; u8 reserved[2];
...@@ -471,17 +476,19 @@ struct i40e_aqc_ns_proxy_data { ...@@ -471,17 +476,19 @@ struct i40e_aqc_ns_proxy_data {
__le16 table_idx_ipv6_0; __le16 table_idx_ipv6_0;
__le16 table_idx_ipv6_1; __le16 table_idx_ipv6_1;
__le16 control; __le16 control;
#define I40E_AQ_NS_PROXY_ADD_0 0x0100 #define I40E_AQ_NS_PROXY_ADD_0 0x0001
#define I40E_AQ_NS_PROXY_DEL_0 0x0200 #define I40E_AQ_NS_PROXY_DEL_0 0x0002
#define I40E_AQ_NS_PROXY_ADD_1 0x0400 #define I40E_AQ_NS_PROXY_ADD_1 0x0004
#define I40E_AQ_NS_PROXY_DEL_1 0x0800 #define I40E_AQ_NS_PROXY_DEL_1 0x0008
#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x1000 #define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x0010
#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x2000 #define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x0020
#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x4000 #define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x0040
#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x8000 #define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x0080
#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0001 #define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0100
#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0002 #define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0200
#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0004 #define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0400
#define I40E_AQ_NS_PROXY_OFFLOAD_ENABLE 0x0800
#define I40E_AQ_NS_PROXY_DIRECTED_OFFLOAD_ENABLE 0x1000
u8 mac_addr_0[6]; u8 mac_addr_0[6];
u8 mac_addr_1[6]; u8 mac_addr_1[6];
u8 local_mac_addr[6]; u8 local_mac_addr[6];
...@@ -1582,6 +1589,24 @@ struct i40e_aqc_configure_partition_bw_data { ...@@ -1582,6 +1589,24 @@ struct i40e_aqc_configure_partition_bw_data {
I40E_CHECK_STRUCT_LEN(0x22, i40e_aqc_configure_partition_bw_data); I40E_CHECK_STRUCT_LEN(0x22, i40e_aqc_configure_partition_bw_data);
/* Get and set the active HMC resource profile and status.
* (direct 0x0500) and (direct 0x0501)
*/
struct i40e_aq_get_set_hmc_resource_profile {
u8 pm_profile;
u8 pe_vf_enabled;
u8 reserved[14];
};
I40E_CHECK_CMD_LENGTH(i40e_aq_get_set_hmc_resource_profile);
enum i40e_aq_hmc_profile {
/* I40E_HMC_PROFILE_NO_CHANGE = 0, reserved */
I40E_HMC_PROFILE_DEFAULT = 1,
I40E_HMC_PROFILE_FAVOR_VF = 2,
I40E_HMC_PROFILE_EQUAL = 3,
};
/* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */ /* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */
/* set in param0 for get phy abilities to report qualified modules */ /* set in param0 for get phy abilities to report qualified modules */
......
...@@ -148,6 +148,11 @@ i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len) ...@@ -148,6 +148,11 @@ i40e_notify_client_of_vf_msg(struct i40e_vsi *vsi, u32 vf_id, u8 *msg, u16 len)
"Cannot locate client instance virtual channel receive routine\n"); "Cannot locate client instance virtual channel receive routine\n");
continue; continue;
} }
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) {
dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort virtchnl_receive\n");
continue;
}
cdev->client->ops->virtchnl_receive(&cdev->lan_info, cdev->client->ops->virtchnl_receive(&cdev->lan_info,
cdev->client, cdev->client,
vf_id, msg, len); vf_id, msg, len);
...@@ -181,6 +186,11 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi) ...@@ -181,6 +186,11 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi)
"Cannot locate client instance l2_param_change routine\n"); "Cannot locate client instance l2_param_change routine\n");
continue; continue;
} }
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) {
dev_dbg(&vsi->back->pdev->dev, "Client is not open, abort l2 param change\n");
continue;
}
cdev->lan_info.params = params; cdev->lan_info.params = params;
cdev->client->ops->l2_param_change(&cdev->lan_info, cdev->client->ops->l2_param_change(&cdev->lan_info,
cdev->client, cdev->client,
...@@ -298,6 +308,11 @@ void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id) ...@@ -298,6 +308,11 @@ void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id)
"Cannot locate client instance VF reset routine\n"); "Cannot locate client instance VF reset routine\n");
continue; continue;
} }
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) {
dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-reset\n");
continue;
}
cdev->client->ops->vf_reset(&cdev->lan_info, cdev->client->ops->vf_reset(&cdev->lan_info,
cdev->client, vf_id); cdev->client, vf_id);
} }
...@@ -328,6 +343,11 @@ void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs) ...@@ -328,6 +343,11 @@ void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs)
"Cannot locate client instance VF enable routine\n"); "Cannot locate client instance VF enable routine\n");
continue; continue;
} }
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) {
dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-enable\n");
continue;
}
cdev->client->ops->vf_enable(&cdev->lan_info, cdev->client->ops->vf_enable(&cdev->lan_info,
cdev->client, num_vfs); cdev->client, num_vfs);
} }
...@@ -362,6 +382,11 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id, ...@@ -362,6 +382,11 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id,
"Cannot locate client instance VF capability routine\n"); "Cannot locate client instance VF capability routine\n");
continue; continue;
} }
if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED,
&cdev->state)) {
dev_dbg(&pf->pdev->dev, "Client is not open, abort vf-capable\n");
continue;
}
capable = cdev->client->ops->vf_capable(&cdev->lan_info, capable = cdev->client->ops->vf_capable(&cdev->lan_info,
cdev->client, cdev->client,
vf_id); vf_id);
...@@ -551,6 +576,7 @@ void i40e_client_subtask(struct i40e_pf *pf) ...@@ -551,6 +576,7 @@ void i40e_client_subtask(struct i40e_pf *pf)
set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); set_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
} else { } else {
/* remove client instance */ /* remove client instance */
mutex_unlock(&i40e_client_instance_mutex);
i40e_client_del_instance(pf, client); i40e_client_del_instance(pf, client);
atomic_dec(&client->ref_cnt); atomic_dec(&client->ref_cnt);
continue; continue;
...@@ -637,7 +663,7 @@ int i40e_lan_del_device(struct i40e_pf *pf) ...@@ -637,7 +663,7 @@ int i40e_lan_del_device(struct i40e_pf *pf)
static int i40e_client_release(struct i40e_client *client) static int i40e_client_release(struct i40e_client *client)
{ {
struct i40e_client_instance *cdev, *tmp; struct i40e_client_instance *cdev, *tmp;
struct i40e_pf *pf = NULL; struct i40e_pf *pf;
int ret = 0; int ret = 0;
LIST_HEAD(cdevs_tmp); LIST_HEAD(cdevs_tmp);
...@@ -647,12 +673,12 @@ static int i40e_client_release(struct i40e_client *client) ...@@ -647,12 +673,12 @@ static int i40e_client_release(struct i40e_client *client)
if (strncmp(cdev->client->name, client->name, if (strncmp(cdev->client->name, client->name,
I40E_CLIENT_STR_LENGTH)) I40E_CLIENT_STR_LENGTH))
continue; continue;
pf = (struct i40e_pf *)cdev->lan_info.pf;
if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) { if (test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
if (atomic_read(&cdev->ref_cnt) > 0) { if (atomic_read(&cdev->ref_cnt) > 0) {
ret = I40E_ERR_NOT_READY; ret = I40E_ERR_NOT_READY;
goto out; goto out;
} }
pf = (struct i40e_pf *)cdev->lan_info.pf;
if (client->ops && client->ops->close) if (client->ops && client->ops->close)
client->ops->close(&cdev->lan_info, client, client->ops->close(&cdev->lan_info, client,
false); false);
......
...@@ -36,9 +36,9 @@ ...@@ -36,9 +36,9 @@
#define I40E_CLIENT_VERSION_MINOR 01 #define I40E_CLIENT_VERSION_MINOR 01
#define I40E_CLIENT_VERSION_BUILD 00 #define I40E_CLIENT_VERSION_BUILD 00
#define I40E_CLIENT_VERSION_STR \ #define I40E_CLIENT_VERSION_STR \
XSTRINGIFY(I40E_CLIENT_VERSION_MAJOR) "." \ __stringify(I40E_CLIENT_VERSION_MAJOR) "." \
XSTRINGIFY(I40E_CLIENT_VERSION_MINOR) "." \ __stringify(I40E_CLIENT_VERSION_MINOR) "." \
XSTRINGIFY(I40E_CLIENT_VERSION_BUILD) __stringify(I40E_CLIENT_VERSION_BUILD)
struct i40e_client_version { struct i40e_client_version {
u8 major; u8 major;
......
...@@ -1560,13 +1560,13 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset, ...@@ -1560,13 +1560,13 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
} }
#endif #endif
for (i = 0; i < vsi->num_queue_pairs; i++) { for (i = 0; i < vsi->num_queue_pairs; i++) {
snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_packets", i); snprintf(p, ETH_GSTRING_LEN, "tx-%d.tx_packets", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, "tx-%u.tx_bytes", i); snprintf(p, ETH_GSTRING_LEN, "tx-%d.tx_bytes", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_packets", i); snprintf(p, ETH_GSTRING_LEN, "rx-%d.rx_packets", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, "rx-%u.rx_bytes", i); snprintf(p, ETH_GSTRING_LEN, "rx-%d.rx_bytes", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1) if (vsi != pf->vsi[pf->lan_vsi] || pf->hw.partition_id != 1)
...@@ -1581,16 +1581,16 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset, ...@@ -1581,16 +1581,16 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
} }
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_tx_packets", i); "veb.tc_%d_tx_packets", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_tx_bytes", i); "veb.tc_%d_tx_bytes", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_rx_packets", i); "veb.tc_%d_rx_packets", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_rx_bytes", i); "veb.tc_%d_rx_bytes", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
} }
...@@ -1601,23 +1601,23 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset, ...@@ -1601,23 +1601,23 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
} }
for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"port.tx_priority_%u_xon", i); "port.tx_priority_%d_xon", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"port.tx_priority_%u_xoff", i); "port.tx_priority_%d_xoff", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"port.rx_priority_%u_xon", i); "port.rx_priority_%d_xon", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"port.rx_priority_%u_xoff", i); "port.rx_priority_%d_xoff", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) { for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
snprintf(p, ETH_GSTRING_LEN, snprintf(p, ETH_GSTRING_LEN,
"port.rx_priority_%u_xon_2_xoff", i); "port.rx_priority_%d_xon_2_xoff", i);
p += ETH_GSTRING_LEN; p += ETH_GSTRING_LEN;
} }
/* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */ /* BUG_ON(p - data != I40E_STATS_LEN * ETH_GSTRING_LEN); */
......
...@@ -7985,72 +7985,34 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf) ...@@ -7985,72 +7985,34 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed, static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
u8 *lut, u16 lut_size) u8 *lut, u16 lut_size)
{ {
struct i40e_aqc_get_set_rss_key_data rss_key;
struct i40e_pf *pf = vsi->back; struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw; struct i40e_hw *hw = &pf->hw;
bool pf_lut = false; int ret = 0;
u8 *rss_lut;
int ret, i;
memcpy(&rss_key, seed, sizeof(rss_key));
rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL);
if (!rss_lut)
return -ENOMEM;
/* Populate the LUT with max no. of queues in round robin fashion */
for (i = 0; i < vsi->rss_table_size; i++)
rss_lut[i] = i % vsi->rss_size;
ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key); if (seed) {
struct i40e_aqc_get_set_rss_key_data *seed_dw =
(struct i40e_aqc_get_set_rss_key_data *)seed;
ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw);
if (ret) { if (ret) {
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"Cannot set RSS key, err %s aq_err %s\n", "Cannot set RSS key, err %s aq_err %s\n",
i40e_stat_str(&pf->hw, ret), i40e_stat_str(hw, ret),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); i40e_aq_str(hw, hw->aq.asq_last_status));
goto config_rss_aq_out; return ret;
} }
}
if (lut) {
bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
if (vsi->type == I40E_VSI_MAIN) ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
pf_lut = true; if (ret) {
ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut,
vsi->rss_table_size);
if (ret)
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"Cannot set RSS lut, err %s aq_err %s\n", "Cannot set RSS lut, err %s aq_err %s\n",
i40e_stat_str(&pf->hw, ret), i40e_stat_str(hw, ret),
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); i40e_aq_str(hw, hw->aq.asq_last_status));
config_rss_aq_out:
kfree(rss_lut);
return ret; return ret;
} }
}
/**
* i40e_vsi_config_rss - Prepare for VSI(VMDq) RSS if used
* @vsi: VSI structure
**/
static int i40e_vsi_config_rss(struct i40e_vsi *vsi)
{
u8 seed[I40E_HKEY_ARRAY_SIZE];
struct i40e_pf *pf = vsi->back;
u8 *lut;
int ret;
if (!(pf->flags & I40E_FLAG_RSS_AQ_CAPABLE))
return 0;
lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
if (!lut)
return -ENOMEM;
i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
vsi->rss_size = min_t(int, pf->alloc_rss_size, vsi->num_queue_pairs);
ret = i40e_config_rss_aq(vsi, seed, lut, vsi->rss_table_size);
kfree(lut);
return ret; return ret;
} }
...@@ -8100,6 +8062,46 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed, ...@@ -8100,6 +8062,46 @@ static int i40e_get_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
return ret; return ret;
} }
/**
* i40e_vsi_config_rss - Prepare for VSI(VMDq) RSS if used
* @vsi: VSI structure
**/
static int i40e_vsi_config_rss(struct i40e_vsi *vsi)
{
u8 seed[I40E_HKEY_ARRAY_SIZE];
struct i40e_pf *pf = vsi->back;
u8 *lut;
int ret;
if (!(pf->flags & I40E_FLAG_RSS_AQ_CAPABLE))
return 0;
if (!vsi->rss_size)
vsi->rss_size = min_t(int, pf->alloc_rss_size,
vsi->num_queue_pairs);
if (!vsi->rss_size)
return -EINVAL;
lut = kzalloc(vsi->rss_table_size, GFP_KERNEL);
if (!lut)
return -ENOMEM;
/* Use the user configured hash keys and lookup table if there is one,
* otherwise use default
*/
if (vsi->rss_lut_user)
memcpy(lut, vsi->rss_lut_user, vsi->rss_table_size);
else
i40e_fill_rss_lut(pf, lut, vsi->rss_table_size, vsi->rss_size);
if (vsi->rss_hkey_user)
memcpy(seed, vsi->rss_hkey_user, I40E_HKEY_ARRAY_SIZE);
else
netdev_rss_key_fill((void *)seed, I40E_HKEY_ARRAY_SIZE);
ret = i40e_config_rss_aq(vsi, seed, lut, vsi->rss_table_size);
kfree(lut);
return ret;
}
/** /**
* i40e_config_rss_reg - Configure RSS keys and lut by writing registers * i40e_config_rss_reg - Configure RSS keys and lut by writing registers
* @vsi: Pointer to vsi structure * @vsi: Pointer to vsi structure
...@@ -11603,7 +11605,8 @@ static int __init i40e_init_module(void) ...@@ -11603,7 +11605,8 @@ static int __init i40e_init_module(void)
* it can't be any worse than using the system workqueue which * it can't be any worse than using the system workqueue which
* was already single threaded * was already single threaded
*/ */
i40e_wq = create_singlethread_workqueue(i40e_driver_name); i40e_wq = alloc_workqueue("%s", WQ_UNBOUND | WQ_MEM_RECLAIM, 1,
i40e_driver_name);
if (!i40e_wq) { if (!i40e_wq) {
pr_err("%s: Failed to create workqueue\n", i40e_driver_name); pr_err("%s: Failed to create workqueue\n", i40e_driver_name);
return -ENOMEM; return -ENOMEM;
......
...@@ -2840,10 +2840,9 @@ static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, ...@@ -2840,10 +2840,9 @@ static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
I40E_TXD_QW1_CMD_SHIFT); I40E_TXD_QW1_CMD_SHIFT);
/* notify HW of packet */ /* notify HW of packet */
if (!tail_bump) if (!tail_bump) {
prefetchw(tx_desc + 1); prefetchw(tx_desc + 1);
} else {
if (tail_bump) {
/* Force memory writes to complete before letting h/w /* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only * know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs, * applicable for weak-ordered memory model archs,
...@@ -2852,7 +2851,6 @@ static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, ...@@ -2852,7 +2851,6 @@ static inline void i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
wmb(); wmb();
writel(i, tx_ring->tail); writel(i, tx_ring->tail);
} }
return; return;
dma_error: dma_error:
......
...@@ -204,6 +204,9 @@ enum i40e_admin_queue_opc { ...@@ -204,6 +204,9 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_suspend_port_tx = 0x041B, i40e_aqc_opc_suspend_port_tx = 0x041B,
i40e_aqc_opc_resume_port_tx = 0x041C, i40e_aqc_opc_resume_port_tx = 0x041C,
i40e_aqc_opc_configure_partition_bw = 0x041D, i40e_aqc_opc_configure_partition_bw = 0x041D,
/* hmc */
i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
i40e_aqc_opc_set_hmc_resource_profile = 0x0501,
/* phy commands*/ /* phy commands*/
i40e_aqc_opc_get_phy_abilities = 0x0600, i40e_aqc_opc_get_phy_abilities = 0x0600,
...@@ -447,13 +450,15 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration); ...@@ -447,13 +450,15 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_cppm_configuration);
/* Set ARP Proxy command / response (indirect 0x0104) */ /* Set ARP Proxy command / response (indirect 0x0104) */
struct i40e_aqc_arp_proxy_data { struct i40e_aqc_arp_proxy_data {
__le16 command_flags; __le16 command_flags;
#define I40E_AQ_ARP_INIT_IPV4 0x0008 #define I40E_AQ_ARP_INIT_IPV4 0x0800
#define I40E_AQ_ARP_UNSUP_CTL 0x0010 #define I40E_AQ_ARP_UNSUP_CTL 0x1000
#define I40E_AQ_ARP_ENA 0x0020 #define I40E_AQ_ARP_ENA 0x2000
#define I40E_AQ_ARP_ADD_IPV4 0x0040 #define I40E_AQ_ARP_ADD_IPV4 0x4000
#define I40E_AQ_ARP_DEL_IPV4 0x0080 #define I40E_AQ_ARP_DEL_IPV4 0x8000
__le16 table_id; __le16 table_id;
__le32 pfpm_proxyfc; __le32 enabled_offloads;
#define I40E_AQ_ARP_DIRECTED_OFFLOAD_ENABLE 0x00000020
#define I40E_AQ_ARP_OFFLOAD_ENABLE 0x00000800
__le32 ip_addr; __le32 ip_addr;
u8 mac_addr[6]; u8 mac_addr[6];
u8 reserved[2]; u8 reserved[2];
...@@ -468,17 +473,19 @@ struct i40e_aqc_ns_proxy_data { ...@@ -468,17 +473,19 @@ struct i40e_aqc_ns_proxy_data {
__le16 table_idx_ipv6_0; __le16 table_idx_ipv6_0;
__le16 table_idx_ipv6_1; __le16 table_idx_ipv6_1;
__le16 control; __le16 control;
#define I40E_AQ_NS_PROXY_ADD_0 0x0100 #define I40E_AQ_NS_PROXY_ADD_0 0x0001
#define I40E_AQ_NS_PROXY_DEL_0 0x0200 #define I40E_AQ_NS_PROXY_DEL_0 0x0002
#define I40E_AQ_NS_PROXY_ADD_1 0x0400 #define I40E_AQ_NS_PROXY_ADD_1 0x0004
#define I40E_AQ_NS_PROXY_DEL_1 0x0800 #define I40E_AQ_NS_PROXY_DEL_1 0x0008
#define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x1000 #define I40E_AQ_NS_PROXY_ADD_IPV6_0 0x0010
#define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x2000 #define I40E_AQ_NS_PROXY_DEL_IPV6_0 0x0020
#define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x4000 #define I40E_AQ_NS_PROXY_ADD_IPV6_1 0x0040
#define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x8000 #define I40E_AQ_NS_PROXY_DEL_IPV6_1 0x0080
#define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0001 #define I40E_AQ_NS_PROXY_COMMAND_SEQ 0x0100
#define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0002 #define I40E_AQ_NS_PROXY_INIT_IPV6_TBL 0x0200
#define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0004 #define I40E_AQ_NS_PROXY_INIT_MAC_TBL 0x0400
#define I40E_AQ_NS_PROXY_OFFLOAD_ENABLE 0x0800
#define I40E_AQ_NS_PROXY_DIRECTED_OFFLOAD_ENABLE 0x1000
u8 mac_addr_0[6]; u8 mac_addr_0[6];
u8 mac_addr_1[6]; u8 mac_addr_1[6];
u8 local_mac_addr[6]; u8 local_mac_addr[6];
...@@ -1579,6 +1586,24 @@ struct i40e_aqc_configure_partition_bw_data { ...@@ -1579,6 +1586,24 @@ struct i40e_aqc_configure_partition_bw_data {
I40E_CHECK_STRUCT_LEN(0x22, i40e_aqc_configure_partition_bw_data); I40E_CHECK_STRUCT_LEN(0x22, i40e_aqc_configure_partition_bw_data);
/* Get and set the active HMC resource profile and status.
* (direct 0x0500) and (direct 0x0501)
*/
struct i40e_aq_get_set_hmc_resource_profile {
u8 pm_profile;
u8 pe_vf_enabled;
u8 reserved[14];
};
I40E_CHECK_CMD_LENGTH(i40e_aq_get_set_hmc_resource_profile);
enum i40e_aq_hmc_profile {
/* I40E_HMC_PROFILE_NO_CHANGE = 0, reserved */
I40E_HMC_PROFILE_DEFAULT = 1,
I40E_HMC_PROFILE_FAVOR_VF = 2,
I40E_HMC_PROFILE_EQUAL = 3,
};
/* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */ /* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */
/* set in param0 for get phy abilities to report qualified modules */ /* set in param0 for get phy abilities to report qualified modules */
......
...@@ -2068,10 +2068,9 @@ static inline void i40evf_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, ...@@ -2068,10 +2068,9 @@ static inline void i40evf_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
I40E_TXD_QW1_CMD_SHIFT); I40E_TXD_QW1_CMD_SHIFT);
/* notify HW of packet */ /* notify HW of packet */
if (!tail_bump) if (!tail_bump) {
prefetchw(tx_desc + 1); prefetchw(tx_desc + 1);
} else {
if (tail_bump) {
/* Force memory writes to complete before letting h/w /* Force memory writes to complete before letting h/w
* know there are new descriptors to fetch. (Only * know there are new descriptors to fetch. (Only
* applicable for weak-ordered memory model archs, * applicable for weak-ordered memory model archs,
...@@ -2080,7 +2079,6 @@ static inline void i40evf_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, ...@@ -2080,7 +2079,6 @@ static inline void i40evf_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
wmb(); wmb();
writel(i, tx_ring->tail); writel(i, tx_ring->tail);
} }
return; return;
dma_error: dma_error:
......
...@@ -205,6 +205,7 @@ struct i40evf_adapter { ...@@ -205,6 +205,7 @@ struct i40evf_adapter {
u32 flags; u32 flags;
#define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0) #define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0)
#define I40EVF_FLAG_IN_NETPOLL BIT(4)
#define I40EVF_FLAG_IMIR_ENABLED BIT(5) #define I40EVF_FLAG_IMIR_ENABLED BIT(5)
#define I40EVF_FLAG_MQ_CAPABLE BIT(6) #define I40EVF_FLAG_MQ_CAPABLE BIT(6)
#define I40EVF_FLAG_NEED_LINK_UPDATE BIT(7) #define I40EVF_FLAG_NEED_LINK_UPDATE BIT(7)
...@@ -214,11 +215,13 @@ struct i40evf_adapter { ...@@ -214,11 +215,13 @@ struct i40evf_adapter {
#define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(11) #define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(11)
#define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE BIT(12) #define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE BIT(12)
#define I40EVF_FLAG_ADDR_SET_BY_PF BIT(13) #define I40EVF_FLAG_ADDR_SET_BY_PF BIT(13)
#define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(14)
#define I40EVF_FLAG_PROMISC_ON BIT(15) #define I40EVF_FLAG_PROMISC_ON BIT(15)
#define I40EVF_FLAG_ALLMULTI_ON BIT(16) #define I40EVF_FLAG_ALLMULTI_ON BIT(16)
/* duplicates for common code */ /* duplicates for common code */
#define I40E_FLAG_FDIR_ATR_ENABLED 0 #define I40E_FLAG_FDIR_ATR_ENABLED 0
#define I40E_FLAG_DCB_ENABLED 0 #define I40E_FLAG_DCB_ENABLED 0
#define I40E_FLAG_IN_NETPOLL I40EVF_FLAG_IN_NETPOLL
#define I40E_FLAG_RX_CSUM_ENABLED I40EVF_FLAG_RX_CSUM_ENABLED #define I40E_FLAG_RX_CSUM_ENABLED I40EVF_FLAG_RX_CSUM_ENABLED
#define I40E_FLAG_WB_ON_ITR_CAPABLE I40EVF_FLAG_WB_ON_ITR_CAPABLE #define I40E_FLAG_WB_ON_ITR_CAPABLE I40EVF_FLAG_WB_ON_ITR_CAPABLE
#define I40E_FLAG_OUTER_UDP_CSUM_CAPABLE I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE #define I40E_FLAG_OUTER_UDP_CSUM_CAPABLE I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE
...@@ -258,6 +261,7 @@ struct i40evf_adapter { ...@@ -258,6 +261,7 @@ struct i40evf_adapter {
struct work_struct watchdog_task; struct work_struct watchdog_task;
bool netdev_registered; bool netdev_registered;
bool link_up; bool link_up;
enum i40e_aq_link_speed link_speed;
enum i40e_virtchnl_ops current_op; enum i40e_virtchnl_ops current_op;
#define CLIENT_ENABLED(_a) ((_a)->vf_res ? \ #define CLIENT_ENABLED(_a) ((_a)->vf_res ? \
(_a)->vf_res->vf_offload_flags & \ (_a)->vf_res->vf_offload_flags & \
......
...@@ -74,13 +74,33 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = { ...@@ -74,13 +74,33 @@ static const struct i40evf_stats i40evf_gstrings_stats[] = {
static int i40evf_get_settings(struct net_device *netdev, static int i40evf_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd) struct ethtool_cmd *ecmd)
{ {
/* In the future the VF will be able to query the PF for struct i40evf_adapter *adapter = netdev_priv(netdev);
* some information - for now use a dummy value
*/
ecmd->supported = 0; ecmd->supported = 0;
ecmd->autoneg = AUTONEG_DISABLE; ecmd->autoneg = AUTONEG_DISABLE;
ecmd->transceiver = XCVR_DUMMY1; ecmd->transceiver = XCVR_DUMMY1;
ecmd->port = PORT_NONE; ecmd->port = PORT_NONE;
/* Set speed and duplex */
switch (adapter->link_speed) {
case I40E_LINK_SPEED_40GB:
ethtool_cmd_speed_set(ecmd, SPEED_40000);
break;
case I40E_LINK_SPEED_20GB:
ethtool_cmd_speed_set(ecmd, SPEED_20000);
break;
case I40E_LINK_SPEED_10GB:
ethtool_cmd_speed_set(ecmd, SPEED_10000);
break;
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;
}
ecmd->duplex = DUPLEX_FULL;
return 0; return 0;
} }
......
...@@ -1804,6 +1804,8 @@ static void i40evf_reset_task(struct work_struct *work) ...@@ -1804,6 +1804,8 @@ static void i40evf_reset_task(struct work_struct *work)
} }
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER; adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER; adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
/* Open RDMA Client again */
adapter->aq_required |= I40EVF_FLAG_SERVICE_CLIENT_REQUESTED;
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
i40evf_misc_irq_enable(adapter); i40evf_misc_irq_enable(adapter);
...@@ -2833,7 +2835,8 @@ static int __init i40evf_init_module(void) ...@@ -2833,7 +2835,8 @@ static int __init i40evf_init_module(void)
pr_info("%s\n", i40evf_copyright); pr_info("%s\n", i40evf_copyright);
i40evf_wq = create_singlethread_workqueue(i40evf_driver_name); i40evf_wq = alloc_workqueue("%s", WQ_UNBOUND | WQ_MEM_RECLAIM, 1,
i40evf_driver_name);
if (!i40evf_wq) { if (!i40evf_wq) {
pr_err("%s: Failed to create workqueue\n", i40evf_driver_name); pr_err("%s: Failed to create workqueue\n", i40evf_driver_name);
return -ENOMEM; return -ENOMEM;
......
...@@ -816,6 +816,45 @@ void i40evf_set_rss_lut(struct i40evf_adapter *adapter) ...@@ -816,6 +816,45 @@ void i40evf_set_rss_lut(struct i40evf_adapter *adapter)
kfree(vrl); kfree(vrl);
} }
/**
* i40evf_print_link_message - print link up or down
* @adapter: adapter structure
*
* Log a message telling the world of our wonderous link status
*/
static void i40evf_print_link_message(struct i40evf_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
char *speed = "Unknown ";
if (!adapter->link_up) {
netdev_info(netdev, "NIC Link is Down\n");
return;
}
switch (adapter->link_speed) {
case I40E_LINK_SPEED_40GB:
speed = "40 G";
break;
case I40E_LINK_SPEED_20GB:
speed = "20 G";
break;
case I40E_LINK_SPEED_10GB:
speed = "10 G";
break;
case I40E_LINK_SPEED_1GB:
speed = "1000 M";
break;
case I40E_LINK_SPEED_100MB:
speed = "100 M";
break;
default:
break;
}
netdev_info(netdev, "NIC Link is Up %sbps Full Duplex\n", speed);
}
/** /**
* i40evf_request_reset * i40evf_request_reset
* @adapter: adapter structure * @adapter: adapter structure
...@@ -853,15 +892,13 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter, ...@@ -853,15 +892,13 @@ void i40evf_virtchnl_completion(struct i40evf_adapter *adapter,
(struct i40e_virtchnl_pf_event *)msg; (struct i40e_virtchnl_pf_event *)msg;
switch (vpe->event) { switch (vpe->event) {
case I40E_VIRTCHNL_EVENT_LINK_CHANGE: case I40E_VIRTCHNL_EVENT_LINK_CHANGE:
adapter->link_speed =
vpe->event_data.link_event.link_speed;
if (adapter->link_up !=
vpe->event_data.link_event.link_status) {
adapter->link_up = adapter->link_up =
vpe->event_data.link_event.link_status; vpe->event_data.link_event.link_status;
if (adapter->link_up && !netif_carrier_ok(netdev)) { i40evf_print_link_message(adapter);
dev_info(&adapter->pdev->dev, "NIC Link is Up\n");
netif_carrier_on(netdev);
netif_tx_wake_all_queues(netdev);
} else if (!adapter->link_up) {
dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev); netif_tx_stop_all_queues(netdev);
} }
break; break;
......
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