@@ -627,7 +627,8 @@ static int efx_ef10_probe(struct efx_nic *efx)
if (nic_data->datapath_caps &
(1 << MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN))
- efx->net_dev->hw_features |= NETIF_F_RXFCS;
+ netdev_feature_set_bit(NETIF_F_RXFCS_BIT,
+ &efx->net_dev->hw_features);
rc = efx_mcdi_port_get_number(efx);
if (rc < 0)
@@ -1304,9 +1305,11 @@ static void efx_ef10_fini_nic(struct efx_nic *efx)
static int efx_ef10_init_nic(struct efx_nic *efx)
{
struct efx_ef10_nic_data *nic_data = efx->nic_data;
- netdev_features_t hw_enc_features = 0;
+ netdev_features_t hw_enc_features;
int rc;
+ netdev_feature_zero(&hw_enc_features);
+
if (nic_data->must_check_datapath_caps) {
rc = efx_ef10_init_datapath_caps(efx);
if (rc)
@@ -1351,18 +1354,27 @@ static int efx_ef10_init_nic(struct efx_nic *efx)
/* add encapsulated checksum offload features */
if (efx_has_cap(efx, VXLAN_NVGRE) && !efx_ef10_is_vf(efx))
- hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ netdev_feature_set_bits(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM,
+ &hw_enc_features);
/* add encapsulated TSO features */
if (efx_has_cap(efx, TX_TSO_V2_ENCAP)) {
netdev_features_t encap_tso_features;
- encap_tso_features = NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_GRE |
- NETIF_F_GSO_UDP_TUNNEL_CSUM | NETIF_F_GSO_GRE_CSUM;
-
- hw_enc_features |= encap_tso_features | NETIF_F_TSO;
- efx->net_dev->features |= encap_tso_features;
+ netdev_feature_zero(&encap_tso_features);
+ netdev_feature_set_bits(NETIF_F_GSO_UDP_TUNNEL |
+ NETIF_F_GSO_GRE |
+ NETIF_F_GSO_UDP_TUNNEL_CSUM |
+ NETIF_F_GSO_GRE_CSUM,
+ &encap_tso_features);
+
+ netdev_feature_or(&hw_enc_features, hw_enc_features,
+ encap_tso_features);
+ netdev_feature_set_bit(NETIF_F_TSO_BIT, &hw_enc_features);
+ netdev_feature_or(&efx->net_dev->features,
+ efx->net_dev->features,
+ encap_tso_features);
}
- efx->net_dev->hw_enc_features = hw_enc_features;
+ netdev_feature_copy(&efx->net_dev->hw_enc_features, hw_enc_features);
/* don't fail init if RSS setup doesn't work */
rc = efx->type->rx_push_rss_config(efx, false,
@@ -2694,7 +2706,8 @@ static u16 efx_ef10_handle_rx_event_errors(struct efx_channel *channel,
bool handled = false;
if (EFX_QWORD_FIELD(*event, ESF_DZ_RX_ECRC_ERR)) {
- if (!(efx->net_dev->features & NETIF_F_RXALL)) {
+ if (!netdev_feature_test_bit(NETIF_F_RXALL_BIT,
+ efx->net_dev->features)) {
if (!efx->loopback_selftest)
channel->n_rx_eth_crc_err += n_packets;
return EFX_RX_PKT_DISCARD;
@@ -4097,7 +4110,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.always_rx_scatter = true,
.min_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
- .offload_features = EF10_OFFLOAD_FEATURES,
+ .offload_features = { EF10_OFFLOAD_FEATURES },
.mcdi_max_ver = 2,
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
.hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
@@ -4234,7 +4247,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.option_descriptors = true,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
- .offload_features = EF10_OFFLOAD_FEATURES,
+ .offload_features = { EF10_OFFLOAD_FEATURES },
.mcdi_max_ver = 2,
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
.hwtstamp_filters = 1 << HWTSTAMP_FILTER_NONE |
@@ -184,17 +184,26 @@ static int efx_ef100_init_datapath_caps(struct efx_nic *efx)
if (efx_ef100_has_cap(nic_data->datapath_caps2, TX_TSO_V3)) {
struct net_device *net_dev = efx->net_dev;
- netdev_features_t tso = NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GSO_PARTIAL |
- NETIF_F_GSO_UDP_TUNNEL | NETIF_F_GSO_UDP_TUNNEL_CSUM |
- NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM;
-
- net_dev->features |= tso;
- net_dev->hw_features |= tso;
- net_dev->hw_enc_features |= tso;
+ netdev_features_t tso;
+
+ netdev_feature_zero(&tso);
+ netdev_feature_set_bits(NETIF_F_TSO | NETIF_F_TSO6 |
+ NETIF_F_GSO_PARTIAL |
+ NETIF_F_GSO_UDP_TUNNEL |
+ NETIF_F_GSO_UDP_TUNNEL_CSUM |
+ NETIF_F_GSO_GRE | NETIF_F_GSO_GRE_CSUM,
+ &tso);
+
+ netdev_feature_or(&net_dev->features, net_dev->features, tso);
+ netdev_feature_or(&net_dev->hw_features, net_dev->hw_features,
+ tso);
+ netdev_feature_or(&net_dev->hw_enc_features,
+ net_dev->hw_enc_features, tso);
/* EF100 HW can only offload outer checksums if they are UDP,
* so for GRE_CSUM we have to use GSO_PARTIAL.
*/
- net_dev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM;
+ netdev_feature_set_bit(NETIF_F_GSO_GRE_CSUM_BIT,
+ &net_dev->gso_partial_features);
}
efx->num_mac_stats = MCDI_WORD(outbuf,
GET_CAPABILITIES_V4_OUT_MAC_STATS_NUM_STATS);
@@ -704,7 +713,7 @@ const struct efx_nic_type ef100_pf_nic_type = {
.revision = EFX_REV_EF100,
.is_vf = false,
.probe = ef100_probe_pf,
- .offload_features = EF100_OFFLOAD_FEATURES,
+ .offload_features = { EF100_OFFLOAD_FEATURES },
.mcdi_max_ver = 2,
.mcdi_request = ef100_mcdi_request,
.mcdi_poll_response = ef100_mcdi_poll_response,
@@ -789,7 +798,7 @@ const struct efx_nic_type ef100_vf_nic_type = {
.revision = EFX_REV_EF100,
.is_vf = true,
.probe = ef100_probe_vf,
- .offload_features = EF100_OFFLOAD_FEATURES,
+ .offload_features = { EF100_OFFLOAD_FEATURES },
.mcdi_max_ver = 2,
.mcdi_request = ef100_mcdi_request,
.mcdi_poll_response = ef100_mcdi_poll_response,
@@ -1111,11 +1120,15 @@ static int ef100_probe_main(struct efx_nic *efx)
return -ENOMEM;
efx->nic_data = nic_data;
nic_data->efx = efx;
- net_dev->features |= efx->type->offload_features;
- net_dev->hw_features |= efx->type->offload_features;
- net_dev->hw_enc_features |= efx->type->offload_features;
- net_dev->vlan_features |= NETIF_F_HW_CSUM | NETIF_F_SG |
- NETIF_F_HIGHDMA | NETIF_F_ALL_TSO;
+ netdev_feature_set_bits(efx->type->offload_features[0],
+ &net_dev->features);
+ netdev_feature_set_bits(efx->type->offload_features[0],
+ &net_dev->hw_features);
+ netdev_feature_set_bits(efx->type->offload_features[0],
+ &net_dev->hw_enc_features);
+ netdev_feature_set_bits(NETIF_F_HW_CSUM | NETIF_F_SG |
+ NETIF_F_HIGHDMA | NETIF_F_ALL_TSO,
+ &net_dev->vlan_features);
/* Populate design-parameter defaults */
nic_data->tso_max_hdr_len = ESE_EF100_DP_GZ_TSO_MAX_HDR_LEN_DEFAULT;
@@ -64,7 +64,8 @@ void __ef100_rx_packet(struct efx_channel *channel)
prefix = (u32 *)(eh - ESE_GZ_RX_PKT_PREFIX_LEN);
if (ef100_has_fcs_error(channel, prefix) &&
- unlikely(!(efx->net_dev->features & NETIF_F_RXALL)))
+ unlikely(!netdev_feature_test_bit(NETIF_F_RXALL_BIT,
+ efx->net_dev->features)))
goto out;
rx_buf->len = le16_to_cpu((__force __le16)PREFIX_FIELD(prefix, LENGTH));
@@ -76,7 +77,8 @@ void __ef100_rx_packet(struct efx_channel *channel)
goto out;
}
- if (likely(efx->net_dev->features & NETIF_F_RXCSUM)) {
+ if (likely(netdev_feature_test_bit(NETIF_F_RXCSUM_BIT,
+ efx->net_dev->features))) {
if (PREFIX_FIELD(prefix, NT_OR_INNER_L3_CLASS) == 1) {
++channel->n_rx_ip_hdr_chksum_err;
} else {
@@ -61,7 +61,7 @@ static bool ef100_tx_can_tso(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
if (!skb_is_gso_tcp(skb))
return false;
- if (!(efx->net_dev->features & NETIF_F_TSO))
+ if (!netdev_feature_test_bit(NETIF_F_TSO_BIT, efx->net_dev->features))
return false;
mss = skb_shinfo(skb)->gso_size;
@@ -175,9 +175,11 @@ static void ef100_make_send_desc(struct efx_nic *efx,
ESF_GZ_TX_SEND_LEN, buffer->len,
ESF_GZ_TX_SEND_ADDR, buffer->dma_addr);
- if (likely(efx->net_dev->features & NETIF_F_HW_CSUM))
+ if (likely(netdev_feature_test_bit(NETIF_F_HW_CSUM_BIT,
+ efx->net_dev->features)))
ef100_set_tx_csum_partial(skb, buffer, txd);
- if (efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_TX &&
+ if (netdev_feature_test_bit(NETIF_F_HW_VLAN_CTAG_TX_BIT,
+ efx->net_dev->features) &&
skb && skb_vlan_tag_present(skb))
ef100_set_tx_hw_vlan(skb, txd);
}
@@ -202,7 +204,8 @@ static void ef100_make_tso_desc(struct efx_nic *efx,
if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID)
mangleid = ESE_GZ_TX_DESC_IP4_ID_NO_OP;
- if (efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_TX)
+ if (netdev_feature_test_bit(NETIF_F_HW_VLAN_CTAG_TX_BIT,
+ efx->net_dev->features))
vlan_enable = skb_vlan_tag_present(skb);
len = skb->len - buffer->len;
@@ -243,9 +243,11 @@ static int efx_ef10_vadaptor_alloc_set_features(struct efx_nic *efx)
if (port_flags &
(1 << MC_CMD_VPORT_ALLOC_IN_FLAG_VLAN_RESTRICT_LBN))
- efx->fixed_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+ netdev_feature_set_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &efx->fixed_features);
else
- efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+ netdev_feature_clear_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &efx->fixed_features);
return 0;
@@ -991,6 +991,7 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
{
struct net_device *net_dev = efx->net_dev;
int rc = efx_pci_probe_main(efx);
+ netdev_features_t tmp;
if (rc)
return rc;
@@ -1003,29 +1004,34 @@ static int efx_pci_probe_post_io(struct efx_nic *efx)
}
/* Determine netdevice features */
- net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
- NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL);
- if (efx->type->offload_features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
- net_dev->features |= NETIF_F_TSO6;
+ netdev_feature_set_bits(efx->type->offload_features[0] | NETIF_F_SG |
+ NETIF_F_TSO | NETIF_F_RXCSUM | NETIF_F_RXALL,
+ &net_dev->features);
+
+ if (efx->type->offload_features[0] & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM))
+ netdev_feature_set_bit(NETIF_F_TSO6_BIT, &net_dev->features);
/* Check whether device supports TSO */
if (!efx->type->tso_versions || !efx->type->tso_versions(efx))
- net_dev->features &= ~NETIF_F_ALL_TSO;
+ netdev_feature_clear_bits(NETIF_F_ALL_TSO, &net_dev->features);
/* Mask for features that also apply to VLAN devices */
- net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
- NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
- NETIF_F_RXCSUM);
+ netdev_feature_set_bits(NETIF_F_HW_CSUM | NETIF_F_SG |
+ NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
+ NETIF_F_RXCSUM, &net_dev->vlan_features);
- net_dev->hw_features |= net_dev->features & ~efx->fixed_features;
+ netdev_feature_andnot(&tmp, net_dev->features, efx->fixed_features);
+ netdev_feature_or(&net_dev->hw_features, net_dev->hw_features, tmp);
/* Disable receiving frames with bad FCS, by default. */
- net_dev->features &= ~NETIF_F_RXALL;
+ netdev_feature_clear_bit(NETIF_F_RXALL_BIT, &net_dev->features);
/* Disable VLAN filtering by default. It may be enforced if
* the feature is fixed (i.e. VLAN filters are required to
* receive VLAN tagged packets due to vPort restrictions).
*/
- net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
- net_dev->features |= efx->fixed_features;
+ netdev_feature_clear_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &net_dev->features);
+ netdev_feature_or(&net_dev->features, net_dev->features,
+ efx->fixed_features);
rc = efx_register_netdev(efx);
if (!rc)
@@ -1058,7 +1064,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev,
return -ENOMEM;
efx = netdev_priv(net_dev);
efx->type = (const struct efx_nic_type *) entry->driver_data;
- efx->fixed_features |= NETIF_F_HIGHDMA;
+ netdev_feature_set_bit(NETIF_F_HIGHDMA_BIT, &efx->fixed_features);
pci_set_drvdata(pci_dev, efx);
SET_NETDEV_DEV(net_dev, &pci_dev->dev);
@@ -211,10 +211,12 @@ void efx_set_rx_mode(struct net_device *net_dev)
int efx_set_features(struct net_device *net_dev, netdev_features_t data)
{
struct efx_nic *efx = netdev_priv(net_dev);
+ netdev_features_t changed;
int rc;
/* If disabling RX n-tuple filtering, clear existing filters */
- if (net_dev->features & ~data & NETIF_F_NTUPLE) {
+ if (netdev_feature_test_bit(NETIF_F_NTUPLE_BIT, net_dev->features) &&
+ !netdev_feature_test_bit(NETIF_F_NTUPLE_BIT, data)) {
rc = efx->type->filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
if (rc)
return rc;
@@ -223,8 +225,9 @@ int efx_set_features(struct net_device *net_dev, netdev_features_t data)
/* If Rx VLAN filter is changed, update filters via mac_reconfigure.
* If rx-fcs is changed, mac_reconfigure updates that too.
*/
- if ((net_dev->features ^ data) & (NETIF_F_HW_VLAN_CTAG_FILTER |
- NETIF_F_RXFCS)) {
+ netdev_feature_xor(&changed, net_dev->features, data);
+ if (netdev_feature_test_bits(NETIF_F_HW_VLAN_CTAG_FILTER |
+ NETIF_F_RXFCS, changed)) {
/* efx_set_rx_mode() will schedule MAC work to update filters
* when a new features are finally set in net_dev.
*/
@@ -363,8 +366,8 @@ void efx_start_monitor(struct efx_nic *efx)
*/
static void efx_start_datapath(struct efx_nic *efx)
{
- netdev_features_t old_features = efx->net_dev->features;
bool old_rx_scatter = efx->rx_scatter;
+ netdev_features_t old_features;
size_t rx_buf_len;
/* Calculate the rx buffer allocation parameters required to
@@ -409,10 +412,14 @@ static void efx_start_datapath(struct efx_nic *efx)
/* Restore previously fixed features in hw_features and remove
* features which are fixed now
*/
- efx->net_dev->hw_features |= efx->net_dev->features;
- efx->net_dev->hw_features &= ~efx->fixed_features;
- efx->net_dev->features |= efx->fixed_features;
- if (efx->net_dev->features != old_features)
+ netdev_feature_copy(&old_features, efx->net_dev->features);
+ netdev_feature_or(&efx->net_dev->hw_features,
+ efx->net_dev->hw_features, efx->net_dev->features);
+ netdev_feature_andnot(&efx->net_dev->hw_features,
+ efx->net_dev->hw_features, efx->fixed_features);
+ netdev_feature_or(&efx->net_dev->features, efx->net_dev->features,
+ efx->fixed_features);
+ if (!netdev_feature_equal(efx->net_dev->features, old_features))
netdev_features_change(efx->net_dev);
/* RX filters may also have scatter-enabled flags */
@@ -1359,17 +1366,20 @@ void efx_features_check(struct sk_buff *skb, struct net_device *dev,
struct efx_nic *efx = netdev_priv(dev);
if (skb->encapsulation) {
- if (*features & NETIF_F_GSO_MASK)
+ if (netdev_feature_test_bits(NETIF_F_GSO_MASK, *features))
/* Hardware can only do TSO with at most 208 bytes
* of headers.
*/
if (skb_inner_transport_offset(skb) >
EFX_TSO2_MAX_HDRLEN)
- *features &= ~(NETIF_F_GSO_MASK);
- if (*features & (NETIF_F_GSO_MASK | NETIF_F_CSUM_MASK))
+ netdev_feature_clear_bits(NETIF_F_GSO_MASK,
+ features);
+ if (netdev_feature_test_bits(NETIF_F_GSO_MASK |
+ NETIF_F_CSUM_MASK, *features))
if (!efx_can_encap_offloads(efx, skb))
- *features &= ~(NETIF_F_GSO_MASK |
- NETIF_F_CSUM_MASK);
+ netdev_feature_clear_bits(NETIF_F_GSO_MASK |
+ NETIF_F_CSUM_MASK,
+ features);
}
}
@@ -592,8 +592,8 @@ static int ef4_probe_channels(struct ef4_nic *efx)
*/
static void ef4_start_datapath(struct ef4_nic *efx)
{
- netdev_features_t old_features = efx->net_dev->features;
bool old_rx_scatter = efx->rx_scatter;
+ netdev_features_t old_features;
struct ef4_tx_queue *tx_queue;
struct ef4_rx_queue *rx_queue;
struct ef4_channel *channel;
@@ -640,10 +640,14 @@ static void ef4_start_datapath(struct ef4_nic *efx)
/* Restore previously fixed features in hw_features and remove
* features which are fixed now
*/
- efx->net_dev->hw_features |= efx->net_dev->features;
- efx->net_dev->hw_features &= ~efx->fixed_features;
- efx->net_dev->features |= efx->fixed_features;
- if (efx->net_dev->features != old_features)
+ netdev_feature_copy(&old_features, efx->net_dev->features);
+ netdev_feature_or(&efx->net_dev->hw_features,
+ efx->net_dev->hw_features, efx->net_dev->features);
+ netdev_feature_andnot(&efx->net_dev->hw_features,
+ efx->net_dev->hw_features, efx->fixed_features);
+ netdev_feature_or(&efx->net_dev->features, efx->net_dev->features,
+ efx->fixed_features);
+ if (!netdev_feature_equal(efx->net_dev->features, old_features))
netdev_features_change(efx->net_dev);
/* RX filters may also have scatter-enabled flags */
@@ -1698,7 +1702,7 @@ static int ef4_probe_filters(struct ef4_nic *efx)
goto out_unlock;
#ifdef CONFIG_RFS_ACCEL
- if (efx->type->offload_features & NETIF_F_NTUPLE) {
+ if (efx->type->offload_features[0] & NETIF_F_NTUPLE) {
struct ef4_channel *channel;
int i, success = 1;
@@ -2192,17 +2196,21 @@ static void ef4_set_rx_mode(struct net_device *net_dev)
static int ef4_set_features(struct net_device *net_dev, netdev_features_t data)
{
struct ef4_nic *efx = netdev_priv(net_dev);
+ netdev_features_t changed;
int rc;
/* If disabling RX n-tuple filtering, clear existing filters */
- if (net_dev->features & ~data & NETIF_F_NTUPLE) {
+ if (netdev_feature_test_bit(NETIF_F_NTUPLE_BIT, net_dev->features) &&
+ !netdev_feature_test_bit(NETIF_F_NTUPLE_BIT, data)) {
rc = efx->type->filter_clear_rx(efx, EF4_FILTER_PRI_MANUAL);
if (rc)
return rc;
}
/* If Rx VLAN filter is changed, update filters via mac_reconfigure */
- if ((net_dev->features ^ data) & NETIF_F_HW_VLAN_CTAG_FILTER) {
+ netdev_feature_xor(&changed, net_dev->features, data);
+ if (netdev_feature_test_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ changed)) {
/* ef4_set_rx_mode() will schedule MAC work to update filters
* when a new features are finally set in net_dev.
*/
@@ -2886,7 +2894,7 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
return -ENOMEM;
efx = netdev_priv(net_dev);
efx->type = (const struct ef4_nic_type *) entry->driver_data;
- efx->fixed_features |= NETIF_F_HIGHDMA;
+ netdev_feature_set_bit(NETIF_F_HIGHDMA_BIT, &efx->fixed_features);
pci_set_drvdata(pci_dev, efx);
SET_NETDEV_DEV(net_dev, &pci_dev->dev);
@@ -2908,20 +2916,26 @@ static int ef4_pci_probe(struct pci_dev *pci_dev,
if (rc)
goto fail3;
- net_dev->features |= (efx->type->offload_features | NETIF_F_SG |
- NETIF_F_RXCSUM);
+ netdev_feature_set_bits(efx->type->offload_features[0],
+ &net_dev->features);
+ netdev_feature_set_bits(NETIF_F_SG | NETIF_F_RXCSUM,
+ &net_dev->features);
/* Mask for features that also apply to VLAN devices */
- net_dev->vlan_features |= (NETIF_F_HW_CSUM | NETIF_F_SG |
- NETIF_F_HIGHDMA | NETIF_F_RXCSUM);
+ netdev_feature_set_bits(NETIF_F_HW_CSUM | NETIF_F_SG |
+ NETIF_F_HIGHDMA | NETIF_F_RXCSUM,
+ &net_dev->vlan_features);
- net_dev->hw_features = net_dev->features & ~efx->fixed_features;
+ netdev_feature_andnot(&net_dev->hw_features, net_dev->features,
+ efx->fixed_features);
/* Disable VLAN filtering by default. It may be enforced if
* the feature is fixed (i.e. VLAN filters are required to
* receive VLAN tagged packets due to vPort restrictions).
*/
- net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
- net_dev->features |= efx->fixed_features;
+ netdev_feature_clear_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &net_dev->features);
+ netdev_feature_or(&net_dev->features, net_dev->features,
+ efx->fixed_features);
rc = ef4_register_netdev(efx);
if (rc)
@@ -2799,7 +2799,7 @@ const struct ef4_nic_type falcon_a1_nic_type = {
.can_rx_scatter = false,
.max_interrupt_mode = EF4_INT_MODE_MSI,
.timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
- .offload_features = NETIF_F_IP_CSUM,
+ .offload_features = { NETIF_F_IP_CSUM },
};
const struct ef4_nic_type falcon_b0_nic_type = {
@@ -2898,6 +2898,6 @@ const struct ef4_nic_type falcon_b0_nic_type = {
.can_rx_scatter = true,
.max_interrupt_mode = EF4_INT_MODE_MSIX,
.timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH,
- .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE,
+ .offload_features = { NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE },
.max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS,
};
@@ -1153,7 +1153,7 @@ struct ef4_nic_type {
bool always_rx_scatter;
unsigned int max_interrupt_mode;
unsigned int timer_period_max;
- netdev_features_t offload_features;
+ u64 offload_features[NETDEV_FEATURE_DWORDS];
unsigned int max_rx_ip_filters;
};
@@ -1303,7 +1303,7 @@ static inline void ef4_supported_features(const struct ef4_nic *efx,
{
const struct net_device *net_dev = efx->net_dev;
- *supported = net_dev->features | net_dev->hw_features;
+ netdev_feature_or(supported, net_dev->features, net_dev->hw_features);
}
/* Get the current TX queue insert index. */
@@ -438,7 +438,8 @@ ef4_rx_packet_gro(struct ef4_channel *channel, struct ef4_rx_buffer *rx_buf,
return;
}
- if (efx->net_dev->features & NETIF_F_RXHASH)
+ if (netdev_feature_test_bit(NETIF_F_RXHASH_BIT,
+ efx->net_dev->features))
skb_set_hash(skb, ef4_rx_buf_hash(efx, eh),
PKT_HASH_TYPE_L3);
skb->ip_summed = ((rx_buf->flags & EF4_RX_PKT_CSUMMED) ?
@@ -667,7 +668,8 @@ void __ef4_rx_packet(struct ef4_channel *channel)
goto out;
}
- if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
+ if (unlikely(!netdev_feature_test_bit(NETIF_F_RXCSUM_BIT,
+ efx->net_dev->features)))
rx_buf->flags &= ~EF4_RX_PKT_CSUMMED;
if ((rx_buf->flags & EF4_RX_PKT_TCP) && !channel->type->receive_skb)
@@ -921,7 +921,7 @@ static u16 efx_farch_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
(void) rx_ev_other_err;
#endif
- if (efx->net_dev->features & NETIF_F_RXALL)
+ if (netdev_feature_test_bit(NETIF_F_RXALL_BIT, efx->net_dev->features))
/* don't discard frame for CRC error */
rx_ev_eth_crc_err = false;
@@ -1322,16 +1322,20 @@ int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining)
goto fail;
efx_supported_features(efx, &supported);
- if ((supported & NETIF_F_HW_VLAN_CTAG_FILTER) &&
+ if (netdev_feature_test_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ supported) &&
!(efx_mcdi_filter_match_supported(table, false,
(EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC)) &&
efx_mcdi_filter_match_supported(table, false,
(EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC_IG)))) {
netif_info(efx, probe, net_dev,
"VLAN filters are not supported in this firmware variant\n");
- net_dev->features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
- efx->fixed_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
- net_dev->hw_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+ netdev_feature_clear_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &net_dev->features);
+ netdev_feature_clear_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &efx->fixed_features);
+ netdev_feature_clear_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ &net_dev->hw_features);
}
table->entry = vzalloc(array_size(EFX_MCDI_FILTER_TBL_ROWS,
@@ -1343,7 +1347,8 @@ int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining)
table->mc_promisc_last = false;
table->vlan_filter =
- !!(efx->net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
+ netdev_feature_test_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ efx->net_dev->features);
INIT_LIST_HEAD(&table->vlan_list);
init_rwsem(&table->lock);
@@ -1760,7 +1765,8 @@ void efx_mcdi_filter_sync_rx_mode(struct efx_nic *efx)
* Do it in advance to avoid conflicts for unicast untagged and
* VLAN 0 tagged filters.
*/
- vlan_filter = !!(net_dev->features & NETIF_F_HW_VLAN_CTAG_FILTER);
+ vlan_filter = netdev_feature_test_bit(NETIF_F_HW_VLAN_CTAG_FILTER_BIT,
+ net_dev->features);
if (table->vlan_filter != vlan_filter) {
table->vlan_filter = vlan_filter;
efx_mcdi_filter_remove_old(efx);
@@ -1097,7 +1097,8 @@ int efx_mcdi_set_mac(struct efx_nic *efx)
MCDI_POPULATE_DWORD_1(cmdbytes, SET_MAC_IN_FLAGS,
SET_MAC_IN_FLAG_INCLUDE_FCS,
- !!(efx->net_dev->features & NETIF_F_RXFCS));
+ netdev_feature_test_bit(NETIF_F_RXFCS_BIT,
+ efx->net_dev->features));
switch (efx->wanted_fc) {
case EFX_FC_RX | EFX_FC_TX:
@@ -1477,7 +1477,7 @@ struct efx_nic_type {
bool option_descriptors;
unsigned int min_interrupt_mode;
unsigned int timer_period_max;
- netdev_features_t offload_features;
+ u64 offload_features[NETDEV_FEATURE_DWORDS];
int mcdi_max_ver;
unsigned int max_rx_ip_filters;
u32 hwtstamp_filters;
@@ -1686,7 +1686,7 @@ static inline void efx_supported_features(const struct efx_nic *efx,
{
const struct net_device *net_dev = efx->net_dev;
- *supported = net_dev->features | net_dev->hw_features;
+ netdev_feature_or(supported, net_dev->features, net_dev->hw_features);
}
/* Get the current TX queue insert index. */
@@ -387,7 +387,8 @@ void __efx_rx_packet(struct efx_channel *channel)
if (!efx_do_xdp(efx, channel, rx_buf, &eh))
goto out;
- if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
+ if (unlikely(!netdev_feature_test_bit(NETIF_F_RXCSUM_BIT,
+ efx->net_dev->features)))
rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
if ((rx_buf->flags & EFX_RX_PKT_TCP) && !channel->type->receive_skb)
@@ -525,7 +525,8 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
return;
}
- if (efx->net_dev->features & NETIF_F_RXHASH &&
+ if (netdev_feature_test_bit(NETIF_F_RXHASH_BIT,
+ efx->net_dev->features) &&
efx_rx_buf_hash_valid(efx, eh))
skb_set_hash(skb, efx_rx_buf_hash(efx, eh),
PKT_HASH_TYPE_L3);
@@ -804,7 +805,7 @@ int efx_probe_filters(struct efx_nic *efx)
goto out_unlock;
#ifdef CONFIG_RFS_ACCEL
- if (efx->type->offload_features & NETIF_F_NTUPLE) {
+ if (efx->type->offload_features[0] & NETIF_F_NTUPLE) {
struct efx_channel *channel;
int i, success = 1;
@@ -1088,8 +1088,8 @@ const struct efx_nic_type siena_a0_nic_type = {
.option_descriptors = false,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
.timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH,
- .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
- NETIF_F_RXHASH | NETIF_F_NTUPLE),
+ .offload_features = { (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+ NETIF_F_RXHASH | NETIF_F_NTUPLE) },
.mcdi_max_ver = 1,
.max_rx_ip_filters = FR_BZ_RX_FILTER_TBL0_ROWS,
.hwtstamp_filters = (1 << HWTSTAMP_FILTER_NONE |
Use netdev_feature_xxx helpers to replace the logical operation for netdev features. For the driver initializes the offloaded_features when define structure . So it's unable to change the prototype from u64 to bitmap. Define it as u64 array instead. Signed-off-by: Jian Shen <shenjian15@huawei.com> --- drivers/net/ethernet/sfc/ef10.c | 37 +++++++++++----- drivers/net/ethernet/sfc/ef100_nic.c | 43 +++++++++++------- drivers/net/ethernet/sfc/ef100_rx.c | 6 ++- drivers/net/ethernet/sfc/ef100_tx.c | 11 +++-- drivers/net/ethernet/sfc/ef10_sriov.c | 6 ++- drivers/net/ethernet/sfc/efx.c | 32 ++++++++------ drivers/net/ethernet/sfc/efx_common.c | 36 +++++++++------ drivers/net/ethernet/sfc/falcon/efx.c | 46 +++++++++++++------- drivers/net/ethernet/sfc/falcon/falcon.c | 4 +- drivers/net/ethernet/sfc/falcon/net_driver.h | 4 +- drivers/net/ethernet/sfc/falcon/rx.c | 6 ++- drivers/net/ethernet/sfc/farch.c | 2 +- drivers/net/ethernet/sfc/mcdi_filters.c | 18 +++++--- drivers/net/ethernet/sfc/mcdi_port_common.c | 3 +- drivers/net/ethernet/sfc/net_driver.h | 4 +- drivers/net/ethernet/sfc/rx.c | 3 +- drivers/net/ethernet/sfc/rx_common.c | 5 ++- drivers/net/ethernet/sfc/siena.c | 4 +- 18 files changed, 172 insertions(+), 98 deletions(-)