Merge tag 'mac80211-next-for-net-next-2021-01-27' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says:

====================
More updates:
 * many minstrel improvements, including removal of the old
   minstrel in favour of minstrel_ht
 * speed improvements on FQ
 * support for RX decapsulation (header conversion) offload
 * RTNL reduction: limit RTNL usage in the wireless stack
   mostly to where really needed (regulatory not yet) to
   reduce contention on it

* tag 'mac80211-next-for-net-next-2021-01-27' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next: (24 commits)
  mac80211: minstrel_ht: fix regression in the max_prob_rate fix
  virt_wifi: fix deadlock on RTNL
  cfg80211: avoid holding the RTNL when calling the driver
  cfg80211: change netdev registration/unregistration semantics
  mac80211: minstrel_ht: fix rounding error in throughput calculation
  mac80211: minstrel_ht: increase stats update interval
  mac80211: minstrel_ht: fix max probability rate selection
  mac80211: minstrel_ht: improve sample rate selection
  mac80211: minstrel_ht: improve ampdu length estimation
  mac80211: minstrel_ht: remove old ewma based rate average code
  mac80211: remove legacy minstrel rate control
  mac80211: minstrel_ht: add support for OFDM rates on non-HT clients
  mac80211: minstrel_ht: clean up CCK code
  mac80211: introduce aql_enable node in debugfs
  cfg80211: Add phyrate conversion support for extended MCS in 60GHz band
  cfg80211: add VHT rate entries for MCS-10 and MCS-11
  mac80211: reduce peer HE MCS/NSS to own capabilities
  mac80211: remove NSS number of 160MHz if not support 160MHz for HE
  mac80211_hwsim: add 6GHz channels
  mac80211: add LDPC encoding to ieee80211_parse_tx_radiotap
  ...
====================

