aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap')
-rw-r--r--drivers/net/wireless/hostap/hostap.h3
-rw-r--r--drivers/net/wireless/hostap/hostap_80211_rx.c21
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c32
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c5
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c63
-rw-r--r--drivers/net/wireless/hostap/hostap_main.c20
-rw-r--r--drivers/net/wireless/hostap/hostap_wlan.h14
7 files changed, 91 insertions, 67 deletions
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 547ba84dc797..3a386a636cca 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
67int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], 67int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
68 struct iw_quality qual[], int buf_size, 68 struct iw_quality qual[], int buf_size,
69 int aplist); 69 int aplist);
70int prism2_ap_translate_scan(struct net_device *dev, char *buffer); 70int prism2_ap_translate_scan(struct net_device *dev,
71 struct iw_request_info *info, char *buffer);
71int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); 72int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
72 73
73 74
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 020f450e9dba..f106bc1585a4 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -78,6 +78,9 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
78 prism_header = 2; 78 prism_header = 2;
79 phdrlen = sizeof(struct linux_wlan_ng_cap_hdr); 79 phdrlen = sizeof(struct linux_wlan_ng_cap_hdr);
80 } 80 }
81 } else if (dev->type == ARPHRD_IEEE80211_RADIOTAP) {
82 prism_header = 3;
83 phdrlen = sizeof(struct hostap_radiotap_rx);
81 } else { 84 } else {
82 prism_header = 0; 85 prism_header = 0;
83 phdrlen = 0; 86 phdrlen = 0;
@@ -165,6 +168,24 @@ hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
165 hdr->ssi_noise = htonl(rx_stats->noise); 168 hdr->ssi_noise = htonl(rx_stats->noise);
166 hdr->preamble = htonl(0); /* unknown */ 169 hdr->preamble = htonl(0); /* unknown */
167 hdr->encoding = htonl(1); /* cck */ 170 hdr->encoding = htonl(1); /* cck */
171 } else if (prism_header == 3) {
172 struct hostap_radiotap_rx *hdr;
173 hdr = (struct hostap_radiotap_rx *)skb_push(skb, phdrlen);
174 memset(hdr, 0, phdrlen);
175 hdr->hdr.it_len = cpu_to_le16(phdrlen);
176 hdr->hdr.it_present =
177 cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
178 (1 << IEEE80211_RADIOTAP_CHANNEL) |
179 (1 << IEEE80211_RADIOTAP_RATE) |
180 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
181 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE));
182 hdr->tsft = cpu_to_le64(rx_stats->mac_time);
183 hdr->chan_freq = cpu_to_le16(freq_list[local->channel - 1]);
184 hdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_CCK |
185 IEEE80211_CHAN_2GHZ);
186 hdr->rate = rx_stats->rate / 5;
187 hdr->dbm_antsignal = rx_stats->signal;
188 hdr->dbm_antnoise = rx_stats->noise;
168 } 189 }
169 190
170 ret = skb->len - phdrlen; 191 ret = skb->len - phdrlen;
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index ab981afd481d..af3d4ef2a80b 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
2420 2420
2421/* Translate our list of Access Points & Stations to a card independant 2421/* Translate our list of Access Points & Stations to a card independant
2422 * format that the Wireless Tools will understand - Jean II */ 2422 * format that the Wireless Tools will understand - Jean II */
2423int prism2_ap_translate_scan(struct net_device *dev, char *buffer) 2423int prism2_ap_translate_scan(struct net_device *dev,
2424 struct iw_request_info *info, char *buffer)
2424{ 2425{
2425 struct hostap_interface *iface; 2426 struct hostap_interface *iface;
2426 local_info_t *local; 2427 local_info_t *local;
@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2449 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 2450 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2450 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN); 2451 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
2451 iwe.len = IW_EV_ADDR_LEN; 2452 iwe.len = IW_EV_ADDR_LEN;
2452 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 2453 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2453 IW_EV_ADDR_LEN); 2454 &iwe, IW_EV_ADDR_LEN);
2454 2455
2455 /* Use the mode to indicate if it's a station or 2456 /* Use the mode to indicate if it's a station or
2456 * an Access Point */ 2457 * an Access Point */
@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2461 else 2462 else
2462 iwe.u.mode = IW_MODE_INFRA; 2463 iwe.u.mode = IW_MODE_INFRA;
2463 iwe.len = IW_EV_UINT_LEN; 2464 iwe.len = IW_EV_UINT_LEN;
2464 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 2465 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2465 IW_EV_UINT_LEN); 2466 &iwe, IW_EV_UINT_LEN);
2466 2467
2467 /* Some quality */ 2468 /* Some quality */
2468 memset(&iwe, 0, sizeof(iwe)); 2469 memset(&iwe, 0, sizeof(iwe));
@@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2477 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); 2478 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2478 iwe.u.qual.updated = sta->last_rx_updated; 2479 iwe.u.qual.updated = sta->last_rx_updated;
2479 iwe.len = IW_EV_QUAL_LEN; 2480 iwe.len = IW_EV_QUAL_LEN;
2480 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 2481 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2481 IW_EV_QUAL_LEN); 2482 &iwe, IW_EV_QUAL_LEN);
2482 2483
2483#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT 2484#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2484 if (sta->ap) { 2485 if (sta->ap) {
@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2486 iwe.cmd = SIOCGIWESSID; 2487 iwe.cmd = SIOCGIWESSID;
2487 iwe.u.data.length = sta->u.ap.ssid_len; 2488 iwe.u.data.length = sta->u.ap.ssid_len;
2488 iwe.u.data.flags = 1; 2489 iwe.u.data.flags = 1;
2489 current_ev = iwe_stream_add_point(current_ev, end_buf, 2490 current_ev = iwe_stream_add_point(info, current_ev,
2490 &iwe, 2491 end_buf, &iwe,
2491 sta->u.ap.ssid); 2492 sta->u.ap.ssid);
2492 2493
2493 memset(&iwe, 0, sizeof(iwe)); 2494 memset(&iwe, 0, sizeof(iwe));
@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2497 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 2498 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2498 else 2499 else
2499 iwe.u.data.flags = IW_ENCODE_DISABLED; 2500 iwe.u.data.flags = IW_ENCODE_DISABLED;
2500 current_ev = iwe_stream_add_point(current_ev, end_buf, 2501 current_ev = iwe_stream_add_point(info, current_ev,
2501 &iwe, 2502 end_buf, &iwe,
2502 sta->u.ap.ssid 2503 sta->u.ap.ssid);
2503 /* 0 byte memcpy */);
2504 2504
2505 if (sta->u.ap.channel > 0 && 2505 if (sta->u.ap.channel > 0 &&
2506 sta->u.ap.channel <= FREQ_COUNT) { 2506 sta->u.ap.channel <= FREQ_COUNT) {
@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2510 * 100000; 2510 * 100000;
2511 iwe.u.freq.e = 1; 2511 iwe.u.freq.e = 1;
2512 current_ev = iwe_stream_add_event( 2512 current_ev = iwe_stream_add_event(
2513 current_ev, end_buf, &iwe, 2513 info, current_ev, end_buf, &iwe,
2514 IW_EV_FREQ_LEN); 2514 IW_EV_FREQ_LEN);
2515 } 2515 }
2516 2516
@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2519 sprintf(buf, "beacon_interval=%d", 2519 sprintf(buf, "beacon_interval=%d",
2520 sta->listen_interval); 2520 sta->listen_interval);
2521 iwe.u.data.length = strlen(buf); 2521 iwe.u.data.length = strlen(buf);
2522 current_ev = iwe_stream_add_point(current_ev, end_buf, 2522 current_ev = iwe_stream_add_point(info, current_ev,
2523 &iwe, buf); 2523 end_buf, &iwe, buf);
2524 } 2524 }
2525#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 2525#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2526 2526
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index 936f52e3d95c..09004a632ae7 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3204,6 +3204,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
3204 local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY; 3204 local->auth_algs = PRISM2_AUTH_OPEN | PRISM2_AUTH_SHARED_KEY;
3205 local->sram_type = -1; 3205 local->sram_type = -1;
3206 local->scan_channel_mask = 0xffff; 3206 local->scan_channel_mask = 0xffff;
3207 local->monitor_type = PRISM2_MONITOR_RADIOTAP;
3207 3208
3208 /* Initialize task queue structures */ 3209 /* Initialize task queue structures */
3209 INIT_WORK(&local->reset_queue, handle_reset_queue); 3210 INIT_WORK(&local->reset_queue, handle_reset_queue);
@@ -3416,7 +3417,7 @@ static void prism2_free_local_data(struct net_device *dev)
3416} 3417}
3417 3418
3418 3419
3419#ifndef PRISM2_PLX 3420#if (defined(PRISM2_PCI) && defined(CONFIG_PM)) || defined(PRISM2_PCCARD)
3420static void prism2_suspend(struct net_device *dev) 3421static void prism2_suspend(struct net_device *dev)
3421{ 3422{
3422 struct hostap_interface *iface; 3423 struct hostap_interface *iface;
@@ -3435,7 +3436,7 @@ static void prism2_suspend(struct net_device *dev)
3435 /* Disable hardware and firmware */ 3436 /* Disable hardware and firmware */
3436 prism2_hw_shutdown(dev, 0); 3437 prism2_hw_shutdown(dev, 0);
3437} 3438}
3438#endif /* PRISM2_PLX */ 3439#endif /* (PRISM2_PCI && CONFIG_PM) || PRISM2_PCCARD */
3439 3440
3440 3441
3441/* These might at some point be compiled separately and used as separate 3442/* These might at some point be compiled separately and used as separate
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 0ca0bfeb0ada..3f8b1d7036e5 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -897,6 +897,8 @@ static void hostap_monitor_set_type(local_info_t *local)
897 if (local->monitor_type == PRISM2_MONITOR_PRISM || 897 if (local->monitor_type == PRISM2_MONITOR_PRISM ||
898 local->monitor_type == PRISM2_MONITOR_CAPHDR) { 898 local->monitor_type == PRISM2_MONITOR_CAPHDR) {
899 dev->type = ARPHRD_IEEE80211_PRISM; 899 dev->type = ARPHRD_IEEE80211_PRISM;
900 } else if (local->monitor_type == PRISM2_MONITOR_RADIOTAP) {
901 dev->type = ARPHRD_IEEE80211_RADIOTAP;
900 } else { 902 } else {
901 dev->type = ARPHRD_IEEE80211; 903 dev->type = ARPHRD_IEEE80211;
902 } 904 }
@@ -1793,6 +1795,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
1793 1795
1794#ifndef PRISM2_NO_STATION_MODES 1796#ifndef PRISM2_NO_STATION_MODES
1795static char * __prism2_translate_scan(local_info_t *local, 1797static char * __prism2_translate_scan(local_info_t *local,
1798 struct iw_request_info *info,
1796 struct hfa384x_hostscan_result *scan, 1799 struct hfa384x_hostscan_result *scan,
1797 struct hostap_bss_info *bss, 1800 struct hostap_bss_info *bss,
1798 char *current_ev, char *end_buf) 1801 char *current_ev, char *end_buf)
@@ -1823,7 +1826,7 @@ static char * __prism2_translate_scan(local_info_t *local,
1823 iwe.cmd = SIOCGIWAP; 1826 iwe.cmd = SIOCGIWAP;
1824 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1827 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1825 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN); 1828 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
1826 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1829 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
1827 IW_EV_ADDR_LEN); 1830 IW_EV_ADDR_LEN);
1828 1831
1829 /* Other entries will be displayed in the order we give them */ 1832 /* Other entries will be displayed in the order we give them */
@@ -1832,7 +1835,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1832 iwe.cmd = SIOCGIWESSID; 1835 iwe.cmd = SIOCGIWESSID;
1833 iwe.u.data.length = ssid_len; 1836 iwe.u.data.length = ssid_len;
1834 iwe.u.data.flags = 1; 1837 iwe.u.data.flags = 1;
1835 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid); 1838 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1839 &iwe, ssid);
1836 1840
1837 memset(&iwe, 0, sizeof(iwe)); 1841 memset(&iwe, 0, sizeof(iwe));
1838 iwe.cmd = SIOCGIWMODE; 1842 iwe.cmd = SIOCGIWMODE;
@@ -1847,8 +1851,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1847 iwe.u.mode = IW_MODE_MASTER; 1851 iwe.u.mode = IW_MODE_MASTER;
1848 else 1852 else
1849 iwe.u.mode = IW_MODE_ADHOC; 1853 iwe.u.mode = IW_MODE_ADHOC;
1850 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1854 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1851 IW_EV_UINT_LEN); 1855 &iwe, IW_EV_UINT_LEN);
1852 } 1856 }
1853 1857
1854 memset(&iwe, 0, sizeof(iwe)); 1858 memset(&iwe, 0, sizeof(iwe));
@@ -1864,8 +1868,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1864 if (chan > 0) { 1868 if (chan > 0) {
1865 iwe.u.freq.m = freq_list[chan - 1] * 100000; 1869 iwe.u.freq.m = freq_list[chan - 1] * 100000;
1866 iwe.u.freq.e = 1; 1870 iwe.u.freq.e = 1;
1867 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1871 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1868 IW_EV_FREQ_LEN); 1872 &iwe, IW_EV_FREQ_LEN);
1869 } 1873 }
1870 1874
1871 if (scan) { 1875 if (scan) {
@@ -1884,8 +1888,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1884 | IW_QUAL_NOISE_UPDATED 1888 | IW_QUAL_NOISE_UPDATED
1885 | IW_QUAL_QUAL_INVALID 1889 | IW_QUAL_QUAL_INVALID
1886 | IW_QUAL_DBM; 1890 | IW_QUAL_DBM;
1887 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1891 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1888 IW_EV_QUAL_LEN); 1892 &iwe, IW_EV_QUAL_LEN);
1889 } 1893 }
1890 1894
1891 memset(&iwe, 0, sizeof(iwe)); 1895 memset(&iwe, 0, sizeof(iwe));
@@ -1895,13 +1899,13 @@ static char * __prism2_translate_scan(local_info_t *local,
1895 else 1899 else
1896 iwe.u.data.flags = IW_ENCODE_DISABLED; 1900 iwe.u.data.flags = IW_ENCODE_DISABLED;
1897 iwe.u.data.length = 0; 1901 iwe.u.data.length = 0;
1898 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); 1902 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
1899 1903
1900 /* TODO: add SuppRates into BSS table */ 1904 /* TODO: add SuppRates into BSS table */
1901 if (scan) { 1905 if (scan) {
1902 memset(&iwe, 0, sizeof(iwe)); 1906 memset(&iwe, 0, sizeof(iwe));
1903 iwe.cmd = SIOCGIWRATE; 1907 iwe.cmd = SIOCGIWRATE;
1904 current_val = current_ev + IW_EV_LCP_LEN; 1908 current_val = current_ev + iwe_stream_lcp_len(info);
1905 pos = scan->sup_rates; 1909 pos = scan->sup_rates;
1906 for (i = 0; i < sizeof(scan->sup_rates); i++) { 1910 for (i = 0; i < sizeof(scan->sup_rates); i++) {
1907 if (pos[i] == 0) 1911 if (pos[i] == 0)
@@ -1909,11 +1913,11 @@ static char * __prism2_translate_scan(local_info_t *local,
1909 /* Bit rate given in 500 kb/s units (+ 0x80) */ 1913 /* Bit rate given in 500 kb/s units (+ 0x80) */
1910 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000); 1914 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
1911 current_val = iwe_stream_add_value( 1915 current_val = iwe_stream_add_value(
1912 current_ev, current_val, end_buf, &iwe, 1916 info, current_ev, current_val, end_buf, &iwe,
1913 IW_EV_PARAM_LEN); 1917 IW_EV_PARAM_LEN);
1914 } 1918 }
1915 /* Check if we added any event */ 1919 /* Check if we added any event */
1916 if ((current_val - current_ev) > IW_EV_LCP_LEN) 1920 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
1917 current_ev = current_val; 1921 current_ev = current_val;
1918 } 1922 }
1919 1923
@@ -1924,15 +1928,15 @@ static char * __prism2_translate_scan(local_info_t *local,
1924 iwe.cmd = IWEVCUSTOM; 1928 iwe.cmd = IWEVCUSTOM;
1925 sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval)); 1929 sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
1926 iwe.u.data.length = strlen(buf); 1930 iwe.u.data.length = strlen(buf);
1927 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 1931 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1928 buf); 1932 &iwe, buf);
1929 1933
1930 memset(&iwe, 0, sizeof(iwe)); 1934 memset(&iwe, 0, sizeof(iwe));
1931 iwe.cmd = IWEVCUSTOM; 1935 iwe.cmd = IWEVCUSTOM;
1932 sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate)); 1936 sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
1933 iwe.u.data.length = strlen(buf); 1937 iwe.u.data.length = strlen(buf);
1934 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 1938 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1935 buf); 1939 &iwe, buf);
1936 1940
1937 if (local->last_scan_type == PRISM2_HOSTSCAN && 1941 if (local->last_scan_type == PRISM2_HOSTSCAN &&
1938 (capabilities & WLAN_CAPABILITY_IBSS)) { 1942 (capabilities & WLAN_CAPABILITY_IBSS)) {
@@ -1940,8 +1944,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1940 iwe.cmd = IWEVCUSTOM; 1944 iwe.cmd = IWEVCUSTOM;
1941 sprintf(buf, "atim=%d", le16_to_cpu(scan->atim)); 1945 sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
1942 iwe.u.data.length = strlen(buf); 1946 iwe.u.data.length = strlen(buf);
1943 current_ev = iwe_stream_add_point(current_ev, end_buf, 1947 current_ev = iwe_stream_add_point(info, current_ev,
1944 &iwe, buf); 1948 end_buf, &iwe, buf);
1945 } 1949 }
1946 } 1950 }
1947 kfree(buf); 1951 kfree(buf);
@@ -1950,16 +1954,16 @@ static char * __prism2_translate_scan(local_info_t *local,
1950 memset(&iwe, 0, sizeof(iwe)); 1954 memset(&iwe, 0, sizeof(iwe));
1951 iwe.cmd = IWEVGENIE; 1955 iwe.cmd = IWEVGENIE;
1952 iwe.u.data.length = bss->wpa_ie_len; 1956 iwe.u.data.length = bss->wpa_ie_len;
1953 current_ev = iwe_stream_add_point( 1957 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1954 current_ev, end_buf, &iwe, bss->wpa_ie); 1958 &iwe, bss->wpa_ie);
1955 } 1959 }
1956 1960
1957 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) { 1961 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
1958 memset(&iwe, 0, sizeof(iwe)); 1962 memset(&iwe, 0, sizeof(iwe));
1959 iwe.cmd = IWEVGENIE; 1963 iwe.cmd = IWEVGENIE;
1960 iwe.u.data.length = bss->rsn_ie_len; 1964 iwe.u.data.length = bss->rsn_ie_len;
1961 current_ev = iwe_stream_add_point( 1965 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1962 current_ev, end_buf, &iwe, bss->rsn_ie); 1966 &iwe, bss->rsn_ie);
1963 } 1967 }
1964 1968
1965 return current_ev; 1969 return current_ev;
@@ -1969,6 +1973,7 @@ static char * __prism2_translate_scan(local_info_t *local,
1969/* Translate scan data returned from the card to a card independant 1973/* Translate scan data returned from the card to a card independant
1970 * format that the Wireless Tools will understand - Jean II */ 1974 * format that the Wireless Tools will understand - Jean II */
1971static inline int prism2_translate_scan(local_info_t *local, 1975static inline int prism2_translate_scan(local_info_t *local,
1976 struct iw_request_info *info,
1972 char *buffer, int buflen) 1977 char *buffer, int buflen)
1973{ 1978{
1974 struct hfa384x_hostscan_result *scan; 1979 struct hfa384x_hostscan_result *scan;
@@ -1999,13 +2004,14 @@ static inline int prism2_translate_scan(local_info_t *local,
1999 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { 2004 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
2000 bss->included = 1; 2005 bss->included = 1;
2001 current_ev = __prism2_translate_scan( 2006 current_ev = __prism2_translate_scan(
2002 local, scan, bss, current_ev, end_buf); 2007 local, info, scan, bss, current_ev,
2008 end_buf);
2003 found++; 2009 found++;
2004 } 2010 }
2005 } 2011 }
2006 if (!found) { 2012 if (!found) {
2007 current_ev = __prism2_translate_scan( 2013 current_ev = __prism2_translate_scan(
2008 local, scan, NULL, current_ev, end_buf); 2014 local, info, scan, NULL, current_ev, end_buf);
2009 } 2015 }
2010 /* Check if there is space for one more entry */ 2016 /* Check if there is space for one more entry */
2011 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { 2017 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2023,7 +2029,7 @@ static inline int prism2_translate_scan(local_info_t *local,
2023 bss = list_entry(ptr, struct hostap_bss_info, list); 2029 bss = list_entry(ptr, struct hostap_bss_info, list);
2024 if (bss->included) 2030 if (bss->included)
2025 continue; 2031 continue;
2026 current_ev = __prism2_translate_scan(local, NULL, bss, 2032 current_ev = __prism2_translate_scan(local, info, NULL, bss,
2027 current_ev, end_buf); 2033 current_ev, end_buf);
2028 /* Check if there is space for one more entry */ 2034 /* Check if there is space for one more entry */
2029 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { 2035 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2070,7 +2076,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
2070 } 2076 }
2071 local->scan_timestamp = 0; 2077 local->scan_timestamp = 0;
2072 2078
2073 res = prism2_translate_scan(local, extra, data->length); 2079 res = prism2_translate_scan(local, info, extra, data->length);
2074 2080
2075 if (res >= 0) { 2081 if (res >= 0) {
2076 data->length = res; 2082 data->length = res;
@@ -2103,7 +2109,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
2103 * Jean II */ 2109 * Jean II */
2104 2110
2105 /* Translate to WE format */ 2111 /* Translate to WE format */
2106 res = prism2_ap_translate_scan(dev, extra); 2112 res = prism2_ap_translate_scan(dev, info, extra);
2107 if (res >= 0) { 2113 if (res >= 0) {
2108 printk(KERN_DEBUG "Scan result translation succeeded " 2114 printk(KERN_DEBUG "Scan result translation succeeded "
2109 "(length=%d)\n", res); 2115 "(length=%d)\n", res);
@@ -2516,7 +2522,8 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
2516 case PRISM2_PARAM_MONITOR_TYPE: 2522 case PRISM2_PARAM_MONITOR_TYPE:
2517 if (value != PRISM2_MONITOR_80211 && 2523 if (value != PRISM2_MONITOR_80211 &&
2518 value != PRISM2_MONITOR_CAPHDR && 2524 value != PRISM2_MONITOR_CAPHDR &&
2519 value != PRISM2_MONITOR_PRISM) { 2525 value != PRISM2_MONITOR_PRISM &&
2526 value != PRISM2_MONITOR_RADIOTAP) {
2520 ret = -EINVAL; 2527 ret = -EINVAL;
2521 break; 2528 break;
2522 } 2529 }
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index a38e85f334df..756ab56c1f40 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -597,25 +597,7 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
597static int hostap_80211_header_parse(const struct sk_buff *skb, 597static int hostap_80211_header_parse(const struct sk_buff *skb,
598 unsigned char *haddr) 598 unsigned char *haddr)
599{ 599{
600 struct hostap_interface *iface = netdev_priv(skb->dev); 600 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
601 local_info_t *local = iface->local;
602
603 if (local->monitor_type == PRISM2_MONITOR_PRISM ||
604 local->monitor_type == PRISM2_MONITOR_CAPHDR) {
605 const unsigned char *mac = skb_mac_header(skb);
606
607 if (*(u32 *)mac == LWNG_CAP_DID_BASE) {
608 memcpy(haddr,
609 mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10,
610 ETH_ALEN); /* addr2 */
611 } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */
612 memcpy(haddr,
613 mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10,
614 ETH_ALEN); /* addr2 */
615 }
616 } else
617 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
618
619 return ETH_ALEN; 601 return ETH_ALEN;
620} 602}
621 603
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index 15445bce2ac7..ffdf4876121b 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -5,6 +5,7 @@
5#include <linux/netdevice.h> 5#include <linux/netdevice.h>
6#include <linux/mutex.h> 6#include <linux/mutex.h>
7#include <net/iw_handler.h> 7#include <net/iw_handler.h>
8#include <net/ieee80211_radiotap.h>
8 9
9#include "hostap_config.h" 10#include "hostap_config.h"
10#include "hostap_common.h" 11#include "hostap_common.h"
@@ -55,6 +56,17 @@ struct linux_wlan_ng_cap_hdr {
55 __be32 encoding; 56 __be32 encoding;
56} __attribute__ ((packed)); 57} __attribute__ ((packed));
57 58
59struct hostap_radiotap_rx {
60 struct ieee80211_radiotap_header hdr;
61 __le64 tsft;
62 u8 rate;
63 u8 padding;
64 __le16 chan_freq;
65 __le16 chan_flags;
66 s8 dbm_antsignal;
67 s8 dbm_antnoise;
68} __attribute__ ((packed));
69
58#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */ 70#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */
59#define LWNG_CAPHDR_VERSION 0x80211001 71#define LWNG_CAPHDR_VERSION 0x80211001
60 72
@@ -734,7 +746,7 @@ struct local_info {
734 unsigned long scan_timestamp; /* Time started to scan */ 746 unsigned long scan_timestamp; /* Time started to scan */
735 enum { 747 enum {
736 PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1, 748 PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
737 PRISM2_MONITOR_CAPHDR = 2 749 PRISM2_MONITOR_CAPHDR = 2, PRISM2_MONITOR_RADIOTAP = 3
738 } monitor_type; 750 } monitor_type;
739 int monitor_allow_fcserr; 751 int monitor_allow_fcserr;
740 752