Skip to content

Commit

Permalink
Merge branch 'qed-ethtool-rss'
Browse files Browse the repository at this point in the history
Yuval Mintz says:

====================
qed*: [mostly] Ethtool RSS configuration

Most of the content [code-wise] in this series is for allowing various
RSS-related configuration via ethtool.

In addition, this also removed an unnecessary versioning scheme between
the drivers and bump the driver version.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 14, 2016
2 parents 6c61403 + 7c2d7d7 commit b9aa78d
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 71 deletions.
4 changes: 1 addition & 3 deletions drivers/net/ethernet/qlogic/qed/qed.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include "qed_hsi.h"

extern const struct qed_common_ops qed_common_ops_pass;
#define DRV_MODULE_VERSION "8.7.0.0"
#define DRV_MODULE_VERSION "8.7.1.20"

#define MAX_HWFNS_PER_DEVICE (4)
#define NAME_SIZE 16
Expand Down Expand Up @@ -507,6 +507,4 @@ u32 qed_unzip_data(struct qed_hwfn *p_hwfn,

int qed_slowpath_irq_req(struct qed_hwfn *hwfn);

#define QED_ETH_INTERFACE_VERSION 300

#endif /* _QED_H */
25 changes: 2 additions & 23 deletions drivers/net/ethernet/qlogic/qed/qed_l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,6 @@
#include "qed_reg_addr.h"
#include "qed_sp.h"

enum qed_rss_caps {
QED_RSS_IPV4 = 0x1,
QED_RSS_IPV6 = 0x2,
QED_RSS_IPV4_TCP = 0x4,
QED_RSS_IPV6_TCP = 0x8,
QED_RSS_IPV4_UDP = 0x10,
QED_RSS_IPV6_UDP = 0x20,
};

/* Should be the same as ETH_RSS_IND_TABLE_ENTRIES_NUM */
#define QED_RSS_IND_TABLE_SIZE 128
#define QED_RSS_KEY_SIZE 10 /* size in 32b chunks */

struct qed_rss_params {
u8 update_rss_config;
u8 rss_enable;
Expand Down Expand Up @@ -1744,9 +1731,7 @@ static int qed_update_vport(struct qed_dev *cdev,
sp_rss_params.update_rss_capabilities = 1;
sp_rss_params.update_rss_ind_table = 1;
sp_rss_params.update_rss_key = 1;
sp_rss_params.rss_caps = QED_RSS_IPV4 |
QED_RSS_IPV6 |
QED_RSS_IPV4_TCP | QED_RSS_IPV6_TCP;
sp_rss_params.rss_caps = params->rss_params.rss_caps;
sp_rss_params.rss_table_size_log = 7; /* 2^7 = 128 */
memcpy(sp_rss_params.rss_ind_table,
params->rss_params.rss_ind_table,
Expand Down Expand Up @@ -2043,14 +2028,8 @@ static const struct qed_eth_ops qed_eth_ops_pass = {
.get_vport_stats = &qed_get_vport_stats,
};

const struct qed_eth_ops *qed_get_eth_ops(u32 version)
const struct qed_eth_ops *qed_get_eth_ops(void)
{
if (version != QED_ETH_INTERFACE_VERSION) {
pr_notice("Cannot supply ethtool operations [%08x != %08x]\n",
version, QED_ETH_INTERFACE_VERSION);
return NULL;
}

return &qed_eth_ops_pass;
}
EXPORT_SYMBOL(qed_get_eth_ops);
Expand Down
11 changes: 0 additions & 11 deletions drivers/net/ethernet/qlogic/qed/qed_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1172,14 +1172,3 @@ const struct qed_common_ops qed_common_ops_pass = {
.chain_free = &qed_chain_free,
.set_led = &qed_set_led,
};

u32 qed_get_protocol_version(enum qed_protocol protocol)
{
switch (protocol) {
case QED_PROTOCOL_ETH:
return QED_ETH_INTERFACE_VERSION;
default:
return 0;
}
}
EXPORT_SYMBOL(qed_get_protocol_version);
10 changes: 6 additions & 4 deletions drivers/net/ethernet/qlogic/qede/qede.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@

#define QEDE_MAJOR_VERSION 8
#define QEDE_MINOR_VERSION 7
#define QEDE_REVISION_VERSION 0
#define QEDE_ENGINEERING_VERSION 0
#define QEDE_REVISION_VERSION 1
#define QEDE_ENGINEERING_VERSION 20
#define DRV_MODULE_VERSION __stringify(QEDE_MAJOR_VERSION) "." \
__stringify(QEDE_MINOR_VERSION) "." \
__stringify(QEDE_REVISION_VERSION) "." \
__stringify(QEDE_ENGINEERING_VERSION)

#define QEDE_ETH_INTERFACE_VERSION 300

#define DRV_MODULE_SYM qede

struct qede_stats {
Expand Down Expand Up @@ -156,6 +154,10 @@ struct qede_dev {
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))

struct qede_stats stats;
#define QEDE_RSS_INDIR_INITED BIT(0)
#define QEDE_RSS_KEY_INITED BIT(1)
#define QEDE_RSS_CAPS_INITED BIT(2)
u32 rss_params_inited; /* bit-field to track initialized rss params */
struct qed_update_vport_rss_params rss_params;
u16 q_num_rx_buffers; /* Must be a power of two */
u16 q_num_tx_buffers; /* Must be a power of two */
Expand Down
237 changes: 236 additions & 1 deletion drivers/net/ethernet/qlogic/qede/qede_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,236 @@ static int qede_set_phys_id(struct net_device *dev,
return 0;
}

static int qede_get_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
{
info->data = RXH_IP_SRC | RXH_IP_DST;

switch (info->flow_type) {
case TCP_V4_FLOW:
case TCP_V6_FLOW:
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)
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)
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case IPV4_FLOW:
case IPV6_FLOW:
break;
default:
info->data = 0;
break;
}

return 0;
}

static int qede_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info,
u32 *rules __always_unused)
{
struct qede_dev *edev = netdev_priv(dev);

switch (info->cmd) {
case ETHTOOL_GRXRINGS:
info->data = edev->num_rss;
return 0;
case ETHTOOL_GRXFH:
return qede_get_rss_flags(edev, info);
default:
DP_ERR(edev, "Command parameters not supported\n");
return -EOPNOTSUPP;
}
}

static int qede_set_rss_flags(struct qede_dev *edev, struct ethtool_rxnfc *info)
{
struct qed_update_vport_params vport_update_params;
u8 set_caps = 0, clr_caps = 0;

DP_VERBOSE(edev, QED_MSG_DEBUG,
"Set rss flags command parameters: flow type = %d, data = %llu\n",
info->flow_type, info->data);

switch (info->flow_type) {
case TCP_V4_FLOW:
case TCP_V6_FLOW:
/* For TCP only 4-tuple hash is supported */
if (info->data ^ (RXH_IP_SRC | RXH_IP_DST |
RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
DP_INFO(edev, "Command parameters not supported\n");
return -EINVAL;
}
return 0;
case UDP_V4_FLOW:
/* For UDP either 2-tuple hash or 4-tuple hash is supported */
if (info->data == (RXH_IP_SRC | RXH_IP_DST |
RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
set_caps = QED_RSS_IPV4_UDP;
DP_VERBOSE(edev, QED_MSG_DEBUG,
"UDP 4-tuple enabled\n");
} else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
clr_caps = QED_RSS_IPV4_UDP;
DP_VERBOSE(edev, QED_MSG_DEBUG,
"UDP 4-tuple disabled\n");
} else {
return -EINVAL;
}
break;
case UDP_V6_FLOW:
/* For UDP either 2-tuple hash or 4-tuple hash is supported */
if (info->data == (RXH_IP_SRC | RXH_IP_DST |
RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
set_caps = QED_RSS_IPV6_UDP;
DP_VERBOSE(edev, QED_MSG_DEBUG,
"UDP 4-tuple enabled\n");
} else if (info->data == (RXH_IP_SRC | RXH_IP_DST)) {
clr_caps = QED_RSS_IPV6_UDP;
DP_VERBOSE(edev, QED_MSG_DEBUG,
"UDP 4-tuple disabled\n");
} else {
return -EINVAL;
}
break;
case IPV4_FLOW:
case IPV6_FLOW:
/* For IP only 2-tuple hash is supported */
if (info->data ^ (RXH_IP_SRC | RXH_IP_DST)) {
DP_INFO(edev, "Command parameters not supported\n");
return -EINVAL;
}
return 0;
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
case AH_V4_FLOW:
case ESP_V4_FLOW:
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
case AH_V6_FLOW:
case ESP_V6_FLOW:
case IP_USER_FLOW:
case ETHER_FLOW:
/* RSS is not supported for these protocols */
if (info->data) {
DP_INFO(edev, "Command parameters not supported\n");
return -EINVAL;
}
return 0;
default:
return -EINVAL;
}

/* 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))
return 0;

/* Update internal configuration */
edev->rss_params.rss_caps = (edev->rss_params.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);
}

return 0;
}

static int qede_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
{
struct qede_dev *edev = netdev_priv(dev);

switch (info->cmd) {
case ETHTOOL_SRXFH:
return qede_set_rss_flags(edev, info);
default:
DP_INFO(edev, "Command parameters not supported\n");
return -EOPNOTSUPP;
}
}

static u32 qede_get_rxfh_indir_size(struct net_device *dev)
{
return QED_RSS_IND_TABLE_SIZE;
}

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);
}

