COUNTRY_CODE_MAX
};
+#define NUM_PMKID_CACHE 16
+
+typedef struct _RT_PMKID_LIST
+{
+ u8 bUsed;
+ u8 Bssid[6];
+ u8 PMKID[16];
+ u8 SsidBuf[33];
+ u8* ssid_octet;
+ u16 ssid_length;
+} RT_PMKID_LIST, *PRT_PMKID_LIST;
+
+
#include "ieee80211_r8192s.h"
struct ieee80211_device {
int bcrx_sta_key; /* use individual keys to override default keys even
* with RX of broad/multicast frames */
+ RT_PMKID_LIST PMKIDList[NUM_PMKID_CACHE];
/* Fragmentation structures */
// each streaming contain a entry
struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
}
+inline int SecIsInPMKIDList(struct ieee80211_device *ieee, u8 *bssid)
+{
+ int i = 0;
+
+ do
+ {
+ if ((ieee->PMKIDList[i].bUsed) && (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0))
+ {
+ break;
+ }
+ else
+ {
+ i++;
+ }
+ } while (i < NUM_PMKID_CACHE);
+
+ if (i == NUM_PMKID_CACHE)
+ {
+ i = -1;
+ }
+ else
+ {
+ }
+
+ return (i);
+
+}
inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
{
struct sk_buff *skb;
unsigned int cxvernum_ie_len=0;
struct ieee80211_crypt_data* crypt;
int encrypt;
+ int PMKCacheIdx;
unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
unsigned int wmm_info_len = beacon->qos_data.supported?9:0;
{
cxvernum_ie_len = 5+2;
}
+
+ PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid);
+ if (PMKCacheIdx >= 0)
+ {
+ wpa_ie_len += 18;
+ printk("[PMK cache]: WPA2 IE length: %x\n", wpa_ie_len);
+ }
+
len = sizeof(struct ieee80211_assoc_request_frame)+ 2
+ beacon->ssid_len//essid tagged val
+ rate_len//rates tagged val
tag = skb_put(skb, wpa_ie_len);
if (wpa_ie_len){
memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
+ if (PMKCacheIdx >= 0)
+ {
+ tag = skb_put(skb, 18);
+ *tag = 1;
+ *(tag + 1) = 0;
+ memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID, 16);
+ }
}
tag = skb_put(skb,wmm_info_len);
return ret;
}
+static int r8192_wx_set_pmkid(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ int i;
+ struct r8192_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device* ieee = priv->ieee80211;
+ struct iw_pmksa* pPMK = (struct iw_pmksa*)extra;
+ int intReturn = false;
+
+ switch (pPMK->cmd)
+ {
+ case IW_PMKSA_ADD:
+ for (i = 0; i < NUM_PMKID_CACHE; i++)
+ {
+ if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == 0)
+ {
+ memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
+ memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
+ ieee->PMKIDList[i].bUsed = true;
+ intReturn = true;
+ goto __EXIT__;
+ }
+ }
+
+ for (i = 0; i < NUM_PMKID_CACHE; i++)
+ {
+ if (ieee->PMKIDList[i].bUsed == false)
+ {
+ memcpy(ieee->PMKIDList[i].PMKID, pPMK->pmkid, IW_PMKID_LEN);
+ memcpy(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN);
+ ieee->PMKIDList[i].bUsed = true;
+ intReturn = true;
+ goto __EXIT__;
+ }
+ }
+ break;
+
+ case IW_PMKSA_REMOVE:
+ for (i = 0; i < NUM_PMKID_CACHE; i++)
+ {
+ if (memcmp(ieee->PMKIDList[i].Bssid, pPMK->bssid.sa_data, ETH_ALEN) == true)
+ {
+ memset(&ieee->PMKIDList[i], 0x00, sizeof(RT_PMKID_LIST));
+ intReturn = true;
+ break;
+ }
+ }
+ break;
+
+ case IW_PMKSA_FLUSH:
+ memset(&ieee->PMKIDList[0], 0x00, (sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE));
+ intReturn = true;
+ break;
+
+ default:
+ break;
+ }
+
+__EXIT__:
+ return (intReturn);
+
+}
+
static int r8192_wx_set_gen_ie(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *data, char *extra)
NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */
r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */
- NULL, /* SIOCSIWPMKSA */
+ r8192_wx_set_pmkid, /* SIOCSIWPMKSA */
NULL, /*---hole---*/
};