aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath10k/wmi.c
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2015-02-26 07:23:17 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2015-03-07 02:57:35 -0500
commit6a94888f173f10d24d69d25fb99ab50bf750e0e3 (patch)
treeeefbd4fb998a2c089106b64d3b47410bffdda8da /drivers/net/wireless/ath/ath10k/wmi.c
parentbc657a36b8999c285a11e1e0abcdca0b18149948 (diff)
ath10k: refactor p2p noa code
Some files are getting bloated and it makes sense to split some of the code into separate files. Do so with the P2P NoA code and prepare it for reuse. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c91
1 files changed, 4 insertions, 87 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 7fc81f2fef36..29aef7eb4d6c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -26,6 +26,7 @@
26#include "mac.h" 26#include "mac.h"
27#include "testmode.h" 27#include "testmode.h"
28#include "wmi-ops.h" 28#include "wmi-ops.h"
29#include "p2p.h"
29 30
30/* MAIN WMI cmd track */ 31/* MAIN WMI cmd track */
31static struct wmi_cmd_map wmi_cmd_map = { 32static struct wmi_cmd_map wmi_cmd_map = {
@@ -2276,109 +2277,25 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
2276 tim->bitmap_ctrl, pvm_len); 2277 tim->bitmap_ctrl, pvm_len);
2277} 2278}
2278 2279
2279static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
2280 const struct wmi_p2p_noa_info *noa)
2281{
2282 struct ieee80211_p2p_noa_attr *noa_attr;
2283 u8 ctwindow_oppps = noa->ctwindow_oppps;
2284 u8 ctwindow = ctwindow_oppps >> WMI_P2P_OPPPS_CTWINDOW_OFFSET;
2285 bool oppps = !!(ctwindow_oppps & WMI_P2P_OPPPS_ENABLE_BIT);
2286 __le16 *noa_attr_len;
2287 u16 attr_len;
2288 u8 noa_descriptors = noa->num_descriptors;
2289 int i;
2290
2291 /* P2P IE */
2292 data[0] = WLAN_EID_VENDOR_SPECIFIC;
2293 data[1] = len - 2;
2294 data[2] = (WLAN_OUI_WFA >> 16) & 0xff;
2295 data[3] = (WLAN_OUI_WFA >> 8) & 0xff;
2296 data[4] = (WLAN_OUI_WFA >> 0) & 0xff;
2297 data[5] = WLAN_OUI_TYPE_WFA_P2P;
2298
2299 /* NOA ATTR */
2300 data[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE;
2301 noa_attr_len = (__le16 *)&data[7]; /* 2 bytes */
2302 noa_attr = (struct ieee80211_p2p_noa_attr *)&data[9];
2303
2304 noa_attr->index = noa->index;
2305 noa_attr->oppps_ctwindow = ctwindow;
2306 if (oppps)
2307 noa_attr->oppps_ctwindow |= IEEE80211_P2P_OPPPS_ENABLE_BIT;
2308
2309 for (i = 0; i < noa_descriptors; i++) {
2310 noa_attr->desc[i].count =
2311 __le32_to_cpu(noa->descriptors[i].type_count);
2312 noa_attr->desc[i].duration = noa->descriptors[i].duration;
2313 noa_attr->desc[i].interval = noa->descriptors[i].interval;
2314 noa_attr->desc[i].start_time = noa->descriptors[i].start_time;
2315 }
2316
2317 attr_len = 2; /* index + oppps_ctwindow */
2318 attr_len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
2319 *noa_attr_len = __cpu_to_le16(attr_len);
2320}
2321
2322static u32 ath10k_p2p_calc_noa_ie_len(const struct wmi_p2p_noa_info *noa)
2323{
2324 u32 len = 0;
2325 u8 noa_descriptors = noa->num_descriptors;
2326 u8 opp_ps_info = noa->ctwindow_oppps;
2327 bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT);
2328
2329 if (!noa_descriptors && !opps_enabled)
2330 return len;
2331
2332 len += 1 + 1 + 4; /* EID + len + OUI */
2333 len += 1 + 2; /* noa attr + attr len */
2334 len += 1 + 1; /* index + oppps_ctwindow */
2335 len += noa_descriptors * sizeof(struct ieee80211_p2p_noa_desc);
2336
2337 return len;
2338}
2339
2340static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, 2280static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
2341 struct sk_buff *bcn, 2281 struct sk_buff *bcn,
2342 const struct wmi_p2p_noa_info *noa) 2282 const struct wmi_p2p_noa_info *noa)
2343{ 2283{
2344 u8 *new_data, *old_data = arvif->u.ap.noa_data;
2345 u32 new_len;
2346
2347 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) 2284 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
2348 return; 2285 return;
2349 2286
2350 ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); 2287 ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed);
2351 if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) {
2352 new_len = ath10k_p2p_calc_noa_ie_len(noa);
2353 if (!new_len)
2354 goto cleanup;
2355 2288
2356 new_data = kmalloc(new_len, GFP_ATOMIC); 2289 if (noa->changed & WMI_P2P_NOA_CHANGED_BIT)
2357 if (!new_data) 2290 ath10k_p2p_noa_update(arvif, noa);
2358 goto cleanup;
2359
2360 ath10k_p2p_fill_noa_ie(new_data, new_len, noa);
2361
2362 spin_lock_bh(&ar->data_lock);
2363 arvif->u.ap.noa_data = new_data;
2364 arvif->u.ap.noa_len = new_len;
2365 spin_unlock_bh(&ar->data_lock);
2366 kfree(old_data);
2367 }
2368 2291
2369 if (arvif->u.ap.noa_data) 2292 if (arvif->u.ap.noa_data)
2370 if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC)) 2293 if (!pskb_expand_head(bcn, 0, arvif->u.ap.noa_len, GFP_ATOMIC))
2371 memcpy(skb_put(bcn, arvif->u.ap.noa_len), 2294 memcpy(skb_put(bcn, arvif->u.ap.noa_len),
2372 arvif->u.ap.noa_data, 2295 arvif->u.ap.noa_data,
2373 arvif->u.ap.noa_len); 2296 arvif->u.ap.noa_len);
2374 return;
2375 2297
2376cleanup: 2298 return;
2377 spin_lock_bh(&ar->data_lock);
2378 arvif->u.ap.noa_data = NULL;
2379 arvif->u.ap.noa_len = 0;
2380 spin_unlock_bh(&ar->data_lock);
2381 kfree(old_data);
2382} 2299}
2383 2300
2384static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb, 2301static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,