mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-11-10 16:49:17 +00:00
fix: select monitor-channel callback from cfg80211 header type
Keep the internal monitor-channel API independent of kernel versions and select a correctly typed cfg80211 adapter at compile time. This covers Ubuntu 6.8.0-147 and stable/backports without release-string heuristics or function-pointer casts. Validation: reproduced the original failure on Ubuntu 6.8.0-147; all three modules build on 6.8.0-146, 6.8.0-147 and 6.17.0-14. Fixes #107.
This commit is contained in:
1 parent
43db8006cb
commit
a827d291bb
6 files changed
+16
-67
No files matched your search
+4
-2
@@ -49,8 +49,10 @@ it to the host kernel version or redefine `LINUX_VERSION_CODE`.
|
|||||||
## Compatibility scope
|
## Compatibility scope
|
||||||
|
|
||||||
The override selects the wireless API changes since Linux 6.12, including
|
The override selects the wireless API changes since Linux 6.12, including
|
||||||
monitor-channel callbacks, radio/link arguments, radar notifications and
|
radio/link arguments, radar notifications and newer cfg80211 callbacks.
|
||||||
newer cfg80211 callbacks. Timer, USB, memory-management and module namespace
|
The monitor-channel callback is selected from the actual cfg80211 header type
|
||||||
|
so distribution backports also work without changing the version override.
|
||||||
|
Timer, USB, memory-management and module namespace
|
||||||
checks continue to use the target kernel version. Older target kernels with
|
checks continue to use the target kernel version. Older target kernels with
|
||||||
newer backports may need additional wireless API adaptations.
|
newer backports may need additional wireless API adaptations.
|
||||||
|
|
||||||
|
|||||||
@@ -1832,19 +1832,10 @@ void set_vendor_extension_ie(char *command){
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif//CONFIG_SET_VENDOR_EXTENSION_IE
|
#endif//CONFIG_SET_VENDOR_EXTENSION_IE
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev,
|
|
||||||
struct cfg80211_chan_def *chandef);
|
|
||||||
#else
|
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
#endif
|
|
||||||
int rwnx_atoi2(char *value, int c_len);
|
int rwnx_atoi2(char *value, int c_len);
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter)
|
|
||||||
#else
|
|
||||||
void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
struct cfg80211_chan_def *chandef = NULL;
|
struct cfg80211_chan_def *chandef = NULL;
|
||||||
int freq = 0;
|
int freq = 0;
|
||||||
@@ -1867,11 +1858,7 @@ void set_mon_chan(struct rwnx_vif *vif, char *parameter)
|
|||||||
chandef->center_freq1 = chandef->chan->center_freq;
|
chandef->center_freq1 = chandef->chan->center_freq;
|
||||||
chandef->center_freq2 = 0;
|
chandef->center_freq2 = 0;
|
||||||
|
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef);
|
|
||||||
#else
|
|
||||||
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef);
|
rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef);
|
||||||
#endif
|
|
||||||
|
|
||||||
vfree(chandef->chan);
|
vfree(chandef->chan);
|
||||||
vfree(chandef);
|
vfree(chandef);
|
||||||
@@ -2136,11 +2123,7 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
|
|||||||
char *set_parameter;
|
char *set_parameter;
|
||||||
skip = strlen(CMD_SET_MON_FREQ) + 1;
|
skip = strlen(CMD_SET_MON_FREQ) + 1;
|
||||||
set_parameter = command + skip;
|
set_parameter = command + skip;
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
set_mon_chan(vif, net, set_parameter);
|
|
||||||
#else
|
|
||||||
set_mon_chan(vif, set_parameter);
|
set_mon_chan(vif, set_parameter);
|
||||||
#endif
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,11 +62,7 @@ int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val);
|
|||||||
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base);
|
unsigned int command_strtoul(const char *cp, char **endp, unsigned int base);
|
||||||
int str_starts(const char *str, const char *start);
|
int str_starts(const char *str, const char *start);
|
||||||
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
|
int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len);
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter);
|
|
||||||
#else
|
|
||||||
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
|
void set_mon_chan(struct rwnx_vif *vif, char *parameter);
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _AIC_PRIV_CMD_H_ */
|
#endif /* _AIC_PRIV_CMD_H_ */
|
||||||
|
|
||||||
@@ -28,28 +28,6 @@
|
|||||||
#define AICWF_CFG80211_VERSION_CODE LINUX_VERSION_CODE
|
#define AICWF_CFG80211_VERSION_CODE LINUX_VERSION_CODE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* cfg80211_ops.set_monitor_channel() gained a "struct net_device *dev"
|
|
||||||
* parameter. The change went into mainline 6.13, but it was also
|
|
||||||
* backported to the 6.12 stable series starting with 6.12.101, so a
|
|
||||||
* plain ">= 6.13.0" test misses 6.12.101 and later. Those kernels then
|
|
||||||
* compile against the old prototype, which is fatal with
|
|
||||||
* -Wincompatible-pointer-types:
|
|
||||||
*
|
|
||||||
* rwnx_main.c: error: initialization of
|
|
||||||
* 'int (*)(struct wiphy *, struct net_device *, struct cfg80211_chan_def *)'
|
|
||||||
* from incompatible pointer type
|
|
||||||
* 'int (*)(struct wiphy *, struct cfg80211_chan_def *)'
|
|
||||||
*
|
|
||||||
* Debian 13 (6.12.107) is one such kernel. The 6.12.101 threshold
|
|
||||||
* covers both the backport and mainline, and leaves 6.11 and earlier
|
|
||||||
* 6.12.x on the old prototype. Keep the check in one place so every
|
|
||||||
* consumer stays in sync.
|
|
||||||
*/
|
|
||||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 12, 101)
|
|
||||||
#define AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
||||||
#error "Minimum kernel version supported is 3.10"
|
#error "Minimum kernel version supported is 3.10"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4451,13 +4451,8 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, struct net_device *dev,
|
|
||||||
struct cfg80211_chan_def *chandef)
|
|
||||||
#else
|
|
||||||
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
|
static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
|
||||||
struct cfg80211_chan_def *chandef)
|
struct cfg80211_chan_def *chandef)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||||
struct rwnx_vif *rwnx_vif;
|
struct rwnx_vif *rwnx_vif;
|
||||||
@@ -4511,21 +4506,19 @@ static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
/* Newer cfg80211 stacks pass dev; the firmware still has one monitor vif. */
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
static int rwnx_cfg80211_set_monitor_channel_with_dev(struct wiphy *wiphy,
|
||||||
struct net_device *dev,
|
struct net_device *dev,
|
||||||
struct cfg80211_chan_def *chandef)
|
struct cfg80211_chan_def *chandef)
|
||||||
{
|
{
|
||||||
return rwnx_cfg80211_set_monitor_channel(wiphy, dev, chandef);
|
return rwnx_cfg80211_set_monitor_channel(wiphy, chandef);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
struct cfg80211_chan_def *chandef)
|
struct cfg80211_chan_def *chandef)
|
||||||
{
|
{
|
||||||
return rwnx_cfg80211_set_monitor_channel(wiphy, chandef);
|
return rwnx_cfg80211_set_monitor_channel(wiphy, chandef);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @probe_peer: probe an associated client. Before 7.3 the driver returns a
|
* @probe_peer: probe an associated client. Before 7.3 the driver returns a
|
||||||
@@ -5119,11 +5112,7 @@ static int rwnx_cfg80211_get_channel(struct wiphy *wiphy,
|
|||||||
if (rwnx_vif->vif_index == rwnx_hw->monitor_vif)
|
if (rwnx_vif->vif_index == rwnx_hw->monitor_vif)
|
||||||
{
|
{
|
||||||
//retrieve channel from firmware
|
//retrieve channel from firmware
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
rwnx_cfg80211_set_monitor_channel(wiphy, wdev->netdev, NULL);
|
|
||||||
#else
|
|
||||||
rwnx_cfg80211_set_monitor_channel(wiphy, NULL);
|
rwnx_cfg80211_set_monitor_channel(wiphy, NULL);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if channel context is valid
|
//Check if channel context is valid
|
||||||
@@ -6677,7 +6666,14 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
|
|||||||
.start_ap = rwnx_cfg80211_start_ap,
|
.start_ap = rwnx_cfg80211_start_ap,
|
||||||
.change_beacon = rwnx_cfg80211_change_beacon,
|
.change_beacon = rwnx_cfg80211_change_beacon,
|
||||||
.stop_ap = rwnx_cfg80211_stop_ap,
|
.stop_ap = rwnx_cfg80211_stop_ap,
|
||||||
.set_monitor_channel = rwnx_cfg80211_set_monitor_channel,
|
/* Select the actual header ABI, including distro/stable backports such
|
||||||
|
* as Ubuntu 6.8.0-147 and Linux 6.12.101. No function-pointer casts. */
|
||||||
|
.set_monitor_channel = __builtin_choose_expr(
|
||||||
|
__builtin_types_compatible_p(
|
||||||
|
typeof(((struct cfg80211_ops *)0)->set_monitor_channel),
|
||||||
|
typeof(&rwnx_cfg80211_set_monitor_channel_with_dev)),
|
||||||
|
rwnx_cfg80211_set_monitor_channel_with_dev,
|
||||||
|
rwnx_cfg80211_set_monitor_channel),
|
||||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||||
.probe_peer = rwnx_cfg80211_probe_client,
|
.probe_peer = rwnx_cfg80211_probe_client,
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -91,14 +91,8 @@ void aicwf_p2p_alive_timeout(struct timer_list *t);
|
|||||||
int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
|
int rwnx_send_check_p2p(struct cfg80211_scan_request *param);
|
||||||
void apm_staloss_work_process(struct work_struct *work);
|
void apm_staloss_work_process(struct work_struct *work);
|
||||||
void apm_probe_sta_work_process(struct work_struct *work);
|
void apm_probe_sta_work_process(struct work_struct *work);
|
||||||
#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV
|
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
|
||||||
struct net_device *dev,
|
|
||||||
struct cfg80211_chan_def *chandef);
|
|
||||||
#else
|
|
||||||
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy,
|
||||||
struct cfg80211_chan_def *chandef);
|
struct cfg80211_chan_def *chandef);
|
||||||
#endif
|
|
||||||
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
#if AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(7, 3, 0)
|
||||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||||
const u8 *peer, u64 cookie);
|
const u8 *peer, u64 cookie);
|
||||||
|
|||||||
Reference in new issue
Block a user