aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2200.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r--drivers/net/wireless/ipw2200.c599
1 files changed, 573 insertions, 26 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 11730448a821..94172558cd03 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -65,6 +65,11 @@ static const char ipw_modes[] = {
65}; 65};
66static int antenna = CFG_SYS_ANTENNA_BOTH; 66static int antenna = CFG_SYS_ANTENNA_BOTH;
67 67
68#ifdef CONFIG_IPW2200_PROMISCUOUS
69static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
70#endif
71
72
68#ifdef CONFIG_IPW_QOS 73#ifdef CONFIG_IPW_QOS
69static int qos_enable = 0; 74static int qos_enable = 0;
70static int qos_burst_enable = 0; 75static int qos_burst_enable = 0;
@@ -1272,6 +1277,105 @@ static ssize_t show_cmd_log(struct device *d,
1272 1277
1273static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL); 1278static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
1274 1279
1280#ifdef CONFIG_IPW2200_PROMISCUOUS
1281static void ipw_prom_free(struct ipw_priv *priv);
1282static int ipw_prom_alloc(struct ipw_priv *priv);
1283static ssize_t store_rtap_iface(struct device *d,
1284 struct device_attribute *attr,
1285 const char *buf, size_t count)
1286{
1287 struct ipw_priv *priv = dev_get_drvdata(d);
1288 int rc = 0;
1289
1290 if (count < 1)
1291 return -EINVAL;
1292
1293 switch (buf[0]) {
1294 case '0':
1295 if (!rtap_iface)
1296 return count;
1297
1298 if (netif_running(priv->prom_net_dev)) {
1299 IPW_WARNING("Interface is up. Cannot unregister.\n");
1300 return count;
1301 }
1302
1303 ipw_prom_free(priv);
1304 rtap_iface = 0;
1305 break;
1306
1307 case '1':
1308 if (rtap_iface)
1309 return count;
1310
1311 rc = ipw_prom_alloc(priv);
1312 if (!rc)
1313 rtap_iface = 1;
1314 break;
1315
1316 default:
1317 return -EINVAL;
1318 }
1319
1320 if (rc) {
1321 IPW_ERROR("Failed to register promiscuous network "
1322 "device (error %d).\n", rc);
1323 }
1324
1325 return count;
1326}
1327
1328static ssize_t show_rtap_iface(struct device *d,
1329 struct device_attribute *attr,
1330 char *buf)
1331{
1332 struct ipw_priv *priv = dev_get_drvdata(d);
1333 if (rtap_iface)
1334 return sprintf(buf, "%s", priv->prom_net_dev->name);
1335 else {
1336 buf[0] = '-';
1337 buf[1] = '1';
1338 buf[2] = '\0';
1339 return 3;
1340 }
1341}
1342
1343static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface,
1344 store_rtap_iface);
1345
1346static ssize_t store_rtap_filter(struct device *d,
1347 struct device_attribute *attr,
1348 const char *buf, size_t count)
1349{
1350 struct ipw_priv *priv = dev_get_drvdata(d);
1351
1352 if (!priv->prom_priv) {
1353 IPW_ERROR("Attempting to set filter without "
1354 "rtap_iface enabled.\n");
1355 return -EPERM;
1356 }
1357
1358 priv->prom_priv->filter = simple_strtol(buf, NULL, 0);
1359
1360 IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n",
1361 BIT_ARG16(priv->prom_priv->filter));
1362
1363 return count;
1364}
1365
1366static ssize_t show_rtap_filter(struct device *d,
1367 struct device_attribute *attr,
1368 char *buf)
1369{
1370 struct ipw_priv *priv = dev_get_drvdata(d);
1371 return sprintf(buf, "0x%04X",
1372 priv->prom_priv ? priv->prom_priv->filter : 0);
1373}
1374
1375static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter,
1376 store_rtap_filter);
1377#endif
1378
1275static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 1379static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1276 char *buf) 1380 char *buf)
1277{ 1381{
@@ -2028,16 +2132,11 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
2028 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE); 2132 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
2029} 2133}
2030 2134
2031static int ipw_send_system_config(struct ipw_priv *priv, 2135static int ipw_send_system_config(struct ipw_priv *priv)
2032 struct ipw_sys_config *config)
2033{ 2136{
2034 if (!priv || !config) { 2137 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,
2035 IPW_ERROR("Invalid args\n"); 2138 sizeof(priv->sys_config),
2036 return -1; 2139 &priv->sys_config);
2037 }
2038
2039 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config),
2040 config);
2041} 2140}
2042 2141
2043static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 2142static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -3704,7 +3803,17 @@ static void ipw_bg_disassociate(void *data)
3704static void ipw_system_config(void *data) 3803static void ipw_system_config(void *data)
3705{ 3804{
3706 struct ipw_priv *priv = data; 3805 struct ipw_priv *priv = data;
3707 ipw_send_system_config(priv, &priv->sys_config); 3806
3807#ifdef CONFIG_IPW2200_PROMISCUOUS
3808 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
3809 priv->sys_config.accept_all_data_frames = 1;
3810 priv->sys_config.accept_non_directed_frames = 1;
3811 priv->sys_config.accept_all_mgmt_bcpr = 1;
3812 priv->sys_config.accept_all_mgmt_frames = 1;
3813 }
3814#endif
3815
3816 ipw_send_system_config(priv);
3708} 3817}
3709 3818
3710struct ipw_status_code { 3819struct ipw_status_code {
@@ -7138,7 +7247,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
7138 else 7247 else
7139 priv->sys_config.answer_broadcast_ssid_probe = 0; 7248 priv->sys_config.answer_broadcast_ssid_probe = 0;
7140 7249
7141 err = ipw_send_system_config(priv, &priv->sys_config); 7250 err = ipw_send_system_config(priv);
7142 if (err) { 7251 if (err) {
7143 IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); 7252 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
7144 return err; 7253 return err;
@@ -7454,15 +7563,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7454 /* Magic struct that slots into the radiotap header -- no reason 7563 /* Magic struct that slots into the radiotap header -- no reason
7455 * to build this manually element by element, we can write it much 7564 * to build this manually element by element, we can write it much
7456 * more efficiently than we can parse it. ORDER MATTERS HERE */ 7565 * more efficiently than we can parse it. ORDER MATTERS HERE */
7457 struct ipw_rt_hdr { 7566 struct ipw_rt_hdr *ipw_rt;
7458 struct ieee80211_radiotap_header rt_hdr;
7459 u8 rt_flags; /* radiotap packet flags */
7460 u8 rt_rate; /* rate in 500kb/s */
7461 u16 rt_channel; /* channel in mhz */
7462 u16 rt_chbitmask; /* channel bitfield */
7463 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7464 u8 rt_antenna; /* antenna number */
7465 } *ipw_rt;
7466 7567
7467 short len = le16_to_cpu(pkt->u.frame.length); 7568 short len = le16_to_cpu(pkt->u.frame.length);
7468 7569
@@ -7516,9 +7617,11 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7516 /* Big bitfield of all the fields we provide in radiotap */ 7617 /* Big bitfield of all the fields we provide in radiotap */
7517 ipw_rt->rt_hdr.it_present = 7618 ipw_rt->rt_hdr.it_present =
7518 ((1 << IEEE80211_RADIOTAP_FLAGS) | 7619 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7620 (1 << IEEE80211_RADIOTAP_TSFT) |
7519 (1 << IEEE80211_RADIOTAP_RATE) | 7621 (1 << IEEE80211_RADIOTAP_RATE) |
7520 (1 << IEEE80211_RADIOTAP_CHANNEL) | 7622 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7521 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | 7623 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7624 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
7522 (1 << IEEE80211_RADIOTAP_ANTENNA)); 7625 (1 << IEEE80211_RADIOTAP_ANTENNA));
7523 7626
7524 /* Zero the flags, we'll add to them as we go */ 7627 /* Zero the flags, we'll add to them as we go */
@@ -7604,6 +7707,220 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7604} 7707}
7605#endif 7708#endif
7606 7709
7710#ifdef CONFIG_IPW2200_PROMISCUOUS
7711#define ieee80211_is_probe_response(fc) \
7712 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \
7713 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )
7714
7715#define ieee80211_is_management(fc) \
7716 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
7717
7718#define ieee80211_is_control(fc) \
7719 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
7720
7721#define ieee80211_is_data(fc) \
7722 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
7723
7724#define ieee80211_is_assoc_request(fc) \
7725 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)
7726
7727#define ieee80211_is_reassoc_request(fc) \
7728 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
7729
7730static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7731 struct ipw_rx_mem_buffer *rxb,
7732 struct ieee80211_rx_stats *stats)
7733{
7734 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7735 struct ipw_rx_frame *frame = &pkt->u.frame;
7736 struct ipw_rt_hdr *ipw_rt;
7737
7738 /* First cache any information we need before we overwrite
7739 * the information provided in the skb from the hardware */
7740 struct ieee80211_hdr *hdr;
7741 u16 channel = frame->received_channel;
7742 u8 phy_flags = frame->antennaAndPhy;
7743 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
7744 s8 noise = frame->noise;
7745 u8 rate = frame->rate;
7746 short len = le16_to_cpu(pkt->u.frame.length);
7747 u64 tsf = 0;
7748 struct sk_buff *skb;
7749 int hdr_only = 0;
7750 u16 filter = priv->prom_priv->filter;
7751
7752 /* If the filter is set to not include Rx frames then return */
7753 if (filter & IPW_PROM_NO_RX)
7754 return;
7755
7756 if (!noise)
7757 noise = priv->last_noise;
7758
7759 /* We received data from the HW, so stop the watchdog */
7760 priv->prom_net_dev->trans_start = jiffies;
7761
7762 if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
7763 priv->prom_priv->ieee->stats.rx_errors++;
7764 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7765 return;
7766 }
7767
7768 /* We only process data packets if the interface is open */
7769 if (unlikely(!netif_running(priv->prom_net_dev))) {
7770 priv->prom_priv->ieee->stats.rx_dropped++;
7771 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7772 return;
7773 }
7774
7775 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7776 * that now */
7777 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7778 /* FIXME: Should alloc bigger skb instead */
7779 priv->prom_priv->ieee->stats.rx_dropped++;
7780 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7781 return;
7782 }
7783
7784 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
7785 if (ieee80211_is_management(hdr->frame_ctl)) {
7786 if (filter & IPW_PROM_NO_MGMT)
7787 return;
7788 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
7789 hdr_only = 1;
7790 } else if (ieee80211_is_control(hdr->frame_ctl)) {
7791 if (filter & IPW_PROM_NO_CTL)
7792 return;
7793 if (filter & IPW_PROM_CTL_HEADER_ONLY)
7794 hdr_only = 1;
7795 } else if (ieee80211_is_data(hdr->frame_ctl)) {
7796 if (filter & IPW_PROM_NO_DATA)
7797 return;
7798 if (filter & IPW_PROM_DATA_HEADER_ONLY)
7799 hdr_only = 1;
7800 }
7801
7802 /* Copy the SKB since this is for the promiscuous side */
7803 skb = skb_copy(rxb->skb, GFP_ATOMIC);
7804 if (skb == NULL) {
7805 IPW_ERROR("skb_clone failed for promiscuous copy.\n");
7806 return;
7807 }
7808
7809 /* copy the frame data to write after where the radiotap header goes */
7810 ipw_rt = (void *)skb->data;
7811
7812 if (hdr_only)
7813 len = ieee80211_get_hdrlen(hdr->frame_ctl);
7814
7815 memcpy(ipw_rt->payload, hdr, len);
7816
7817 /* Zero the radiotap static buffer ... We only need to zero the bytes
7818 * NOT part of our real header, saves a little time.
7819 *
7820 * No longer necessary since we fill in all our data. Purge before
7821 * merging patch officially.
7822 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7823 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7824 */
7825
7826 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7827 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7828 ipw_rt->rt_hdr.it_len = sizeof(*ipw_rt); /* total header+data */
7829
7830 /* Set the size of the skb to the size of the frame */
7831 skb_put(skb, ipw_rt->rt_hdr.it_len + len);
7832
7833 /* Big bitfield of all the fields we provide in radiotap */
7834 ipw_rt->rt_hdr.it_present =
7835 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7836 (1 << IEEE80211_RADIOTAP_TSFT) |
7837 (1 << IEEE80211_RADIOTAP_RATE) |
7838 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7839 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7840 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
7841 (1 << IEEE80211_RADIOTAP_ANTENNA));
7842
7843 /* Zero the flags, we'll add to them as we go */
7844 ipw_rt->rt_flags = 0;
7845
7846 ipw_rt->rt_tsf = tsf;
7847
7848 /* Convert to DBM */
7849 ipw_rt->rt_dbmsignal = signal;
7850 ipw_rt->rt_dbmnoise = noise;
7851
7852 /* Convert the channel data and set the flags */
7853 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(channel));
7854 if (channel > 14) { /* 802.11a */
7855 ipw_rt->rt_chbitmask =
7856 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7857 } else if (phy_flags & (1 << 5)) { /* 802.11b */
7858 ipw_rt->rt_chbitmask =
7859 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7860 } else { /* 802.11g */
7861 ipw_rt->rt_chbitmask =
7862 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7863 }
7864
7865 /* set the rate in multiples of 500k/s */
7866 switch (rate) {
7867 case IPW_TX_RATE_1MB:
7868 ipw_rt->rt_rate = 2;
7869 break;
7870 case IPW_TX_RATE_2MB:
7871 ipw_rt->rt_rate = 4;
7872 break;
7873 case IPW_TX_RATE_5MB:
7874 ipw_rt->rt_rate = 10;
7875 break;
7876 case IPW_TX_RATE_6MB:
7877 ipw_rt->rt_rate = 12;
7878 break;
7879 case IPW_TX_RATE_9MB:
7880 ipw_rt->rt_rate = 18;
7881 break;
7882 case IPW_TX_RATE_11MB:
7883 ipw_rt->rt_rate = 22;
7884 break;
7885 case IPW_TX_RATE_12MB:
7886 ipw_rt->rt_rate = 24;
7887 break;
7888 case IPW_TX_RATE_18MB:
7889 ipw_rt->rt_rate = 36;
7890 break;
7891 case IPW_TX_RATE_24MB:
7892 ipw_rt->rt_rate = 48;
7893 break;
7894 case IPW_TX_RATE_36MB:
7895 ipw_rt->rt_rate = 72;
7896 break;
7897 case IPW_TX_RATE_48MB:
7898 ipw_rt->rt_rate = 96;
7899 break;
7900 case IPW_TX_RATE_54MB:
7901 ipw_rt->rt_rate = 108;
7902 break;
7903 default:
7904 ipw_rt->rt_rate = 0;
7905 break;
7906 }
7907
7908 /* antenna number */
7909 ipw_rt->rt_antenna = (phy_flags & 3);
7910
7911 /* set the preamble flag if we have it */
7912 if (phy_flags & (1 << 6))
7913 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7914
7915 IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
7916
7917 if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
7918 priv->prom_priv->ieee->stats.rx_errors++;
7919 dev_kfree_skb_any(skb);
7920 }
7921}
7922#endif
7923
7607static int is_network_packet(struct ipw_priv *priv, 7924static int is_network_packet(struct ipw_priv *priv,
7608 struct ieee80211_hdr_4addr *header) 7925 struct ieee80211_hdr_4addr *header)
7609{ 7926{
@@ -7830,15 +8147,21 @@ static void ipw_rx(struct ipw_priv *priv)
7830 8147
7831 priv->rx_packets++; 8148 priv->rx_packets++;
7832 8149
8150#ifdef CONFIG_IPW2200_PROMISCUOUS
8151 if (priv->prom_net_dev && netif_running(priv->prom_net_dev))
8152 ipw_handle_promiscuous_rx(priv, rxb, &stats);
8153#endif
8154
7833#ifdef CONFIG_IPW2200_MONITOR 8155#ifdef CONFIG_IPW2200_MONITOR
7834 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 8156 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7835#ifdef CONFIG_IEEE80211_RADIOTAP 8157#ifdef CONFIG_IEEE80211_RADIOTAP
7836 ipw_handle_data_packet_monitor(priv, 8158
7837 rxb, 8159 ipw_handle_data_packet_monitor(priv,
7838 &stats); 8160 rxb,
8161 &stats);
7839#else 8162#else
7840 ipw_handle_data_packet(priv, rxb, 8163 ipw_handle_data_packet(priv, rxb,
7841 &stats); 8164 &stats);
7842#endif 8165#endif
7843 break; 8166 break;
7844 } 8167 }
@@ -9880,6 +10203,88 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9880 return 0; 10203 return 0;
9881} 10204}
9882 10205
10206#ifdef CONFIG_IPW2200_PROMISCUOUS
10207static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
10208 struct ieee80211_txb *txb)
10209{
10210 struct ieee80211_rx_stats dummystats;
10211 struct ieee80211_hdr *hdr;
10212 u8 n;
10213 u16 filter = priv->prom_priv->filter;
10214 int hdr_only = 0;
10215
10216 if (filter & IPW_PROM_NO_TX)
10217 return;
10218
10219 memset(&dummystats, 0, sizeof(dummystats));
10220
10221 /* Filtering of fragment chains is done agains the first fragment */
10222 hdr = (void *)txb->fragments[0]->data;
10223 if (ieee80211_is_management(hdr->frame_ctl)) {
10224 if (filter & IPW_PROM_NO_MGMT)
10225 return;
10226 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
10227 hdr_only = 1;
10228 } else if (ieee80211_is_control(hdr->frame_ctl)) {
10229 if (filter & IPW_PROM_NO_CTL)
10230 return;
10231 if (filter & IPW_PROM_CTL_HEADER_ONLY)
10232 hdr_only = 1;
10233 } else if (ieee80211_is_data(hdr->frame_ctl)) {
10234 if (filter & IPW_PROM_NO_DATA)
10235 return;
10236 if (filter & IPW_PROM_DATA_HEADER_ONLY)
10237 hdr_only = 1;
10238 }
10239
10240 for(n=0; n<txb->nr_frags; ++n) {
10241 struct sk_buff *src = txb->fragments[n];
10242 struct sk_buff *dst;
10243 struct ieee80211_radiotap_header *rt_hdr;
10244 int len;
10245
10246 if (hdr_only) {
10247 hdr = (void *)src->data;
10248 len = ieee80211_get_hdrlen(hdr->frame_ctl);
10249 } else
10250 len = src->len;
10251
10252 dst = alloc_skb(
10253 len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC);
10254 if (!dst) continue;
10255
10256 rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr));
10257
10258 rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
10259 rt_hdr->it_pad = 0;
10260 rt_hdr->it_present = 0; /* after all, it's just an idea */
10261 rt_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
10262
10263 *(u16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
10264 ieee80211chan2mhz(priv->channel));
10265 if (priv->channel > 14) /* 802.11a */
10266 *(u16*)skb_put(dst, sizeof(u16)) =
10267 cpu_to_le16(IEEE80211_CHAN_OFDM |
10268 IEEE80211_CHAN_5GHZ);
10269 else if (priv->ieee->mode == IEEE_B) /* 802.11b */
10270 *(u16*)skb_put(dst, sizeof(u16)) =
10271 cpu_to_le16(IEEE80211_CHAN_CCK |
10272 IEEE80211_CHAN_2GHZ);
10273 else /* 802.11g */
10274 *(u16*)skb_put(dst, sizeof(u16)) =
10275 cpu_to_le16(IEEE80211_CHAN_OFDM |
10276 IEEE80211_CHAN_2GHZ);
10277
10278 rt_hdr->it_len = dst->len;
10279
10280 memcpy(skb_put(dst, len), src->data, len);
10281
10282 if (!ieee80211_rx(priv->prom_priv->ieee, dst, &dummystats))
10283 dev_kfree_skb_any(dst);
10284 }
10285}
10286#endif
10287
9883static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, 10288static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
9884 struct net_device *dev, int pri) 10289 struct net_device *dev, int pri)
9885{ 10290{
@@ -9897,6 +10302,11 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
9897 goto fail_unlock; 10302 goto fail_unlock;
9898 } 10303 }
9899 10304
10305#ifdef CONFIG_IPW2200_PROMISCUOUS
10306 if (rtap_iface && netif_running(priv->prom_net_dev))
10307 ipw_handle_promiscuous_tx(priv, txb);
10308#endif
10309
9900 ret = ipw_tx_skb(priv, txb, pri); 10310 ret = ipw_tx_skb(priv, txb, pri);
9901 if (ret == NETDEV_TX_OK) 10311 if (ret == NETDEV_TX_OK)
9902 __ipw_led_activity_on(priv); 10312 __ipw_led_activity_on(priv);
@@ -10344,12 +10754,21 @@ static int ipw_config(struct ipw_priv *priv)
10344 |= CFG_BT_COEXISTENCE_OOB; 10754 |= CFG_BT_COEXISTENCE_OOB;
10345 } 10755 }
10346 10756
10757#ifdef CONFIG_IPW2200_PROMISCUOUS
10758 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
10759 priv->sys_config.accept_all_data_frames = 1;
10760 priv->sys_config.accept_non_directed_frames = 1;
10761 priv->sys_config.accept_all_mgmt_bcpr = 1;
10762 priv->sys_config.accept_all_mgmt_frames = 1;
10763 }
10764#endif
10765
10347 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 10766 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10348 priv->sys_config.answer_broadcast_ssid_probe = 1; 10767 priv->sys_config.answer_broadcast_ssid_probe = 1;
10349 else 10768 else
10350 priv->sys_config.answer_broadcast_ssid_probe = 0; 10769 priv->sys_config.answer_broadcast_ssid_probe = 0;
10351 10770
10352 if (ipw_send_system_config(priv, &priv->sys_config)) 10771 if (ipw_send_system_config(priv))
10353 goto error; 10772 goto error;
10354 10773
10355 init_supported_rates(priv, &priv->rates); 10774 init_supported_rates(priv, &priv->rates);
@@ -10887,6 +11306,10 @@ static struct attribute *ipw_sysfs_entries[] = {
10887 &dev_attr_led.attr, 11306 &dev_attr_led.attr,
10888 &dev_attr_speed_scan.attr, 11307 &dev_attr_speed_scan.attr,
10889 &dev_attr_net_stats.attr, 11308 &dev_attr_net_stats.attr,
11309#ifdef CONFIG_IPW2200_PROMISCUOUS
11310 &dev_attr_rtap_iface.attr,
11311 &dev_attr_rtap_filter.attr,
11312#endif
10890 NULL 11313 NULL
10891}; 11314};
10892 11315
@@ -10895,6 +11318,109 @@ static struct attribute_group ipw_attribute_group = {
10895 .attrs = ipw_sysfs_entries, 11318 .attrs = ipw_sysfs_entries,
10896}; 11319};
10897 11320
11321#ifdef CONFIG_IPW2200_PROMISCUOUS
11322static int ipw_prom_open(struct net_device *dev)
11323{
11324 struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
11325 struct ipw_priv *priv = prom_priv->priv;
11326
11327 IPW_DEBUG_INFO("prom dev->open\n");
11328 netif_carrier_off(dev);
11329 netif_stop_queue(dev);
11330
11331 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11332 priv->sys_config.accept_all_data_frames = 1;
11333 priv->sys_config.accept_non_directed_frames = 1;
11334 priv->sys_config.accept_all_mgmt_bcpr = 1;
11335 priv->sys_config.accept_all_mgmt_frames = 1;
11336
11337 ipw_send_system_config(priv);
11338 }
11339
11340 return 0;
11341}
11342
11343static int ipw_prom_stop(struct net_device *dev)
11344{
11345 struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
11346 struct ipw_priv *priv = prom_priv->priv;
11347
11348 IPW_DEBUG_INFO("prom dev->stop\n");
11349
11350 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11351 priv->sys_config.accept_all_data_frames = 0;
11352 priv->sys_config.accept_non_directed_frames = 0;
11353 priv->sys_config.accept_all_mgmt_bcpr = 0;
11354 priv->sys_config.accept_all_mgmt_frames = 0;
11355
11356 ipw_send_system_config(priv);
11357 }
11358
11359 return 0;
11360}
11361
11362static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
11363{
11364 IPW_DEBUG_INFO("prom dev->xmit\n");
11365 netif_stop_queue(dev);
11366 return -EOPNOTSUPP;
11367}
11368
11369static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
11370{
11371 struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
11372 return &prom_priv->ieee->stats;
11373}
11374
11375static int ipw_prom_alloc(struct ipw_priv *priv)
11376{
11377 int rc = 0;
11378
11379 if (priv->prom_net_dev)
11380 return -EPERM;
11381
11382 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
11383 if (priv->prom_net_dev == NULL)
11384 return -ENOMEM;
11385
11386 priv->prom_priv = ieee80211_priv(priv->prom_net_dev);
11387 priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);
11388 priv->prom_priv->priv = priv;
11389
11390 strcpy(priv->prom_net_dev->name, "rtap%d");
11391
11392 priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
11393 priv->prom_net_dev->open = ipw_prom_open;
11394 priv->prom_net_dev->stop = ipw_prom_stop;
11395 priv->prom_net_dev->get_stats = ipw_prom_get_stats;
11396 priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
11397
11398 priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
11399
11400 rc = register_netdev(priv->prom_net_dev);
11401 if (rc) {
11402 free_ieee80211(priv->prom_net_dev);
11403 priv->prom_net_dev = NULL;
11404 return rc;
11405 }
11406
11407 return 0;
11408}
11409
11410static void ipw_prom_free(struct ipw_priv *priv)
11411{
11412 if (!priv->prom_net_dev)
11413 return;
11414
11415 unregister_netdev(priv->prom_net_dev);
11416 free_ieee80211(priv->prom_net_dev);
11417
11418 priv->prom_net_dev = NULL;
11419}
11420
11421#endif
11422
11423
10898static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 11424static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
10899{ 11425{
10900 int err = 0; 11426 int err = 0;
@@ -11025,6 +11551,18 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11025 goto out_remove_sysfs; 11551 goto out_remove_sysfs;
11026 } 11552 }
11027 11553
11554#ifdef CONFIG_IPW2200_PROMISCUOUS
11555 if (rtap_iface) {
11556 err = ipw_prom_alloc(priv);
11557 if (err) {
11558 IPW_ERROR("Failed to register promiscuous network "
11559 "device (error %d).\n", err);
11560 unregister_netdev(priv->net_dev);
11561 goto out_remove_sysfs;
11562 }
11563 }
11564#endif
11565
11028 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg " 11566 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
11029 "channels, %d 802.11a channels)\n", 11567 "channels, %d 802.11a channels)\n",
11030 priv->ieee->geo.name, priv->ieee->geo.bg_channels, 11568 priv->ieee->geo.name, priv->ieee->geo.bg_channels,
@@ -11104,6 +11642,10 @@ static void ipw_pci_remove(struct pci_dev *pdev)
11104 priv->error = NULL; 11642 priv->error = NULL;
11105 } 11643 }
11106 11644
11645#ifdef CONFIG_IPW2200_PROMISCUOUS
11646 ipw_prom_free(priv);
11647#endif
11648
11107 free_irq(pdev->irq, priv); 11649 free_irq(pdev->irq, priv);
11108 iounmap(priv->hw_base); 11650 iounmap(priv->hw_base);
11109 pci_release_regions(pdev); 11651 pci_release_regions(pdev);
@@ -11228,6 +11770,11 @@ MODULE_PARM_DESC(debug, "debug output mask");
11228module_param(channel, int, 0444); 11770module_param(channel, int, 0444);
11229MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11771MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
11230 11772
11773#ifdef CONFIG_IPW2200_PROMISCUOUS
11774module_param(rtap_iface, int, 0444);
11775MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");
11776#endif
11777
11231#ifdef CONFIG_IPW_QOS 11778#ifdef CONFIG_IPW_QOS
11232module_param(qos_enable, int, 0444); 11779module_param(qos_enable, int, 0444);
11233MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis"); 11780MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");