Merge branch 'qed-ethtool-rss'
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>
This commit is contained in:
Коммит
b9aa78d4fb
|
@ -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
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -141,19 +141,10 @@ static
|
|||
int __init qede_init(void)
|
||||
{
|
||||
int ret;
|
||||
u32 qed_ver;
|
||||
|
||||
pr_notice("qede_init: %s\n", version);
|
||||
|
||||
qed_ver = qed_get_protocol_version(QED_PROTOCOL_ETH);
|
||||
if (qed_ver != QEDE_ETH_INTERFACE_VERSION) {
|
||||
pr_notice("Version mismatch [%08x != %08x]\n",
|
||||
qed_ver,
|
||||
QEDE_ETH_INTERFACE_VERSION);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qed_ops = qed_get_eth_ops(QEDE_ETH_INTERFACE_VERSION);
|
||||
qed_ops = qed_get_eth_ops();
|
||||
if (!qed_ops) {
|
||||
pr_notice("Failed to get qed ethtool operations\n");
|
||||
return -EINVAL;
|
||||
|
@ -2835,10 +2826,10 @@ static int qede_start_queues(struct qede_dev *edev)
|
|||
int rc, tc, i;
|
||||
int vlan_removal_en = 1;
|
||||
struct qed_dev *cdev = edev->cdev;
|
||||
struct qed_update_vport_rss_params *rss_params = &edev->rss_params;
|
||||
struct qed_update_vport_params vport_update_params;
|
||||
struct qed_queue_start_common_params q_params;
|
||||
struct qed_start_vport_params start = {0};
|
||||
bool reset_rss_indir = false;
|
||||
|
||||
if (!edev->num_rss) {
|
||||
DP_ERR(edev,
|
||||
|
@ -2933,16 +2924,50 @@ static int qede_start_queues(struct qede_dev *edev)
|
|||
/* Fill struct with RSS params */
|
||||
if (QEDE_RSS_CNT(edev) > 1) {
|
||||
vport_update_params.update_rss_flg = 1;
|
||||
for (i = 0; i < 128; i++)
|
||||
rss_params->rss_ind_table[i] =
|
||||
ethtool_rxfh_indir_default(i, QEDE_RSS_CNT(edev));
|
||||
netdev_rss_key_fill(rss_params->rss_key,
|
||||
sizeof(rss_params->rss_key));
|
||||
|
||||
/* Need to validate current RSS config uses valid entries */
|
||||
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++) {
|
||||
if (edev->rss_params.rss_ind_table[i] >=
|
||||
edev->num_rss) {
|
||||
reset_rss_indir = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(edev->rss_params_inited & QEDE_RSS_INDIR_INITED) ||
|
||||
reset_rss_indir) {
|
||||
u16 val;
|
||||
|
||||
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++) {
|
||||
u16 indir_val;
|
||||
|
||||
val = QEDE_RSS_CNT(edev);
|
||||
indir_val = ethtool_rxfh_indir_default(i, val);
|
||||
edev->rss_params.rss_ind_table[i] = indir_val;
|
||||
}
|
||||
edev->rss_params_inited |= QEDE_RSS_INDIR_INITED;
|
||||
}
|
||||
|
||||
if (!(edev->rss_params_inited & QEDE_RSS_KEY_INITED)) {
|
||||
netdev_rss_key_fill(edev->rss_params.rss_key,
|
||||
sizeof(edev->rss_params.rss_key));
|
||||
edev->rss_params_inited |= QEDE_RSS_KEY_INITED;
|
||||
}
|
||||
|
||||
if (!(edev->rss_params_inited & QEDE_RSS_CAPS_INITED)) {
|
||||
edev->rss_params.rss_caps = QED_RSS_IPV4 |
|
||||
QED_RSS_IPV6 |
|
||||
QED_RSS_IPV4_TCP |
|
||||
QED_RSS_IPV6_TCP;
|
||||
edev->rss_params_inited |= QEDE_RSS_CAPS_INITED;
|
||||
}
|
||||
|
||||
memcpy(&vport_update_params.rss_params, &edev->rss_params,
|
||||
sizeof(vport_update_params.rss_params));
|
||||
} else {
|
||||
memset(rss_params, 0, sizeof(*rss_params));
|
||||
memset(&vport_update_params.rss_params, 0,
|
||||
sizeof(vport_update_params.rss_params));
|
||||
}
|
||||
memcpy(&vport_update_params.rss_params, rss_params,
|
||||
sizeof(*rss_params));
|
||||
|
||||
rc = edev->ops->vport_update(cdev, &vport_update_params);
|
||||
if (rc) {
|
||||
|
|
|
@ -27,6 +27,7 @@ struct qed_dev_eth_info {
|
|||
struct qed_update_vport_rss_params {
|
||||
u16 rss_ind_table[128];
|
||||
u32 rss_key[10];
|
||||
u8 rss_caps;
|
||||
};
|
||||
|
||||
struct qed_update_vport_params {
|
||||
|
@ -167,7 +168,7 @@ struct qed_eth_ops {
|
|||
struct qed_eth_stats *stats);
|
||||
};
|
||||
|
||||
const struct qed_eth_ops *qed_get_eth_ops(u32 version);
|
||||
const struct qed_eth_ops *qed_get_eth_ops(void);
|
||||
void qed_put_eth_ops(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -271,15 +271,6 @@ struct qed_common_ops {
|
|||
enum qed_led_mode mode);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief qed_get_protocol_version
|
||||
*
|
||||
* @param protocol
|
||||
*
|
||||
* @return version supported by qed for given protocol driver
|
||||
*/
|
||||
u32 qed_get_protocol_version(enum qed_protocol protocol);
|
||||
|
||||
#define MASK_FIELD(_name, _value) \
|
||||
((_value) &= (_name ## _MASK))
|
||||
|
||||
|
@ -524,4 +515,15 @@ static inline void internal_ram_wr(void __iomem *addr,
|
|||
__internal_ram_wr(NULL, addr, size, data);
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
#define QED_RSS_IND_TABLE_SIZE 128
|
||||
#define QED_RSS_KEY_SIZE 10 /* size in 32b chunks */
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче