Skip to content

Commit

Permalink
net: extend netdev features
Browse files Browse the repository at this point in the history
For the prototype of netdev_features_t is u64, and the number
of netdevice feature bits is 64 now. So there is no space to
introduce new feature bit.

I did a small change for this. Keep the prototype of
netdev_feature_t, and extend the feature members in struct
net_device to an array of netdev_features_t. So more features
bits can be used.

As this change, some functions which use netdev_features_t as
parameter or returen value will be affected.
I did below changes:
a. parameter: "netdev_features_t" to "netdev_features_t *"
b. return value: "netdev_feature_t" to "void", and add
"netdev_feature_t *" as output parameter.

I kept some functions no change, which are surely useing the
first 64 bit of net device features now, such as function
nedev_add_tso_features(). In order to minimize to changes.

For the features are array now, so it's unable to do logical
operation directly. I introduce a inline function set for
them, including "netdev_features_and/andnot/or/xor/equal/empty".

For NETDEV_FEATURE_COUNT may be more than 64, so the shift
operation for NETDEV_FEATURE_COUNT is illegal. I changed some
macroes and functions, which does shift opertion with it.

I haven't finished all the changes, for it affected all the
drivers which use the feature, need more time and test. I
sent this RFC patch, want to know whether this change is
acceptable, and how to improve it.

Any comments will be helpful.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
  • Loading branch information
IronShen authored and intel-lab-lkp committed Jul 10, 2021
1 parent 5e43741 commit 378137e
Show file tree
Hide file tree
Showing 14 changed files with 493 additions and 337 deletions.
34 changes: 17 additions & 17 deletions drivers/net/ethernet/hisilicon/hns/hns_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ static void hns_nic_rx_checksum(struct hns_nic_ring_data *ring_data,
u32 l4id;

/* check if RX checksum offload is enabled */
if (unlikely(!(netdev->features & NETIF_F_RXCSUM)))
if (unlikely(!(netdev->features[0] & NETIF_F_RXCSUM)))
return;

/* In hardware, we only support checksum for the following protocols:
Expand Down Expand Up @@ -1768,17 +1768,17 @@ static int hns_nic_change_mtu(struct net_device *ndev, int new_mtu)
}

static int hns_nic_set_features(struct net_device *netdev,
netdev_features_t features)
netdev_features_t *features)
{
struct hns_nic_priv *priv = netdev_priv(netdev);

switch (priv->enet_ver) {
case AE_VERSION_1:
if (features & (NETIF_F_TSO | NETIF_F_TSO6))
if (features[0] & (NETIF_F_TSO | NETIF_F_TSO6))
netdev_info(netdev, "enet v1 do not support tso!\n");
break;
default:
if (features & (NETIF_F_TSO | NETIF_F_TSO6)) {
if (features[0] & (NETIF_F_TSO | NETIF_F_TSO6)) {
priv->ops.fill_desc = fill_tso_desc;
priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso;
/* The chip only support 7*4096 */
Expand All @@ -1789,24 +1789,23 @@ static int hns_nic_set_features(struct net_device *netdev,
}
break;
}
netdev->features = features;
netdev->features[0] = features[0];
return 0;
}

static netdev_features_t hns_nic_fix_features(
struct net_device *netdev, netdev_features_t features)
static void hns_nic_fix_features(struct net_device *netdev,
netdev_features_t *features)
{
struct hns_nic_priv *priv = netdev_priv(netdev);

switch (priv->enet_ver) {
case AE_VERSION_1:
features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
features[0] &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
NETIF_F_HW_VLAN_CTAG_FILTER);
break;
default:
break;
}
return features;
}

