Skip to content

Commit

Permalink
net: hns3: add support for hw tc offload of tc flower
Browse files Browse the repository at this point in the history
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: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jian Shen authored and David S. Miller committed Dec 10, 2020
1 parent 0f993fe commit 0205ec0
Show file tree
Hide file tree
Showing 4 changed files with 397 additions and 13 deletions.
11 changes: 11 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hnae3.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
70 changes: 68 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit 0205ec0

Please sign in to comment.