mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-09-26 17:44:16 +00:00
fix: support Linux 7.3 cfg80211 API
7.3 lands the last part of a two-commit series that converts several
cfg80211_ops cookie parameters from driver-invented output values to
values cfg80211 pre-assigns and passes in as input, and renames
probe_client to probe_peer. Building against 7.3 fails with 5 errors:
- cfg80211_probe_status() gained an MLO link_id parameter between cookie
and acked (kernel commit 010e955c203e). This driver has no MLO
support; -1 is the documented value for non-MLO.
- cfg80211_ops::probe_client was renamed to probe_peer (4ab9b637b94a).
- cfg80211_ops::mgmt_tx, ::remain_on_channel and ::probe_peer all
changed their cookie parameter from u64 * to u64 (914781c72813):
cfg80211 now pre-assigns the cookie before calling the driver instead
of the driver inventing one and returning it through the pointer.
The cookie change is more than a type fix. This driver invents its
mgmt_tx/remain_on_channel/probe_peer cookies from a skb pointer, an
internal roc_cookie_cnt counter, and an internal probe_id counter
respectively, and separately re-derives "the same" value later when
reporting completion. Once cfg80211 assigns the cookie itself, the
completion report must echo back the value cfg80211 gave the driver.
Two of the three ops are thin wrappers around a lower-level helper that
is also called from a purely-internal path with no cfg80211-assigned
cookie to honor: rwnx_start_mgmt_xmit() is reused by TDLS, and
rwnx_cfg80211_remain_on_channel_() starts the internal RoC from inside
mgmt_tx. Each of those helpers gets a bool (use_given_cookie / the
existing mgmt_roc_flag) so the internal callers keep inventing a cookie
exactly as before on every kernel, while the cfg80211 op wrappers honor
the pre-assigned value on 7.3+ and thread it through to the completion
report. probe_peer has no helper and no internal caller; the op stores
the cookie itself.
- rwnx_start_mgmt_xmit() gains use_given_cookie; the resulting cookie is
stored in a new rwnx_sw_txhdr::cookie and echoed back via
cfg80211_mgmt_tx_status(). Because sw_txhdr comes from a kmem_cache
and is never zeroed, every one of the five allocation sites
initialises the field -- to the skb pointer, which is exactly what the
completion path reported before the field existed -- so the
TXU_CNTRL_MGMT filter on the reporting side is not what keeps it safe.
- rwnx_cfg80211_remain_on_channel_()'s mgmt_roc_flag also selects the
cookie source, stored in a new rwnx_roc_elem::cookie that the
rwnx_msg_rx.c completion handlers read.
- rwnx_cfg80211_probe_client() stores the given cookie in a new
apm_probe_sta::cookie field for the async probe-status work.
Every gate this adds uses AICWF_CFG80211_VERSION_CODE, so an OpenWrt
backports build selects these paths from the wireless stack's version
rather than the kernel's, matching the existing 7.2 gates.
On kernels before 7.3 the compiled behaviour is identical to main with
two exceptions, both requested in review and both changing only the
order of a store relative to a queue/send: *cookie for probe_client is
taken from probe_id before queue_work() rather than after it, and the
RoC cookie is read from roc_cookie_cnt once, before rwnx_send_roc(),
rather than after it returns. In each case the value differs from
main's only if the worker/RX path has already completed and bumped the
counter in between -- a window in which main returns N+1 while having
already reported N to cfg80211. The reported and returned values now
agree by construction.
v2, addressing review:
- RoC: the cookie is decided and stored in roc_elem before the element
is published and rwnx_send_roc() is called, so an early channel-switch
indication cannot report an uninitialised cookie.
- probe_peer: the cookie is stored before queue_work(), so a worker
running immediately on another CPU reports the right one.
- Monitor injection: intended to initialise sw_txhdr->cookie in
rwnx_start_monitor_if_xmit(), but the store landed in
rwnx_start_xmit() instead, where it is never read. Fixed in v5.
- Pre-3.14: use_given_cookie is part of that signature too and both
old-signature callers pass false.
- Rebased onto the OpenWrt backport-version change.
v3:
- rwnx_main.h gated the probe_client prototype on LINUX_VERSION_CODE
while rwnx_main.c gated the definition on AICWF_CFG80211_VERSION_CODE.
Identical on a native build, but a backports build with the two
decoupled would see a u64 * prototype against a u64 definition.
- rwnx_cfg80211_remain_on_channel() no longer duplicates the whole call
to the shared helper just to change one argument; only the cookie
pointer is selected by version.
v4:
- rwnx_cfg80211_remain_on_channel_() no longer writes *cookie before
rwnx_send_roc(). The cookie is snapshotted into a local, roc_elem
keeps its early assignment, and *cookie is written where it was
before this patch: inside the error == 0 branch.
v5:
- The monitor-injection initialisation is now where it was always
meant to be: rwnx_start_monitor_if_xmit(), between the skb
assignment and raw_frame = 1, ungated, since that path runs on every
kernel with CONFIG_RWNX_MON_XMIT. The value is (unsigned long)skb_mgmt,
which is what rwnx_txdatacfm() reported for these frames before.
- The remaining allocation sites that did not set the field --
intf_tx() and rwnx_probersp_work() -- now do, so all five do.
- The internal RoC's block-local cookie in rwnx_cfg80211_mgmt_tx() is
renamed roc_cookie: on 7.3 it had come to shadow a same-typed
parameter with a different meaning.
- Comment fixes: the rwnx_start_mgmt_xmit() kerneldoc documents
use_given_cookie; the probe_peer comment states the 7.3 contract; the
two #endif trailers that close chains now opening on the 7.3 gate say
so; the unused rx_addr is explained on the 7.3 arm as well.
- Rebased onto main (set_monitor_channel on 6.12 stable).
Verified against real linux-cachyos-bc250 (7.2.6) and linux-cachyos-rc-bc250
(7.3-rc4) headers with LLVM=1, the way DKMS builds them, asserting on exit
code and module count:
upstream main @ 7.2.6 rc=0, 3 modules, 13 warnings
upstream main @ 7.3-rc4 rc=2 - the errors this patch fixes
this branch @ 7.2.6 rc=0, 3 modules, 13 warnings
this branch @ 7.3-rc4 rc=0, 3 modules, 13 warnings
warning sets on 7.2.6: identical, and none names a function this
patch touches.
The backports configuration is not something I can build here, so the
header/definition agreement in v3 rests on both sites using the same
macro rather than on a test.
This commit is contained in:
@@ -335,6 +335,12 @@ struct apm_probe_sta {
|
||||
u8 sta_mac_addr[6];
|
||||
u8 vif_idx;
|
||||
u64 probe_id;
|
||||
/*
|
||||
* 7.3+ only: the cookie cfg80211_ops::probe_peer() was called with,
|
||||
* echoed back via cfg80211_probe_status() once the probe completes.
|
||||
* See rwnx_cfg80211_probe_client().
|
||||
*/
|
||||
u64 cookie;
|
||||
struct work_struct apmprobestaWork;
|
||||
struct workqueue_struct *apmprobesta_wq;
|
||||
};
|
||||
@@ -675,6 +681,16 @@ struct rwnx_roc_elem {
|
||||
bool mgmt_roc;
|
||||
/* Indicate if we have switch on the RoC channel */
|
||||
bool on_chan;
|
||||
/*
|
||||
* The cookie reported to cfg80211 for this RoC, via
|
||||
* cfg80211_ready_on_channel() / cfg80211_remain_on_channel_expired().
|
||||
* On 7.3+, for a RoC started directly by cfg80211_ops::remain_on_channel(),
|
||||
* this is the cookie cfg80211 pre-assigned; on every older kernel, and
|
||||
* always for the purely-internal RoC started from inside mgmt_tx, it is
|
||||
* rwnx_hw->roc_cookie_cnt at RoC-start time. See
|
||||
* rwnx_cfg80211_remain_on_channel_().
|
||||
*/
|
||||
u64 cookie;
|
||||
};
|
||||
|
||||
/* Structure containing channel survey information received from MAC */
|
||||
|
||||
@@ -3940,7 +3940,21 @@ void apm_probe_sta_work_process(struct work_struct *work)
|
||||
spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock);
|
||||
|
||||
printk("sta %pM found = %d\n", mac, found);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
/*
|
||||
* 7.3 added an MLO link_id parameter between cookie and acked. This
|
||||
* driver has no MLO support, and -1 is the documented value for
|
||||
* "non-MLO" (see the cfg80211_probe_status() kerneldoc). The cookie
|
||||
* source also changes here: sta_probe.cookie is the value cfg80211
|
||||
* pre-assigned via probe_peer(), which now must be echoed back
|
||||
* instead of the driver's own probe_id counter -- see
|
||||
* rwnx_cfg80211_probe_client().
|
||||
*/
|
||||
if(found)
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.cookie, -1, 1, 0, false, GFP_ATOMIC);
|
||||
else
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.cookie, -1, 0, 0, false, GFP_ATOMIC);
|
||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
if(found)
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, 0, false, GFP_ATOMIC);
|
||||
else
|
||||
@@ -4497,11 +4511,20 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
|
||||
|
||||
/**
|
||||
* @probe_client: probe an associated client, must return a cookie that it
|
||||
* later passes to cfg80211_probe_status().
|
||||
* @probe_peer: probe an associated client. Before 7.3 the driver returns a
|
||||
* cookie of its own and passes the same value to cfg80211_probe_status()
|
||||
* later; from 7.3 the cookie is assigned by cfg80211, passed in, and must
|
||||
* be echoed back unchanged. Renamed from @probe_client upstream; kept as
|
||||
* rwnx_cfg80211_probe_client() here since only the cfg80211_ops field
|
||||
* name changed, not this driver's own naming.
|
||||
*/
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 cookie)
|
||||
#else
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 *cookie)
|
||||
#endif
|
||||
{
|
||||
//struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
struct rwnx_vif *vif = netdev_priv(dev);
|
||||
@@ -4525,9 +4548,21 @@ int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
|
||||
memcpy(vif->sta_probe.sta_mac_addr, peer, 6);
|
||||
queue_work(vif->sta_probe.apmprobesta_wq, &vif->sta_probe.apmprobestaWork);
|
||||
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
/*
|
||||
* 7.3 made this an input parameter: cfg80211 pre-assigns the cookie
|
||||
* before calling us instead of us inventing one and returning it. Save
|
||||
* it before queueing the work: the worker may run on another CPU as
|
||||
* soon as it is queued, and it echoes this value back via
|
||||
* cfg80211_probe_status() once the probe completes.
|
||||
*/
|
||||
vif->sta_probe.cookie = cookie;
|
||||
#else
|
||||
*cookie = vif->sta_probe.probe_id;
|
||||
#endif
|
||||
|
||||
queue_work(vif->sta_probe.apmprobesta_wq, &vif->sta_probe.apmprobestaWork);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4728,6 +4763,7 @@ rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev = &rwnx_vif->wdev;
|
||||
#endif
|
||||
struct rwnx_roc_elem *roc_elem;
|
||||
u64 roc_cookie;
|
||||
struct mm_add_if_cfm add_if_cfm;
|
||||
struct mm_remain_on_channel_cfm roc_cfm;
|
||||
int error;
|
||||
@@ -4819,6 +4855,34 @@ rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy,
|
||||
/* Initialize the OFFCHAN TX queue to allow off-channel transmissions */
|
||||
rwnx_txq_offchan_init(rwnx_vif);
|
||||
|
||||
/*
|
||||
* Decide the cookie before the element is published and the request
|
||||
* sent: the RX path can deliver the channel-switch indication and
|
||||
* call cfg80211_ready_on_channel() with roc_elem->cookie before this
|
||||
* thread resumes, so it must already be the final value by then.
|
||||
* Taking one snapshot here also keeps that value and the one reported
|
||||
* back to the caller below identical: rwnx_send_roc() sleeps, and the
|
||||
* RoC expiry handler increments roc_cookie_cnt, so re-reading the
|
||||
* counter afterwards could return a different value than the one
|
||||
* already reported to cfg80211.
|
||||
*/
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
/*
|
||||
* mgmt_roc_flag is false only for the direct cfg80211
|
||||
* .remain_on_channel call path (see rwnx_cfg80211_remain_on_channel()
|
||||
* below), where on 7.3+ *cookie already holds the value cfg80211
|
||||
* pre-assigned and must be honored rather than overwritten. The
|
||||
* purely-internal RoC this function also serves (started from
|
||||
* inside mgmt_tx, mgmt_roc_flag true) never goes through that
|
||||
* cfg80211 op, so there is no pre-assigned value to honor there --
|
||||
* keep inventing one, exactly as on every older kernel.
|
||||
*/
|
||||
roc_cookie = mgmt_roc_flag ? (u64)(rwnx_hw->roc_cookie_cnt) : *cookie;
|
||||
#else
|
||||
roc_cookie = (u64)(rwnx_hw->roc_cookie_cnt);
|
||||
#endif
|
||||
roc_elem->cookie = roc_cookie;
|
||||
|
||||
/* Forward the information to the FMAC */
|
||||
rwnx_hw->roc_elem = roc_elem;
|
||||
error = rwnx_send_roc(rwnx_hw, rwnx_vif, chan, duration, &roc_cfm);
|
||||
@@ -4827,7 +4891,12 @@ rwnx_cfg80211_remain_on_channel_(struct wiphy *wiphy,
|
||||
if (error == 0) {
|
||||
|
||||
/* Set the cookie value */
|
||||
*cookie = (u64)(rwnx_hw->roc_cookie_cnt);
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
if (mgmt_roc_flag)
|
||||
*cookie = roc_cookie;
|
||||
#else
|
||||
*cookie = roc_cookie;
|
||||
#endif
|
||||
if(roc_cfm.status) {
|
||||
// failed to roc
|
||||
rwnx_hw->roc_elem = NULL;
|
||||
@@ -4857,18 +4926,42 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
enum nl80211_channel_type channel_type,
|
||||
#endif
|
||||
unsigned int duration, u64 *cookie
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
|
||||
unsigned int duration,
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
/*
|
||||
* 7.3 made this cookie an input parameter: cfg80211
|
||||
* pre-assigns it before calling us instead of us
|
||||
* inventing one and returning it. See
|
||||
* rwnx_cfg80211_remain_on_channel_(). rx_addr is
|
||||
* unused for the reason given in the 7.2 arm below:
|
||||
* it is always NULL for this driver.
|
||||
*/
|
||||
u64 cookie, const u8 *rx_addr
|
||||
#elif AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 2, 0)
|
||||
/*
|
||||
* 7.2 added an optional receive address filter for the off-channel
|
||||
* period. cfg80211 refuses a non-NULL one unless the driver sets
|
||||
* NL80211_EXT_FEATURE_ROC_ADDR_FILTER, which this one does not, so it
|
||||
* is always NULL here. mac80211 ignores it in the same way.
|
||||
*/
|
||||
, const u8 *rx_addr
|
||||
u64 *cookie, const u8 *rx_addr
|
||||
#else
|
||||
u64 *cookie
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
/*
|
||||
* 7.3 passes the cookie by value, while the shared helper still takes a
|
||||
* pointer because its internal caller invents one. Only the argument
|
||||
* differs, so pick it here and leave the call itself alone.
|
||||
*/
|
||||
u64 local_cookie = cookie;
|
||||
u64 *cookie_ptr = &local_cookie;
|
||||
#else
|
||||
u64 *cookie_ptr = cookie;
|
||||
#endif
|
||||
|
||||
return rwnx_cfg80211_remain_on_channel_(wiphy,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
|
||||
wdev,
|
||||
@@ -4879,7 +4972,7 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
channel_type,
|
||||
#endif
|
||||
duration, cookie, false);
|
||||
duration, cookie_ptr, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5057,7 +5150,17 @@ struct ieee80211_channel *rwnx_cfg80211_get_channel(struct wiphy *wiphy)
|
||||
/**
|
||||
* @mgmt_tx: Transmit a management frame.
|
||||
*/
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0))
|
||||
static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params,
|
||||
/*
|
||||
* 7.3 made this cookie an input parameter: cfg80211
|
||||
* pre-assigns it before calling us instead of us
|
||||
* inventing one and returning it. See
|
||||
* rwnx_start_mgmt_xmit().
|
||||
*/
|
||||
u64 cookie)
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params,
|
||||
u64 *cookie)
|
||||
@@ -5072,7 +5175,7 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
bool dont_wait_for_ack,
|
||||
#endif
|
||||
u64 *cookie)
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
#endif /* AICWF_CFG80211_VERSION_CODE >= 7.3 / LINUX_VERSION_CODE >= 3.14 */
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
|
||||
@@ -5159,7 +5262,8 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
u64 cookie;
|
||||
/* The internal RoC's own cookie; deliberately not the mgmt_tx one. */
|
||||
u64 roc_cookie;
|
||||
int error;
|
||||
|
||||
AICWFDBG(LOGINFO, "mgmt rx remain on chan\n");
|
||||
@@ -5167,13 +5271,13 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
/* Start a ROC procedure for 30ms */
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
|
||||
error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel,
|
||||
30, &cookie, true);
|
||||
30, &roc_cookie, true);
|
||||
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
|
||||
error = rwnx_cfg80211_remain_on_channel_(wiphy, wdev, channel, NL80211_CHAN_NO_HT,
|
||||
30, &cookie, true);
|
||||
30, &roc_cookie, true);
|
||||
#else
|
||||
error = rwnx_cfg80211_remain_on_channel_(wiphy, dev, channel, NL80211_CHAN_NO_HT,
|
||||
30, &cookie, true);
|
||||
30, &roc_cookie, true);
|
||||
#endif
|
||||
|
||||
if (error) {
|
||||
@@ -5190,11 +5294,16 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
#endif
|
||||
|
||||
send_frame:
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, cookie);
|
||||
#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0))
|
||||
{
|
||||
u64 local_cookie = cookie;
|
||||
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, &local_cookie, true);
|
||||
}
|
||||
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, params, offchan, cookie, false);
|
||||
#else
|
||||
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, channel, offchan, wait, buf, len, no_cck, dont_wait_for_ack, cookie);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
return rwnx_start_mgmt_xmit(rwnx_vif, rwnx_sta, channel, offchan, wait, buf, len, no_cck, dont_wait_for_ack, cookie, false);
|
||||
#endif /* AICWF_CFG80211_VERSION_CODE >= 7.3 / LINUX_VERSION_CODE >= 3.14 */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6552,7 +6661,11 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
|
||||
.change_beacon = rwnx_cfg80211_change_beacon,
|
||||
.stop_ap = rwnx_cfg80211_stop_ap,
|
||||
.set_monitor_channel = rwnx_cfg80211_set_monitor_channel,
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
.probe_peer = rwnx_cfg80211_probe_client,
|
||||
#else
|
||||
.probe_client = rwnx_cfg80211_probe_client,
|
||||
#endif
|
||||
// .mgmt_frame_register = rwnx_cfg80211_mgmt_frame_register,
|
||||
.set_wiphy_params = rwnx_cfg80211_set_wiphy_params,
|
||||
.set_txq_params = rwnx_cfg80211_set_txq_params,
|
||||
|
||||
@@ -99,8 +99,13 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef);
|
||||
#endif
|
||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 cookie);
|
||||
#else
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 *cookie);
|
||||
#endif
|
||||
void rwnx_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
|
||||
struct net_device *dev,
|
||||
|
||||
@@ -123,13 +123,13 @@ static inline int rwnx_rx_chan_switch_ind(struct rwnx_hw *rwnx_hw,
|
||||
if (!roc_elem->mgmt_roc) {
|
||||
/* Inform the host that we have switch on the indicated off-channel */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
|
||||
cfg80211_ready_on_channel(roc_elem->wdev->netdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_ready_on_channel(roc_elem->wdev->netdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, roc_elem->duration, GFP_ATOMIC);
|
||||
#else
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_ready_on_channel(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, roc_elem->duration, GFP_ATOMIC);
|
||||
#endif
|
||||
}
|
||||
@@ -245,13 +245,13 @@ static inline int rwnx_rx_remain_on_channel_exp_ind(struct rwnx_hw *rwnx_hw,
|
||||
/* Inform the host that off-channel period has expired */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev->netdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev->netdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC);
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, NL80211_CHAN_HT20, GFP_ATOMIC);
|
||||
#else
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, (u64)(rwnx_hw->roc_cookie_cnt),
|
||||
cfg80211_remain_on_channel_expired(roc_elem->wdev, roc_elem->cookie,
|
||||
roc_elem->chan, GFP_ATOMIC);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -775,9 +775,9 @@ rwnx_tdls_send_mgmt_packet_data(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_v
|
||||
|
||||
params.len = skb->len;
|
||||
params.buf = skb->data;
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, ¶ms, false, &cookie);
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, ¶ms, false, &cookie, false);
|
||||
#else
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie);
|
||||
ret = rwnx_start_mgmt_xmit(rwnx_vif, NULL, NULL, false, 0, skb->data, skb->len, false, false, &cookie, false);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -1325,6 +1325,7 @@ int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg)
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = rwnx_vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = (unsigned long)skb;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
|
||||
@@ -1541,6 +1542,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = rwnx_vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = (unsigned long)skb;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
|
||||
@@ -1630,7 +1632,12 @@ free:
|
||||
* @params: Mgmt frame parameters
|
||||
* @offchan: Indicate whether the frame must be send via the offchan TXQ.
|
||||
* (is is redundant with params->offchan ?)
|
||||
* @cookie: updated with a unique value to identify the frame with upper layer
|
||||
* @cookie: on return, the value cfg80211_mgmt_tx_status() will report for
|
||||
* this frame: invented here (the skb pointer) unless
|
||||
* @use_given_cookie is set, in which case *@cookie is kept.
|
||||
* @use_given_cookie: *@cookie already holds the cookie cfg80211 assigned
|
||||
* (7.3+, the direct .mgmt_tx path only); honour it instead of
|
||||
* inventing one. Every other caller passes false.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1638,7 +1645,7 @@ free:
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct cfg80211_mgmt_tx_params *params, bool offchan,
|
||||
u64 *cookie)
|
||||
u64 *cookie, bool use_given_cookie)
|
||||
#else
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct ieee80211_channel *channel, bool offchan,
|
||||
@@ -1649,7 +1656,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
|
||||
bool dont_wait_for_ack,
|
||||
#endif
|
||||
u64 *cookie)
|
||||
u64 *cookie, bool use_given_cookie)
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = vif->rwnx_hw;
|
||||
@@ -1703,6 +1710,17 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* use_given_cookie is true only for the direct cfg80211 .mgmt_tx call
|
||||
* path on 7.3+, where *cookie already holds the value cfg80211
|
||||
* pre-assigned and must be echoed back via cfg80211_mgmt_tx_status()
|
||||
* later -- see rwnx_cfg80211_mgmt_tx(). TDLS's internal reuse of this
|
||||
* function (use_given_cookie == false) never goes through that cfg80211
|
||||
* op, so it still gets an invented, locally-unique cookie exactly as
|
||||
* before this fix, and on every kernel older than 7.3 every caller
|
||||
* passes use_given_cookie == false, also leaving this unchanged.
|
||||
*/
|
||||
if (!use_given_cookie)
|
||||
*cookie = (unsigned long)skb;
|
||||
|
||||
/*
|
||||
@@ -1773,6 +1791,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = *cookie;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
#ifdef CONFIG_RWNX_AMSDUS_TX
|
||||
@@ -1924,6 +1943,7 @@ void rwnx_probersp_work(struct work_struct *work)
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = rwnx_vif;
|
||||
sw_txhdr->skb = skb;
|
||||
sw_txhdr->cookie = (unsigned long)skb;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
#ifdef CONFIG_RWNX_AMSDUS_TX
|
||||
@@ -2278,6 +2298,15 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d
|
||||
sw_txhdr->rwnx_sta = sta;
|
||||
sw_txhdr->rwnx_vif = vif;
|
||||
sw_txhdr->skb = skb_mgmt;
|
||||
/*
|
||||
* Injected frames are flagged TXU_CNTRL_MGMT below and complete through
|
||||
* the same path as management frames, which reports sw_txhdr->cookie to
|
||||
* cfg80211_mgmt_tx_status(). There is no cfg80211-assigned cookie for an
|
||||
* injected frame, so this is the skb-derived value that path reported
|
||||
* before the field existed. Not gated on 7.3: this path runs on every
|
||||
* kernel with CONFIG_RWNX_MON_XMIT.
|
||||
*/
|
||||
sw_txhdr->cookie = (unsigned long)skb_mgmt;
|
||||
sw_txhdr->headroom = headroom;
|
||||
sw_txhdr->map_len = skb_mgmt->len - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
sw_txhdr->raw_frame = 1;
|
||||
@@ -2389,7 +2418,7 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
||||
#endif
|
||||
/* Confirm transmission to CFG80211 */
|
||||
cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev,
|
||||
(unsigned long)skb,
|
||||
sw_txhdr->cookie,
|
||||
(skb->data + sw_txhdr->headroom),
|
||||
sw_txhdr->frame_len,
|
||||
rwnx_txst.acknowledged,
|
||||
|
||||
@@ -130,6 +130,17 @@ struct rwnx_sw_txhdr {
|
||||
#endif
|
||||
u32 need_cfm;
|
||||
struct sk_buff *skb;
|
||||
/*
|
||||
* The cookie cfg80211_mgmt_tx_status() reports for this frame. sw_txhdr
|
||||
* comes from a kmem_cache and is never zeroed, so every allocation site
|
||||
* sets this: (unsigned long)skb, which is what the completion path
|
||||
* reported before the field existed, except in rwnx_start_mgmt_xmit(),
|
||||
* which stores the cfg80211-assigned cookie it was handed on 7.3+ (see
|
||||
* use_given_cookie there). Only frames flagged TXU_CNTRL_MGMT are ever
|
||||
* reported, but the field is initialised unconditionally so that filter
|
||||
* is not what keeps it safe.
|
||||
*/
|
||||
u64 cookie;
|
||||
|
||||
size_t map_len;
|
||||
dma_addr_t dma_addr;
|
||||
@@ -158,7 +169,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev);
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct cfg80211_mgmt_tx_params *params, bool offchan,
|
||||
u64 *cookie);
|
||||
u64 *cookie, bool use_given_cookie);
|
||||
#else
|
||||
int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
struct ieee80211_channel *channel, bool offchan,
|
||||
@@ -169,7 +180,7 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
|
||||
bool dont_wait_for_ack,
|
||||
#endif
|
||||
u64 *cookie);
|
||||
u64 *cookie, bool use_given_cookie);
|
||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */
|
||||
#ifdef CONFIG_RWNX_MON_XMIT
|
||||
netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb,
|
||||
|
||||
Reference in New Issue
Block a user