ath6kl: handle probe response from P2P device in P2P GO mode
authorAarthi Thiruvengadam <athiruve@qca.qualcomm.com>
Thu, 15 Mar 2012 21:34:56 +0000 (14:34 -0700)
committerKalle Valo <kvalo@qca.qualcomm.com>
Tue, 20 Mar 2012 08:33:11 +0000 (10:33 +0200)
When the device is in P2P GO mode and in listen state, the correct behavior is
to see two different probe response frames - one from P2P device and the other
from GO. wpa_supplicant uses the same mechanism to send the frame in both cases
(ath6kl_mgmt_tx). For GO probe response, ath6kl needs to call
ath6kl_send_go_probe_resp (this will add only WSC/P2P IEs and the rest of the
IEs are filled in by the firmware). That was done based on the nw_type ==
AP_NETWORK which would work if P2P Device role were in a separate netdev. When
P2P Device and GO use the same netdev, ath6kl needs to use the special GO probe
response case only if SSID is longer than P2P wildcard SSID.

Signed-off-by: Aarthi Thiruvengadam <athiruve@qca.qualcomm.com>
Reviewed-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/core.h

index 00d3895..b605f4a 100644 (file)
@@ -2747,6 +2747,21 @@ static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
        return false;
 }
 
+/* Check if SSID length is greater than DIRECT- */
+static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
+{
+       const struct ieee80211_mgmt *mgmt;
+       mgmt = (const struct ieee80211_mgmt *) buf;
+
+       /* variable[1] contains the SSID tag length */
+       if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
+           (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
+               return true;
+       }
+
+       return false;
+}
+
 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
                          struct ieee80211_channel *chan, bool offchan,
                          enum nl80211_channel_type channel_type,
@@ -2761,11 +2776,11 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
        bool more_data, queued;
 
        mgmt = (const struct ieee80211_mgmt *) buf;
-       if (buf + len >= mgmt->u.probe_resp.variable &&
-           vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
-           ieee80211_is_probe_resp(mgmt->frame_control)) {
+       if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
+           ieee80211_is_probe_resp(mgmt->frame_control) &&
+           ath6kl_is_p2p_go_ssid(buf, len)) {
                /*
-                * Send Probe Response frame in AP mode using a separate WMI
+                * Send Probe Response frame in GO mode using a separate WMI
                 * command to allow the target to fill in the generic IEs.
                 */
                *cookie = 0; /* TX status not supported */
index f1dd890..17697eb 100644 (file)
@@ -205,6 +205,8 @@ struct ath6kl_fw_ie {
 #define ATH6KL_CONF_ENABLE_TX_BURST            BIT(3)
 #define ATH6KL_CONF_UART_DEBUG                 BIT(4)
 
+#define P2P_WILDCARD_SSID_LEN                  7 /* DIRECT- */
+
 enum wlan_low_pwr_state {
        WLAN_POWER_STATE_ON,
        WLAN_POWER_STATE_CUT_PWR,