From 0c5553b1392dea5ba5ad678790367c1275ed1172 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 15 Jun 2009 21:59:50 +0200 Subject: iwmc3200wifi: invalidate keys when changing the BSSID While associated, we have to invalidate our key cache if we clear our BSSID through siwap. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/wext.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 584c94d0f399..889194931b4e 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -82,6 +82,7 @@ static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { struct iwm_priv *iwm = ndev_to_iwm(dev); + int ret; if (iwm->conf.mode == UMAC_MODE_IBSS) return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); @@ -104,10 +105,26 @@ static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, } if (iwm->umac_profile_active) { + int i; + if (!memcmp(&iwm->umac_profile->bssid[0], iwm->bssid, ETH_ALEN)) return 0; - iwm_invalidate_mlme_profile(iwm); + /* + * If we're clearing the BSSID, and we're associated, + * we have to clear the keys as they're no longer valid. + */ + if (is_zero_ether_addr(ap_addr->sa_data)) { + for (i = 0; i < IWM_NUM_KEYS; i++) + iwm->keys[i].in_use = 0; + + } + + ret = iwm_invalidate_mlme_profile(iwm); + if (ret < 0) { + IWM_ERR(iwm, "Couldn't invalidate profile\n"); + return ret; + } } if (iwm->umac_profile->ssid.ssid_len) -- cgit v1.2.3 From 13e0fe70960e95cdea89b71aa3d046ec71efac8c Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Mon, 15 Jun 2009 21:59:52 +0200 Subject: iwmc3200wifi: cfg80211 key hooks implemetation This patch implements the new cfg80211 privacy related hooks: add/get/set_key and the set_default_key one. With this implementation we can now call the wext-compat *encode* routines and reduce our own wext code. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 172 ++++++++++++++++ drivers/net/wireless/iwmc3200wifi/commands.c | 72 +++---- drivers/net/wireless/iwmc3200wifi/commands.h | 3 +- drivers/net/wireless/iwmc3200wifi/iwm.h | 14 +- drivers/net/wireless/iwmc3200wifi/main.c | 4 +- drivers/net/wireless/iwmc3200wifi/wext.c | 286 ++------------------------- 6 files changed, 219 insertions(+), 332 deletions(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index bc89b1ef0cad..739bd9b0ddea 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -130,6 +131,173 @@ static struct ieee80211_supported_band iwm_band_5ghz = { .n_bitrates = iwm_a_rates_size, }; +static int iwm_key_init(struct iwm_key *key, u8 key_index, + const u8 *mac_addr, struct key_params *params) +{ + key->hdr.key_idx = key_index; + if (!mac_addr || is_broadcast_ether_addr(mac_addr)) { + key->hdr.multicast = 1; + memset(key->hdr.mac, 0xff, ETH_ALEN); + } else { + key->hdr.multicast = 0; + memcpy(key->hdr.mac, mac_addr, ETH_ALEN); + } + + if (params) { + if (params->key_len > WLAN_MAX_KEY_LEN || + params->seq_len > IW_ENCODE_SEQ_MAX_SIZE) + return -EINVAL; + + key->cipher = params->cipher; + key->key_len = params->key_len; + key->seq_len = params->seq_len; + memcpy(key->key, params->key, key->key_len); + memcpy(key->seq, params->seq, key->seq_len); + } + + return 0; +} + +static int iwm_reset_profile(struct iwm_priv *iwm) +{ + int ret; + + if (!iwm->umac_profile_active) + return 0; + + /* + * If there is a current active profile, but no + * default key, it's not worth trying to associate again. + */ + if (iwm->default_key < 0) + return 0; + + /* + * Here we have an active profile, but a key setting changed. + * We thus have to invalidate the current profile, and push the + * new one. Keys will be pushed when association takes place. + */ + ret = iwm_invalidate_mlme_profile(iwm); + if (ret < 0) { + IWM_ERR(iwm, "Couldn't invalidate profile\n"); + return ret; + } + + return iwm_send_mlme_profile(iwm); +} + +static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, + u8 key_index, const u8 *mac_addr, + struct key_params *params) +{ + struct iwm_priv *iwm = ndev_to_iwm(ndev); + struct iwm_key *key = &iwm->keys[key_index]; + int ret; + + IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr); + + memset(key, 0, sizeof(struct iwm_key)); + ret = iwm_key_init(key, key_index, mac_addr, params); + if (ret < 0) { + IWM_ERR(iwm, "Invalid key_params\n"); + return ret; + } + + /* + * The WEP keys can be set before or after setting the essid. + * We need to handle both cases by simply pushing the keys after + * we send the profile. + * If the profile is not set yet (i.e. we're pushing keys before + * the essid), we set the cipher appropriately. + * If the profile is set, we havent associated yet because our + * cipher was incorrectly set. So we invalidate and send the + * profile again. + */ + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) { + u8 *ucast_cipher = &iwm->umac_profile->sec.ucast_cipher; + u8 *mcast_cipher = &iwm->umac_profile->sec.mcast_cipher; + + IWM_DBG_WEXT(iwm, DBG, "WEP key\n"); + + if (key->cipher == WLAN_CIPHER_SUITE_WEP40) + *ucast_cipher = *mcast_cipher = UMAC_CIPHER_TYPE_WEP_40; + if (key->cipher == WLAN_CIPHER_SUITE_WEP104) + *ucast_cipher = *mcast_cipher = + UMAC_CIPHER_TYPE_WEP_104; + + return iwm_reset_profile(iwm); + } + + return iwm_set_key(iwm, 0, key); +} + +static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, + u8 key_index, const u8 *mac_addr, void *cookie, + void (*callback)(void *cookie, + struct key_params*)) +{ + struct iwm_priv *iwm = ndev_to_iwm(ndev); + struct iwm_key *key = &iwm->keys[key_index]; + struct key_params params; + + IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index); + + memset(¶ms, 0, sizeof(params)); + + params.cipher = key->cipher; + params.key_len = key->key_len; + params.seq_len = key->seq_len; + params.seq = key->seq; + params.key = key->key; + + callback(cookie, ¶ms); + + return key->key_len ? 0 : -ENOENT; +} + + +static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, + u8 key_index, const u8 *mac_addr) +{ + struct iwm_priv *iwm = ndev_to_iwm(ndev); + struct iwm_key *key = &iwm->keys[key_index]; + + if (!iwm->keys[key_index].key_len) { + IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index); + return 0; + } + + if (key_index == iwm->default_key) + iwm->default_key = -1; + + return iwm_set_key(iwm, 1, key); +} + +static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, + struct net_device *ndev, + u8 key_index) +{ + struct iwm_priv *iwm = ndev_to_iwm(ndev); + int ret; + + IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); + + if (!iwm->keys[key_index].key_len) { + IWM_ERR(iwm, "Key %d not used\n", key_index); + return -EINVAL; + } + + ret = iwm_set_tx_key(iwm, key_index); + if (ret < 0) + return ret; + + iwm->default_key = key_index; + + return iwm_reset_profile(iwm); +} + + int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) { struct wiphy *wiphy = iwm_to_wiphy(iwm); @@ -326,6 +494,10 @@ static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) static struct cfg80211_ops iwm_cfg80211_ops = { .change_virtual_intf = iwm_cfg80211_change_iface, + .add_key = iwm_cfg80211_add_key, + .get_key = iwm_cfg80211_get_key, + .del_key = iwm_cfg80211_del_key, + .set_default_key = iwm_cfg80211_set_default_key, .scan = iwm_cfg80211_scan, .set_wiphy_params = iwm_cfg80211_set_wiphy_params, .join_ibss = iwm_cfg80211_join_ibss, diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 337a884f52df..145f6f5ae747 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c @@ -524,9 +524,6 @@ int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx) { struct iwm_umac_tx_key_id tx_key_id; - if (!iwm->default_key || !iwm->default_key->in_use) - return -EINVAL; - tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID; tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) - sizeof(struct iwm_umac_wifi_if)); @@ -569,10 +566,9 @@ static int iwm_check_profile(struct iwm_priv *iwm) return 0; } -int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, - struct iwm_key *key) +int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key) { - int ret; + int ret = 0; u8 cmd[64], *sta_addr, *key_data, key_len; s8 key_idx; u16 cmd_size = 0; @@ -582,9 +578,6 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd; struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd; - if (set_tx_key) - iwm->default_key = key; - /* * We check if our current profile is valid. * If not, we dont push the key, we just cache them, @@ -603,8 +596,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, key_idx = key->hdr.key_idx; if (!remove) { - IWM_DBG_WEXT(iwm, DBG, "key_idx:%d set tx key:%d\n", - key_idx, set_tx_key); + IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx); IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len); IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n", key_hdr->mac, key_hdr->key_idx, key_hdr->multicast); @@ -616,8 +608,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, iwm->umac_profile->sec.auth_type, iwm->umac_profile->sec.flags); - switch (key->alg) { - case UMAC_CIPHER_TYPE_WEP_40: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY; wep40->hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_key_wep40) - @@ -631,7 +623,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, cmd_size = sizeof(struct iwm_umac_key_wep40); break; - case UMAC_CIPHER_TYPE_WEP_104: + case WLAN_CIPHER_SUITE_WEP104: wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY; wep104->hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_key_wep104) - @@ -645,7 +637,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, cmd_size = sizeof(struct iwm_umac_key_wep104); break; - case UMAC_CIPHER_TYPE_CCMP: + case WLAN_CIPHER_SUITE_CCMP: key_hdr->key_idx++; ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY; ccmp->hdr.buf_size = @@ -657,13 +649,13 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, memcpy(ccmp->key, key_data, key_len); - if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID) - memcpy(ccmp->iv_count, key->rx_seq, 6); + if (key->seq_len) + memcpy(ccmp->iv_count, key->seq, key->seq_len); cmd_size = sizeof(struct iwm_umac_key_ccmp); break; - case UMAC_CIPHER_TYPE_TKIP: + case WLAN_CIPHER_SUITE_TKIP: key_hdr->key_idx++; tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY; tkip->hdr.buf_size = @@ -680,8 +672,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE, IWM_TKIP_MIC_SIZE); - if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID) - memcpy(ccmp->iv_count, key->rx_seq, 6); + if (key->seq_len) + memcpy(ccmp->iv_count, key->seq, key->seq_len); cmd_size = sizeof(struct iwm_umac_key_tkip); break; @@ -690,8 +682,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, return -ENOTSUPP; } - if ((key->alg == UMAC_CIPHER_TYPE_CCMP) || - (key->alg == UMAC_CIPHER_TYPE_TKIP)) + if ((key->cipher == WLAN_CIPHER_SUITE_TKIP) || + (key->cipher == WLAN_CIPHER_SUITE_CCMP)) /* * UGLY_UGLY_UGLY * Copied HACK from the MWG driver. @@ -702,23 +694,11 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, schedule_timeout_interruptible(usecs_to_jiffies(300)); ret = iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1); - if (ret < 0) - goto err; - - /* - * We need a default key only if it is set and - * if we're doing WEP. - */ - if (iwm->default_key == key && - ((key->alg == UMAC_CIPHER_TYPE_WEP_40) || - (key->alg == UMAC_CIPHER_TYPE_WEP_104))) { - ret = iwm_set_tx_key(iwm, key_idx); - if (ret < 0) - goto err; - } } else { struct iwm_umac_key_remove key_remove; + IWM_DBG_WEXT(iwm, ERR, "Removing key_idx:%d\n", key_idx); + key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY; key_remove.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_key_remove) - @@ -732,13 +712,9 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, if (ret < 0) return ret; - iwm->keys[key_idx].in_use = 0; + iwm->keys[key_idx].key_len = 0; } - return 0; - - err: - kfree(key); return ret; } @@ -761,22 +737,24 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) } for (i = 0; i < IWM_NUM_KEYS; i++) - if (iwm->keys[i].in_use) { - int default_key = 0; + if (iwm->keys[i].key_len) { struct iwm_key *key = &iwm->keys[i]; - if (key == iwm->default_key) - default_key = 1; - /* Wait for the profile before sending the keys */ wait_event_interruptible_timeout(iwm->mlme_queue, (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) || test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)), 3 * HZ); - ret = iwm_set_key(iwm, 0, default_key, key); + ret = iwm_set_key(iwm, 0, key); if (ret < 0) return ret; + + if (iwm->default_key == i) { + ret = iwm_set_tx_key(iwm, i); + if (ret < 0) + return ret; + } } return 0; diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h index 36b13a130595..3510df8ff391 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.h +++ b/drivers/net/wireless/iwmc3200wifi/commands.h @@ -406,8 +406,7 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm); int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); -int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key, - struct iwm_key *key); +int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key); int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags); int iwm_send_umac_channel_list(struct iwm_priv *iwm); int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids, diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index d8d4ae2d91b0..90b05d999635 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -162,13 +162,11 @@ struct iwm_umac_key_hdr { struct iwm_key { struct iwm_umac_key_hdr hdr; - u8 in_use; - u8 alg; - u32 flags; - u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 key_len; - u8 key[32]; + u32 cipher; + u8 key[WLAN_MAX_KEY_LEN]; + u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; + int key_len; + int seq_len; }; #define IWM_RX_ID_HASH 0xff @@ -276,7 +274,7 @@ struct iwm_priv { struct iwm_tx_queue txq[IWM_TX_QUEUES]; struct iwm_key keys[IWM_NUM_KEYS]; - struct iwm_key *default_key; + s8 default_key; DECLARE_BITMAP(wifi_ntfy, WIFI_IF_NTFY_MAX); wait_queue_head_t wifi_ntfy_queue; diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c index 844872213a12..7f56c06a53db 100644 --- a/drivers/net/wireless/iwmc3200wifi/main.c +++ b/drivers/net/wireless/iwmc3200wifi/main.c @@ -230,7 +230,7 @@ int iwm_priv_init(struct iwm_priv *iwm) for (i = 0; i < IWM_NUM_KEYS; i++) memset(&iwm->keys[i], 0, sizeof(struct iwm_key)); - iwm->default_key = NULL; + iwm->default_key = -1; init_timer(&iwm->watchdog); iwm->watchdog.function = iwm_watchdog; @@ -709,7 +709,7 @@ int __iwm_down(struct iwm_priv *iwm) iwm->umac_profile = NULL; iwm_bss_list_clean(iwm); - iwm->default_key = NULL; + iwm->default_key = -1; iwm->core_enabled = 0; ret = iwm_bus_disable(iwm); diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 889194931b4e..3062f37bbe95 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -84,6 +84,8 @@ static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, struct iwm_priv *iwm = ndev_to_iwm(dev); int ret; + IWM_DBG_WEXT(iwm, DBG, "Set BSSID: %pM\n", ap_addr->sa_data); + if (iwm->conf.mode == UMAC_MODE_IBSS) return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); @@ -116,8 +118,7 @@ static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, */ if (is_zero_ether_addr(ap_addr->sa_data)) { for (i = 0; i < IWM_NUM_KEYS; i++) - iwm->keys[i].in_use = 0; - + iwm->keys[i].key_len = 0; } ret = iwm_invalidate_mlme_profile(iwm); @@ -163,6 +164,8 @@ static int iwm_wext_siwessid(struct net_device *dev, size_t len = data->length; int ret; + IWM_DBG_WEXT(iwm, DBG, "Set ESSID: >%s<\n", ssid); + if (iwm->conf.mode == UMAC_MODE_IBSS) return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); @@ -212,27 +215,6 @@ static int iwm_wext_giwessid(struct net_device *dev, return 0; } -static struct iwm_key * -iwm_key_init(struct iwm_priv *iwm, u8 key_idx, bool in_use, - struct iw_encode_ext *ext, u8 alg) -{ - struct iwm_key *key = &iwm->keys[key_idx]; - - memset(key, 0, sizeof(struct iwm_key)); - memcpy(key->hdr.mac, ext->addr.sa_data, ETH_ALEN); - key->hdr.key_idx = key_idx; - if (is_broadcast_ether_addr(ext->addr.sa_data)) - key->hdr.multicast = 1; - - key->in_use = in_use; - key->flags = ext->ext_flags; - key->alg = alg; - key->key_len = ext->key_len; - memcpy(key->key, ext->key, ext->key_len); - - return key; -} - static int iwm_wext_giwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rate, char *extra) @@ -244,184 +226,6 @@ static int iwm_wext_giwrate(struct net_device *dev, return 0; } -static int iwm_wext_siwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *key_buf) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - struct iwm_key *uninitialized_var(key); - int idx, i, uninitialized_var(alg), remove = 0, ret; - - IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", erq->length); - IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags); - - if (!iwm->umac_profile) { - IWM_ERR(iwm, "UMAC profile not allocated yet\n"); - return -ENODEV; - } - - if (erq->length == WLAN_KEY_LEN_WEP40) { - alg = UMAC_CIPHER_TYPE_WEP_40; - iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_40; - iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_40; - } else if (erq->length == WLAN_KEY_LEN_WEP104) { - alg = UMAC_CIPHER_TYPE_WEP_104; - iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_104; - iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_104; - } - - if (erq->flags & IW_ENCODE_RESTRICTED) - iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK; - else - iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN; - - idx = erq->flags & IW_ENCODE_INDEX; - if (idx == 0) { - if (iwm->default_key) - for (i = 0; i < IWM_NUM_KEYS; i++) { - if (iwm->default_key == &iwm->keys[i]) { - idx = i; - break; - } - } - else - iwm->default_key = &iwm->keys[idx]; - } else if (idx < 1 || idx > 4) { - return -EINVAL; - } else - idx--; - - if (erq->flags & IW_ENCODE_DISABLED) - remove = 1; - else if (erq->length == 0) { - if (!iwm->keys[idx].in_use) - return -EINVAL; - iwm->default_key = &iwm->keys[idx]; - } - - if (erq->length) { - key = &iwm->keys[idx]; - memset(key, 0, sizeof(struct iwm_key)); - memset(key->hdr.mac, 0xff, ETH_ALEN); - key->hdr.key_idx = idx; - key->hdr.multicast = 1; - key->in_use = !remove; - key->alg = alg; - key->key_len = erq->length; - memcpy(key->key, key_buf, erq->length); - - IWM_DBG_WEXT(iwm, DBG, "Setting key %d, default: %d\n", - idx, !!iwm->default_key); - } - - if (remove) { - if ((erq->flags & IW_ENCODE_NOKEY) || (erq->length == 0)) { - int j; - for (j = 0; j < IWM_NUM_KEYS; j++) - if (iwm->keys[j].in_use) { - struct iwm_key *k = &iwm->keys[j]; - - k->in_use = 0; - ret = iwm_set_key(iwm, remove, 0, k); - if (ret < 0) - return ret; - } - - iwm->umac_profile->sec.ucast_cipher = - UMAC_CIPHER_TYPE_NONE; - iwm->umac_profile->sec.mcast_cipher = - UMAC_CIPHER_TYPE_NONE; - iwm->umac_profile->sec.auth_type = - UMAC_AUTH_TYPE_OPEN; - - return 0; - } else { - key->in_use = 0; - return iwm_set_key(iwm, remove, 0, key); - } - } - - /* - * If we havent set a profile yet, we cant set keys. - * Keys will be pushed after we're associated. - */ - if (!iwm->umac_profile_active) - return 0; - - /* - * If there is a current active profile, but no - * default key, it's not worth trying to associate again. - */ - if (!iwm->default_key) - return 0; - - /* - * Here we have an active profile, but a key setting changed. - * We thus have to invalidate the current profile, and push the - * new one. Keys will be pushed when association takes place. - */ - ret = iwm_invalidate_mlme_profile(iwm); - if (ret < 0) { - IWM_ERR(iwm, "Couldn't invalidate profile\n"); - return ret; - } - - return iwm_send_mlme_profile(iwm); -} - -static int iwm_wext_giwencode(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *key) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - int idx, i; - - idx = erq->flags & IW_ENCODE_INDEX; - if (idx < 1 || idx > 4) { - idx = -1; - if (!iwm->default_key) { - erq->length = 0; - erq->flags |= IW_ENCODE_NOKEY; - return 0; - } else - for (i = 0; i < IWM_NUM_KEYS; i++) { - if (iwm->default_key == &iwm->keys[i]) { - idx = i; - break; - } - } - if (idx < 0) - return -EINVAL; - } else - idx--; - - erq->flags = idx + 1; - - if (!iwm->keys[idx].in_use) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - - memcpy(key, iwm->keys[idx].key, - min_t(int, erq->length, iwm->keys[idx].key_len)); - erq->length = iwm->keys[idx].key_len; - erq->flags |= IW_ENCODE_ENABLED; - - if (iwm->umac_profile->mode == UMAC_MODE_BSS) { - switch (iwm->umac_profile->sec.auth_type) { - case UMAC_AUTH_TYPE_OPEN: - erq->flags |= IW_ENCODE_OPEN; - break; - default: - erq->flags |= IW_ENCODE_RESTRICTED; - break; - } - } - - return 0; -} - static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version) { if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) @@ -481,6 +285,8 @@ static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt) { u8 *auth_type = &iwm->umac_profile->sec.auth_type; + IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt); + if (key_mgt == IW_AUTH_KEY_MGMT_802_1X) *auth_type = UMAC_AUTH_TYPE_8021X; else if (key_mgt == IW_AUTH_KEY_MGMT_PSK) { @@ -530,6 +336,8 @@ static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg) { u8 *auth_type = &iwm->umac_profile->sec.auth_type; + IWM_DBG_WEXT(iwm, DBG, "auth_alg: 0x%x\n", auth_alg); + switch (auth_alg) { case IW_AUTH_ALG_OPEN_SYSTEM: *auth_type = UMAC_AUTH_TYPE_OPEN; @@ -541,6 +349,7 @@ static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg) return -EINVAL; *auth_type = UMAC_AUTH_TYPE_RSNA_PSK; } else { + IWM_DBG_WEXT(iwm, DBG, "WEP shared key\n"); *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK; } break; @@ -603,75 +412,6 @@ static int iwm_wext_giwauth(struct net_device *dev, return 0; } -static int iwm_wext_siwencodeext(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *erq, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - struct iwm_key *key; - struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; - int uninitialized_var(alg), idx, i, remove = 0; - - IWM_DBG_WEXT(iwm, DBG, "alg: 0x%x\n", ext->alg); - IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", ext->key_len); - IWM_DBG_WEXT(iwm, DBG, "ext_flags: 0x%x\n", ext->ext_flags); - IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags); - IWM_DBG_WEXT(iwm, DBG, "length: 0x%x\n", erq->length); - - switch (ext->alg) { - case IW_ENCODE_ALG_NONE: - remove = 1; - break; - case IW_ENCODE_ALG_WEP: - if (ext->key_len == WLAN_KEY_LEN_WEP40) - alg = UMAC_CIPHER_TYPE_WEP_40; - else if (ext->key_len == WLAN_KEY_LEN_WEP104) - alg = UMAC_CIPHER_TYPE_WEP_104; - else { - IWM_ERR(iwm, "Invalid key length: %d\n", ext->key_len); - return -EINVAL; - } - - break; - case IW_ENCODE_ALG_TKIP: - alg = UMAC_CIPHER_TYPE_TKIP; - break; - case IW_ENCODE_ALG_CCMP: - alg = UMAC_CIPHER_TYPE_CCMP; - break; - default: - return -EOPNOTSUPP; - } - - idx = erq->flags & IW_ENCODE_INDEX; - - if (idx == 0) { - if (iwm->default_key) - for (i = 0; i < IWM_NUM_KEYS; i++) { - if (iwm->default_key == &iwm->keys[i]) { - idx = i; - break; - } - } - } else if (idx < 1 || idx > 4) { - return -EINVAL; - } else - idx--; - - if (erq->flags & IW_ENCODE_DISABLED) - remove = 1; - else if ((erq->length == 0) || - (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) { - iwm->default_key = &iwm->keys[idx]; - if (iwm->umac_profile_active && ext->alg == IW_ENCODE_ALG_WEP) - return iwm_set_tx_key(iwm, idx); - } - - key = iwm_key_init(iwm, idx, !remove, ext, alg); - - return iwm_set_key(iwm, remove, !iwm->default_key, key); -} - static const iw_handler iwm_handlers[] = { (iw_handler) NULL, /* SIOCSIWCOMMIT */ @@ -716,8 +456,8 @@ static const iw_handler iwm_handlers[] = (iw_handler) NULL, /* SIOCGIWTXPOW */ (iw_handler) NULL, /* SIOCSIWRETRY */ (iw_handler) NULL, /* SIOCGIWRETRY */ - (iw_handler) iwm_wext_siwencode, /* SIOCSIWENCODE */ - (iw_handler) iwm_wext_giwencode, /* SIOCGIWENCODE */ + (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ + (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ (iw_handler) iwm_wext_siwpower, /* SIOCSIWPOWER */ (iw_handler) iwm_wext_giwpower, /* SIOCGIWPOWER */ (iw_handler) NULL, /* -- hole -- */ @@ -726,7 +466,7 @@ static const iw_handler iwm_handlers[] = (iw_handler) NULL, /* SIOCGIWGENIE */ (iw_handler) iwm_wext_siwauth, /* SIOCSIWAUTH */ (iw_handler) iwm_wext_giwauth, /* SIOCGIWAUTH */ - (iw_handler) iwm_wext_siwencodeext, /* SIOCSIWENCODEEXT */ + (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ (iw_handler) NULL, /* SIOCGIWENCODEEXT */ (iw_handler) NULL, /* SIOCSIWPMKSA */ (iw_handler) NULL, /* -- hole -- */ -- cgit v1.2.3 From 257862f3faef397f1a677ae6a5a1828fa00a97b1 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Mon, 15 Jun 2009 21:59:56 +0200 Subject: iwmc3200wifi: rfkill cleanup The patch cleans up the unused rfkill related structures and flags. It also adds wext and cfg80211 handlers for txpower auto and off so that software rfkill could be issued by user space. Signed-off-by: Zhu Yi Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwmc3200wifi/iwm.h | 7 +------ drivers/net/wireless/iwmc3200wifi/netdev.c | 12 ++---------- drivers/net/wireless/iwmc3200wifi/rx.c | 18 +++++++++--------- drivers/net/wireless/iwmc3200wifi/sdio.c | 6 +----- drivers/net/wireless/iwmc3200wifi/wext.c | 4 ++-- 6 files changed, 39 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 0cdd7ef68b78..d0629d4757d7 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -500,6 +500,28 @@ static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return 0; } +static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, + enum tx_power_setting type, int dbm) +{ + switch (type) { + case TX_POWER_AUTOMATIC: + return 0; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) +{ + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + + *dbm = iwm->txpower; + + return 0; +} + static struct cfg80211_ops iwm_cfg80211_ops = { .change_virtual_intf = iwm_cfg80211_change_iface, .add_key = iwm_cfg80211_add_key, @@ -510,6 +532,8 @@ static struct cfg80211_ops iwm_cfg80211_ops = { .set_wiphy_params = iwm_cfg80211_set_wiphy_params, .join_ibss = iwm_cfg80211_join_ibss, .leave_ibss = iwm_cfg80211_leave_ibss, + .set_tx_power = iwm_cfg80211_set_txpower, + .get_tx_power = iwm_cfg80211_get_txpower, }; struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev) diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 90b05d999635..4da57f737f27 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -184,10 +184,6 @@ struct iwm_key { #define IWM_STATUS_ASSOCIATING 3 #define IWM_STATUS_ASSOCIATED 4 -#define IWM_RADIO_RFKILL_OFF 0 -#define IWM_RADIO_RFKILL_HW 1 -#define IWM_RADIO_RFKILL_SW 2 - struct iwm_tx_queue { int id; struct sk_buff_head queue; @@ -221,7 +217,6 @@ struct iwm_priv { struct iwm_conf conf; unsigned long status; - unsigned long radio; struct list_head pending_notif; wait_queue_head_t notif_queue; @@ -240,6 +235,7 @@ struct iwm_priv { u8 bssid[ETH_ALEN]; u8 channel; u16 rate; + u32 txpower; struct iwm_sta_info sta_table[IWM_STA_TABLE_NUM]; struct list_head bss_list; @@ -290,7 +286,6 @@ struct iwm_priv { struct timer_list watchdog; struct work_struct reset_worker; struct mutex mutex; - struct rfkill *rfkill; char private[0] __attribute__((__aligned__(NETDEV_ALIGN))); }; diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index d4deb4b471e5..e94e96955b99 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -55,23 +55,15 @@ static int iwm_open(struct net_device *ndev) { struct iwm_priv *iwm = ndev_to_iwm(ndev); - int ret = 0; - - if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio)) - ret = iwm_up(iwm); - return ret; + return iwm_up(iwm); } static int iwm_stop(struct net_device *ndev) { struct iwm_priv *iwm = ndev_to_iwm(ndev); - int ret = 0; - - if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio)) - ret = iwm_down(iwm); - return ret; + return iwm_down(iwm); } /* diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 49a8be7c5396..55871da695a9 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -143,17 +143,18 @@ static int iwm_ntf_init_complete(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size, struct iwm_wifi_cmd *cmd) { + struct wiphy *wiphy = iwm_to_wiphy(iwm); struct iwm_umac_notif_init_complete *init_complete = (struct iwm_umac_notif_init_complete *)(buf); u16 status = le16_to_cpu(init_complete->status); + bool blocked = (status == UMAC_NTFY_INIT_COMPLETE_STATUS_ERR); - if (status == UMAC_NTFY_INIT_COMPLETE_STATUS_ERR) { + if (blocked) IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is on (radio off)\n"); - set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio); - } else { + else IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is off (radio on)\n"); - clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio); - } + + wiphy_rfkill_set_hw_state(wiphy, blocked); return 0; } @@ -875,6 +876,7 @@ static int iwm_ntf_statistics(struct iwm_priv *iwm, u8 *buf, /* UMAC passes rate info multiplies by 2 */ iwm->rate = max_rate >> 1; } + iwm->txpower = le32_to_cpu(stats->tx_power); wstats->status = 0; @@ -1015,6 +1017,7 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf, static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size, struct iwm_wifi_cmd *cmd) { + struct wiphy *wiphy = iwm_to_wiphy(iwm); struct iwm_lmac_card_state *state = (struct iwm_lmac_card_state *) (buf + sizeof(struct iwm_umac_wifi_in_hdr)); u32 flags = le32_to_cpu(state->flags); @@ -1023,10 +1026,7 @@ static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf, flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF", flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF"); - if (flags & IWM_CARD_STATE_HW_DISABLED) - set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio); - else - clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio); + wiphy_rfkill_set_hw_state(wiphy, flags & IWM_CARD_STATE_HW_DISABLED); return 0; } diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c index 916681837fd2..b93f620ee4f1 100644 --- a/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/drivers/net/wireless/iwmc3200wifi/sdio.c @@ -506,11 +506,7 @@ static struct sdio_driver iwm_sdio_driver = { static int __init iwm_sdio_init_module(void) { - int ret; - - ret = sdio_register_driver(&iwm_sdio_driver); - - return ret; + return sdio_register_driver(&iwm_sdio_driver); } static void __exit iwm_sdio_exit_module(void) diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 3062f37bbe95..973457383c11 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -452,8 +452,8 @@ static const iw_handler iwm_handlers[] = (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) NULL, /* SIOCSIWTXPOW */ - (iw_handler) NULL, /* SIOCGIWTXPOW */ + (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */ + (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */ (iw_handler) NULL, /* SIOCSIWRETRY */ (iw_handler) NULL, /* SIOCGIWRETRY */ (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ -- cgit v1.2.3 From bc92afd92088ab41223383cc6863ab4792533c54 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 1 Jul 2009 21:26:57 +0200 Subject: cfg80211: implement iwpower Just on/off and timeout, and with a hacky cfg80211 method until we figure out what we want, though this is probably sufficient as we want to use pm_qos for wifi everywhere. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 22 +++++++++ drivers/net/wireless/iwmc3200wifi/wext.c | 47 +------------------ include/net/cfg80211.h | 13 ++++++ net/mac80211/Kconfig | 16 ------- net/mac80211/cfg.c | 26 +++++++++++ net/mac80211/mlme.c | 5 -- net/mac80211/wext.c | 70 +--------------------------- net/wireless/Kconfig | 16 +++++++ net/wireless/core.c | 11 ++++- net/wireless/wext-compat.c | 60 ++++++++++++++++++++++++ 10 files changed, 151 insertions(+), 135 deletions(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index d0629d4757d7..54bebba8e27e 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -522,6 +522,27 @@ static int iwm_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) return 0; } +static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy, + struct net_device *dev, + bool enabled, int timeout) +{ + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + u32 power_index; + + if (enabled) + power_index = IWM_POWER_INDEX_DEFAULT; + else + power_index = IWM_POWER_INDEX_MIN; + + if (power_index == iwm->conf.power_index) + return 0; + + iwm->conf.power_index = power_index; + + return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, + CFG_POWER_INDEX, iwm->conf.power_index); +} + static struct cfg80211_ops iwm_cfg80211_ops = { .change_virtual_intf = iwm_cfg80211_change_iface, .add_key = iwm_cfg80211_add_key, @@ -534,6 +555,7 @@ static struct cfg80211_ops iwm_cfg80211_ops = { .leave_ibss = iwm_cfg80211_leave_ibss, .set_tx_power = iwm_cfg80211_set_txpower, .get_tx_power = iwm_cfg80211_get_txpower, + .set_power_mgmt = iwm_cfg80211_set_power_mgmt, }; struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev) diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 973457383c11..2e7eaf96cf93 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -238,49 +238,6 @@ static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version) return 0; } -static int iwm_wext_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - u32 power_index; - - if (wrq->disabled) { - power_index = IWM_POWER_INDEX_MIN; - goto set; - } else - power_index = IWM_POWER_INDEX_DEFAULT; - - switch (wrq->flags & IW_POWER_MODE) { - case IW_POWER_ON: - case IW_POWER_MODE: - case IW_POWER_ALL_R: - break; - default: - return -EINVAL; - } - - set: - if (power_index == iwm->conf.power_index) - return 0; - - iwm->conf.power_index = power_index; - - return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, - CFG_POWER_INDEX, iwm->conf.power_index); -} - -static int iwm_wext_giwpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - wrqu->power.disabled = (iwm->conf.power_index == IWM_POWER_INDEX_MIN); - - return 0; -} - static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt) { u8 *auth_type = &iwm->umac_profile->sec.auth_type; @@ -458,8 +415,8 @@ static const iw_handler iwm_handlers[] = (iw_handler) NULL, /* SIOCGIWRETRY */ (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ - (iw_handler) iwm_wext_siwpower, /* SIOCSIWPOWER */ - (iw_handler) iwm_wext_giwpower, /* SIOCGIWPOWER */ + (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */ + (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* SIOCSIWGENIE */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 07085216532d..82b7d804f6da 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1023,6 +1023,10 @@ struct cfg80211_ops { #ifdef CONFIG_NL80211_TESTMODE int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); #endif + + /* some temporary stuff to finish wext */ + int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout); }; /* @@ -1262,6 +1266,8 @@ struct wireless_dev { u8 bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; s8 default_key, default_mgmt_key; + bool ps; + int ps_timeout; } wext; #endif }; @@ -1606,6 +1612,13 @@ int cfg80211_wext_giwtxpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *data, char *keybuf); +int cfg80211_wext_siwpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrq, char *extra); +int cfg80211_wext_giwpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrq, char *extra); + /* * callbacks for asynchronous cfg80211 methods, notification * functions and BSS handling helpers diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index ba2643a43c73..41a32cd919af 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -14,22 +14,6 @@ config MAC80211 comment "CFG80211 needs to be enabled for MAC80211" depends on CFG80211=n -config MAC80211_DEFAULT_PS - bool "enable powersave by default" - depends on MAC80211 - default y - help - This option enables powersave mode by default. - - If this causes your applications to misbehave you should fix your - applications instead -- they need to register their network - latency requirement, see Documentation/power/pm_qos_interface.txt. - -config MAC80211_DEFAULT_PS_VALUE - int - default 1 if MAC80211_DEFAULT_PS - default 0 - menu "Rate control algorithm selection" depends on MAC80211 != n diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 03de4024597a..8c7b2cdbeeda 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1388,6 +1388,31 @@ int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) } #endif +static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, + bool enabled, int timeout) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_conf *conf = &local->hw.conf; + + if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) + return -EOPNOTSUPP; + + if (enabled == sdata->u.mgd.powersave && + timeout == conf->dynamic_ps_timeout) + return 0; + + sdata->u.mgd.powersave = enabled; + conf->dynamic_ps_timeout = timeout; + + if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); + + ieee80211_recalc_ps(local, -1); + + return 0; +} + struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1431,4 +1456,5 @@ struct cfg80211_ops mac80211_config_ops = { .get_tx_power = ieee80211_get_tx_power, .rfkill_poll = ieee80211_rfkill_poll, CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) + .set_power_mgmt = ieee80211_set_power_mgmt, }; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fbb93a70ddc7..2a7860009f9c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2360,11 +2360,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) ifmgd->flags |= IEEE80211_STA_WMM_ENABLED; hw_flags = sdata->local->hw.flags; - - if (hw_flags & IEEE80211_HW_SUPPORTS_PS) { - ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE; - sdata->local->hw.conf.dynamic_ps_timeout = 500; - } } /* configuration hooks */ diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index d4e61dc903e8..f77929802c7a 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -255,72 +255,6 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev, return 0; } -static int ieee80211_ioctl_siwpower(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *wrq, - char *extra) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_conf *conf = &local->hw.conf; - int timeout = 0; - bool ps; - - if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) - return -EOPNOTSUPP; - - if (sdata->vif.type != NL80211_IFTYPE_STATION) - return -EINVAL; - - if (wrq->disabled) { - ps = false; - timeout = 0; - goto set; - } - - switch (wrq->flags & IW_POWER_MODE) { - case IW_POWER_ON: /* If not specified */ - case IW_POWER_MODE: /* If set all mask */ - case IW_POWER_ALL_R: /* If explicitely state all */ - ps = true; - break; - default: /* Otherwise we ignore */ - return -EINVAL; - } - - if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT)) - return -EINVAL; - - if (wrq->flags & IW_POWER_TIMEOUT) - timeout = wrq->value / 1000; - - set: - if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout) - return 0; - - sdata->u.mgd.powersave = ps; - conf->dynamic_ps_timeout = timeout; - - if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); - - ieee80211_recalc_ps(local, -1); - - return 0; -} - -static int ieee80211_ioctl_giwpower(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, - char *extra) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - wrqu->power.disabled = !sdata->u.mgd.powersave; - - return 0; -} - /* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev) { @@ -436,8 +370,8 @@ static const iw_handler ieee80211_handler[] = (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ - (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ - (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ + (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */ + (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 040263118a20..c6031d5b135f 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig @@ -26,6 +26,22 @@ config CFG80211_REG_DEBUG If unsure, say N. +config CFG80211_DEFAULT_PS + bool "enable powersave by default" + depends on CFG80211 + default y + help + This option enables powersave mode by default. + + If this causes your applications to misbehave you should fix your + applications instead -- they need to register their network + latency requirement, see Documentation/power/pm_qos_interface.txt. + +config CFG80211_DEFAULT_PS_VALUE + int + default 1 if CFG80211_DEFAULT_PS + default 0 + config CFG80211_DEBUGFS bool "cfg80211 DebugFS entries" depends on CFG80211 && DEBUG_FS diff --git a/net/wireless/core.c b/net/wireless/core.c index e2f80dd0e4a6..413d291d07d7 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -550,12 +550,21 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, } wdev->netdev = dev; wdev->sme_state = CFG80211_SME_IDLE; + mutex_unlock(&rdev->devlist_mtx); #ifdef CONFIG_WIRELESS_EXT wdev->wext.default_key = -1; wdev->wext.default_mgmt_key = -1; wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; + wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE; + wdev->wext.ps_timeout = 500; + if (rdev->ops->set_power_mgmt) + if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, + wdev->wext.ps, + wdev->wext.ps_timeout)) { + /* assume this means it's off */ + wdev->wext.ps = false; + } #endif - mutex_unlock(&rdev->devlist_mtx); break; case NETDEV_GOING_DOWN: if (!wdev->ssid_len) diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 02f052fc1808..2e1ab78fb0d7 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -987,3 +987,63 @@ int cfg80211_wext_giwauth(struct net_device *dev, return -EOPNOTSUPP; } EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth); + +int cfg80211_wext_siwpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrq, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + bool ps = wdev->wext.ps; + int timeout = wdev->wext.ps_timeout; + int err; + + if (wdev->iftype != NL80211_IFTYPE_STATION) + return -EINVAL; + + if (!rdev->ops->set_power_mgmt) + return -EOPNOTSUPP; + + if (wrq->disabled) { + ps = false; + } else { + switch (wrq->flags & IW_POWER_MODE) { + case IW_POWER_ON: /* If not specified */ + case IW_POWER_MODE: /* If set all mask */ + case IW_POWER_ALL_R: /* If explicitely state all */ + ps = true; + break; + default: /* Otherwise we ignore */ + return -EINVAL; + } + + if (wrq->flags & ~(IW_POWER_MODE | IW_POWER_TIMEOUT)) + return -EINVAL; + + if (wrq->flags & IW_POWER_TIMEOUT) + timeout = wrq->value / 1000; + } + + err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, ps, timeout); + if (err) + return err; + + wdev->wext.ps = ps; + wdev->wext.ps_timeout = timeout; + + return 0; + +} +EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower); + +int cfg80211_wext_giwpower(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrq, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + wrq->disabled = !wdev->wext.ps; + + return 0; +} +EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); -- cgit v1.2.3 From 9967d46aa5ba065650d3352ab5d906f56ba17648 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 16 Jul 2009 17:34:10 +0800 Subject: iwmc3200wifi: cfg80211 managed mode port This patch ports iwmc3200wifi to the cfg80211 managed mode API. Signed-off-by: Samuel Ortiz Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/cfg80211.c | 195 ++++++++++++++++ drivers/net/wireless/iwmc3200wifi/rx.c | 16 +- drivers/net/wireless/iwmc3200wifi/wext.c | 320 +++------------------------ 3 files changed, 239 insertions(+), 292 deletions(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 0aa389564c71..ee4031764389 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -305,6 +305,25 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, return iwm_reset_profile(iwm); } +int iwm_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + u8 *mac, struct station_info *sinfo) +{ + struct iwm_priv *iwm = ndev_to_iwm(ndev); + + if (memcmp(mac, iwm->bssid, ETH_ALEN)) + return -ENOENT; + + sinfo->filled |= STATION_INFO_TX_BITRATE; + sinfo->txrate.legacy = iwm->rate * 10; + + if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) { + sinfo->filled |= STATION_INFO_SIGNAL; + sinfo->signal = iwm->wstats.qual.level; + } + + return 0; +} + int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) { @@ -500,6 +519,179 @@ static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) return 0; } +static int iwm_set_auth_type(struct iwm_priv *iwm, + enum nl80211_auth_type sme_auth_type) +{ + u8 *auth_type = &iwm->umac_profile->sec.auth_type; + + switch (sme_auth_type) { + case NL80211_AUTHTYPE_AUTOMATIC: + case NL80211_AUTHTYPE_OPEN_SYSTEM: + IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n"); + *auth_type = UMAC_AUTH_TYPE_OPEN; + break; + case NL80211_AUTHTYPE_SHARED_KEY: + if (iwm->umac_profile->sec.flags & + (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) { + IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n"); + *auth_type = UMAC_AUTH_TYPE_RSNA_PSK; + } else { + IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n"); + *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK; + } + + break; + default: + IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type); + return -ENOTSUPP; + } + + return 0; +} + +static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version) +{ + if (!wpa_version) { + iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE; + return 0; + } + + if (wpa_version & NL80211_WPA_VERSION_2) + iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK; + + if (wpa_version & NL80211_WPA_VERSION_1) + iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK; + + return 0; +} + +static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast) +{ + u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher : + &iwm->umac_profile->sec.mcast_cipher; + + if (!cipher) { + *profile_cipher = UMAC_CIPHER_TYPE_NONE; + return 0; + } + + switch (cipher) { + case IW_AUTH_CIPHER_NONE: + *profile_cipher = UMAC_CIPHER_TYPE_NONE; + break; + case WLAN_CIPHER_SUITE_WEP40: + *profile_cipher = UMAC_CIPHER_TYPE_WEP_40; + break; + case WLAN_CIPHER_SUITE_WEP104: + *profile_cipher = UMAC_CIPHER_TYPE_WEP_104; + break; + case WLAN_CIPHER_SUITE_TKIP: + *profile_cipher = UMAC_CIPHER_TYPE_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + *profile_cipher = UMAC_CIPHER_TYPE_CCMP; + break; + default: + IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher); + return -ENOTSUPP; + } + + return 0; +} + +static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt) +{ + u8 *auth_type = &iwm->umac_profile->sec.auth_type; + + IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt); + + if (key_mgt == WLAN_AKM_SUITE_8021X) + *auth_type = UMAC_AUTH_TYPE_8021X; + else if (key_mgt == WLAN_AKM_SUITE_PSK) { + if (iwm->umac_profile->sec.flags & + (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) + *auth_type = UMAC_AUTH_TYPE_RSNA_PSK; + else + *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK; + } else { + IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt); + return -EINVAL; + } + + return 0; +} + + +static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_connect_params *sme) +{ + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + struct ieee80211_channel *chan = sme->channel; + int ret; + + if (!test_bit(IWM_STATUS_READY, &iwm->status)) + return -EIO; + + if (!sme->ssid) + return -EINVAL; + + if (chan) + iwm->channel = + ieee80211_frequency_to_channel(chan->center_freq); + + iwm->umac_profile->ssid.ssid_len = sme->ssid_len; + memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len); + + if (sme->bssid) { + IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid); + memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN); + iwm->umac_profile->bss_num = 1; + } else { + memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN); + iwm->umac_profile->bss_num = 0; + } + + ret = iwm_set_auth_type(iwm, sme->auth_type); + if (ret < 0) + return ret; + + ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions); + if (ret < 0) + return ret; + + if (sme->crypto.n_ciphers_pairwise) { + ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0], + true); + if (ret < 0) + return ret; + } + + ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false); + if (ret < 0) + return ret; + + if (sme->crypto.n_akm_suites) { + ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]); + if (ret < 0) + return ret; + } + + return iwm_send_mlme_profile(iwm); +} + +static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, + u16 reason_code) +{ + struct iwm_priv *iwm = wiphy_to_iwm(wiphy); + + IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active); + + if (iwm->umac_profile_active) + return iwm_invalidate_mlme_profile(iwm); + + return 0; +} + static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, enum tx_power_setting type, int dbm) { @@ -549,8 +741,11 @@ static struct cfg80211_ops iwm_cfg80211_ops = { .get_key = iwm_cfg80211_get_key, .del_key = iwm_cfg80211_del_key, .set_default_key = iwm_cfg80211_set_default_key, + .get_station = iwm_cfg80211_get_station, .scan = iwm_cfg80211_scan, .set_wiphy_params = iwm_cfg80211_set_wiphy_params, + .connect = iwm_cfg80211_connect, + .disconnect = iwm_cfg80211_disconnect, .join_ibss = iwm_cfg80211_join_ibss, .leave_ibss = iwm_cfg80211_leave_ibss, .set_tx_power = iwm_cfg80211_set_txpower, diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 218933b8800b..82b572a6fc0b 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -503,13 +503,10 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, { struct iwm_umac_notif_assoc_complete *complete = (struct iwm_umac_notif_assoc_complete *)buf; - union iwreq_data wrqu; IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n", complete->bssid, complete->status); - memset(&wrqu, 0, sizeof(wrqu)); - clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status); switch (le32_to_cpu(complete->status)) { @@ -520,7 +517,10 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, iwm_link_on(iwm); - memcpy(wrqu.ap_addr.sa_data, complete->bssid, ETH_ALEN); + cfg80211_connect_result(iwm_to_ndev(iwm), + complete->bssid, + NULL, 0, NULL, 0, + WLAN_STATUS_SUCCESS, GFP_KERNEL); break; case UMAC_ASSOC_COMPLETE_FAILURE: clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); @@ -528,6 +528,11 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, iwm->channel = 0; iwm_link_off(iwm); + + cfg80211_connect_result(iwm_to_ndev(iwm), complete->bssid, + NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); default: break; } @@ -537,9 +542,6 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, return 0; } - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(iwm_to_ndev(iwm), SIOCGIWAP, &wrqu, NULL); - return 0; } diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 2e7eaf96cf93..c3c90d5963bf 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -21,31 +21,11 @@ * */ -#include -#include #include -#include -#include #include -#include #include "iwm.h" -#include "umac.h" #include "commands.h" -#include "debug.h" - -static struct iw_statistics *iwm_get_wireless_stats(struct net_device *dev) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - struct iw_statistics *wstats = &iwm->wstats; - - if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) { - memset(wstats, 0, sizeof(struct iw_statistics)); - wstats->qual.updated = IW_QUAL_ALL_INVALID; - } - - return wstats; -} static int iwm_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, @@ -53,14 +33,12 @@ static int iwm_wext_siwfreq(struct net_device *dev, { struct iwm_priv *iwm = ndev_to_iwm(dev); - if (freq->flags == IW_FREQ_AUTO) - return 0; - - /* frequency/channel can only be set in IBSS mode */ - if (iwm->conf.mode != UMAC_MODE_IBSS) + switch (iwm->conf.mode) { + case UMAC_MODE_IBSS: + return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); + default: return -EOPNOTSUPP; - - return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); + } } static int iwm_wext_giwfreq(struct net_device *dev, @@ -69,69 +47,29 @@ static int iwm_wext_giwfreq(struct net_device *dev, { struct iwm_priv *iwm = ndev_to_iwm(dev); - if (iwm->conf.mode == UMAC_MODE_IBSS) + switch (iwm->conf.mode) { + case UMAC_MODE_IBSS: return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); - - freq->e = 0; - freq->m = iwm->channel; - - return 0; + case UMAC_MODE_BSS: + return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); + default: + return -EOPNOTSUPP; + } } static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { struct iwm_priv *iwm = ndev_to_iwm(dev); - int ret; - - IWM_DBG_WEXT(iwm, DBG, "Set BSSID: %pM\n", ap_addr->sa_data); - if (iwm->conf.mode == UMAC_MODE_IBSS) + switch (iwm->conf.mode) { + case UMAC_MODE_IBSS: return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); - - if (!test_bit(IWM_STATUS_READY, &iwm->status)) - return -EIO; - - if (is_zero_ether_addr(ap_addr->sa_data) || - is_broadcast_ether_addr(ap_addr->sa_data)) { - IWM_DBG_WEXT(iwm, DBG, "clear mandatory bssid %pM\n", - iwm->umac_profile->bssid[0]); - memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN); - iwm->umac_profile->bss_num = 0; - } else { - IWM_DBG_WEXT(iwm, DBG, "add mandatory bssid %pM\n", - ap_addr->sa_data); - memcpy(&iwm->umac_profile->bssid[0], ap_addr->sa_data, - ETH_ALEN); - iwm->umac_profile->bss_num = 1; - } - - if (iwm->umac_profile_active) { - int i; - - if (!memcmp(&iwm->umac_profile->bssid[0], iwm->bssid, ETH_ALEN)) - return 0; - - /* - * If we're clearing the BSSID, and we're associated, - * we have to clear the keys as they're no longer valid. - */ - if (is_zero_ether_addr(ap_addr->sa_data)) { - for (i = 0; i < IWM_NUM_KEYS; i++) - iwm->keys[i].key_len = 0; - } - - ret = iwm_invalidate_mlme_profile(iwm); - if (ret < 0) { - IWM_ERR(iwm, "Couldn't invalidate profile\n"); - return ret; - } + case UMAC_MODE_BSS: + return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); + default: + return -EOPNOTSUPP; } - - if (iwm->umac_profile->ssid.ssid_len) - return iwm_send_mlme_profile(iwm); - - return 0; } static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info, @@ -143,17 +81,10 @@ static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info, case UMAC_MODE_IBSS: return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); case UMAC_MODE_BSS: - if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) { - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(&ap_addr->sa_data, iwm->bssid, ETH_ALEN); - } else - memset(&ap_addr->sa_data, 0, ETH_ALEN); - break; + return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); default: return -EOPNOTSUPP; } - - return 0; } static int iwm_wext_siwessid(struct net_device *dev, @@ -161,36 +92,15 @@ static int iwm_wext_siwessid(struct net_device *dev, struct iw_point *data, char *ssid) { struct iwm_priv *iwm = ndev_to_iwm(dev); - size_t len = data->length; - int ret; - - IWM_DBG_WEXT(iwm, DBG, "Set ESSID: >%s<\n", ssid); - if (iwm->conf.mode == UMAC_MODE_IBSS) + switch (iwm->conf.mode) { + case UMAC_MODE_IBSS: return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); - - if (!test_bit(IWM_STATUS_READY, &iwm->status)) - return -EIO; - - if (len > 0 && ssid[len - 1] == '\0') - len--; - - if (iwm->umac_profile_active) { - if (iwm->umac_profile->ssid.ssid_len == len && - !memcmp(iwm->umac_profile->ssid.ssid, ssid, len)) - return 0; - - ret = iwm_invalidate_mlme_profile(iwm); - if (ret < 0) { - IWM_ERR(iwm, "Couldn't invalidate profile\n"); - return ret; - } + case UMAC_MODE_BSS: + return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); + default: + return -EOPNOTSUPP; } - - iwm->umac_profile->ssid.ssid_len = len; - memcpy(iwm->umac_profile->ssid.ssid, ssid, len); - - return iwm_send_mlme_profile(iwm); } static int iwm_wext_giwessid(struct net_device *dev, @@ -199,174 +109,14 @@ static int iwm_wext_giwessid(struct net_device *dev, { struct iwm_priv *iwm = ndev_to_iwm(dev); - if (iwm->conf.mode == UMAC_MODE_IBSS) + switch (iwm->conf.mode) { + case UMAC_MODE_IBSS: return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); - - if (!test_bit(IWM_STATUS_READY, &iwm->status)) - return -EIO; - - data->length = iwm->umac_profile->ssid.ssid_len; - if (data->length) { - memcpy(ssid, iwm->umac_profile->ssid.ssid, data->length); - data->flags = 1; - } else - data->flags = 0; - - return 0; -} - -static int iwm_wext_giwrate(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rate, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - rate->value = iwm->rate * 1000000; - - return 0; -} - -static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version) -{ - if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) - iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK; - else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) - iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK; - else - iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE; - - return 0; -} - -static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt) -{ - u8 *auth_type = &iwm->umac_profile->sec.auth_type; - - IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt); - - if (key_mgt == IW_AUTH_KEY_MGMT_802_1X) - *auth_type = UMAC_AUTH_TYPE_8021X; - else if (key_mgt == IW_AUTH_KEY_MGMT_PSK) { - if (iwm->umac_profile->sec.flags & - (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) - *auth_type = UMAC_AUTH_TYPE_RSNA_PSK; - else - *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK; - } else { - IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt); - return -EINVAL; - } - - return 0; -} - -static int iwm_set_cipher(struct iwm_priv *iwm, u8 cipher, u8 ucast) -{ - u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher : - &iwm->umac_profile->sec.mcast_cipher; - - switch (cipher) { - case IW_AUTH_CIPHER_NONE: - *profile_cipher = UMAC_CIPHER_TYPE_NONE; - break; - case IW_AUTH_CIPHER_WEP40: - *profile_cipher = UMAC_CIPHER_TYPE_WEP_40; - break; - case IW_AUTH_CIPHER_TKIP: - *profile_cipher = UMAC_CIPHER_TYPE_TKIP; - break; - case IW_AUTH_CIPHER_CCMP: - *profile_cipher = UMAC_CIPHER_TYPE_CCMP; - break; - case IW_AUTH_CIPHER_WEP104: - *profile_cipher = UMAC_CIPHER_TYPE_WEP_104; - break; - default: - IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher); - return -ENOTSUPP; - } - - return 0; -} - -static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg) -{ - u8 *auth_type = &iwm->umac_profile->sec.auth_type; - - IWM_DBG_WEXT(iwm, DBG, "auth_alg: 0x%x\n", auth_alg); - - switch (auth_alg) { - case IW_AUTH_ALG_OPEN_SYSTEM: - *auth_type = UMAC_AUTH_TYPE_OPEN; - break; - case IW_AUTH_ALG_SHARED_KEY: - if (iwm->umac_profile->sec.flags & - (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) { - if (*auth_type == UMAC_AUTH_TYPE_8021X) - return -EINVAL; - *auth_type = UMAC_AUTH_TYPE_RSNA_PSK; - } else { - IWM_DBG_WEXT(iwm, DBG, "WEP shared key\n"); - *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK; - } - break; - case IW_AUTH_ALG_LEAP: - default: - IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", auth_alg); - return -ENOTSUPP; - } - - return 0; -} - -static int iwm_wext_siwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - int ret; - - if ((data->flags) & - (IW_AUTH_WPA_VERSION | IW_AUTH_KEY_MGMT | - IW_AUTH_WPA_ENABLED | IW_AUTH_80211_AUTH_ALG)) { - /* We need to invalidate the current profile */ - if (iwm->umac_profile_active) { - ret = iwm_invalidate_mlme_profile(iwm); - if (ret < 0) { - IWM_ERR(iwm, "Couldn't invalidate profile\n"); - return ret; - } - } - } - - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - return iwm_set_wpa_version(iwm, data->value); - break; - case IW_AUTH_CIPHER_PAIRWISE: - return iwm_set_cipher(iwm, data->value, 1); - break; - case IW_AUTH_CIPHER_GROUP: - return iwm_set_cipher(iwm, data->value, 0); - break; - case IW_AUTH_KEY_MGMT: - return iwm_set_key_mgt(iwm, data->value); - break; - case IW_AUTH_80211_AUTH_ALG: - return iwm_set_auth_alg(iwm, data->value); - break; + case UMAC_MODE_BSS: + return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); default: - return -ENOTSUPP; + return -EOPNOTSUPP; } - - return 0; -} - -static int iwm_wext_giwauth(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - return 0; } static const iw_handler iwm_handlers[] = @@ -404,7 +154,7 @@ static const iw_handler iwm_handlers[] = (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* SIOCSIWRATE */ - (iw_handler) iwm_wext_giwrate, /* SIOCGIWRATE */ + (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */ (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ @@ -419,10 +169,10 @@ static const iw_handler iwm_handlers[] = (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWGENIE */ + (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ (iw_handler) NULL, /* SIOCGIWGENIE */ - (iw_handler) iwm_wext_siwauth, /* SIOCSIWAUTH */ - (iw_handler) iwm_wext_giwauth, /* SIOCGIWAUTH */ + (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */ + (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */ (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ (iw_handler) NULL, /* SIOCGIWENCODEEXT */ (iw_handler) NULL, /* SIOCSIWPMKSA */ @@ -432,6 +182,6 @@ static const iw_handler iwm_handlers[] = const struct iw_handler_def iwm_iw_handler_def = { .num_standard = ARRAY_SIZE(iwm_handlers), .standard = (iw_handler *) iwm_handlers, - .get_wireless_stats = iwm_get_wireless_stats, + .get_wireless_stats = cfg80211_wireless_stats, }; -- cgit v1.2.3 From 0e82ffe3b90bcad72cfe80e4379946b8fb0691ca Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Jul 2009 12:01:50 +0200 Subject: cfg80211: combine iwfreq implementations Until now we implemented iwfreq for managed mode, we needed to keep the implementations separate, but now that we have all versions implemented we can combine them and export just one handler. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/wext.c | 34 +-------------- include/net/cfg80211.h | 20 +++------ net/mac80211/wext.c | 73 +------------------------------- net/wireless/core.h | 3 ++ net/wireless/ibss.c | 5 +-- net/wireless/nl80211.c | 2 + net/wireless/wext-compat.c | 54 ++++++++++++++++++++++- net/wireless/wext-compat.h | 21 +++++++++ net/wireless/wext-sme.c | 5 +-- 9 files changed, 91 insertions(+), 126 deletions(-) create mode 100644 net/wireless/wext-compat.h (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index c3c90d5963bf..8058e9991c30 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -27,36 +27,6 @@ #include "iwm.h" #include "commands.h" -static int iwm_wext_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - switch (iwm->conf.mode) { - case UMAC_MODE_IBSS: - return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); - default: - return -EOPNOTSUPP; - } -} - -static int iwm_wext_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - switch (iwm->conf.mode) { - case UMAC_MODE_IBSS: - return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); - case UMAC_MODE_BSS: - return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); - default: - return -EOPNOTSUPP; - } -} - static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { @@ -125,8 +95,8 @@ static const iw_handler iwm_handlers[] = (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ (iw_handler) NULL, /* SIOCSIWNWID */ (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) iwm_wext_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) iwm_wext_giwfreq, /* SIOCGIWFREQ */ + (iw_handler) cfg80211_wext_siwfreq, /* SIOCSIWFREQ */ + (iw_handler) cfg80211_wext_giwfreq, /* SIOCGIWFREQ */ (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0d278777e39c..5d249c4bf225 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1595,12 +1595,6 @@ int cfg80211_wext_siwmlme(struct net_device *dev, int cfg80211_wext_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); -int cfg80211_ibss_wext_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra); -int cfg80211_ibss_wext_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra); int cfg80211_ibss_wext_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid); @@ -1614,12 +1608,6 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra); -int cfg80211_mgd_wext_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra); -int cfg80211_mgd_wext_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra); int cfg80211_mgd_wext_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid); @@ -1642,8 +1630,12 @@ int cfg80211_wext_giwauth(struct net_device *dev, struct iw_request_info *info, struct iw_param *data, char *extra); -struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, - struct iw_freq *freq); +int cfg80211_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); +int cfg80211_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); int cfg80211_wext_siwrate(struct net_device *dev, struct iw_request_info *info, diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 5acb8140ee58..7cd9aa79ef52 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -27,75 +27,6 @@ #include "aes_ccm.h" -static int ieee80211_ioctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; - struct ieee80211_channel *chan; - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); - else if (sdata->vif.type == NL80211_IFTYPE_STATION) - return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra); - - /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ - if (freq->e == 0) { - if (freq->m < 0) - return -EINVAL; - else - chan = ieee80211_get_channel(local->hw.wiphy, - ieee80211_channel_to_frequency(freq->m)); - } else { - int i, div = 1000000; - for (i = 0; i < freq->e; i++) - div /= 10; - if (div <= 0) - return -EINVAL; - chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div); - } - - if (!chan) - return -EINVAL; - - if (chan->flags & IEEE80211_CHAN_DISABLED) - return -EINVAL; - - /* - * no change except maybe auto -> fixed, ignore the HT - * setting so you can fix a channel you're on already - */ - if (local->oper_channel == chan) - return 0; - - local->oper_channel = chan; - local->oper_channel_type = NL80211_CHAN_NO_HT; - ieee80211_hw_config(local, 0); - - return 0; -} - - -static int ieee80211_ioctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); - else if (sdata->vif.type == NL80211_IFTYPE_STATION) - return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); - - freq->m = local->oper_channel->center_freq; - freq->e = 6; - - return 0; -} - - static int ieee80211_ioctl_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) @@ -173,8 +104,8 @@ static const iw_handler ieee80211_handler[] = (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ (iw_handler) NULL, /* SIOCSIWNWID */ (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */ + (iw_handler) cfg80211_wext_siwfreq, /* SIOCSIWFREQ */ + (iw_handler) cfg80211_wext_giwfreq, /* SIOCGIWFREQ */ (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ diff --git a/net/wireless/core.h b/net/wireless/core.h index 4276b70cd975..6d903c1d721d 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -66,6 +66,9 @@ struct cfg80211_registered_device { struct work_struct conn_work; struct work_struct event_work; + /* current channel */ + struct ieee80211_channel *channel; + #ifdef CONFIG_CFG80211_DEBUGFS /* Debugfs entries */ struct wiphy_debugfsdentries { diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 8b65e212ae49..de9ac49cd907 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -7,6 +7,7 @@ #include #include #include +#include "wext-compat.h" #include "nl80211.h" @@ -312,8 +313,6 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, return err; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); int cfg80211_ibss_wext_giwfreq(struct net_device *dev, struct iw_request_info *info, @@ -342,8 +341,6 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev, /* no channel if not joining */ return -EINVAL; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq); int cfg80211_ibss_wext_siwessid(struct net_device *dev, struct iw_request_info *info, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index c951eb2b07d5..0cd548267d4a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -757,6 +757,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) channel_type); if (result) goto bad_res; + + rdev->channel = chan; } changed = 0; diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index c7351a98e660..fc2e7768967d 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -14,6 +14,7 @@ #include #include #include +#include "wext-compat.h" #include "core.h" int cfg80211_wext_giwname(struct net_device *dev, @@ -300,7 +301,6 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, return ERR_PTR(-EINVAL); return chan; } -EXPORT_SYMBOL_GPL(cfg80211_wext_freq); int cfg80211_wext_siwrts(struct net_device *dev, struct iw_request_info *info, @@ -759,6 +759,58 @@ int cfg80211_wext_giwencode(struct net_device *dev, } EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); +int cfg80211_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + struct ieee80211_channel *chan; + int err; + + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: + return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra); + case NL80211_IFTYPE_ADHOC: + return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra); + default: + chan = cfg80211_wext_freq(wdev->wiphy, freq); + if (!chan) + return -EINVAL; + if (IS_ERR(chan)) + return PTR_ERR(chan); + err = rdev->ops->set_channel(wdev->wiphy, chan, + NL80211_CHAN_NO_HT); + if (err) + return err; + rdev->channel = chan; + return 0; + } +} +EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq); + +int cfg80211_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + + switch (wdev->iftype) { + case NL80211_IFTYPE_STATION: + return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra); + case NL80211_IFTYPE_ADHOC: + return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); + default: + if (!rdev->channel) + return -EINVAL; + freq->m = rdev->channel->center_freq; + freq->e = 6; + return 0; + } +} +EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq); + int cfg80211_wext_siwtxpower(struct net_device *dev, struct iw_request_info *info, union iwreq_data *data, char *extra) diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h new file mode 100644 index 000000000000..23a6b5a83f2d --- /dev/null +++ b/net/wireless/wext-compat.h @@ -0,0 +1,21 @@ +#ifndef __WEXT_COMPAT +#define __WEXT_COMPAT + +int cfg80211_ibss_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); +int cfg80211_ibss_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); + +int cfg80211_mgd_wext_siwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); +int cfg80211_mgd_wext_giwfreq(struct net_device *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra); + +struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, + struct iw_freq *freq); + +#endif /* __WEXT_COMPAT */ diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 4c689fd865b0..509279a1cfb2 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -8,6 +8,7 @@ #include #include #include +#include "wext-compat.h" #include "nl80211.h" int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, @@ -108,8 +109,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, cfg80211_unlock_rdev(rdev); return err; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq); int cfg80211_mgd_wext_giwfreq(struct net_device *dev, struct iw_request_info *info, @@ -138,8 +137,6 @@ int cfg80211_mgd_wext_giwfreq(struct net_device *dev, /* no channel if not joining */ return -EINVAL; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwfreq); int cfg80211_mgd_wext_siwessid(struct net_device *dev, struct iw_request_info *info, -- cgit v1.2.3 From 562e482265ac4d660d9f0114419591d62f44361d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Jul 2009 12:01:51 +0200 Subject: cfg80211: combine IWAP handlers Since we now have IWAP handlers for all modes, we can combine them into one. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/wext.c | 34 ++------------------- include/net/cfg80211.h | 24 ++++----------- net/mac80211/wext.c | 41 ++----------------------- net/wireless/ibss.c | 4 --- net/wireless/wext-compat.c | 52 +++++++++++++++++++++++++++----- net/wireless/wext-compat.h | 12 ++++++++ net/wireless/wext-sme.c | 4 --- 7 files changed, 66 insertions(+), 105 deletions(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 8058e9991c30..5319b16474e3 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -27,36 +27,6 @@ #include "iwm.h" #include "commands.h" -static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - switch (iwm->conf.mode) { - case UMAC_MODE_IBSS: - return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); - case UMAC_MODE_BSS: - return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); - default: - return -EOPNOTSUPP; - } -} - -static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - switch (iwm->conf.mode) { - case UMAC_MODE_IBSS: - return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); - case UMAC_MODE_BSS: - return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); - default: - return -EOPNOTSUPP; - } -} - static int iwm_wext_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) @@ -111,8 +81,8 @@ static const iw_handler iwm_handlers[] = (iw_handler) NULL, /* SIOCGIWSPY */ (iw_handler) NULL, /* SIOCSIWTHRSPY */ (iw_handler) NULL, /* SIOCGIWTHRSPY */ - (iw_handler) iwm_wext_siwap, /* SIOCSIWAP */ - (iw_handler) iwm_wext_giwap, /* SIOCGIWAP */ + (iw_handler) cfg80211_wext_siwap, /* SIOCSIWAP */ + (iw_handler) cfg80211_wext_giwap, /* SIOCGIWAP */ (iw_handler) NULL, /* SIOCSIWMLME */ (iw_handler) NULL, /* SIOCGIWAPLIST */ (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 5d249c4bf225..3348c16e1f35 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1601,12 +1601,6 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, int cfg80211_ibss_wext_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid); -int cfg80211_ibss_wext_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra); -int cfg80211_ibss_wext_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra); int cfg80211_mgd_wext_siwessid(struct net_device *dev, struct iw_request_info *info, @@ -1614,12 +1608,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid); -int cfg80211_mgd_wext_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra); -int cfg80211_mgd_wext_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra); int cfg80211_wext_siwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); @@ -1686,12 +1674,12 @@ int cfg80211_wext_giwpower(struct net_device *dev, struct iw_request_info *info, struct iw_param *wrq, char *extra); -int cfg80211_wds_wext_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *addr, char *extra); -int cfg80211_wds_wext_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *addr, char *extra); +int cfg80211_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); +int cfg80211_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); /* * callbacks for asynchronous cfg80211 methods, notification diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 7cd9aa79ef52..72866c8b8c3d 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -59,43 +59,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev, } -static int ieee80211_ioctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); - - if (sdata->vif.type == NL80211_IFTYPE_STATION) - return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); - - if (sdata->vif.type == NL80211_IFTYPE_WDS) - return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra); - return -EOPNOTSUPP; -} - - -static int ieee80211_ioctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); - - if (sdata->vif.type == NL80211_IFTYPE_STATION) - return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); - - if (sdata->vif.type == NL80211_IFTYPE_WDS) - return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra); - - return -EOPNOTSUPP; -} - - /* Structures to export the Wireless Handlers */ static const iw_handler ieee80211_handler[] = @@ -120,8 +83,8 @@ static const iw_handler ieee80211_handler[] = (iw_handler) NULL, /* SIOCGIWSPY */ (iw_handler) NULL, /* SIOCSIWTHRSPY */ (iw_handler) NULL, /* SIOCGIWTHRSPY */ - (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */ - (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */ + (iw_handler) cfg80211_wext_siwap, /* SIOCSIWAP */ + (iw_handler) cfg80211_wext_giwap, /* SIOCGIWAP */ (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */ (iw_handler) NULL, /* SIOCGIWAPLIST */ (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index de9ac49cd907..f955225ed911 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -466,8 +466,6 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, return err; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); int cfg80211_ibss_wext_giwap(struct net_device *dev, struct iw_request_info *info, @@ -493,6 +491,4 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev, return 0; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap); #endif diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index fc2e7768967d..c27774bd0107 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1149,9 +1149,9 @@ int cfg80211_wext_giwpower(struct net_device *dev, } EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); -int cfg80211_wds_wext_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *addr, char *extra) +static int cfg80211_wds_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *addr, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); @@ -1177,11 +1177,10 @@ int cfg80211_wds_wext_siwap(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap); -int cfg80211_wds_wext_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *addr, char *extra) +static int cfg80211_wds_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *addr, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; @@ -1193,7 +1192,6 @@ int cfg80211_wds_wext_giwap(struct net_device *dev, return 0; } -EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap); int cfg80211_wext_siwrate(struct net_device *dev, struct iw_request_info *info, @@ -1327,3 +1325,41 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) return &wstats; } EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); + +int cfg80211_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); + case NL80211_IFTYPE_STATION: + return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra); + case NL80211_IFTYPE_WDS: + return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra); + default: + return -EOPNOTSUPP; + } +} +EXPORT_SYMBOL_GPL(cfg80211_wext_siwap); + +int cfg80211_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); + case NL80211_IFTYPE_STATION: + return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra); + case NL80211_IFTYPE_WDS: + return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra); + default: + return -EOPNOTSUPP; + } +} +EXPORT_SYMBOL_GPL(cfg80211_wext_giwap); diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index 23a6b5a83f2d..51028ebf19ae 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -7,6 +7,12 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, int cfg80211_ibss_wext_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra); +int cfg80211_ibss_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); +int cfg80211_ibss_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); int cfg80211_mgd_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, @@ -14,6 +20,12 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, int cfg80211_mgd_wext_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra); +int cfg80211_mgd_wext_siwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); +int cfg80211_mgd_wext_giwap(struct net_device *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra); struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 509279a1cfb2..1aa31cc55113 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -273,8 +273,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); return err; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap); int cfg80211_mgd_wext_giwap(struct net_device *dev, struct iw_request_info *info, @@ -299,8 +297,6 @@ int cfg80211_mgd_wext_giwap(struct net_device *dev, return 0; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwap); int cfg80211_wext_siwgenie(struct net_device *dev, struct iw_request_info *info, -- cgit v1.2.3 From 1f9298f96082692bdfe73af6fc2167f627f21647 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Jul 2009 12:01:52 +0200 Subject: cfg80211: combine IWESSID handlers Since we now have handlers IWESSID for all modes, we can combine them into one. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/wext.c | 36 ++------------------------------ include/net/cfg80211.h | 20 ++++++------------ net/mac80211/wext.c | 35 ++----------------------------- net/wireless/ibss.c | 4 ---- net/wireless/wext-compat.c | 34 ++++++++++++++++++++++++++++++ net/wireless/wext-compat.h | 12 +++++++++++ net/wireless/wext-sme.c | 4 ---- 7 files changed, 56 insertions(+), 89 deletions(-) (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c index 5319b16474e3..9196024a2890 100644 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ b/drivers/net/wireless/iwmc3200wifi/wext.c @@ -27,38 +27,6 @@ #include "iwm.h" #include "commands.h" -static int iwm_wext_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - switch (iwm->conf.mode) { - case UMAC_MODE_IBSS: - return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); - case UMAC_MODE_BSS: - return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); - default: - return -EOPNOTSUPP; - } -} - -static int iwm_wext_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct iwm_priv *iwm = ndev_to_iwm(dev); - - switch (iwm->conf.mode) { - case UMAC_MODE_IBSS: - return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); - case UMAC_MODE_BSS: - return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); - default: - return -EOPNOTSUPP; - } -} - static const iw_handler iwm_handlers[] = { (iw_handler) NULL, /* SIOCSIWCOMMIT */ @@ -87,8 +55,8 @@ static const iw_handler iwm_handlers[] = (iw_handler) NULL, /* SIOCGIWAPLIST */ (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ - (iw_handler) iwm_wext_siwessid, /* SIOCSIWESSID */ - (iw_handler) iwm_wext_giwessid, /* SIOCGIWESSID */ + (iw_handler) cfg80211_wext_siwessid, /* SIOCSIWESSID */ + (iw_handler) cfg80211_wext_giwessid, /* SIOCGIWESSID */ (iw_handler) NULL, /* SIOCSIWNICKN */ (iw_handler) NULL, /* SIOCGIWNICKN */ (iw_handler) NULL, /* -- hole -- */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 3348c16e1f35..e1b92358242b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1595,19 +1595,6 @@ int cfg80211_wext_siwmlme(struct net_device *dev, int cfg80211_wext_giwrange(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); -int cfg80211_ibss_wext_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid); -int cfg80211_ibss_wext_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid); - -int cfg80211_mgd_wext_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid); -int cfg80211_mgd_wext_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid); int cfg80211_wext_siwgenie(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *extra); @@ -1624,7 +1611,12 @@ int cfg80211_wext_siwfreq(struct net_device *dev, int cfg80211_wext_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra); - +int cfg80211_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); +int cfg80211_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); int cfg80211_wext_siwrate(struct net_device *dev, struct iw_request_info *info, struct iw_param *rate, char *extra); diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 72866c8b8c3d..aa250c3e8fda 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -27,37 +27,6 @@ #include "aes_ccm.h" -static int ieee80211_ioctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); - else if (sdata->vif.type == NL80211_IFTYPE_STATION) - return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); - - return -EOPNOTSUPP; -} - - -static int ieee80211_ioctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); - else if (sdata->vif.type == NL80211_IFTYPE_STATION) - return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); - - return -EOPNOTSUPP; -} - /* Structures to export the Wireless Handlers */ @@ -89,8 +58,8 @@ static const iw_handler ieee80211_handler[] = (iw_handler) NULL, /* SIOCGIWAPLIST */ (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ - (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */ - (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */ + (iw_handler) cfg80211_wext_siwessid, /* SIOCSIWESSID */ + (iw_handler) cfg80211_wext_giwessid, /* SIOCGIWESSID */ (iw_handler) NULL, /* SIOCSIWNICKN */ (iw_handler) NULL, /* SIOCGIWNICKN */ (iw_handler) NULL, /* -- hole -- */ diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index f955225ed911..4d7a084b35e2 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -381,8 +381,6 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, return err; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); int cfg80211_ibss_wext_giwessid(struct net_device *dev, struct iw_request_info *info, @@ -410,8 +408,6 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev, return 0; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid); int cfg80211_ibss_wext_siwap(struct net_device *dev, struct iw_request_info *info, diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index c27774bd0107..083e4c33d95d 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1363,3 +1363,37 @@ int cfg80211_wext_giwap(struct net_device *dev, } } EXPORT_SYMBOL_GPL(cfg80211_wext_giwap); + +int cfg80211_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); + case NL80211_IFTYPE_STATION: + return cfg80211_mgd_wext_siwessid(dev, info, data, ssid); + default: + return -EOPNOTSUPP; + } +} +EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid); + +int cfg80211_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid) +{ + struct wireless_dev *wdev = dev->ieee80211_ptr; + + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); + case NL80211_IFTYPE_STATION: + return cfg80211_mgd_wext_giwessid(dev, info, data, ssid); + default: + return -EOPNOTSUPP; + } +} +EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index 51028ebf19ae..c0310d93c2e5 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -13,6 +13,12 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, int cfg80211_ibss_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra); +int cfg80211_ibss_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); +int cfg80211_ibss_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); int cfg80211_mgd_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, @@ -26,6 +32,12 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, int cfg80211_mgd_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra); +int cfg80211_mgd_wext_siwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); +int cfg80211_mgd_wext_giwessid(struct net_device *dev, + struct iw_request_info *info, + struct iw_point *data, char *ssid); struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 1aa31cc55113..7bacbd1c2af6 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -192,8 +192,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); return err; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid); int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct iw_request_info *info, @@ -218,8 +216,6 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, return 0; } -/* temporary symbol - mark GPL - in the future the handler won't be */ -EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwessid); int cfg80211_mgd_wext_siwap(struct net_device *dev, struct iw_request_info *info, -- cgit v1.2.3 From a9a11622c5c742c115fad371c0397ae86dd3bb67 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 27 Jul 2009 12:01:53 +0200 Subject: cfg80211: self-contained wext handling where possible Finally! This is what you've all been waiting for! This patch makes cfg80211 take care of wext emulation _completely_ by itself, drivers that don't need things cfg80211 doesn't do yet don't even need to be aware of wireless extensions. This means we can also clean up mac80211's and iwm's Kconfig and make it possible to build them w/o wext now! RIP wext. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwmc3200wifi/Kconfig | 1 - drivers/net/wireless/iwmc3200wifi/Makefile | 2 +- drivers/net/wireless/iwmc3200wifi/iwm.h | 2 - drivers/net/wireless/iwmc3200wifi/netdev.c | 1 - drivers/net/wireless/iwmc3200wifi/wext.c | 95 ----------------------------- net/mac80211/Kconfig | 1 - net/mac80211/Makefile | 1 - net/mac80211/ieee80211_i.h | 4 -- net/mac80211/iface.c | 1 - net/mac80211/scan.c | 1 - net/mac80211/wext.c | 98 ------------------------------ net/wireless/core.c | 3 + net/wireless/mlme.c | 2 + net/wireless/scan.c | 1 + net/wireless/sme.c | 2 + net/wireless/wext-compat.c | 40 ++++++++++++ net/wireless/wext-compat.h | 5 ++ 17 files changed, 54 insertions(+), 206 deletions(-) delete mode 100644 drivers/net/wireless/iwmc3200wifi/wext.c delete mode 100644 net/mac80211/wext.c (limited to 'drivers/net/wireless/iwmc3200wifi/wext.c') diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig index 030401d367d3..c62da435285a 100644 --- a/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/drivers/net/wireless/iwmc3200wifi/Kconfig @@ -2,7 +2,6 @@ config IWM tristate "Intel Wireless Multicomm 3200 WiFi driver" depends on MMC && WLAN_80211 && EXPERIMENTAL depends on CFG80211 - select WIRELESS_EXT select FW_LOADER help The Intel Wireless Multicomm 3200 hardware is a combo diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile index 927f022545c1..d34291b652d3 100644 --- a/drivers/net/wireless/iwmc3200wifi/Makefile +++ b/drivers/net/wireless/iwmc3200wifi/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_IWM) := iwmc3200wifi.o iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o -iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o +iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 2175a481d2f4..7a51bc340fda 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h @@ -306,8 +306,6 @@ static inline void *iwm_private(struct iwm_priv *iwm) #define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb)) #define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb) -extern const struct iw_handler_def iwm_iw_handler_def; - void *iwm_if_alloc(int sizeof_bus, struct device *dev, struct iwm_if_ops *if_ops); void iwm_if_free(struct iwm_priv *iwm); diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c index 092d28ae56a0..30116d1b4489 100644 --- a/drivers/net/wireless/iwmc3200wifi/netdev.c +++ b/drivers/net/wireless/iwmc3200wifi/netdev.c @@ -123,7 +123,6 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev, } ndev->netdev_ops = &iwm_netdev_ops; - ndev->wireless_handlers = &iwm_iw_handler_def; ndev->ieee80211_ptr = wdev; SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); wdev->netdev = ndev; diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c deleted file mode 100644 index 9196024a2890..000000000000 --- a/drivers/net/wireless/iwmc3200wifi/wext.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Intel Wireless Multicomm 3200 WiFi driver - * - * Copyright (C) 2009 Intel Corporation - * Samuel Ortiz - * Zhu Yi - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - */ - -#include -#include - -#include "iwm.h" -#include "commands.h" - -static const iw_handler iwm_handlers[] = -{ - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) cfg80211_wext_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) cfg80211_wext_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ - (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ - (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ - (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ - (iw_handler) NULL, /* SIOCSIWTHRSPY */ - (iw_handler) NULL, /* SIOCGIWTHRSPY */ - (iw_handler) cfg80211_wext_siwap, /* SIOCSIWAP */ - (iw_handler) cfg80211_wext_giwap, /* SIOCGIWAP */ - (iw_handler) NULL, /* SIOCSIWMLME */ - (iw_handler) NULL, /* SIOCGIWAPLIST */ - (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ - (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ - (iw_handler) cfg80211_wext_siwessid, /* SIOCSIWESSID */ - (iw_handler) cfg80211_wext_giwessid, /* SIOCGIWESSID */ - (iw_handler) NULL, /* SIOCSIWNICKN */ - (iw_handler) NULL, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* SIOCSIWRATE */ - (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */ - (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ - (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ - (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */ - (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */ - (iw_handler) NULL, /* SIOCSIWRETRY */ - (iw_handler) NULL, /* SIOCGIWRETRY */ - (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ - (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ - (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */ - (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ - (iw_handler) NULL, /* SIOCGIWGENIE */ - (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */ - (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */ - (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ - (iw_handler) NULL, /* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ - (iw_handler) NULL, /* -- hole -- */ -}; - -const struct iw_handler_def iwm_iw_handler_def = { - .num_standard = ARRAY_SIZE(iwm_handlers), - .standard = (iw_handler *) iwm_handlers, - .get_wireless_stats = cfg80211_wireless_stats, -}; - diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 19a4c66e143e..7dd77b6d4c9a 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig @@ -6,7 +6,6 @@ config MAC80211 select CRYPTO_ARC4 select CRYPTO_AES select CRC32 - select WIRELESS_EXT ---help--- This option enables the hardware independent IEEE 802.11 networking stack. diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 91284a74ff91..9f3cf7129324 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -3,7 +3,6 @@ obj-$(CONFIG_MAC80211) += mac80211.o # mac80211 objects mac80211-y := \ main.o \ - wext.o \ sta_info.o \ wep.o \ wpa.o \ diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c6b25cb73284..aec6853cb435 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "key.h" #include "sta_info.h" @@ -951,9 +950,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, void ieee80211_configure_filter(struct ieee80211_local *local); u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); -/* wireless extensions */ -extern const struct iw_handler_def ieee80211_iw_handler_def; - /* STA code */ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d79a21105042..6c655b6547fb 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -684,7 +684,6 @@ static void ieee80211_if_setup(struct net_device *dev) { ether_setup(dev); dev->netdev_ops = &ieee80211_dataif_ops; - dev->wireless_handlers = &ieee80211_iw_handler_def; dev->destructor = free_netdev; } diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 147772a2977c..45731000eb8d 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "ieee80211_i.h" #include "driver-ops.h" diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c deleted file mode 100644 index aa250c3e8fda..000000000000 --- a/net/mac80211/wext.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * Copyright 2005-2006, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ieee80211_i.h" -#include "led.h" -#include "rate.h" -#include "wpa.h" -#include "aes_ccm.h" - - - -/* Structures to export the Wireless Handlers */ - -static const iw_handler ieee80211_handler[] = -{ - (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */ - (iw_handler) NULL, /* SIOCSIWNWID */ - (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) cfg80211_wext_siwfreq, /* SIOCSIWFREQ */ - (iw_handler) cfg80211_wext_giwfreq, /* SIOCGIWFREQ */ - (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */ - (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */ - (iw_handler) NULL, /* SIOCSIWSENS */ - (iw_handler) NULL, /* SIOCGIWSENS */ - (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */ - (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */ - (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */ - (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */ - (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */ - (iw_handler) NULL, /* SIOCSIWSPY */ - (iw_handler) NULL, /* SIOCGIWSPY */ - (iw_handler) NULL, /* SIOCSIWTHRSPY */ - (iw_handler) NULL, /* SIOCGIWTHRSPY */ - (iw_handler) cfg80211_wext_siwap, /* SIOCSIWAP */ - (iw_handler) cfg80211_wext_giwap, /* SIOCGIWAP */ - (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */ - (iw_handler) NULL, /* SIOCGIWAPLIST */ - (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */ - (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */ - (iw_handler) cfg80211_wext_siwessid, /* SIOCSIWESSID */ - (iw_handler) cfg80211_wext_giwessid, /* SIOCGIWESSID */ - (iw_handler) NULL, /* SIOCSIWNICKN */ - (iw_handler) NULL, /* SIOCGIWNICKN */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) cfg80211_wext_siwrate, /* SIOCSIWRATE */ - (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */ - (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ - (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ - (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ - (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */ - (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */ - (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */ - (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ - (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ - (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */ - (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */ - (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */ - (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) NULL, /* -- hole -- */ - (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */ - (iw_handler) NULL, /* SIOCGIWGENIE */ - (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */ - (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */ - (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ - (iw_handler) NULL, /* SIOCGIWENCODEEXT */ - (iw_handler) NULL, /* SIOCSIWPMKSA */ - (iw_handler) NULL, /* -- hole -- */ -}; - -const struct iw_handler_def ieee80211_iw_handler_def = -{ - .num_standard = ARRAY_SIZE(ieee80211_handler), - .standard = (iw_handler *) ieee80211_handler, - .get_wireless_stats = cfg80211_wireless_stats, -}; diff --git a/net/wireless/core.c b/net/wireless/core.c index 442c9f389799..f9fee65dc06a 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -19,6 +19,7 @@ #include "core.h" #include "sysfs.h" #include "debugfs.h" +#include "wext-compat.h" /* name for sysfs, %d is appended */ #define PHY_NAME "phy" @@ -665,6 +666,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, wdev->sme_state = CFG80211_SME_IDLE; mutex_unlock(&rdev->devlist_mtx); #ifdef CONFIG_WIRELESS_EXT + if (!dev->wireless_handlers) + dev->wireless_handlers = &cfg80211_wext_handler; wdev->wext.default_key = -1; wdev->wext.default_mgmt_key = -1; wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 30058a80d7af..097a87d7bae1 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include "core.h" #include "nl80211.h" diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2a2683f6c04a..67714d7ed5b4 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -14,6 +14,7 @@ #include #include "core.h" #include "nl80211.h" +#include "wext-compat.h" #define IEEE80211_SCAN_RESULT_EXPIRE (15 * HZ) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a19741097989..d2b5d4ce0a00 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include "nl80211.h" diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 083e4c33d95d..e4e90e249bab 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -1397,3 +1397,43 @@ int cfg80211_wext_giwessid(struct net_device *dev, } } EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); + +static const iw_handler cfg80211_handlers[] = { + [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, + [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq, + [IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) cfg80211_wext_giwfreq, + [IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode, + [IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode, + [IW_IOCTL_IDX(SIOCGIWRANGE)] = (iw_handler) cfg80211_wext_giwrange, + [IW_IOCTL_IDX(SIOCSIWAP)] = (iw_handler) cfg80211_wext_siwap, + [IW_IOCTL_IDX(SIOCGIWAP)] = (iw_handler) cfg80211_wext_giwap, + [IW_IOCTL_IDX(SIOCSIWMLME)] = (iw_handler) cfg80211_wext_siwmlme, + [IW_IOCTL_IDX(SIOCSIWSCAN)] = (iw_handler) cfg80211_wext_siwscan, + [IW_IOCTL_IDX(SIOCGIWSCAN)] = (iw_handler) cfg80211_wext_giwscan, + [IW_IOCTL_IDX(SIOCSIWESSID)] = (iw_handler) cfg80211_wext_siwessid, + [IW_IOCTL_IDX(SIOCGIWESSID)] = (iw_handler) cfg80211_wext_giwessid, + [IW_IOCTL_IDX(SIOCSIWRATE)] = (iw_handler) cfg80211_wext_siwrate, + [IW_IOCTL_IDX(SIOCGIWRATE)] = (iw_handler) cfg80211_wext_giwrate, + [IW_IOCTL_IDX(SIOCSIWRTS)] = (iw_handler) cfg80211_wext_siwrts, + [IW_IOCTL_IDX(SIOCGIWRTS)] = (iw_handler) cfg80211_wext_giwrts, + [IW_IOCTL_IDX(SIOCSIWFRAG)] = (iw_handler) cfg80211_wext_siwfrag, + [IW_IOCTL_IDX(SIOCGIWFRAG)] = (iw_handler) cfg80211_wext_giwfrag, + [IW_IOCTL_IDX(SIOCSIWTXPOW)] = (iw_handler) cfg80211_wext_siwtxpower, + [IW_IOCTL_IDX(SIOCGIWTXPOW)] = (iw_handler) cfg80211_wext_giwtxpower, + [IW_IOCTL_IDX(SIOCSIWRETRY)] = (iw_handler) cfg80211_wext_siwretry, + [IW_IOCTL_IDX(SIOCGIWRETRY)] = (iw_handler) cfg80211_wext_giwretry, + [IW_IOCTL_IDX(SIOCSIWENCODE)] = (iw_handler) cfg80211_wext_siwencode, + [IW_IOCTL_IDX(SIOCGIWENCODE)] = (iw_handler) cfg80211_wext_giwencode, + [IW_IOCTL_IDX(SIOCSIWPOWER)] = (iw_handler) cfg80211_wext_siwpower, + [IW_IOCTL_IDX(SIOCGIWPOWER)] = (iw_handler) cfg80211_wext_giwpower, + [IW_IOCTL_IDX(SIOCSIWGENIE)] = (iw_handler) cfg80211_wext_siwgenie, + [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth, + [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth, + [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext, +}; + +const struct iw_handler_def cfg80211_wext_handler = { + .num_standard = ARRAY_SIZE(cfg80211_handlers), + .standard = cfg80211_handlers, + .get_wireless_stats = cfg80211_wireless_stats, +}; diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h index c0310d93c2e5..9a3774749589 100644 --- a/net/wireless/wext-compat.h +++ b/net/wireless/wext-compat.h @@ -1,6 +1,9 @@ #ifndef __WEXT_COMPAT #define __WEXT_COMPAT +#include +#include + int cfg80211_ibss_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra); @@ -42,4 +45,6 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev, struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); + +extern const struct iw_handler_def cfg80211_wext_handler; #endif /* __WEXT_COMPAT */ -- cgit v1.2.3