Link: https://lore.kernel.org/r/20210127210915.135550-1-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski
2021-01-27 19:01:06 -08:00
63 changed files with 2101 additions and 1938 deletions
+123 -23
View File
@@ -1460,6 +1460,7 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
* @RATE_INFO_FLAGS_DMG: 60GHz MCS
* @RATE_INFO_FLAGS_HE_MCS: HE MCS information
* @RATE_INFO_FLAGS_EDMG: 60GHz MCS in EDMG mode
* @RATE_INFO_FLAGS_EXTENDED_SC_DMG: 60GHz extended SC MCS
*/
enum rate_info_flags {
RATE_INFO_FLAGS_MCS = BIT(0),
@@ -1468,6 +1469,7 @@ enum rate_info_flags {
RATE_INFO_FLAGS_DMG = BIT(3),
RATE_INFO_FLAGS_HE_MCS = BIT(4),
RATE_INFO_FLAGS_EDMG = BIT(5),
RATE_INFO_FLAGS_EXTENDED_SC_DMG = BIT(6),
};
/**
@@ -3630,9 +3632,10 @@ struct mgmt_frame_regs {
* All callbacks except where otherwise noted should return 0
* on success or a negative error code.
*
* All operations are currently invoked under rtnl for consistency with the
* wireless extensions but this is subject to reevaluation as soon as this
* code is used more widely and we have a first user without wext.
* All operations are invoked with the wiphy mutex held. The RTNL may be
* held in addition (due to wireless extensions) but this cannot be relied
* upon except in cases where documented below. Note that due to ordering,
* the RTNL also cannot be acquired in any handlers.
*
* @suspend: wiphy device needs to be suspended. The variable @wow will
* be %NULL or contain the enabled Wake-on-Wireless triggers that are
@@ -3647,11 +3650,14 @@ struct mgmt_frame_regs {
* the new netdev in the wiphy's network namespace! Returns the struct
* wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must
* also set the address member in the wdev.
* This additionally holds the RTNL to be able to do netdev changes.
*
* @del_virtual_intf: remove the virtual interface
* This additionally holds the RTNL to be able to do netdev changes.
*
* @change_virtual_intf: change type/configuration of virtual interface,
* keep the struct wireless_dev's iftype updated.
* This additionally holds the RTNL to be able to do netdev changes.
*
* @add_key: add a key with the given parameters. @mac_addr will be %NULL
* when adding a group key.
@@ -4741,6 +4747,7 @@ struct wiphy_iftype_akm_suites {
/**
* struct wiphy - wireless hardware description
* @mtx: mutex for the data (structures) of this device
* @reg_notifier: the driver's regulatory notification callback,
* note that if your driver uses wiphy_apply_custom_regulatory()
* the reg_notifier's request can be passed as NULL
@@ -4934,6 +4941,8 @@ struct wiphy_iftype_akm_suites {
* @sar_capa: SAR control capabilities
*/
struct wiphy {
struct mutex mtx;
/* assign these fields before you register the wiphy */
u8 perm_addr[ETH_ALEN];
@@ -5186,6 +5195,37 @@ static inline struct wiphy *wiphy_new(const struct cfg80211_ops *ops,
*/
int wiphy_register(struct wiphy *wiphy);
/* this is a define for better error reporting (file/line) */
#define lockdep_assert_wiphy(wiphy) lockdep_assert_held(&(wiphy)->mtx)
/**
* rcu_dereference_wiphy - rcu_dereference with debug checking
* @wiphy: the wiphy to check the locking on
* @p: The pointer to read, prior to dereferencing
*
* Do an rcu_dereference(p), but check caller either holds rcu_read_lock()
* or RTNL. Note: Please prefer wiphy_dereference() or rcu_dereference().
*/
#define rcu_dereference_wiphy(wiphy, p) \
rcu_dereference_check(p, lockdep_is_held(&wiphy->mtx))
/**
* wiphy_dereference - fetch RCU pointer when updates are prevented by wiphy mtx
* @wiphy: the wiphy to check the locking on
* @p: The pointer to read, prior to dereferencing
*
* Return the value of the specified RCU-protected pointer, but omit the
* READ_ONCE(), because caller holds the wiphy mutex used for updates.
*/
#define wiphy_dereference(wiphy, p) \
rcu_dereference_protected(p, lockdep_is_held(&wiphy->mtx))
/**
* get_wiphy_regdom - get custom regdomain for the given wiphy
* @wiphy: the wiphy to get the regdomain from
*/
const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy);
/**
* wiphy_unregister - deregister a wiphy from cfg80211
*
@@ -5210,6 +5250,35 @@ struct cfg80211_internal_bss;
struct cfg80211_cached_keys;
struct cfg80211_cqm_config;
/**
* wiphy_lock - lock the wiphy
* @wiphy: the wiphy to lock
*
* This is mostly exposed so it can be done around registering and
* unregistering netdevs that aren't created through cfg80211 calls,
* since that requires locking in cfg80211 when the notifiers is
* called, but that cannot differentiate which way it's called.
*
* When cfg80211 ops are called, the wiphy is already locked.
*/
static inline void wiphy_lock(struct wiphy *wiphy)
__acquires(&wiphy->mtx)
{
mutex_lock(&wiphy->mtx);
__acquire(&wiphy->mtx);
}
/**
* wiphy_unlock - unlock the wiphy again
* @wiphy: the wiphy to unlock
*/
static inline void wiphy_unlock(struct wiphy *wiphy)
__releases(&wiphy->mtx)
{
__release(&wiphy->mtx);
mutex_unlock(&wiphy->mtx);
}
/**
* struct wireless_dev - wireless device state
*
@@ -5217,7 +5286,10 @@ struct cfg80211_cqm_config;
* that uses the ieee80211_ptr field in struct net_device (this
* is intentional so it can be allocated along with the netdev.)
* It need not be registered then as netdev registration will
* be intercepted by cfg80211 to see the new wireless device.
* be intercepted by cfg80211 to see the new wireless device,
* however, drivers must lock the wiphy before registering or
* unregistering netdevs if they pre-create any netdevs (in ops
* called from cfg80211, the wiphy is already locked.)
*
* For non-netdev uses, it must also be allocated by the driver
* in response to the cfg80211 callbacks that require it, as
@@ -5226,6 +5298,7 @@ struct cfg80211_cqm_config;
*
* @wiphy: pointer to hardware description
* @iftype: interface type
* @registered: is this wdev already registered with cfg80211
* @list: (private) Used to collect the interfaces
* @netdev: (private) Used to reference back to the netdev, may be %NULL
* @identifier: (private) Identifier used in nl80211 to identify this
@@ -5309,7 +5382,7 @@ struct wireless_dev {
struct mutex mtx;
bool use_4addr, is_running;
bool use_4addr, is_running, registered;
u8 address[ETH_ALEN] __aligned(sizeof(u16));
@@ -5978,18 +6051,18 @@ int regulatory_set_wiphy_regd(struct wiphy *wiphy,
struct ieee80211_regdomain *rd);
/**
* regulatory_set_wiphy_regd_sync_rtnl - set regdom for self-managed drivers
* regulatory_set_wiphy_regd_sync - set regdom for self-managed drivers
* @wiphy: the wireless device we want to process the regulatory domain on
* @rd: the regulatory domain information to use for this wiphy
*
* This functions requires the RTNL to be held and applies the new regdomain
* synchronously to this wiphy. For more details see
* regulatory_set_wiphy_regd().
* This functions requires the RTNL and the wiphy mutex to be held and
* applies the new regdomain synchronously to this wiphy. For more details
* see regulatory_set_wiphy_regd().
*
* Return: 0 on success. -EINVAL, -EPERM
*/
int regulatory_set_wiphy_regd_sync_rtnl(struct wiphy *wiphy,
struct ieee80211_regdomain *rd);
int regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
struct ieee80211_regdomain *rd);
/**
* wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
@@ -6107,7 +6180,7 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid);
void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid);
/**
* cfg80211_sched_scan_stopped_rtnl - notify that the scheduled scan has stopped
* cfg80211_sched_scan_stopped_locked - notify that the scheduled scan has stopped
*
* @wiphy: the wiphy on which the scheduled scan stopped
* @reqid: identifier for the related scheduled scan request
@@ -6115,9 +6188,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid);
* The driver can call this function to inform cfg80211 that the
* scheduled scan had to be stopped, for whatever reason. The driver
* is then called back via the sched_scan_stop operation when done.
* This function should be called with rtnl locked.
* This function should be called with the wiphy mutex held.
*/
void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy, u64 reqid);
void cfg80211_sched_scan_stopped_locked(struct wiphy *wiphy, u64 reqid);
/**
* cfg80211_inform_bss_frame_data - inform cfg80211 of a received BSS frame
@@ -7554,7 +7627,7 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
* also checks if IR-relaxation conditions apply, to allow beaconing under
* more permissive conditions.
*
* Requires the RTNL to be held.
* Requires the wiphy mutex to be held.
*/
bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef,
@@ -7652,18 +7725,45 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
* cfg80211_unregister_wdev - remove the given wdev
* @wdev: struct wireless_dev to remove
*
* Call this function only for wdevs that have no netdev assigned,
* e.g. P2P Devices. It removes the device from the list so that
* it can no longer be used. It is necessary to call this function
* even when cfg80211 requests the removal of the interface by
* calling the del_virtual_intf() callback. The function must also
* be called when the driver wishes to unregister the wdev, e.g.
* when the device is unbound from the driver.
* This function removes the device so it can no longer be used. It is necessary
* to call this function even when cfg80211 requests the removal of the device
* by calling the del_virtual_intf() callback. The function must also be called
* when the driver wishes to unregister the wdev, e.g. when the hardware device
* is unbound from the driver.
*
* Requires the RTNL to be held.
* Requires the RTNL and wiphy mutex to be held.
*/
void cfg80211_unregister_wdev(struct wireless_dev *wdev);
/**
* cfg80211_register_netdevice - register the given netdev
* @dev: the netdev to register
*
* Note: In contexts coming from cfg80211 callbacks, you must call this rather
* than register_netdevice(), unregister_netdev() is impossible as the RTNL is
* held. Otherwise, both register_netdevice() and register_netdev() are usable
* instead as well.
*
* Requires the RTNL and wiphy mutex to be held.
*/
int cfg80211_register_netdevice(struct net_device *dev);
/**
* cfg80211_unregister_netdevice - unregister the given netdev
* @dev: the netdev to register
*
* Note: In contexts coming from cfg80211 callbacks, you must call this rather
* than unregister_netdevice(), unregister_netdev() is impossible as the RTNL
* is held. Otherwise, both unregister_netdevice() and unregister_netdev() are
* usable instead as well.
*
* Requires the RTNL and wiphy mutex to be held.
*/
static inline void cfg80211_unregister_netdevice(struct net_device *dev)
{
cfg80211_unregister_wdev(dev->ieee80211_ptr);
}
/**
* struct cfg80211_ft_event_params - FT Information Elements
* @ies: FT IEs
+5 -6
View File
@@ -19,8 +19,6 @@ struct fq_tin;
* @flowchain: can be linked to fq_tin's new_flows or old_flows. Used for DRR++
* (deficit round robin) based round robin queuing similar to the one
* found in net/sched/sch_fq_codel.c
* @backlogchain: can be linked to other fq_flow and fq. Used to keep track of
* fat flows and efficient head-dropping if packet limit is reached
* @queue: sk_buff queue to hold packets
* @backlog: number of bytes pending in the queue. The number of packets can be
* found in @queue.qlen
@@ -29,7 +27,6 @@ struct fq_tin;
struct fq_flow {
struct fq_tin *tin;
struct list_head flowchain;
struct list_head backlogchain;
struct sk_buff_head queue;
u32 backlog;
int deficit;
@@ -47,6 +44,8 @@ struct fq_flow {
struct fq_tin {
struct list_head new_flows;
struct list_head old_flows;
struct list_head tin_list;
struct fq_flow default_flow;
u32 backlog_bytes;
u32 backlog_packets;
u32 overlimit;
@@ -59,14 +58,14 @@ struct fq_tin {
/**
* struct fq - main container for fair queuing purposes
*
* @backlogs: linked to fq_flows. Used to maintain fat flows for efficient
* head-dropping when @backlog reaches @limit
* @limit: max number of packets that can be queued across all flows
* @backlog: number of packets queued across all flows
*/
struct fq {
struct fq_flow *flows;
struct list_head backlogs;
unsigned long *flows_bitmap;
struct list_head tin_backlog;
spinlock_t lock;
u32 flows_cnt;
u32 limit;
+115 -62
View File
@@ -11,35 +11,37 @@
/* functions that are embedded into includer */
static void
__fq_adjust_removal(struct fq *fq, struct fq_flow *flow, unsigned int packets,
unsigned int bytes, unsigned int truesize)
{
struct fq_tin *tin = flow->tin;
int idx;
tin->backlog_bytes -= bytes;
tin->backlog_packets -= packets;
flow->backlog -= bytes;
fq->backlog -= packets;
fq->memory_usage -= truesize;
if (flow->backlog)
return;
if (flow == &tin->default_flow) {
list_del_init(&tin->tin_list);
return;
}
idx = flow - fq->flows;
__clear_bit(idx, fq->flows_bitmap);
}
static void fq_adjust_removal(struct fq *fq,
struct fq_flow *flow,
struct sk_buff *skb)
{
struct fq_tin *tin = flow->tin;
tin->backlog_bytes -= skb->len;
tin->backlog_packets--;
flow->backlog -= skb->len;
fq->backlog--;
fq->memory_usage -= skb->truesize;
}
static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
{
struct fq_flow *i;
if (flow->backlog == 0) {
list_del_init(&flow->backlogchain);
} else {
i = flow;
list_for_each_entry_continue(i, &fq->backlogs, backlogchain)
if (i->backlog < flow->backlog)
break;
list_move_tail(&flow->backlogchain,
&i->backlogchain);
}
__fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize);
}
static struct sk_buff *fq_flow_dequeue(struct fq *fq,
@@ -54,11 +56,37 @@ static struct sk_buff *fq_flow_dequeue(struct fq *fq,
return NULL;
fq_adjust_removal(fq, flow, skb);
fq_rejigger_backlog(fq, flow);
return skb;
}
static int fq_flow_drop(struct fq *fq, struct fq_flow *flow,
fq_skb_free_t free_func)
{
unsigned int packets = 0, bytes = 0, truesize = 0;
struct fq_tin *tin = flow->tin;
struct sk_buff *skb;
int pending;
lockdep_assert_held(&fq->lock);
pending = min_t(int, 32, skb_queue_len(&flow->queue) / 2);
do {
skb = __skb_dequeue(&flow->queue);
if (!skb)
break;
packets++;
bytes += skb->len;
truesize += skb->truesize;
free_func(fq, tin, flow, skb);
} while (packets < pending);
__fq_adjust_removal(fq, flow, packets, bytes, truesize);
return packets;
}
static struct sk_buff *fq_tin_dequeue(struct fq *fq,
struct fq_tin *tin,
fq_tin_dequeue_t dequeue_func)
@@ -115,8 +143,7 @@ static u32 fq_flow_idx(struct fq *fq, struct sk_buff *skb)
static struct fq_flow *fq_flow_classify(struct fq *fq,
struct fq_tin *tin, u32 idx,
struct sk_buff *skb,
fq_flow_get_default_t get_default_func)
struct sk_buff *skb)
{
struct fq_flow *flow;
@@ -124,7 +151,7 @@ static struct fq_flow *fq_flow_classify(struct fq *fq,
flow = &fq->flows[idx];
if (flow->tin && flow->tin != tin) {
flow = get_default_func(fq, tin, idx, skb);
flow = &tin->default_flow;
tin->collisions++;
fq->collisions++;
}
@@ -135,36 +162,56 @@ static struct fq_flow *fq_flow_classify(struct fq *fq,
return flow;
}
static void fq_recalc_backlog(struct fq *fq,
struct fq_tin *tin,
struct fq_flow *flow)
static struct fq_flow *fq_find_fattest_flow(struct fq *fq)
{
struct fq_flow *i;
struct fq_tin *tin;
struct fq_flow *flow = NULL;
u32 len = 0;
int i;
if (list_empty(&flow->backlogchain))
list_add_tail(&flow->backlogchain, &fq->backlogs);
for_each_set_bit(i, fq->flows_bitmap, fq->flows_cnt) {
struct fq_flow *cur = &fq->flows[i];
unsigned int cur_len;
i = flow;
list_for_each_entry_continue_reverse(i, &fq->backlogs,
backlogchain)
if (i->backlog > flow->backlog)
break;
cur_len = cur->backlog;
if (cur_len <= len)
continue;
list_move(&flow->backlogchain, &i->backlogchain);
flow = cur;
len = cur_len;
}
list_for_each_entry(tin, &fq->tin_backlog, tin_list) {
unsigned int cur_len = tin->default_flow.backlog;
if (cur_len <= len)
continue;
flow = &tin->default_flow;
len = cur_len;
}
return flow;
}
static void fq_tin_enqueue(struct fq *fq,
struct fq_tin *tin, u32 idx,
struct sk_buff *skb,
fq_skb_free_t free_func,
fq_flow_get_default_t get_default_func)
fq_skb_free_t free_func)
{
struct fq_flow *flow;
bool oom;
lockdep_assert_held(&fq->lock);
flow = fq_flow_classify(fq, tin, idx, skb, get_default_func);
flow = fq_flow_classify(fq, tin, idx, skb);
if (!flow->backlog) {
if (flow != &tin->default_flow)
__set_bit(idx, fq->flows_bitmap);
else if (list_empty(&tin->tin_list))
list_add(&tin->tin_list, &fq->tin_backlog);
}
flow->tin = tin;
flow->backlog += skb->len;
@@ -173,8 +220,6 @@ static void fq_tin_enqueue(struct fq *fq,
fq->memory_usage += skb->truesize;
fq->backlog++;
fq_recalc_backlog(fq, tin, flow);
if (list_empty(&flow->flowchain)) {
flow->deficit = fq->quantum;
list_add_tail(&flow->flowchain,
@@ -184,18 +229,13 @@ static void fq_tin_enqueue(struct fq *fq,
__skb_queue_tail(&flow->queue, skb);
oom = (fq->memory_usage > fq->memory_limit);
while (fq->backlog > fq->limit || oom) {
flow = list_first_entry_or_null(&fq->backlogs,
struct fq_flow,
backlogchain);
flow = fq_find_fattest_flow(fq);
if (!flow)
return;
skb = fq_flow_dequeue(fq, flow);
if (!skb)
if (!fq_flow_drop(fq, flow, free_func))
return;
free_func(fq, flow->tin, flow, skb);
flow->tin->overlimit++;
fq->overlimit++;
if (oom) {
@@ -224,8 +264,6 @@ static void fq_flow_filter(struct fq *fq,
fq_adjust_removal(fq, flow, skb);
free_func(fq, tin, flow, skb);
}
fq_rejigger_backlog(fq, flow);
}
static void fq_tin_filter(struct fq *fq,
@@ -248,16 +286,18 @@ static void fq_flow_reset(struct fq *fq,
struct fq_flow *flow,
fq_skb_free_t free_func)
{
struct fq_tin *tin = flow->tin;
struct sk_buff *skb;
while ((skb = fq_flow_dequeue(fq, flow)))
free_func(fq, flow->tin, flow, skb);
free_func(fq, tin, flow, skb);
if (!list_empty(&flow->flowchain))
if (!list_empty(&flow->flowchain)) {
list_del_init(&flow->flowchain);
if (!list_empty(&flow->backlogchain))
list_del_init(&flow->backlogchain);
if (list_empty(&tin->new_flows) &&
list_empty(&tin->old_flows))
list_del_init(&tin->tin_list);
}
flow->tin = NULL;
@@ -283,6 +323,7 @@ static void fq_tin_reset(struct fq *fq,
fq_flow_reset(fq, flow, free_func);
}
WARN_ON_ONCE(!list_empty(&tin->tin_list));
WARN_ON_ONCE(tin->backlog_bytes);
WARN_ON_ONCE(tin->backlog_packets);
}
@@ -290,7 +331,6 @@ static void fq_tin_reset(struct fq *fq,
static void fq_flow_init(struct fq_flow *flow)
{
INIT_LIST_HEAD(&flow->flowchain);
INIT_LIST_HEAD(&flow->backlogchain);
__skb_queue_head_init(&flow->queue);
}
@@ -298,6 +338,8 @@ static void fq_tin_init(struct fq_tin *tin)
{
INIT_LIST_HEAD(&tin->new_flows);
INIT_LIST_HEAD(&tin->old_flows);
INIT_LIST_HEAD(&tin->tin_list);
fq_flow_init(&tin->default_flow);
}
static int fq_init(struct fq *fq, int flows_cnt)
@@ -305,8 +347,8 @@ static int fq_init(struct fq *fq, int flows_cnt)
int i;
memset(fq, 0, sizeof(fq[0]));
INIT_LIST_HEAD(&fq->backlogs);
spin_lock_init(&fq->lock);
INIT_LIST_HEAD(&fq->tin_backlog);
fq->flows_cnt = max_t(u32, flows_cnt, 1);
fq->quantum = 300;
fq->limit = 8192;
@@ -316,6 +358,14 @@ static int fq_init(struct fq *fq, int flows_cnt)
if (!fq->flows)
return -ENOMEM;
fq->flows_bitmap = kcalloc(BITS_TO_LONGS(fq->flows_cnt), sizeof(long),
GFP_KERNEL);
if (!fq->flows_bitmap) {
kvfree(fq->flows);
fq->flows = NULL;
return -ENOMEM;
}
for (i = 0; i < fq->flows_cnt; i++)
fq_flow_init(&fq->flows[i]);
@@ -332,6 +382,9 @@ static void fq_reset(struct fq *fq,
kvfree(fq->flows);
fq->flows = NULL;
kfree(fq->flows_bitmap);
fq->flows_bitmap = NULL;
}
#endif
+21 -5
View File
@@ -1296,6 +1296,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* the "0-length PSDU" field included there. The value for it is
* in &struct ieee80211_rx_status. Note that if this value isn't
* known the frame shouldn't be reported.
* @RX_FLAG_8023: the frame has an 802.3 header (decap offload performed by
* hardware or driver)
*/
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = BIT(0),
@@ -1328,6 +1330,7 @@ enum mac80211_rx_flags {
RX_FLAG_RADIOTAP_HE_MU = BIT(27),
RX_FLAG_RADIOTAP_LSIG = BIT(28),
RX_FLAG_NO_PSDU = BIT(29),
RX_FLAG_8023 = BIT(30),
};
/**
@@ -1649,11 +1652,15 @@ enum ieee80211_vif_flags {
* The driver supports sending frames passed as 802.3 frames by mac80211.
* It must also support sending 802.11 packets for the same interface.
* @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
* @IEEE80211_OFFLOAD_DECAP_ENABLED: rx encapsulation offload is enabled
* The driver supports passing received 802.11 frames as 802.3 frames to
* mac80211.
*/
enum ieee80211_offload_flags {
IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0),
IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1),
IEEE80211_OFFLOAD_DECAP_ENABLED = BIT(2),
};
/**
@@ -2389,6 +2396,9 @@ struct ieee80211_txq {
* @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
* offload
*
* @IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD: Hardware supports rx decapsulation
* offload
*
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@@ -2442,6 +2452,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -3881,6 +3892,8 @@ enum ieee80211_reconfig_type {
* @sta_set_4addr: Called to notify the driver when a station starts/stops using
* 4-address mode
* @set_sar_specs: Update the SAR (TX power) settings.
* @sta_set_decap_offload: Called to notify the driver when a station is allowed
* to use rx decapsulation offload
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -4198,6 +4211,9 @@ struct ieee80211_ops {
struct ieee80211_sta *sta, bool enabled);
int (*set_sar_specs)(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enabled);
};
/**
@@ -5513,7 +5529,7 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
void *data);
/**
* ieee80211_iterate_active_interfaces_rtnl - iterate active interfaces
* ieee80211_iterate_active_interfaces_mtx - iterate active interfaces
*
* This function iterates over the interfaces associated with a given
* hardware that are currently active and calls the callback for them.
@@ -5524,12 +5540,12 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
* @iterator: the iterator function to call, cannot sleep
* @data: first argument of the iterator function
*/
void ieee80211_iterate_active_interfaces_rtnl(struct ieee80211_hw *hw,
u32 iter_flags,
void (*iterator)(void *data,
void ieee80211_iterate_active_interfaces_mtx(struct ieee80211_hw *hw,
u32 iter_flags,
void (*iterator)(void *data,
u8 *mac,
struct ieee80211_vif *vif),
void *data);
void *data);
/**
* ieee80211_iterate_stations_atomic - iterate stations