mwifiex: append peer mac address TLV in key material command to firmware
authorAvinash Patil <patila@marvell.com>
Wed, 9 May 2012 01:30:18 +0000 (18:30 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 16 May 2012 16:46:35 +0000 (12:46 -0400)
Modify key related cfg80211 handlers to copy peer mac address for
pairwise keys. If peer mac address is not present or group keys,
it will be sent as broadcast mac address.
This would be required since hostapd downloads per peer PTK.

Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: Kiran Divekar <dkiran@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/fw.h
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sta_cmd.c
drivers/net/wireless/mwifiex/sta_ioctl.c

index ff627e1f8378c822db43ba53f2fdf6c60f123d27..e09f0c2e46ab19657b26f3ff7fa309d91e1e30d0 100644 (file)
@@ -97,8 +97,10 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
                         u8 key_index, bool pairwise, const u8 *mac_addr)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
+       const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+       const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
 
-       if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
+       if (mwifiex_set_encode(priv, NULL, 0, key_index, peer_mac, 1)) {
                wiphy_err(wiphy, "deleting the crypto keys\n");
                return -EFAULT;
        }
@@ -168,7 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
        if (!priv->sec_info.wep_enabled)
                return 0;
 
-       if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) {
+       if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) {
                wiphy_err(wiphy, "set default Tx key index\n");
                return -EFAULT;
        }
@@ -185,9 +187,11 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
                         struct key_params *params)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
+       const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+       const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
 
        if (mwifiex_set_encode(priv, params->key, params->key_len,
-                              key_index, 0)) {
+                              key_index, peer_mac, 0)) {
                wiphy_err(wiphy, "crypto keys added\n");
                return -EFAULT;
        }
@@ -947,7 +951,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
        priv->wep_key_curr_index = 0;
        priv->sec_info.encryption_mode = 0;
        priv->sec_info.is_authtype_auto = 0;
-       ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
+       ret = mwifiex_set_encode(priv, NULL, 0, 0, NULL, 1);
 
        if (mode == NL80211_IFTYPE_ADHOC) {
                /* "privacy" is set only for ad-hoc mode */
@@ -995,7 +999,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
                                " with key len %d\n", sme->key_len);
                        priv->wep_key_curr_index = sme->key_idx;
                        ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
-                                                       sme->key_idx, 0);
+                                                sme->key_idx, NULL, 0);
                }
        }
 done:
index 5f6adeb9b950ca9e7c25a7c1cd591fa1dadd5f15..39969184a3f9146636a0eb8feb5a7f660e1d23d4 100644 (file)
@@ -104,6 +104,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define TLV_TYPE_TSFTIMESTAMP       (PROPRIETARY_TLV_BASE_ID + 19)
 #define TLV_TYPE_RSSI_HIGH          (PROPRIETARY_TLV_BASE_ID + 22)
 #define TLV_TYPE_AUTH_TYPE          (PROPRIETARY_TLV_BASE_ID + 31)
+#define TLV_TYPE_STA_MAC_ADDR       (PROPRIETARY_TLV_BASE_ID + 32)
 #define TLV_TYPE_CHANNELBANDLIST    (PROPRIETARY_TLV_BASE_ID + 42)
 #define TLV_TYPE_RATE_DROP_CONTROL  (PROPRIETARY_TLV_BASE_ID + 82)
 #define TLV_TYPE_RATE_SCOPE         (PROPRIETARY_TLV_BASE_ID + 83)
@@ -1103,6 +1104,16 @@ struct host_cmd_ds_802_11_eeprom_access {
        u8 value;
 } __packed;
 
+struct host_cmd_tlv {
+       __le16 type;
+       __le16 len;
+} __packed;
+
+struct host_cmd_tlv_mac_addr {
+       struct host_cmd_tlv tlv;
+       u8 mac_addr[ETH_ALEN];
+} __packed;
+
 struct host_cmd_ds_802_11_rf_channel {
        __le16 action;
        __le16 current_channel;
index e324e29be544615565152e50a130539fba0a7b52..ed978de956d825d2b96706eaff88de0ab30e94ab 100644 (file)
@@ -935,7 +935,8 @@ int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
 int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel);
 
 int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
-                      int key_len, u8 key_index, int disable);
+                      int key_len, u8 key_index, const u8 *mac_addr,
+                      int disable);
 
 int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
 
index 3697aaa863ddd52795ad0f9e5e1f9684b8efcd36..40e025da6bc28463749b76fed338a3c335c0f1b4 100644 (file)
@@ -498,7 +498,8 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
 {
        struct host_cmd_ds_802_11_key_material *key_material =
                &cmd->params.key_material;
-       u16 key_param_len = 0;
+       struct host_cmd_tlv_mac_addr *tlv_mac;
+       u16 key_param_len = 0, cmd_size;
        int ret = 0;
        const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
@@ -614,11 +615,26 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
                        cpu_to_le16((u16) enc_key->key_len +
                                    KEYPARAMSET_FIXED_LEN);
 
-               key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
+               key_param_len = (u16)(enc_key->key_len + KEYPARAMSET_FIXED_LEN)
                                + sizeof(struct mwifiex_ie_types_header);
 
                cmd->size = cpu_to_le16(sizeof(key_material->action) + S_DS_GEN
                                        + key_param_len);
+
+               if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) {
+                       tlv_mac = (void *)((u8 *)&key_material->key_param_set +
+                                          key_param_len);
+                       tlv_mac->tlv.type = cpu_to_le16(TLV_TYPE_STA_MAC_ADDR);
+                       tlv_mac->tlv.len = cpu_to_le16(ETH_ALEN);
+                       memcpy(tlv_mac->mac_addr, enc_key->mac_addr, ETH_ALEN);
+                       cmd_size = key_param_len + S_DS_GEN +
+                                  sizeof(key_material->action) +
+                                  sizeof(struct host_cmd_tlv_mac_addr);
+               } else {
+                       cmd_size = key_param_len + S_DS_GEN +
+                                  sizeof(key_material->action);
+               }
+               cmd->size = cpu_to_le16(cmd_size);
        }
 
        return ret;
index 9265e421e7705ab0c8d226aa4377f2162eb1e369..106c449477b2924029942b9b3863b312b527d24c 100644 (file)
@@ -1219,7 +1219,8 @@ mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
  * with requisite parameters and calls the IOCTL handler.
  */
 int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
-                       int key_len, u8 key_index, int disable)
+                       int key_len, u8 key_index,
+                       const u8 *mac_addr, int disable)
 {
        struct mwifiex_ds_encrypt_key encrypt_key;
 
@@ -1229,8 +1230,12 @@ int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
                encrypt_key.key_index = key_index;
                if (key_len)
                        memcpy(encrypt_key.key_material, key, key_len);
+               if (mac_addr)
+                       memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
        } else {
                encrypt_key.key_disable = true;
+               if (mac_addr)
+                       memcpy(encrypt_key.mac_addr, mac_addr, ETH_ALEN);
        }
 
        return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);