static int hns_nic_uc_sync(struct net_device *netdev, const unsigned char *addr)
Expand Down Expand Up @@ -2163,8 +2162,8 @@ static void hns_nic_set_priv_ops(struct net_device *netdev)
priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx;
} else {
priv->ops.get_rxd_bnum = get_v2rx_desc_bnum;
if ((netdev->features & NETIF_F_TSO) ||
(netdev->features & NETIF_F_TSO6)) {
if ((netdev->features[0] & NETIF_F_TSO) ||
(netdev->features[0] & NETIF_F_TSO6)) {
priv->ops.fill_desc = fill_tso_desc;
priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso;
/* This chip only support 7*4096 */
Expand Down Expand Up @@ -2325,22 +2324,23 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
ndev->netdev_ops = &hns_nic_netdev_ops;
hns_ethtool_set_ops(ndev);

ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
ndev->features[0] |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO;
ndev->vlan_features |=
ndev->vlan_features[0] |=
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
ndev->vlan_features |= NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO;
ndev->vlan_features[0] |= NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO;

/* MTU range: 68 - 9578 (v1) or 9706 (v2) */
ndev->min_mtu = MAC_MIN_MTU;
switch (priv->enet_ver) {
case AE_VERSION_2:
ndev->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_NTUPLE;
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
ndev->features[0] |=
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_NTUPLE;
ndev->hw_features[0] |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6;
ndev->vlan_features |= NETIF_F_TSO | NETIF_F_TSO6;
ndev->vlan_features[0] |= NETIF_F_TSO | NETIF_F_TSO6;
ndev->max_mtu = MAC_MAX_MTU_V2 -
(ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN);
break;
Expand Down
97 changes: 49 additions & 48 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ static int hns3_handle_vtags(struct hns3_enet_ring *tx_ring,
return -EINVAL;

if (skb->protocol == htons(ETH_P_8021Q) &&
!(handle->kinfo.netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) {
!(handle->kinfo.netdev->features[0] & NETIF_F_HW_VLAN_CTAG_TX)) {
/* When HW VLAN acceleration is turned off, and the stack
* sets the protocol to 802.1q, the driver just need to
* set the protocol to the encapsulated ethertype.
Expand Down Expand Up @@ -2300,56 +2300,57 @@ static int hns3_nic_do_ioctl(struct net_device *netdev,
}

static int hns3_nic_set_features(struct net_device *netdev,
netdev_features_t features)
netdev_features_t *features)
{
netdev_features_t changed = netdev->features ^ features;
netdev_features_t changed[NETDEV_FEATURE_DWORDS];
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
bool enable;
int ret;

if (changed & (NETIF_F_GRO_HW) && h->ae_algo->ops->set_gro_en) {
enable = !!(features & NETIF_F_GRO_HW);
netdev_features_xor(changed, netdev->features, features);
if (changed[0] & (NETIF_F_GRO_HW) && h->ae_algo->ops->set_gro_en) {
enable = !!(features[0] & NETIF_F_GRO_HW);
ret = h->ae_algo->ops->set_gro_en(h, enable);
if (ret)
return ret;
}

if ((changed & NETIF_F_HW_VLAN_CTAG_RX) &&
if ((changed[0] & NETIF_F_HW_VLAN_CTAG_RX) &&
h->ae_algo->ops->enable_hw_strip_rxvtag) {
enable = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
enable = !!(features[0] & NETIF_F_HW_VLAN_CTAG_RX);
ret = h->ae_algo->ops->enable_hw_strip_rxvtag(h, enable);
if (ret)
return ret;
}

if ((changed & NETIF_F_NTUPLE) && h->ae_algo->ops->enable_fd) {
enable = !!(features & NETIF_F_NTUPLE);
if ((changed[0] & NETIF_F_NTUPLE) && h->ae_algo->ops->enable_fd) {
enable = !!(features[0] & NETIF_F_NTUPLE);
h->ae_algo->ops->enable_fd(h, enable);
}

if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
if ((netdev->features[0] & NETIF_F_HW_TC) >
(features[0] & 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;
}

if ((changed & NETIF_F_HW_VLAN_CTAG_FILTER) &&
if ((changed[0] & NETIF_F_HW_VLAN_CTAG_FILTER) &&
h->ae_algo->ops->enable_vlan_filter) {
enable = !!(features & NETIF_F_HW_VLAN_CTAG_FILTER);
enable = !!(features[0] & NETIF_F_HW_VLAN_CTAG_FILTER);
ret = h->ae_algo->ops->enable_vlan_filter(h, enable);
if (ret)
return ret;
}

netdev->features = features;
netdev_features_copy(netdev->features, features);
return 0;
}

static netdev_features_t hns3_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
static void hns3_features_check(struct sk_buff *skb, struct net_device *dev,
netdev_features_t *features)
{
#define HNS3_MAX_HDR_LEN 480U
#define HNS3_MAX_L4_HDR_LEN 60U
Expand All @@ -2373,9 +2374,7 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb,
* len of 480 bytes.
*/
if (len > HNS3_MAX_HDR_LEN)
features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);

return features;
features[0] &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}

static void hns3_nic_get_stats64(struct net_device *netdev,
Expand Down Expand Up @@ -3127,76 +3126,78 @@ static void hns3_set_default_feature(struct net_device *netdev)

netdev->priv_flags |= IFF_UNICAST_FLT;

netdev->hw_enc_features |= NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
netdev->hw_enc_features[0] |=
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_SCTP_CRC | NETIF_F_TSO_MANGLEID | NETIF_F_FRAGLIST;

netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;

netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
netdev->features[0] |= NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;

netdev->vlan_features |= NETIF_F_RXCSUM |
netdev->vlan_features[0] |= NETIF_F_RXCSUM |
NETIF_F_SG | NETIF_F_GSO | NETIF_F_GRO |
NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;

netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX |
netdev->hw_features[0] |= NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
NETIF_F_GRO | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM | NETIF_F_GSO_UDP_TUNNEL |
NETIF_F_SCTP_CRC | NETIF_F_FRAGLIST;

if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) {
netdev->hw_features |= NETIF_F_GRO_HW;
netdev->features |= NETIF_F_GRO_HW;
netdev->hw_features[0] |= NETIF_F_GRO_HW;
netdev->features[0] |= NETIF_F_GRO_HW;

if (!(h->flags & HNAE3_SUPPORT_VF)) {
netdev->hw_features |= NETIF_F_NTUPLE;
netdev->features |= NETIF_F_NTUPLE;
netdev->hw_features[0] |= NETIF_F_NTUPLE;
netdev->features[0] |= NETIF_F_NTUPLE;
}
}

if (test_bit(HNAE3_DEV_SUPPORT_UDP_GSO_B, ae_dev->caps)) {
netdev->hw_features |= NETIF_F_GSO_UDP_L4;
netdev->features |= NETIF_F_GSO_UDP_L4;
netdev->vlan_features |= NETIF_F_GSO_UDP_L4;
netdev->hw_enc_features |= NETIF_F_GSO_UDP_L4;
netdev->hw_features[0] |= NETIF_F_GSO_UDP_L4;
netdev->features[0] |= NETIF_F_GSO_UDP_L4;
netdev->vlan_features[0] |= NETIF_F_GSO_UDP_L4;
netdev->hw_enc_features[0] |= NETIF_F_GSO_UDP_L4;
}

if (test_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps)) {
netdev->hw_features |= NETIF_F_HW_CSUM;
netdev->features |= NETIF_F_HW_CSUM;
netdev->vlan_features |= NETIF_F_HW_CSUM;
netdev->hw_enc_features |= NETIF_F_HW_CSUM;
netdev->hw_features[0] |= NETIF_F_HW_CSUM;
netdev->features[0] |= NETIF_F_HW_CSUM;
netdev->vlan_features[0] |= NETIF_F_HW_CSUM;
netdev->hw_enc_features[0] |= NETIF_F_HW_CSUM;
} else {
netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->hw_features[0] |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->features[0] |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->vlan_features[0] |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
netdev->hw_enc_features[0] |=
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
}

if (test_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, ae_dev->caps)) {
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_features[0] |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->features[0] |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->vlan_features[0] |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
netdev->hw_enc_features[0] |= 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;
netdev->hw_features[0] |= NETIF_F_HW_TC;
netdev->features[0] |= NETIF_F_HW_TC;
}

if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->hw_features[0] |= NETIF_F_HW_VLAN_CTAG_FILTER;
}

static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
Expand Down Expand Up @@ -3727,7 +3728,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,

skb_checksum_none_assert(skb);

if (!(netdev->features & NETIF_F_RXCSUM))
if (!(netdev->features[0] & NETIF_F_RXCSUM))
return;

if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state))
Expand Down Expand Up @@ -4024,7 +4025,7 @@ static int hns3_handle_bdinfo(struct hns3_enet_ring *ring, struct sk_buff *skb)
* ot_vlan_tag in two layer tag case, and stored at vlan_tag
* in one layer tag case.
*/
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
if (netdev->features[0] & NETIF_F_HW_VLAN_CTAG_RX) {
u16 vlan_tag;

if (hns3_parse_vlan_tag(ring, desc, l234info, &vlan_tag))
Expand Down

0 comments on commit 378137e

Please sign in to comment.