From 264f29db2184d3194a86bc9219574fe809d12d44 Mon Sep 17 00:00:00 2001 From: Lucas Kawatoko <97761679+lucaskawatoko@users.noreply.github.com> Date: Mon, 21 Sep 2026 23:06:15 -0300 Subject: [PATCH] fix: handle set_monitor_channel dev parameter on 6.12 stable cfg80211_ops.set_monitor_channel() gained a "struct net_device *dev" parameter in mainline 6.13, and the change was backported to the 6.12 stable series starting with 6.12.101. Debian 13 ships 6.12.107, so the existing ">= 6.13.0" guards select the old prototype there and the build fails 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 *)' [-Wincompatible-pointer-types] This is the failure reported in #96 for Debian 13 trixie. Introduce AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV in rwnx_compat.h, defined at AICWF_CFG80211_VERSION_CODE >= 6.12.101, and gate the nine set_monitor_channel call sites on it instead of comparing against 6.13.0. The threshold covers both the 6.12 backport and mainline 6.13, while kernels 6.11 and earlier 6.12.x keep the old prototype. The check now lives in one place and follows the existing AICWF_CFG80211_VERSION_CODE convention, so OpenWrt builds can override it with CFG80211_VERSION. The MODULE_IMPORT_NS guard at rwnx_main.c that also checks 6.13.0 is unrelated and is left untouched. Verified with clean builds against linux-headers 5.15.0-191, 6.1.0-53, 6.8.0-139, 6.11.0-8 and 6.12.107+deb13. --- drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c | 8 ++++---- drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h | 2 +- drivers/aic8800/aic8800_fdrv/rwnx_compat.h | 22 +++++++++++++++++++++ drivers/aic8800/aic8800_fdrv/rwnx_main.c | 6 +++--- drivers/aic8800/aic8800_fdrv/rwnx_main.h | 2 +- 5 files changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c index dba2b3e..f5b15dd 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c +++ b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c @@ -1832,7 +1832,7 @@ void set_vendor_extension_ie(char *command){ } #endif//CONFIG_SET_VENDOR_EXTENSION_IE -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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 @@ -1840,7 +1840,7 @@ int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct cfg80211_chan_def *chandef); #endif int rwnx_atoi2(char *value, int c_len); -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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) @@ -1867,7 +1867,7 @@ void set_mon_chan(struct rwnx_vif *vif, char *parameter) chandef->center_freq1 = chandef->chan->center_freq; chandef->center_freq2 = 0; -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 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); @@ -2136,7 +2136,7 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) char *set_parameter; skip = strlen(CMD_SET_MON_FREQ) + 1; set_parameter = command + skip; -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#ifdef AICWF_CFG80211_SET_MONITOR_CHANNEL_HAS_DEV set_mon_chan(vif, net, set_parameter); #else set_mon_chan(vif, set_parameter); diff --git a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h index 23230b1..a126c2d 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h +++ b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h @@ -62,7 +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); int str_starts(const char *str, const char *start); int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len); -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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); diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h index f2e8eb3..d5737bc 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h @@ -28,6 +28,28 @@ #define AICWF_CFG80211_VERSION_CODE LINUX_VERSION_CODE #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) #error "Minimum kernel version supported is 3.10" #endif diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.c b/drivers/aic8800/aic8800_fdrv/rwnx_main.c index 37ae81b..9180fe2 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.c @@ -4420,7 +4420,7 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1, } #endif -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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 @@ -4480,7 +4480,7 @@ static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, } -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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) @@ -5009,7 +5009,7 @@ static int rwnx_cfg80211_get_channel(struct wiphy *wiphy, if (rwnx_vif->vif_index == rwnx_hw->monitor_vif) { //retrieve channel from firmware -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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); diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.h b/drivers/aic8800/aic8800_fdrv/rwnx_main.h index 86aec11..f45e39a 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.h @@ -91,7 +91,7 @@ void aicwf_p2p_alive_timeout(struct timer_list *t); int rwnx_send_check_p2p(struct cfg80211_scan_request *param); void apm_staloss_work_process(struct work_struct *work); void apm_probe_sta_work_process(struct work_struct *work); -#if (AICWF_CFG80211_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +#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);