Commit b7ec45a8 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-next'

Salil Mehta says:

====================
Adds support of RSS to HNS3 Driver for Rev 2(=0x21) H/W

This patch-set mainly adds new additions related to RSS for the new
hardware Revision 0x21. It also adds support to use RSS hash value
provided by the hardware along with descriptor.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9047fa5d 232fc64b
...@@ -479,6 +479,7 @@ struct hnae3_knic_private_info { ...@@ -479,6 +479,7 @@ struct hnae3_knic_private_info {
const struct hnae3_dcb_ops *dcb_ops; const struct hnae3_dcb_ops *dcb_ops;
u16 int_rl_setting; u16 int_rl_setting;
enum pkt_hash_types rss_type;
}; };
struct hnae3_roce_private_info { struct hnae3_roce_private_info {
......
...@@ -2230,6 +2230,21 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring, ...@@ -2230,6 +2230,21 @@ static bool hns3_parse_vlan_tag(struct hns3_enet_ring *ring,
} }
} }
static void hns3_set_rx_skb_rss_type(struct hns3_enet_ring *ring,
struct sk_buff *skb)
{
struct hns3_desc *desc = &ring->desc[ring->next_to_clean];
struct hnae3_handle *handle = ring->tqp->handle;
enum pkt_hash_types rss_type;
if (le32_to_cpu(desc->rx.rss_hash))
rss_type = handle->kinfo.rss_type;
else
rss_type = PKT_HASH_TYPE_NONE;
skb_set_hash(skb, le32_to_cpu(desc->rx.rss_hash), rss_type);
}
static int hns3_handle_rx_bd(struct hns3_enet_ring *ring, static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
struct sk_buff **out_skb, int *out_bnum) struct sk_buff **out_skb, int *out_bnum)
{ {
...@@ -2371,6 +2386,8 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring, ...@@ -2371,6 +2386,8 @@ static int hns3_handle_rx_bd(struct hns3_enet_ring *ring,
ring->tqp_vector->rx_group.total_bytes += skb->len; ring->tqp_vector->rx_group.total_bytes += skb->len;
hns3_rx_checksum(ring, skb, desc); hns3_rx_checksum(ring, skb, desc);
hns3_set_rx_skb_rss_type(ring, skb);
return 0; return 0;
} }
......
...@@ -678,12 +678,13 @@ static int hns3_set_rss(struct net_device *netdev, const u32 *indir, ...@@ -678,12 +678,13 @@ static int hns3_set_rss(struct net_device *netdev, const u32 *indir,
if (!h->ae_algo || !h->ae_algo->ops || !h->ae_algo->ops->set_rss) if (!h->ae_algo || !h->ae_algo->ops || !h->ae_algo->ops->set_rss)
return -EOPNOTSUPP; return -EOPNOTSUPP;
/* currently we only support Toeplitz hash */ if ((h->pdev->revision == 0x20 &&
if ((hfunc != ETH_RSS_HASH_NO_CHANGE) && (hfunc != ETH_RSS_HASH_TOP)) { hfunc != ETH_RSS_HASH_TOP) || (hfunc != ETH_RSS_HASH_NO_CHANGE &&
netdev_err(netdev, hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR)) {
"hash func not supported (only Toeplitz hash)\n"); netdev_err(netdev, "hash func not supported\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (!indir) { if (!indir) {
netdev_err(netdev, netdev_err(netdev,
"set rss failed for indir is empty\n"); "set rss failed for indir is empty\n");
...@@ -1077,6 +1078,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = { ...@@ -1077,6 +1078,7 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
.get_ethtool_stats = hns3_get_stats, .get_ethtool_stats = hns3_get_stats,
.get_sset_count = hns3_get_sset_count, .get_sset_count = hns3_get_sset_count,
.get_rxnfc = hns3_get_rxnfc, .get_rxnfc = hns3_get_rxnfc,
.set_rxnfc = hns3_set_rxnfc,
.get_rxfh_key_size = hns3_get_rss_key_size, .get_rxfh_key_size = hns3_get_rss_key_size,
.get_rxfh_indir_size = hns3_get_rss_indir_size, .get_rxfh_indir_size = hns3_get_rss_indir_size,
.get_rxfh = hns3_get_rss, .get_rxfh = hns3_get_rss,
......
...@@ -2773,6 +2773,22 @@ static int hclge_set_rss_tc_mode(struct hclge_dev *hdev, u16 *tc_valid, ...@@ -2773,6 +2773,22 @@ static int hclge_set_rss_tc_mode(struct hclge_dev *hdev, u16 *tc_valid,
return ret; return ret;
} }
static void hclge_get_rss_type(struct hclge_vport *vport)
{
if (vport->rss_tuple_sets.ipv4_tcp_en ||
vport->rss_tuple_sets.ipv4_udp_en ||
vport->rss_tuple_sets.ipv4_sctp_en ||
vport->rss_tuple_sets.ipv6_tcp_en ||
vport->rss_tuple_sets.ipv6_udp_en ||
vport->rss_tuple_sets.ipv6_sctp_en)
vport->nic.kinfo.rss_type = PKT_HASH_TYPE_L4;
else if (vport->rss_tuple_sets.ipv4_fragment_en ||
vport->rss_tuple_sets.ipv6_fragment_en)
vport->nic.kinfo.rss_type = PKT_HASH_TYPE_L3;
else
vport->nic.kinfo.rss_type = PKT_HASH_TYPE_NONE;
}
static int hclge_set_rss_input_tuple(struct hclge_dev *hdev) static int hclge_set_rss_input_tuple(struct hclge_dev *hdev)
{ {
struct hclge_rss_input_tuple_cmd *req; struct hclge_rss_input_tuple_cmd *req;
...@@ -2792,6 +2808,7 @@ static int hclge_set_rss_input_tuple(struct hclge_dev *hdev) ...@@ -2792,6 +2808,7 @@ static int hclge_set_rss_input_tuple(struct hclge_dev *hdev)
req->ipv6_udp_en = hdev->vport[0].rss_tuple_sets.ipv6_udp_en; req->ipv6_udp_en = hdev->vport[0].rss_tuple_sets.ipv6_udp_en;
req->ipv6_sctp_en = hdev->vport[0].rss_tuple_sets.ipv6_sctp_en; req->ipv6_sctp_en = hdev->vport[0].rss_tuple_sets.ipv6_sctp_en;
req->ipv6_fragment_en = hdev->vport[0].rss_tuple_sets.ipv6_fragment_en; req->ipv6_fragment_en = hdev->vport[0].rss_tuple_sets.ipv6_fragment_en;
hclge_get_rss_type(&hdev->vport[0]);
ret = hclge_cmd_send(&hdev->hw, &desc, 1); ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) if (ret)
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
...@@ -2806,8 +2823,19 @@ static int hclge_get_rss(struct hnae3_handle *handle, u32 *indir, ...@@ -2806,8 +2823,19 @@ static int hclge_get_rss(struct hnae3_handle *handle, u32 *indir,
int i; int i;
/* Get hash algorithm */ /* Get hash algorithm */
if (hfunc) if (hfunc) {
*hfunc = vport->rss_algo; switch (vport->rss_algo) {
case HCLGE_RSS_HASH_ALGO_TOEPLITZ:
*hfunc = ETH_RSS_HASH_TOP;
break;
case HCLGE_RSS_HASH_ALGO_SIMPLE:
*hfunc = ETH_RSS_HASH_XOR;
break;
default:
*hfunc = ETH_RSS_HASH_UNKNOWN;
break;
}
}
/* Get the RSS Key required by the user */ /* Get the RSS Key required by the user */
if (key) if (key)
...@@ -2831,12 +2859,20 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir, ...@@ -2831,12 +2859,20 @@ static int hclge_set_rss(struct hnae3_handle *handle, const u32 *indir,
/* Set the RSS Hash Key if specififed by the user */ /* Set the RSS Hash Key if specififed by the user */
if (key) { if (key) {
switch (hfunc) {
if (hfunc == ETH_RSS_HASH_TOP || case ETH_RSS_HASH_TOP:
hfunc == ETH_RSS_HASH_NO_CHANGE)
hash_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ; hash_algo = HCLGE_RSS_HASH_ALGO_TOEPLITZ;
else break;
case ETH_RSS_HASH_XOR:
hash_algo = HCLGE_RSS_HASH_ALGO_SIMPLE;
break;
case ETH_RSS_HASH_NO_CHANGE:
hash_algo = vport->rss_algo;
break;
default:
return -EINVAL; return -EINVAL;
}
ret = hclge_set_rss_algo_key(hdev, hash_algo, key); ret = hclge_set_rss_algo_key(hdev, hash_algo, key);
if (ret) if (ret)
return ret; return ret;
...@@ -2954,6 +2990,7 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle, ...@@ -2954,6 +2990,7 @@ static int hclge_set_rss_tuple(struct hnae3_handle *handle,
vport->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en; vport->rss_tuple_sets.ipv6_udp_en = req->ipv6_udp_en;
vport->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en; vport->rss_tuple_sets.ipv6_sctp_en = req->ipv6_sctp_en;
vport->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en; vport->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en;
hclge_get_rss_type(vport);
return 0; return 0;
} }
......
...@@ -89,6 +89,7 @@ enum hclgevf_opcode_type { ...@@ -89,6 +89,7 @@ enum hclgevf_opcode_type {
HCLGEVF_OPC_CFG_COM_TQP_QUEUE = 0x0B20, HCLGEVF_OPC_CFG_COM_TQP_QUEUE = 0x0B20,
/* RSS cmd */ /* RSS cmd */
HCLGEVF_OPC_RSS_GENERIC_CONFIG = 0x0D01, HCLGEVF_OPC_RSS_GENERIC_CONFIG = 0x0D01,
HCLGEVF_OPC_RSS_INPUT_TUPLE = 0x0D02,
HCLGEVF_OPC_RSS_INDIR_TABLE = 0x0D07, HCLGEVF_OPC_RSS_INDIR_TABLE = 0x0D07,
HCLGEVF_OPC_RSS_TC_MODE = 0x0D08, HCLGEVF_OPC_RSS_TC_MODE = 0x0D08,
/* Mailbox cmd */ /* Mailbox cmd */
...@@ -148,7 +149,8 @@ struct hclgevf_query_res_cmd { ...@@ -148,7 +149,8 @@ struct hclgevf_query_res_cmd {
__le16 rsv[7]; __le16 rsv[7];
}; };
#define HCLGEVF_RSS_HASH_KEY_OFFSET 4 #define HCLGEVF_RSS_DEFAULT_OUTPORT_B 4
#define HCLGEVF_RSS_HASH_KEY_OFFSET_B 4
#define HCLGEVF_RSS_HASH_KEY_NUM 16 #define HCLGEVF_RSS_HASH_KEY_NUM 16
struct hclgevf_rss_config_cmd { struct hclgevf_rss_config_cmd {
u8 hash_config; u8 hash_config;
...@@ -159,11 +161,11 @@ struct hclgevf_rss_config_cmd { ...@@ -159,11 +161,11 @@ struct hclgevf_rss_config_cmd {
struct hclgevf_rss_input_tuple_cmd { struct hclgevf_rss_input_tuple_cmd {
u8 ipv4_tcp_en; u8 ipv4_tcp_en;
u8 ipv4_udp_en; u8 ipv4_udp_en;
u8 ipv4_stcp_en; u8 ipv4_sctp_en;
u8 ipv4_fragment_en; u8 ipv4_fragment_en;
u8 ipv6_tcp_en; u8 ipv6_tcp_en;
u8 ipv6_udp_en; u8 ipv6_udp_en;
u8 ipv6_stcp_en; u8 ipv6_sctp_en;
u8 ipv6_fragment_en; u8 ipv6_fragment_en;
u8 rsv[16]; u8 rsv[16];
}; };
......
...@@ -46,6 +46,13 @@ ...@@ -46,6 +46,13 @@
#define HCLGEVF_RSS_HASH_ALGO_MASK 0xf #define HCLGEVF_RSS_HASH_ALGO_MASK 0xf
#define HCLGEVF_RSS_CFG_TBL_NUM \ #define HCLGEVF_RSS_CFG_TBL_NUM \
(HCLGEVF_RSS_IND_TBL_SIZE / HCLGEVF_RSS_CFG_TBL_SIZE) (HCLGEVF_RSS_IND_TBL_SIZE / HCLGEVF_RSS_CFG_TBL_SIZE)
#define HCLGEVF_RSS_INPUT_TUPLE_OTHER GENMASK(3, 0)
#define HCLGEVF_RSS_INPUT_TUPLE_SCTP GENMASK(4, 0)
#define HCLGEVF_D_PORT_BIT BIT(0)
#define HCLGEVF_S_PORT_BIT BIT(1)
#define HCLGEVF_D_IP_BIT BIT(2)
#define HCLGEVF_S_IP_BIT BIT(3)
#define HCLGEVF_V_TAG_BIT BIT(4)
/* states of hclgevf device & tasks */ /* states of hclgevf device & tasks */
enum hclgevf_states { enum hclgevf_states {
...@@ -106,12 +113,24 @@ struct hclgevf_cfg { ...@@ -106,12 +113,24 @@ struct hclgevf_cfg {
u32 numa_node_map; u32 numa_node_map;
}; };
struct hclgevf_rss_tuple_cfg {
u8 ipv4_tcp_en;
u8 ipv4_udp_en;
u8 ipv4_sctp_en;
u8 ipv4_fragment_en;
u8 ipv6_tcp_en;
u8 ipv6_udp_en;
u8 ipv6_sctp_en;
u8 ipv6_fragment_en;
};
struct hclgevf_rss_cfg { struct hclgevf_rss_cfg {
u8 rss_hash_key[HCLGEVF_RSS_KEY_SIZE]; /* user configured hash keys */ u8 rss_hash_key[HCLGEVF_RSS_KEY_SIZE]; /* user configured hash keys */
u32 hash_algo; u32 hash_algo;
u32 rss_size; u32 rss_size;
u8 hw_tc_map; u8 hw_tc_map;
u8 rss_indirection_tbl[HCLGEVF_RSS_IND_TBL_SIZE]; /* shadow table */ u8 rss_indirection_tbl[HCLGEVF_RSS_IND_TBL_SIZE]; /* shadow table */
struct hclgevf_rss_tuple_cfg rss_tuple_sets;
}; };
struct hclgevf_misc_vector { struct hclgevf_misc_vector {
......
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