summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
diff options
context:
space:
mode:
authorMintz, Yuval <Yuval.Mintz@cavium.com>2017-01-01 13:57:07 +0200
committerDavid S. Miller <davem@davemloft.net>2017-01-01 21:02:14 -0500
commitf29ffdb65ff0eaf95d2a2b80f0dee3fbd5a64772 (patch)
tree118fc535a39a0cde87f3bf6c483687ffa75adf94 /drivers/net/ethernet/qlogic/qede/qede_ethtool.c
parent04e0fd006a9a670f557815b29ea89ffdac667c4d (diff)
qed*: RSS indirection based on queue-handles
A step toward having qede agnostic to the queue configurations in firmware/hardware - let the RSS indirections use queue handles instead of actual queue indices. Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qede/qede_ethtool.c')
-rw-r--r--drivers/net/ethernet/qlogic/qede/qede_ethtool.c77
1 files changed, 41 insertions, 36 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index 8e971b289d4b..baf264225c12 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -37,6 +37,7 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/capability.h>
+#include <linux/vmalloc.h>
#include "qede.h"
#define QEDE_RQSTAT_OFFSET(stat_name) \
@@ -931,8 +932,7 @@ static int qede_set_channels(struct net_device *dev,
/* Reset the indirection table if rx queue count is updated */
if ((edev->req_queues - edev->req_num_tx) != QEDE_RSS_COUNT(edev)) {
edev->rss_params_inited &= ~QEDE_RSS_INDIR_INITED;
- memset(&edev->rss_params.rss_ind_table, 0,
- sizeof(edev->rss_params.rss_ind_table));
+ memset(edev->rss_ind_table, 0, sizeof(edev->rss_ind_table));
}
qede_reload(edev, NULL, false);
@@ -978,11 +978,11 @@ static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case UDP_V4_FLOW:
- if (edev->rss_params.rss_caps & QED_RSS_IPV4_UDP)
+ if (edev->rss_caps & QED_RSS_IPV4_UDP)
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case UDP_V6_FLOW:
- if (edev->rss_params.rss_caps & QED_RSS_IPV6_UDP)
+ if (edev->rss_caps & QED_RSS_IPV6_UDP)
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case IPV4_FLOW:
@@ -1015,8 +1015,9 @@ static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
{
- struct qed_update_vport_params vport_update_params;
+ struct qed_update_vport_params *vport_update_params;
u8 set_caps = 0, clr_caps = 0;
+ int rc = 0;
DP_VERBOSE(edev, QED_MSG_DEBUG,
"Set rss flags command parameters: flow type = %d, data = %llu\n",
@@ -1091,27 +1092,29 @@ static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
}
/* No action is needed if there is no change in the rss capability */
- if (edev->rss_params.rss_caps == ((edev->rss_params.rss_caps &
- ~clr_caps) | set_caps))
+ if (edev->rss_caps == ((edev->rss_caps & ~clr_caps) | set_caps))
return 0;
/* Update internal configuration */
- edev->rss_params.rss_caps = (edev->rss_params.rss_caps & ~clr_caps) |
- set_caps;
+ edev->rss_caps = ((edev->rss_caps & ~clr_caps) | set_caps);
edev->rss_params_inited |= QEDE_RSS_CAPS_INITED;
/* Re-configure if possible */
- if (netif_running(edev->ndev)) {
- memset(&vport_update_params, 0, sizeof(vport_update_params));
- vport_update_params.update_rss_flg = 1;
- vport_update_params.vport_id = 0;
- memcpy(&vport_update_params.rss_params, &edev->rss_params,
- sizeof(vport_update_params.rss_params));
- return edev->ops->vport_update(edev->cdev,
- &vport_update_params);
+ __qede_lock(edev);
+ if (edev->state == QEDE_STATE_OPEN) {
+ vport_update_params = vzalloc(sizeof(*vport_update_params));
+ if (!vport_update_params) {
+ __qede_unlock(edev);
+ return -ENOMEM;
+ }
+ qede_fill_rss_params(edev, &vport_update_params->rss_params,
+ &vport_update_params->update_rss_flg);
+ rc = edev->ops->vport_update(edev->cdev, vport_update_params);
+ vfree(vport_update_params);
}
+ __qede_unlock(edev);
- return 0;
+ return rc;
}
static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
@@ -1136,7 +1139,7 @@ static u32 qede_get_rxfh_key_size(struct net_device *dev)
{
struct qede_dev *edev = netdev_priv(dev);
- return sizeof(edev->rss_params.rss_key);
+ return sizeof(edev->rss_key);
}
static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
@@ -1151,11 +1154,10 @@ static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
return 0;
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
- indir[i] = edev->rss_params.rss_ind_table[i];
+ indir[i] = edev->rss_ind_table[i];
if (key)
- memcpy(key, edev->rss_params.rss_key,
- qede_get_rxfh_key_size(dev));
+ memcpy(key, edev->rss_key, qede_get_rxfh_key_size(dev));
return 0;
}
@@ -1163,9 +1165,9 @@ static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
static int qede_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc)
{
- struct qed_update_vport_params vport_update_params;
+ struct qed_update_vport_params *vport_update_params;
struct qede_dev *edev = netdev_priv(dev);
- int i;
+ int i, rc = 0;
if (edev->dev_info.common.num_hwfns > 1) {
DP_INFO(edev,
@@ -1181,27 +1183,30 @@ static int qede_set_rxfh(struct net_device *dev, const u32 *indir,
if (indir) {
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
- edev->rss_params.rss_ind_table[i] = indir[i];
+ edev->rss_ind_table[i] = indir[i];
edev->rss_params_inited |= QEDE_RSS_INDIR_INITED;
}
if (key) {
- memcpy(&edev->rss_params.rss_key, key,
- qede_get_rxfh_key_size(dev));
+ memcpy(&edev->rss_key, key, qede_get_rxfh_key_size(dev));
edev->rss_params_inited |= QEDE_RSS_KEY_INITED;
}
- if (netif_running(edev->ndev)) {
- memset(&vport_update_params, 0, sizeof(vport_update_params));
- vport_update_params.update_rss_flg = 1;
- vport_update_params.vport_id = 0;
- memcpy(&vport_update_params.rss_params, &edev->rss_params,
- sizeof(vport_update_params.rss_params));
- return edev->ops->vport_update(edev->cdev,
- &vport_update_params);
+ __qede_lock(edev);
+ if (edev->state == QEDE_STATE_OPEN) {
+ vport_update_params = vzalloc(sizeof(*vport_update_params));
+ if (!vport_update_params) {
+ __qede_unlock(edev);
+ return -ENOMEM;
+ }
+ qede_fill_rss_params(edev, &vport_update_params->rss_params,
+ &vport_update_params->update_rss_flg);
+ rc = edev->ops->vport_update(edev->cdev, vport_update_params);
+ vfree(vport_update_params);
}
+ __qede_unlock(edev);
- return 0;
+ return rc;
}
/* This function enables the interrupt generation and the NAPI on the device */