aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wcn36xx/main.c
diff options
context:
space:
mode:
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>2021-06-05 02:11:33 +0100
committerKalle Valo <kvalo@codeaurora.org>2021-06-14 18:18:12 +0300
commitc7a61af55976dbd11b176d2badda869a7537dca4 (patch)
tree8cbbbd72f3ae3e6e242fd86bae1c9687362f9562 /drivers/net/wireless/ath/wcn36xx/main.c
parentwcn36xx: Do not flush indication queue on suspend/resume (diff)
downloadlinux-dev-c7a61af55976dbd11b176d2badda869a7537dca4.tar.xz
linux-dev-c7a61af55976dbd11b176d2badda869a7537dca4.zip
wcn36xx: Add ipv6 address tracking
Taking code from iwlwifi this commit adds a standard callback for ipv6_addr_change(). This callback allows wcn36xx to know the set of ipv6 addresses. Something we need to know in order to get wowlan working with ipv6. Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> Tested-by: Benjamin Li <benl@squareup.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20210605011140.2004643-6-bryan.odonoghue@linaro.org
Diffstat (limited to 'drivers/net/wireless/ath/wcn36xx/main.c')
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 9731fcbe2e7f..240ecdd52f81 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -25,6 +25,7 @@
#include <linux/rpmsg.h>
#include <linux/soc/qcom/smem_state.h>
#include <linux/soc/qcom/wcnss_ctrl.h>
+#include <net/ipv6.h>
#include "wcn36xx.h"
#include "testmode.h"
@@ -1208,6 +1209,34 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
+#if IS_ENABLED(CONFIG_IPV6)
+static void wcn36xx_ipv6_addr_change(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct inet6_dev *idev)
+{
+ struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
+ struct inet6_ifaddr *ifa;
+ int idx = 0;
+
+ memset(vif_priv->tentative_addrs, 0, sizeof(vif_priv->tentative_addrs));
+
+ read_lock_bh(&idev->lock);
+ list_for_each_entry(ifa, &idev->addr_list, if_list) {
+ vif_priv->target_ipv6_addrs[idx] = ifa->addr;
+ if (ifa->flags & IFA_F_TENTATIVE)
+ __set_bit(idx, vif_priv->tentative_addrs);
+ idx++;
+ if (idx >= WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX)
+ break;
+ wcn36xx_dbg(WCN36XX_DBG_MAC, "%pI6 %s\n", &ifa->addr,
+ (ifa->flags & IFA_F_TENTATIVE) ? "tentative" : NULL);
+ }
+ read_unlock_bh(&idev->lock);
+
+ vif_priv->num_target_ipv6_addrs = idx;
+}
+#endif
+
static const struct ieee80211_ops wcn36xx_ops = {
.start = wcn36xx_start,
.stop = wcn36xx_stop,
@@ -1231,6 +1260,9 @@ static const struct ieee80211_ops wcn36xx_ops = {
.sta_add = wcn36xx_sta_add,
.sta_remove = wcn36xx_sta_remove,
.ampdu_action = wcn36xx_ampdu_action,
+#if IS_ENABLED(CONFIG_IPV6)
+ .ipv6_addr_change = wcn36xx_ipv6_addr_change,
+#endif
CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
};