|
@@ -2548,6 +2548,52 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
|
|
|
+ u8 *rsn_capab)
|
|
|
+{
|
|
|
+ const u8 *rsn_ie;
|
|
|
+ size_t rsn_ie_len;
|
|
|
+ u16 cnt;
|
|
|
+
|
|
|
+ if (!beacon->tail)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
|
|
|
+ if (!rsn_ie)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ rsn_ie_len = *(rsn_ie + 1);
|
|
|
+ /* skip element id and length */
|
|
|
+ rsn_ie += 2;
|
|
|
+
|
|
|
+ /* skip version, group cipher */
|
|
|
+ if (rsn_ie_len < 6)
|
|
|
+ return -EINVAL;
|
|
|
+ rsn_ie += 6;
|
|
|
+ rsn_ie_len -= 6;
|
|
|
+
|
|
|
+ /* skip pairwise cipher suite */
|
|
|
+ if (rsn_ie_len < 2)
|
|
|
+ return -EINVAL;
|
|
|
+ cnt = *((u16 *) rsn_ie);
|
|
|
+ rsn_ie += (2 + cnt * 4);
|
|
|
+ rsn_ie_len -= (2 + cnt * 4);
|
|
|
+
|
|
|
+ /* skip akm suite */
|
|
|
+ if (rsn_ie_len < 2)
|
|
|
+ return -EINVAL;
|
|
|
+ cnt = *((u16 *) rsn_ie);
|
|
|
+ rsn_ie += (2 + cnt * 4);
|
|
|
+ rsn_ie_len -= (2 + cnt * 4);
|
|
|
+
|
|
|
+ if (rsn_ie_len < 2)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ memcpy(rsn_capab, rsn_ie, 2);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|
|
struct cfg80211_ap_settings *info)
|
|
|
{
|
|
@@ -2560,6 +2606,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|
|
struct wmi_connect_cmd p;
|
|
|
int res;
|
|
|
int i, ret;
|
|
|
+ u16 rsn_capab = 0;
|
|
|
|
|
|
ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
|
|
|
|
|
@@ -2700,6 +2747,23 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|
|
vif->next_ch_type != NL80211_CHAN_NO_HT))
|
|
|
return -EIO;
|
|
|
|
|
|
+ /*
|
|
|
+ * Get the PTKSA replay counter in the RSN IE. Supplicant
|
|
|
+ * will use the RSN IE in M3 message and firmware has to
|
|
|
+ * advertise the same in beacon/probe response. Send
|
|
|
+ * the complete RSN IE capability field to firmware
|
|
|
+ */
|
|
|
+ if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
|
|
|
+ test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
|
|
|
+ ar->fw_capabilities)) {
|
|
|
+ res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
|
|
|
+ WLAN_EID_RSN, WMI_RSN_IE_CAPB,
|
|
|
+ (const u8 *) &rsn_capab,
|
|
|
+ sizeof(rsn_capab));
|
|
|
+ if (res < 0)
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
|
|
|
if (res < 0)
|
|
|
return res;
|