18fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* IEEE 802.11 SoftMAC layer 2559a4c318ca303880fc9f26d50711791c16ae2f3Andrea Merello * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com> 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}; 29539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wlan_frequencies); 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} 86539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_freq); 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} 104539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_freq); 1058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_wap(struct ieee80211_device *ieee, 1078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 1088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 1098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 1108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 1118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->ap_addr.sa_family = ARPHRD_ETHER; 1138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR) 1158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -1; 1168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* We want avoid to give to the user inconsistent infos*/ 1188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 1198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->state != IEEE80211_LINKED && 1218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state != IEEE80211_LINKED_SCANNING && 1228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->wap_set == 0) 1238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 1258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 1268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang memcpy(wrqu->ap_addr.sa_data, 1278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.bssid, ETH_ALEN); 1288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 1308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 1328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 133539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_wap); 1348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_wap(struct ieee80211_device *ieee, 1368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 1378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *awrq, 1388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang char *extra) 1398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 1408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret = 0; 1428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 1438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short ifup = ieee->proto_started;//dev->flags & IFF_UP; 1458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct sockaddr *temp = (struct sockaddr *)awrq; 1468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->sync_scan_hurryup = 1; 1488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 1508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* use ifconfig hw ether */ 1518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MASTER){ 1528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 1538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 1548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 1558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (temp->sa_family != ARPHRD_ETHER){ 1578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EINVAL; 1588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 1598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 1608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ifup) 1628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_protocol(ieee); 1638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* just to avoid to give inconsistent infos in the 1658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * get wx method. not really needed otherwise 1668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang */ 1678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 1688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); 170f6aa782f255de96b89ff4fc98dad0d57a9691c8aWei Yongjun ieee->wap_set = !is_zero_ether_addr(temp->sa_data); 1718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 1738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ifup) 1758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_protocol(ieee); 1768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 1778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 1788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 1798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 180539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_wap); 1818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b) 1838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 1840b4ef0a641d47570bcca4c2206f4736c0f5f4d9eGreg Donald int len, ret = 0; 1858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 1868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR) 1888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -1; 1898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* We want avoid to give to the user inconsistent infos*/ 1918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 1928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->current_network.ssid[0] == '\0' || 1948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid_len == 0){ 1958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 1968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 1978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 1988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 1998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->state != IEEE80211_LINKED && 2008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state != IEEE80211_LINKED_SCANNING && 2018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ssid_set == 0){ 2028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 2038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 2048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang len = ieee->current_network.ssid_len; 2068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->essid.length = len; 2070b4ef0a641d47570bcca4c2206f4736c0f5f4d9eGreg Donald strncpy(b, ieee->current_network.ssid, len); 2088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->essid.flags = 1; 2098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 2118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 2128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 2148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 216539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_essid); 2178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_rate(struct ieee80211_device *ieee, 2198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang u32 target_rate = wrqu->bitrate.value; 2248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->rate = target_rate/100000; 2268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //FIXME: we might want to limit rate also in management protocols. 2278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 229539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_rate); 2308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_rate(struct ieee80211_device *ieee, 2328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang u32 tmp_rate; 2368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate); 2378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->bitrate.value = tmp_rate * 500000; 2398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 242539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_rate); 2438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_rts(struct ieee80211_device *ieee, 2458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->rts.disabled || !wrqu->rts.fixed) 2498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->rts = DEFAULT_RTS_THRESHOLD; 2508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 2518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang { 2528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->rts.value < MIN_RTS_THRESHOLD || 2538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.value > MAX_RTS_THRESHOLD) 2548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return -EINVAL; 2558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->rts = wrqu->rts.value; 2568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 259539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_rts); 2608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_rts(struct ieee80211_device *ieee, 2628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 2638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 2648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.value = ieee->rts; 2668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.fixed = 0; /* no auto select */ 2678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); 2688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 2698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 270539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_rts); 271539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit Taine 2728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, 2738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 2748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 2758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->sync_scan_hurryup = 1; 2778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 2798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->mode == ieee->iw_mode) 2818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 2828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->mode == IW_MODE_MONITOR){ 2848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->dev->type = ARPHRD_IEEE80211; 2868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang }else{ 2878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->dev->type = ARPHRD_ETHER; 2888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (!ieee->proto_started){ 2918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->iw_mode = wrqu->mode; 2928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang }else{ 2938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_protocol(ieee); 2948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->iw_mode = wrqu->mode; 2958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_protocol(ieee); 2968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 2978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 2988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 2998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 3008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 3018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 302539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_mode); 3038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangvoid ieee80211_wx_sync_scan_wq(struct work_struct *work) 3058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 306e406322b4b963e622f41d76193d8ca9e5435adb8Mauro Carvalho Chehab struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); 3078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short chan; 3088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang HT_EXTCHNL_OFFSET chan_offset=0; 3098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang HT_CHANNEL_WIDTH bandwidth=0; 3108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int b40M = 0; 311de13a3dad603e1796fba106b38eaf96cabd232c1Sebastian Hahn static int count; 3128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang chan = ieee->current_network.channel; 3138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_off(ieee->dev); 3148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->data_hard_stop) 3168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->data_hard_stop(ieee->dev); 3178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_send_beacons(ieee); 3198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state = IEEE80211_LINKED_SCANNING; 3218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->link_change(ieee->dev); 3220b4ef0a641d47570bcca4c2206f4736c0f5f4d9eGreg Donald ieee->InitialGainHandler(ieee->dev, IG_Backup); 3238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { 3248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang b40M = 1; 3258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; 3268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz; 3278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth); 3288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); 3298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_scan_syncro(ieee); 3318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (b40M) { 3328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang printk("Scan in 20M, back to 40M\n"); 3338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) 3348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan + 2); 3358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) 3368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan - 2); 3378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 3388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan); 3398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); 3408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } else { 3418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->set_chan(ieee->dev, chan); 3428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3440b4ef0a641d47570bcca4c2206f4736c0f5f4d9eGreg Donald ieee->InitialGainHandler(ieee->dev, IG_Restore); 3458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->state = IEEE80211_LINKED; 3468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->link_change(ieee->dev); 3478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang // To prevent the immediately calling watch_dog after scan. 3488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) 3498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang { 3508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; 3518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; 3528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->data_hard_resume) 3548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->data_hard_resume(ieee->dev); 3558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) 3578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_send_beacons(ieee); 3588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_on(ieee->dev); 3608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang count = 0; 3618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 3628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 3648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, 3668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 3678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 3688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret = 0; 3698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 3718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){ 3738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -1; 3748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 3758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ( ieee->state == IEEE80211_LINKED){ 3788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang queue_work(ieee->wq, &ieee->wx_sync_scan_wq); 3798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* intentionally forget to up sem */ 3808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 3818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 3828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 3848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 3858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 3868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 387539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_scan); 3888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_essid(struct ieee80211_device *ieee, 3908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *a, 3918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 3928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 3938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret=0,len; 3958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short proto_started; 3968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang unsigned long flags; 3978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 3988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->sync_scan_hurryup = 1; 3998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 4008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang proto_started = ieee->proto_started; 4028fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ 4048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret= -E2BIG; 4058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 4068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4078fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4088fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->iw_mode == IW_MODE_MONITOR){ 4098fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret= -1; 4108fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto out; 4118fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(proto_started) 4148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_stop_protocol(ieee); 4158fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang /* this is just to be sure that the GET wx callback 4188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang * has consisten infos. not needed otherwise 4198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang */ 4208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_lock_irqsave(&ieee->lock, flags); 4218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->essid.flags && wrqu->essid.length) { 4238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //first flush current network.ssid 4248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; 4258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang strncpy(ieee->current_network.ssid, extra, len+1); 4268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid_len = len+1; 4278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ssid_set = 1; 4288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else{ 4308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ssid_set = 0; 4318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid[0] = '\0'; 4328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->current_network.ssid_len = 0; 4338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang spin_unlock_irqrestore(&ieee->lock, flags); 4358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (proto_started) 4378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee80211_start_protocol(ieee); 4388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangout: 4398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 4408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 4418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 442539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_essid); 4438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, 4458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *b) 4468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 4478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->mode = ieee->iw_mode; 4498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 4508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 451539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_mode); 4528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, 4548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 4558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 4568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 4578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int *parms = (int *)extra; 4598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int enable = (parms[0] > 0); 4608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang short prev = ieee->raw_tx; 4618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 4638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(enable) 4658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->raw_tx = 1; 4668fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 4678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->raw_tx = 0; 4688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang printk(KERN_INFO"raw TX is %s\n", 4708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->raw_tx ? "enabled" : "disabled"); 4718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->iw_mode == IW_MODE_MONITOR) 4738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang { 4748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(prev == 0 && ieee->raw_tx){ 4758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (ieee->data_hard_resume) 4768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->data_hard_resume(ieee->dev); 4778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_on(ieee->dev); 4798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(prev && ieee->raw_tx == 1) 4828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang netif_carrier_off(ieee->dev); 4838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 4848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 4868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 4888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 489539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_rawtx); 4908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 4918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_name(struct ieee80211_device *ieee, 4928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 4938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 4948fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 49567a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcpy(wrqu->name, "802.11", IFNAMSIZ); 49667a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe if (ieee->modulation & IEEE80211_CCK_MODULATION) { 49767a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcat(wrqu->name, "b", IFNAMSIZ); 49867a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe if (ieee->modulation & IEEE80211_OFDM_MODULATION) 49967a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcat(wrqu->name, "/g", IFNAMSIZ); 50067a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) { 50167a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcat(wrqu->name, "g", IFNAMSIZ); 50267a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe } 5038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 50467a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) 50567a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcat(wrqu->name, "/n", IFNAMSIZ); 5068fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 50767a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe if ((ieee->state == IEEE80211_LINKED) || 50867a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe (ieee->state == IEEE80211_LINKED_SCANNING)) 50967a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcat(wrqu->name, " linked", IFNAMSIZ); 51067a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe else if (ieee->state != IEEE80211_NOLINK) 51167a88e6390e52e42b72342a88fab458ada00ba28Peter Huewe strlcat(wrqu->name, " link..", IFNAMSIZ); 5128fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5138fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return 0; 5148fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 515539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_get_name); 5168fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5178fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* this is mostly stolen from hostap */ 5188fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_set_power(struct ieee80211_device *ieee, 5198fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 5208fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 5218fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 5228fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang int ret = 0; 5238fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 5248fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5258fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->power.disabled){ 5268fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_DISABLED; 5278fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto exit; 5288fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5298fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->power.flags & IW_POWER_TIMEOUT) { 5308fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //ieee->ps_period = wrqu->power.value / 1000; 5318fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps_timeout = wrqu->power.value / 1000; 5328fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5338fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5348fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if (wrqu->power.flags & IW_POWER_PERIOD) { 5358fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5368fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //ieee->ps_timeout = wrqu->power.value / 1000; 5378fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps_period = wrqu->power.value / 1000; 5388fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang //wrq->value / 1024; 5398fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5408fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5418fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang switch (wrqu->power.flags & IW_POWER_MODE) { 5428fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_UNICAST_R: 5438fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_UNICAST; 5448fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5458fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_MULTICAST_R: 5468fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_MBCAST; 5478fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5488fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_ALL_R: 5498fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; 5508fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5518fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5528fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang case IW_POWER_ON: 5538fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang // ieee->ps = IEEE80211_PS_DISABLED; 5548fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang break; 5558fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5568fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang default: 5578fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang ret = -EINVAL; 5588fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto exit; 5598fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5608fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5618fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangexit: 5628fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 5638fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang return ret; 5648fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5658fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 566539b4f72d0da83e4d20df7cfc27dc49c00316940Benoit TaineEXPORT_SYMBOL(ieee80211_wx_set_power); 5678fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5688fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang/* this is stolen from hostap */ 5698fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangint ieee80211_wx_get_power(struct ieee80211_device *ieee, 5708fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang struct iw_request_info *info, 5718fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang union iwreq_data *wrqu, char *extra) 5728fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang{ 5738fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang down(&ieee->wx_sem); 5748fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5758fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if(ieee->ps == IEEE80211_PS_DISABLED){ 5768fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.disabled = 1; 5778fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang goto exit; 5788fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5798fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5808fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.disabled = 0; 5818fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5828fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { 5838fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags = IW_POWER_TIMEOUT; 5848fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.value = ieee->ps_timeout * 1000; 5858fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } else { 5868fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang// ret = -EOPNOTSUPP; 5878fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang// goto exit; 5888fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags = IW_POWER_PERIOD; 5898fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.value = ieee->ps_period * 1000; 5908fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang//ieee->current_network.dtim_period * ieee->current_network.beacon_interval * 1024; 5918fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang } 5928fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 5938fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) 594e406322b4b963e622f41d76193d8ca9e5435adb8Mauro Carvalho Chehab wrqu->power.flags |= IW_POWER_ALL_R; 5958fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else if (ieee->ps & IEEE80211_PS_MBCAST) 5968fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags |= IW_POWER_MULTICAST_R; 5978fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang else 5988fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang wrqu->power.flags |= IW_POWER_UNICAST_R; 5998fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 6008fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuangexit: 6018fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang up(&ieee->wx_sem); 6024764ca981b040048766e4f39a45a4b9c5cecff9cPeter Senna Tschudin return 0; 6038fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang 6048fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry Chuang} 6058fc8598e61f6f384f3eaf1d9b09500c12af47b37Jerry ChuangEXPORT_SYMBOL(ieee80211_wx_get_power); 606