static int qede_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
{
struct qede_dev *edev = netdev_priv(dev);
int i;

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;

if (!indir)
return 0;

for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
indir[i] = edev->rss_params.rss_ind_table[i];

if (key)
memcpy(key, edev->rss_params.rss_key,
qede_get_rxfh_key_size(dev));

return 0;
}

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 qede_dev *edev = netdev_priv(dev);
int i;

if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;

if (!indir && !key)
return 0;

if (indir) {
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++)
edev->rss_params.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));
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);
}

return 0;
}

static const struct ethtool_ops qede_ethtool_ops = {
.get_settings = qede_get_settings,
.set_settings = qede_set_settings,
Expand All @@ -585,7 +815,12 @@ static const struct ethtool_ops qede_ethtool_ops = {
.set_phys_id = qede_set_phys_id,
.get_ethtool_stats = qede_get_ethtool_stats,
.get_sset_count = qede_get_sset_count,

.get_rxnfc = qede_get_rxnfc,
.set_rxnfc = qede_set_rxnfc,
.get_rxfh_indir_size = qede_get_rxfh_indir_size,
.get_rxfh_key_size = qede_get_rxfh_key_size,
.get_rxfh = qede_get_rxfh,
.set_rxfh = qede_set_rxfh,
.get_channels = qede_get_channels,
.set_channels = qede_set_channels,
};
Expand Down
Loading

0 comments on commit b9aa78d

Please sign in to comment.