Commit 0205ec04 authored by Jian Shen's avatar Jian Shen Committed by David S. Miller

net: hns3: add support for hw tc offload of tc flower

Some new device supports forwarding packet to queues of specified
TC when flow director rule hit. So add support to configure flow
director rule by tc flower. To avoid rule conflict, add a new flow
director mode HCLGE_FD_TC_FLOWER_ACTIVE, and only one mode can be
active at the same time.
Signed-off-by: default avatarJian Shen <shenjian15@huawei.com>
Signed-off-by: default avatarHuazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0f993fe2
......@@ -459,6 +459,12 @@ struct hnae3_ae_dev {
* Configure the default MAC for specified VF
* get_module_eeprom
* Get the optical module eeprom info.
* add_cls_flower
* Add clsflower rule
* del_cls_flower
* Delete clsflower rule
* cls_flower_active
* Check if any cls flower rule exist
*/
struct hnae3_ae_ops {
int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
......@@ -636,6 +642,11 @@ struct hnae3_ae_ops {
int (*get_module_eeprom)(struct hnae3_handle *handle, u32 offset,
u32 len, u8 *data);
bool (*get_cmdq_stat)(struct hnae3_handle *handle);
int (*add_cls_flower)(struct hnae3_handle *handle,
struct flow_cls_offload *cls_flower, int tc);
int (*del_cls_flower)(struct hnae3_handle *handle,
struct flow_cls_offload *cls_flower);
bool (*cls_flower_active)(struct hnae3_handle *handle);
};
struct hnae3_dcb_ops {
......
......@@ -1668,6 +1668,13 @@ static int hns3_nic_set_features(struct net_device *netdev,
h->ae_algo->ops->enable_fd(h, enable);
}
if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
h->ae_algo->ops->cls_flower_active(h)) {
netdev_err(netdev,
"there are offloaded TC filters active, cannot disable HW TC offload");
return -EINVAL;
}
netdev->features = features;
return 0;
}
......@@ -1818,13 +1825,67 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
kinfo->dcb_ops->setup_tc(h, mqprio_qopt) : -EOPNOTSUPP;
}
static int hns3_setup_tc_cls_flower(struct hns3_nic_priv *priv,
struct flow_cls_offload *flow)
{
int tc = tc_classid_to_hwtc(priv->netdev, flow->classid);
struct hnae3_handle *h = hns3_get_handle(priv->netdev);
switch (flow->command) {
case FLOW_CLS_REPLACE:
if (h->ae_algo->ops->add_cls_flower)
return h->ae_algo->ops->add_cls_flower(h, flow, tc);
break;
case FLOW_CLS_DESTROY:
if (h->ae_algo->ops->del_cls_flower)
return h->ae_algo->ops->del_cls_flower(h, flow);
break;
default:
break;
}
return -EOPNOTSUPP;
}
static int hns3_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
void *cb_priv)
{
struct hns3_nic_priv *priv = cb_priv;
if (!tc_cls_can_offload_and_chain0(priv->netdev, type_data))
return -EOPNOTSUPP;
switch (type) {
case TC_SETUP_CLSFLOWER:
return hns3_setup_tc_cls_flower(priv, type_data);
default:
return -EOPNOTSUPP;
}
}
static LIST_HEAD(hns3_block_cb_list);
static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
if (type != TC_SETUP_QDISC_MQPRIO)
struct hns3_nic_priv *priv = netdev_priv(dev);
int ret;
switch (type) {
case TC_SETUP_QDISC_MQPRIO:
ret = hns3_setup_tc(dev, type_data);
break;
case TC_SETUP_BLOCK:
ret = flow_block_cb_setup_simple(type_data,
&hns3_block_cb_list,
hns3_setup_tc_block_cb,
priv, priv, true);
break;
default:
return -EOPNOTSUPP;
}
return hns3_setup_tc(dev, type_data);
return ret;
}
static int hns3_vlan_rx_add_vid(struct net_device *netdev,
......@@ -2421,6 +2482,11 @@ static void hns3_set_default_feature(struct net_device *netdev)
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
}
if (test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps)) {
netdev->hw_features |= NETIF_F_HW_TC;
netdev->features |= NETIF_F_HW_TC;
}
}
static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
......
......@@ -564,6 +564,7 @@ enum HCLGE_FD_ACTIVE_RULE_TYPE {
HCLGE_FD_RULE_NONE,
HCLGE_FD_ARFS_ACTIVE,
HCLGE_FD_EP_ACTIVE,
HCLGE_FD_TC_FLOWER_ACTIVE,
};
enum HCLGE_FD_PACKET_TYPE {
......@@ -619,13 +620,20 @@ struct hclge_fd_rule {
struct hclge_fd_rule_tuples tuples_mask;
u32 unused_tuple;
u32 flow_type;
u8 action;
u8 tc;
u16 vf_id;
union {
struct {
unsigned long cookie;
u8 tc;
} cls_flower;
struct {
u16 flow_id; /* only used for arfs */
} arfs;
};
u16 queue_id;
u16 vf_id;
u16 location;
u16 flow_id; /* only used for arfs */
enum HCLGE_FD_ACTIVE_RULE_TYPE rule_type;
u8 action;
};
struct hclge_fd_ad_data {
......
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