Commit 7d360f60 authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

wifi: mac80211: add support for restricting netdev features per vif

This can be used to selectively disable feature flags for checksum offload,
scatter/gather or GSO by changing vif->netdev_features.
Removing features from vif->netdev_features does not affect the netdev
features themselves, but instead fixes up skbs in the tx path so that the
offloads are not needed in the driver.

Aside from making it easier to deal with vif type based hardware limitations,
this also makes it possible to optimize performance on hardware without native
GSO support by declaring GSO support in hw->netdev_features and removing it
from vif->netdev_features. This allows mac80211 to handle GSO segmentation
after the sta lookup, but before itxq enqueue, thus reducing the number of
unnecessary sta lookups, as well as some other per-packet processing.
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://lore.kernel.org/r/20221010094338.78070-1-nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 209d70d3
......@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq,
fq_skb_free_t free_func)
{
struct fq_flow *flow;
struct sk_buff *next;
bool oom;
lockdep_assert_held(&fq->lock);
......@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq,
}
flow->tin = tin;
flow->backlog += skb->len;
tin->backlog_bytes += skb->len;
tin->backlog_packets++;
fq->memory_usage += skb->truesize;
fq->backlog++;
skb_list_walk_safe(skb, skb, next) {
skb_mark_not_on_list(skb);
flow->backlog += skb->len;
tin->backlog_bytes += skb->len;
tin->backlog_packets++;
fq->memory_usage += skb->truesize;
fq->backlog++;
__skb_queue_tail(&flow->queue, skb);
}
if (list_empty(&flow->flowchain)) {
flow->deficit = fq->quantum;
......@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq,
&tin->new_flows);
}
__skb_queue_tail(&flow->queue, skb);
oom = (fq->memory_usage > fq->memory_limit);
while (fq->backlog > fq->limit || oom) {
flow = fq_find_fattest_flow(fq);
......
......@@ -1807,6 +1807,10 @@ struct ieee80211_vif_cfg {
* @addr: address of this interface
* @p2p: indicates whether this AP or STA interface is a p2p
* interface, i.e. a GO or p2p-sta respectively
* @netdev_features: tx netdev features supported by the hardware for this
* vif. mac80211 initializes this to hw->netdev_features, and the driver
* can mask out specific tx features. mac80211 will handle software fixup
* for masked offloads (GSO, CSUM)
* @driver_flags: flags/capabilities the driver has for this interface,
* these need to be set (or cleared) when the interface is added
* or, if supported by the driver, the interface type is changed
......@@ -1848,6 +1852,7 @@ struct ieee80211_vif {
struct ieee80211_txq *txq;
netdev_features_t netdev_features;
u32 driver_flags;
u32 offload_flags;
......
......@@ -2178,6 +2178,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
ndev->hw_features |= ndev->features &
MAC80211_SUPPORTED_FEATURES_TX;
sdata->vif.netdev_features = local->hw.netdev_features;
netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
......
This diff is collapsed.
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