2 * Copyright (c) 2015 Qualcomm Atheros, Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 static void ath10k_p2p_noa_ie_fill(u8
*data
, size_t len
,
23 const struct wmi_p2p_noa_info
*noa
)
25 struct ieee80211_p2p_noa_attr
*noa_attr
;
26 u8 ctwindow_oppps
= noa
->ctwindow_oppps
;
27 u8 ctwindow
= ctwindow_oppps
>> WMI_P2P_OPPPS_CTWINDOW_OFFSET
;
28 bool oppps
= !!(ctwindow_oppps
& WMI_P2P_OPPPS_ENABLE_BIT
);
31 u8 noa_descriptors
= noa
->num_descriptors
;
35 data
[0] = WLAN_EID_VENDOR_SPECIFIC
;
37 data
[2] = (WLAN_OUI_WFA
>> 16) & 0xff;
38 data
[3] = (WLAN_OUI_WFA
>> 8) & 0xff;
39 data
[4] = (WLAN_OUI_WFA
>> 0) & 0xff;
40 data
[5] = WLAN_OUI_TYPE_WFA_P2P
;
43 data
[6] = IEEE80211_P2P_ATTR_ABSENCE_NOTICE
;
44 noa_attr_len
= (__le16
*)&data
[7]; /* 2 bytes */
45 noa_attr
= (struct ieee80211_p2p_noa_attr
*)&data
[9];
47 noa_attr
->index
= noa
->index
;
48 noa_attr
->oppps_ctwindow
= ctwindow
;
50 noa_attr
->oppps_ctwindow
|= IEEE80211_P2P_OPPPS_ENABLE_BIT
;
52 for (i
= 0; i
< noa_descriptors
; i
++) {
53 noa_attr
->desc
[i
].count
=
54 __le32_to_cpu(noa
->descriptors
[i
].type_count
);
55 noa_attr
->desc
[i
].duration
= noa
->descriptors
[i
].duration
;
56 noa_attr
->desc
[i
].interval
= noa
->descriptors
[i
].interval
;
57 noa_attr
->desc
[i
].start_time
= noa
->descriptors
[i
].start_time
;
60 attr_len
= 2; /* index + oppps_ctwindow */
61 attr_len
+= noa_descriptors
* sizeof(struct ieee80211_p2p_noa_desc
);
62 *noa_attr_len
= __cpu_to_le16(attr_len
);
65 static size_t ath10k_p2p_noa_ie_len_compute(const struct wmi_p2p_noa_info
*noa
)
69 if (!noa
->num_descriptors
&&
70 !(noa
->ctwindow_oppps
& WMI_P2P_OPPPS_ENABLE_BIT
))
73 len
+= 1 + 1 + 4; /* EID + len + OUI */
74 len
+= 1 + 2; /* noa attr + attr len */
75 len
+= 1 + 1; /* index + oppps_ctwindow */
76 len
+= noa
->num_descriptors
* sizeof(struct ieee80211_p2p_noa_desc
);
81 static void ath10k_p2p_noa_ie_assign(struct ath10k_vif
*arvif
, void *ie
,
84 struct ath10k
*ar
= arvif
->ar
;
86 lockdep_assert_held(&ar
->data_lock
);
88 kfree(arvif
->u
.ap
.noa_data
);
90 arvif
->u
.ap
.noa_data
= ie
;
91 arvif
->u
.ap
.noa_len
= len
;
94 static void __ath10k_p2p_noa_update(struct ath10k_vif
*arvif
,
95 const struct wmi_p2p_noa_info
*noa
)
97 struct ath10k
*ar
= arvif
->ar
;
101 lockdep_assert_held(&ar
->data_lock
);
103 ath10k_p2p_noa_ie_assign(arvif
, NULL
, 0);
105 len
= ath10k_p2p_noa_ie_len_compute(noa
);
109 ie
= kmalloc(len
, GFP_ATOMIC
);
113 ath10k_p2p_noa_ie_fill(ie
, len
, noa
);
114 ath10k_p2p_noa_ie_assign(arvif
, ie
, len
);
117 void ath10k_p2p_noa_update(struct ath10k_vif
*arvif
,
118 const struct wmi_p2p_noa_info
*noa
)
120 struct ath10k
*ar
= arvif
->ar
;
122 spin_lock_bh(&ar
->data_lock
);
123 __ath10k_p2p_noa_update(arvif
, noa
);
124 spin_unlock_bh(&ar
->data_lock
);
127 struct ath10k_p2p_noa_arg
{
129 const struct wmi_p2p_noa_info
*noa
;
132 static void ath10k_p2p_noa_update_vdev_iter(void *data
, u8
*mac
,
133 struct ieee80211_vif
*vif
)
135 struct ath10k_vif
*arvif
= ath10k_vif_to_arvif(vif
);
136 struct ath10k_p2p_noa_arg
*arg
= data
;
138 if (arvif
->vdev_id
!= arg
->vdev_id
)
141 ath10k_p2p_noa_update(arvif
, arg
->noa
);
144 void ath10k_p2p_noa_update_by_vdev_id(struct ath10k
*ar
, u32 vdev_id
,
145 const struct wmi_p2p_noa_info
*noa
)
147 struct ath10k_p2p_noa_arg arg
= {
152 ieee80211_iterate_active_interfaces_atomic(ar
->hw
,
153 IEEE80211_IFACE_ITER_NORMAL
,
154 ath10k_p2p_noa_update_vdev_iter
,