ieee80211_softmac_wx.c revision f6aa782f255de96b89ff4fc98dad0d57a9691c8a
18fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* IEEE 802.11 SoftMAC layer 28fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> 38fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * 48fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * Mostly extracted from the rtl8180-sa2400 driver for the 58fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * in-kernel generic ieee802.11 stack. 68fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * 78fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * Some pieces of code might be stolen from ipw2100 driver 88fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * copyright of who own it's copyright ;-) 98fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * 108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * PS wx handler mostly stolen from hostap, copyright who 118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * own it's copyright ;-) 128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * 138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * released under the GPL 148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang */ 158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 17f6aa782f255de96b89ff4fc98dad0d57a9691c8aWei Yongjun#include <linux/etherdevice.h> 18f6aa782f255de96b89ff4fc98dad0d57a9691c8aWei Yongjun 198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang#include "ieee80211.h" 208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang#include "dot11d.h" 218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* FIXME: add A freqs */ 228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangconst long ieee80211_wlan_frequencies[] = { 248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2412, 2417, 2422, 2427, 258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2432, 2437, 2442, 2447, 268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2452, 2457, 2462, 2467, 278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2472, 2484 288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang}; 298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, 328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret; 358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_freq *fwrq = & wrqu->freq; 368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->iw_mode == IW_MODE_INFRA){ 408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EOPNOTSUPP; 418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* if setting by freq convert to channel */ 458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (fwrq->e == 1) { 468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ((fwrq->m >= (int) 2.412e8 && 478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang fwrq->m <= (int) 2.487e8)) { 488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int f = fwrq->m / 100000; 498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int c = 0; 508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang while ((c < 14) && (f != ieee80211_wlan_frequencies[c])) 528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang c++; 538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* hack to fall through */ 558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang fwrq->e = 0; 568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang fwrq->m = c + 1; 578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){ 618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EOPNOTSUPP; 628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang }else { /* Set the channel */ 658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) { 678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EINVAL; 688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.channel = fwrq->m; 718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, ieee->current_network.channel); 728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) 748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->state == IEEE80211_LINKED){ 758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_send_beacons(ieee); 778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_send_beacons(ieee); 788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = 0; 828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_freq(struct ieee80211_device *ieee, 898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *a, 908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_freq *fwrq = & wrqu->freq; 938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->current_network.channel == 0) 958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -1; 968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //NM 0.7.0 will not accept channel any more. 978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000; 988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang fwrq->e = 1; 998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang// fwrq->m = ieee->current_network.channel; 1008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang// fwrq->e = 0; 1018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 1038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 1048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_wap(struct ieee80211_device *ieee, 1068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 1078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 1088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 1098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 1108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->ap_addr.sa_family = ARPHRD_ETHER; 1128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR) 1148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -1; 1158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* We want avoid to give to the user inconsistent infos*/ 1178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 1188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->state != IEEE80211_LINKED && 1208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state != IEEE80211_LINKED_SCANNING && 1218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->wap_set == 0) 1228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 1248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 1258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang memcpy(wrqu->ap_addr.sa_data, 1268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.bssid, ETH_ALEN); 1278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 1298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 1318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 1328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_wap(struct ieee80211_device *ieee, 1358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 1368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *awrq, 1378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang char *extra) 1388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 1398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret = 0; 1418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 1428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short ifup = ieee->proto_started;//dev->flags & IFF_UP; 1448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct sockaddr *temp = (struct sockaddr *)awrq; 1458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->sync_scan_hurryup = 1; 1478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 1498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* use ifconfig hw ether */ 1508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MASTER){ 1518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 1528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 1538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 1548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (temp->sa_family != ARPHRD_ETHER){ 1568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EINVAL; 1578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 1588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 1598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ifup) 1618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_protocol(ieee); 1628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* just to avoid to give inconsistent infos in the 1648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * get wx method. not really needed otherwise 1658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang */ 1668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 1678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); 169f6aa782f255de96b89ff4fc98dad0d57a9691c8aWei Yongjun ieee->wap_set = !is_zero_ether_addr(temp->sa_data); 1708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 1728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ifup) 1748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_protocol(ieee); 1758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 1768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 1778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 1788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 1798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b) 1818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 1828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int len,ret = 0; 1838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 1848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR) 1868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -1; 1878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* We want avoid to give to the user inconsistent infos*/ 1898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 1908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->current_network.ssid[0] == '\0' || 1928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid_len == 0){ 1938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 1948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 1958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 1968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->state != IEEE80211_LINKED && 1988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state != IEEE80211_LINKED_SCANNING && 1998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ssid_set == 0){ 2008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 2018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 2028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang len = ieee->current_network.ssid_len; 2048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->essid.length = len; 2058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strncpy(b,ieee->current_network.ssid,len); 2068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->essid.flags = 1; 2078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 2098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 2108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 2128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 2148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_rate(struct ieee80211_device *ieee, 2168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang u32 target_rate = wrqu->bitrate.value; 2218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->rate = target_rate/100000; 2238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //FIXME: we might want to limit rate also in management protocols. 2248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 2268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_rate(struct ieee80211_device *ieee, 2308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang u32 tmp_rate; 2348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate); 2358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->bitrate.value = tmp_rate * 500000; 2378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 2408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_rts(struct ieee80211_device *ieee, 2438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->rts.disabled || !wrqu->rts.fixed) 2478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->rts = DEFAULT_RTS_THRESHOLD; 2488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 2498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang { 2508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->rts.value < MIN_RTS_THRESHOLD || 2518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.value > MAX_RTS_THRESHOLD) 2528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -EINVAL; 2538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->rts = wrqu->rts.value; 2548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 2578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_rts(struct ieee80211_device *ieee, 2598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.value = ieee->rts; 2638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.fixed = 0; /* no auto select */ 2648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 2658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 2678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, 2688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 2698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->sync_scan_hurryup = 1; 2728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 2748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->mode == ieee->iw_mode) 2768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 2778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->mode == IW_MODE_MONITOR){ 2798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->dev->type = ARPHRD_IEEE80211; 2818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang }else{ 2828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->dev->type = ARPHRD_ETHER; 2838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (!ieee->proto_started){ 2868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->iw_mode = wrqu->mode; 2878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang }else{ 2888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_protocol(ieee); 2898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->iw_mode = wrqu->mode; 2908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_protocol(ieee); 2918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 2948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 2958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 2978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangvoid ieee80211_wx_sync_scan_wq(struct work_struct *work) 2998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 300e406322b4b963e622f41d76193d8ca9e5435adb8Mauro Carvalho Chehab struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); 3018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short chan; 3028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang HT_EXTCHNL_OFFSET chan_offset=0; 3038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang HT_CHANNEL_WIDTH bandwidth=0; 3048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int b40M = 0; 3058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang static int count = 0; 3068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang chan = ieee->current_network.channel; 3078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_off(ieee->dev); 3088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->data_hard_stop) 3108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->data_hard_stop(ieee->dev); 3118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_send_beacons(ieee); 3138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state = IEEE80211_LINKED_SCANNING; 3158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->link_change(ieee->dev); 3168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->InitialGainHandler(ieee->dev,IG_Backup); 3178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { 3188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang b40M = 1; 3198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; 3208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz; 3218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth); 3228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 3238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_scan_syncro(ieee); 3258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (b40M) { 3268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang printk("Scan in 20M, back to 40M\n"); 3278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) 3288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan + 2); 3298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) 3308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan - 2); 3318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 3328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan); 3338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); 3348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } else { 3358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan); 3368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->InitialGainHandler(ieee->dev,IG_Restore); 3398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state = IEEE80211_LINKED; 3408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->link_change(ieee->dev); 3418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang // To prevent the immediately calling watch_dog after scan. 3428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) 3438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang { 3448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; 3458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; 3468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->data_hard_resume) 3488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->data_hard_resume(ieee->dev); 3498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) 3518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_send_beacons(ieee); 3528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_on(ieee->dev); 3548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang count = 0; 3558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 3568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 3588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, 3608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 3618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 3628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret = 0; 3638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 3658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){ 3678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 3688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 3698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ( ieee->state == IEEE80211_LINKED){ 3728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang queue_work(ieee->wq, &ieee->wx_sync_scan_wq); 3738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* intentionally forget to up sem */ 3748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 3758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 3788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 3798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 3808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 3818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_essid(struct ieee80211_device *ieee, 3838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *a, 3848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 3858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 3868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret=0,len; 3888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short proto_started; 3898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 3908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->sync_scan_hurryup = 1; 3928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 3938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang proto_started = ieee->proto_started; 3958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ 3978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret= -E2BIG; 3988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 3998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR){ 4028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret= -1; 4038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 4048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(proto_started) 4078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_protocol(ieee); 4088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* this is just to be sure that the GET wx callback 4118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * has consisten infos. not needed otherwise 4128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang */ 4138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 4148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->essid.flags && wrqu->essid.length) { 4168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //first flush current network.ssid 4178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; 4188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strncpy(ieee->current_network.ssid, extra, len+1); 4198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid_len = len+1; 4208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ssid_set = 1; 4218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else{ 4238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ssid_set = 0; 4248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid[0] = '\0'; 4258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid_len = 0; 4268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 4288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (proto_started) 4308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_protocol(ieee); 4318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 4328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 4338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 4348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 4358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, 4378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 4388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 4398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->mode = ieee->iw_mode; 4418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 4428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 4438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, 4458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 4468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 4478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 4488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int *parms = (int *)extra; 4508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int enable = (parms[0] > 0); 4518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short prev = ieee->raw_tx; 4528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 4548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(enable) 4568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->raw_tx = 1; 4578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 4588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->raw_tx = 0; 4598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang printk(KERN_INFO"raw TX is %s\n", 4618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->raw_tx ? "enabled" : "disabled"); 4628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->iw_mode == IW_MODE_MONITOR) 4648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang { 4658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(prev == 0 && ieee->raw_tx){ 4668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->data_hard_resume) 4678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->data_hard_resume(ieee->dev); 4688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_on(ieee->dev); 4708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(prev && ieee->raw_tx == 1) 4738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_off(ieee->dev); 4748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 4778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 4798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 4808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_name(struct ieee80211_device *ieee, 4828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 4838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 4848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 4858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcpy(wrqu->name, "802.11"); 4868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->modulation & IEEE80211_CCK_MODULATION){ 4878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcat(wrqu->name, "b"); 4888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->modulation & IEEE80211_OFDM_MODULATION) 4898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcat(wrqu->name, "/g"); 4908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) 4918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcat(wrqu->name, "g"); 4928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) 4938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcat(wrqu->name, "/n"); 4948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if((ieee->state == IEEE80211_LINKED) || 4968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang (ieee->state == IEEE80211_LINKED_SCANNING)) 4978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcat(wrqu->name," linked"); 4988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else if(ieee->state != IEEE80211_NOLINK) 4998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strcat(wrqu->name," link.."); 5008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 5038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 5048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* this is mostly stolen from hostap */ 5078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_power(struct ieee80211_device *ieee, 5088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 5098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 5108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 5118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret = 0; 5128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 5138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->power.disabled){ 5158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_DISABLED; 5168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto exit; 5178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->power.flags & IW_POWER_TIMEOUT) { 5198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //ieee->ps_period = wrqu->power.value / 1000; 5208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps_timeout = wrqu->power.value / 1000; 5218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->power.flags & IW_POWER_PERIOD) { 5248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //ieee->ps_timeout = wrqu->power.value / 1000; 5268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps_period = wrqu->power.value / 1000; 5278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //wrq->value / 1024; 5288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang switch (wrqu->power.flags & IW_POWER_MODE) { 5318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_UNICAST_R: 5328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_UNICAST; 5338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_MULTICAST_R: 5358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_MBCAST; 5368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_ALL_R: 5388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; 5398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_ON: 5428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang // ieee->ps = IEEE80211_PS_DISABLED; 5438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang default: 5468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EINVAL; 5478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto exit; 5488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangexit: 5518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 5528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 5538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 5558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* this is stolen from hostap */ 5578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_power(struct ieee80211_device *ieee, 5588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 5598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 5608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 5618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret =0; 5628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 5648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->ps == IEEE80211_PS_DISABLED){ 5668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.disabled = 1; 5678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto exit; 5688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.disabled = 0; 5718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 5738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags = IW_POWER_TIMEOUT; 5748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.value = ieee->ps_timeout * 1000; 5758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } else { 5768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang// ret = -EOPNOTSUPP; 5778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang// goto exit; 5788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags = IW_POWER_PERIOD; 5798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.value = ieee->ps_period * 1000; 5808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024; 5818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) 584e406322b4b963e622f41d76193d8ca9e5435adb8Mauro Carvalho Chehab wrqu->power.flags |= IW_POWER_ALL_R; 5858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else if (ieee->ps & IEEE80211_PS_MBCAST) 5868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags |= IW_POWER_MULTICAST_R; 5878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 5888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags |= IW_POWER_UNICAST_R; 5898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangexit: 5918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 5928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 5938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 5958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_essid); 5968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_essid); 5978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_rate); 5988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_rate); 5998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_wap); 6008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_wap); 6018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_mode); 6028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_mode); 6038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_scan); 6048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_freq); 6058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_freq); 6068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_rawtx); 6078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_name); 6088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_power); 6098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_power); 6108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wlan_frequencies); 6118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_set_rts); 6128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_rts); 613