aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJames Ketrenos <jketreno@linux.intel.com>2005-08-24 23:33:31 -0400
committerJames Ketrenos <jketreno@linux.intel.com>2005-11-07 18:50:01 -0500
commit823283549da144ff49e65c6e4a670b7784203e0b (patch)
tree84ea52f5016b5af30ba029616bfcd3f77e40e2a0 /drivers/net
parentb095c3819805f87d73d41641a53e4c070360d783 (diff)
Catch ipw2100 up to equivelancy with v1.1.1
* Added WE-18 support. This allows the use of -Dext with wpa_supplicant > 0.4.x (thanks to Hong Liu) * Fixed #339 problem with iwconfig set/get txpower (thanks to Hong Liu) * Fixed #598 problem when with error messages when module loaded with 'disable=1' (thanks to Hong Liu) * Fixed #640 problem with 'iwlist retry' now showing min/max retry * Fixed compatibility with wpa_supplicant and the new -Dipw interface (that included a fix for 64-bit compatibility) * Added CFG_CRC_CHECK which allows passing through packets with bad CRCs while in monitor mode. Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ipw2100.c577
-rw-r--r--drivers/net/wireless/ipw2100.h11
2 files changed, 451 insertions, 137 deletions
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 449c1c085fb9..e7c222119da6 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,12 +167,12 @@ that only one external action is invoked at a time.
167 167
168#include "ipw2100.h" 168#include "ipw2100.h"
169 169
170#define IPW2100_VERSION "1.1.0" 170#define IPW2100_VERSION "1.1.1"
171 171
172#define DRV_NAME "ipw2100" 172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION 173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" 174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" 175#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation"
176 176
177/* Debugging stuff */ 177/* Debugging stuff */
178#ifdef CONFIG_IPW_DEBUG 178#ifdef CONFIG_IPW_DEBUG
@@ -779,7 +779,7 @@ static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
779 779
780 if (err == 0) { 780 if (err == 0) {
781 IPW_DEBUG_INFO("Command completion failed out after %dms.\n", 781 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
782 HOST_COMPLETE_TIMEOUT / (HZ / 100)); 782 1000 * (HOST_COMPLETE_TIMEOUT / HZ));
783 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT; 783 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
784 priv->status &= ~STATUS_CMD_ACTIVE; 784 priv->status &= ~STATUS_CMD_ACTIVE;
785 schedule_reset(priv); 785 schedule_reset(priv);
@@ -1986,7 +1986,7 @@ static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1986 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len)); 1986 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
1987 1987
1988 if (ssid_len) 1988 if (ssid_len)
1989 memcpy((char *)cmd.host_command_parameters, essid, ssid_len); 1989 memcpy(cmd.host_command_parameters, essid, ssid_len);
1990 1990
1991 if (!batch_mode) { 1991 if (!batch_mode) {
1992 err = ipw2100_disable_adapter(priv); 1992 err = ipw2100_disable_adapter(priv);
@@ -2369,13 +2369,15 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i,
2369 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); 2369 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2370 return; 2370 return;
2371 } 2371 }
2372 2372#ifdef CONFIG_IPW2100_MONITOR
2373 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && 2373 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2374 priv->config & CFG_CRC_CHECK &&
2374 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { 2375 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2375 IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); 2376 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2376 priv->ieee->stats.rx_errors++; 2377 priv->ieee->stats.rx_errors++;
2377 return; 2378 return;
2378 } 2379 }
2380#endif
2379 2381
2380 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && 2382 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2381 !(priv->status & STATUS_ASSOCIATED))) { 2383 !(priv->status & STATUS_ASSOCIATED))) {
@@ -2744,7 +2746,6 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2744 priv->net_dev->name, txq->oldest, packet->index); 2746 priv->net_dev->name, txq->oldest, packet->index);
2745 2747
2746 /* DATA packet; we have to unmap and free the SKB */ 2748 /* DATA packet; we have to unmap and free the SKB */
2747 priv->ieee->stats.tx_packets++;
2748 for (i = 0; i < frag_num; i++) { 2749 for (i = 0; i < frag_num; i++) {
2749 tbd = &txq->drv[(packet->index + 1 + i) % txq->entries]; 2750 tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
2750 2751
@@ -2757,8 +2758,6 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2757 tbd->buf_length, PCI_DMA_TODEVICE); 2758 tbd->buf_length, PCI_DMA_TODEVICE);
2758 } 2759 }
2759 2760
2760 priv->ieee->stats.tx_bytes +=
2761 packet->info.d_struct.txb->payload_size;
2762 ieee80211_txb_free(packet->info.d_struct.txb); 2761 ieee80211_txb_free(packet->info.d_struct.txb);
2763 packet->info.d_struct.txb = NULL; 2762 packet->info.d_struct.txb = NULL;
2764 2763
@@ -2767,13 +2766,8 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2767 2766
2768 /* We have a free slot in the Tx queue, so wake up the 2767 /* We have a free slot in the Tx queue, so wake up the
2769 * transmit layer if it is stopped. */ 2768 * transmit layer if it is stopped. */
2770 if (priv->status & STATUS_ASSOCIATED && 2769 if (priv->status & STATUS_ASSOCIATED)
2771 netif_queue_stopped(priv->net_dev)) {
2772 IPW_DEBUG_INFO(KERN_INFO
2773 "%s: Waking net queue.\n",
2774 priv->net_dev->name);
2775 netif_wake_queue(priv->net_dev); 2770 netif_wake_queue(priv->net_dev);
2776 }
2777 2771
2778 /* A packet was processed by the hardware, so update the 2772 /* A packet was processed by the hardware, so update the
2779 * watchdog */ 2773 * watchdog */
@@ -3791,6 +3785,9 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3791 u32 val_len; 3785 u32 val_len;
3792 static int loop = 0; 3786 static int loop = 0;
3793 3787
3788 if (priv->status & STATUS_RF_KILL_MASK)
3789 return 0;
3790
3794 if (loop >= sizeof(ord_data) / sizeof(*ord_data)) 3791 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3795 loop = 0; 3792 loop = 0;
3796 3793
@@ -3947,6 +3944,9 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3947 int length; 3944 int length;
3948 int ret; 3945 int ret;
3949 3946
3947 if (priv->status & STATUS_RF_KILL_MASK)
3948 return 0;
3949
3950 memset(essid, 0, sizeof(essid)); 3950 memset(essid, 0, sizeof(essid));
3951 memset(bssid, 0, sizeof(bssid)); 3951 memset(bssid, 0, sizeof(bssid));
3952 3952
@@ -3986,8 +3986,8 @@ static ssize_t show_debug_level(struct device_driver *d, char *buf)
3986 return sprintf(buf, "0x%08X\n", ipw2100_debug_level); 3986 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3987} 3987}
3988 3988
3989static ssize_t store_debug_level(struct device_driver *d, const char *buf, 3989static ssize_t store_debug_level(struct device_driver *d,
3990 size_t count) 3990 const char *buf, size_t count)
3991{ 3991{
3992 char *p = (char *)buf; 3992 char *p = (char *)buf;
3993 u32 val; 3993 u32 val;
@@ -4943,7 +4943,7 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
4943#endif 4943#endif
4944 /* if BSSID is empty then we disable mandatory bssid mode */ 4944 /* if BSSID is empty then we disable mandatory bssid mode */
4945 if (bssid != NULL) 4945 if (bssid != NULL)
4946 memcpy((u8 *) cmd.host_command_parameters, bssid, ETH_ALEN); 4946 memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
4947 4947
4948 if (!batch_mode) { 4948 if (!batch_mode) {
4949 err = ipw2100_disable_adapter(priv); 4949 err = ipw2100_disable_adapter(priv);
@@ -4959,7 +4959,6 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid,
4959 return err; 4959 return err;
4960} 4960}
4961 4961
4962#ifdef CONFIG_IEEE80211_WPA
4963static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv) 4962static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4964{ 4963{
4965 struct host_command cmd = { 4964 struct host_command cmd = {
@@ -4983,34 +4982,6 @@ static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4983 4982
4984 return err; 4983 return err;
4985} 4984}
4986#endif
4987
4988/*
4989 * Pseudo code for setting up wpa_frame:
4990 */
4991#if 0
4992void x(struct ieee80211_assoc_frame *wpa_assoc)
4993{
4994 struct ipw2100_wpa_assoc_frame frame;
4995 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
4996 IPW_WPA_LISTENINTERVAL | IPW_WPA_AP_ADDRESS;
4997 frame->capab_info = wpa_assoc->capab_info;
4998 frame->lisen_interval = wpa_assoc->listent_interval;
4999 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5000
5001 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5002 * setup here to test it with.
5003 *
5004 * Walk the IEs in the wpa_assoc and figure out the total size of all
5005 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5006 * the IEs from wpa_frame into frame.
5007 */
5008 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5009 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5010
5011 ipw2100_set_wpa_ie(priv, &frame, 0);
5012}
5013#endif
5014 4985
5015static int ipw2100_set_wpa_ie(struct ipw2100_priv *, 4986static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5016 struct ipw2100_wpa_assoc_frame *, int) 4987 struct ipw2100_wpa_assoc_frame *, int)
@@ -5750,11 +5721,10 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5750 return &priv->ieee->stats; 5721 return &priv->ieee->stats;
5751} 5722}
5752 5723
5753/* Support for wpa_supplicant. Will be replaced with WEXT once 5724#if WIRELESS_EXT < 18
5754 * they get WPA support. */ 5725/* Support for wpa_supplicant before WE-18, deprecated. */
5755#ifdef CONFIG_IEEE80211_WPA
5756 5726
5757/* following definitions must match definitions in driver_ipw2100.c */ 5727/* following definitions must match definitions in driver_ipw.c */
5758 5728
5759#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 5729#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5760 5730
@@ -5792,11 +5762,12 @@ struct ipw2100_param {
5792 } wpa_param; 5762 } wpa_param;
5793 struct { 5763 struct {
5794 u32 len; 5764 u32 len;
5795 u8 *data; 5765 u8 reserved[32];
5766 u8 data[0];
5796 } wpa_ie; 5767 } wpa_ie;
5797 struct { 5768 struct {
5798 int command; 5769 u32 command;
5799 int reason_code; 5770 u32 reason_code;
5800 } mlme; 5771 } mlme;
5801 struct { 5772 struct {
5802 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN]; 5773 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
@@ -5811,37 +5782,21 @@ struct ipw2100_param {
5811 } u; 5782 } u;
5812}; 5783};
5813 5784
5814/* end of driver_ipw2100.c code */ 5785/* end of driver_ipw.c code */
5786#endif /* WIRELESS_EXT < 18 */
5815 5787
5816static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) 5788static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
5817{ 5789{
5818 5790 /* This is called when wpa_supplicant loads and closes the driver
5819 struct ieee80211_device *ieee = priv->ieee; 5791 * interface. */
5820 struct ieee80211_security sec = { 5792 priv->ieee->wpa_enabled = value;
5821 .flags = SEC_LEVEL | SEC_ENABLED, 5793 return 0;
5822 };
5823 int ret = 0;
5824
5825 ieee->wpa_enabled = value;
5826
5827 if (value) {
5828 sec.level = SEC_LEVEL_3;
5829 sec.enabled = 1;
5830 } else {
5831 sec.level = SEC_LEVEL_0;
5832 sec.enabled = 0;
5833 }
5834
5835 if (ieee->set_security)
5836 ieee->set_security(ieee->dev, &sec);
5837 else
5838 ret = -EOPNOTSUPP;
5839
5840 return ret;
5841} 5794}
5842 5795
5843#define AUTH_ALG_OPEN_SYSTEM 0x1 5796#if WIRELESS_EXT < 18
5844#define AUTH_ALG_SHARED_KEY 0x2 5797#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
5798#define IW_AUTH_ALG_SHARED_KEY 0x2
5799#endif
5845 5800
5846static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) 5801static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5847{ 5802{
@@ -5852,13 +5807,14 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5852 }; 5807 };
5853 int ret = 0; 5808 int ret = 0;
5854 5809
5855 if (value & AUTH_ALG_SHARED_KEY) { 5810 if (value & IW_AUTH_ALG_SHARED_KEY) {
5856 sec.auth_mode = WLAN_AUTH_SHARED_KEY; 5811 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5857 ieee->open_wep = 0; 5812 ieee->open_wep = 0;
5858 } else { 5813 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
5859 sec.auth_mode = WLAN_AUTH_OPEN; 5814 sec.auth_mode = WLAN_AUTH_OPEN;
5860 ieee->open_wep = 1; 5815 ieee->open_wep = 1;
5861 } 5816 } else
5817 return -EINVAL;
5862 5818
5863 if (ieee->set_security) 5819 if (ieee->set_security)
5864 ieee->set_security(ieee->dev, &sec); 5820 ieee->set_security(ieee->dev, &sec);
@@ -5868,10 +5824,29 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
5868 return ret; 5824 return ret;
5869} 5825}
5870 5826
5871static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value) 5827void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5828 char *wpa_ie, int wpa_ie_len)
5872{ 5829{
5873 5830
5831 struct ipw2100_wpa_assoc_frame frame;
5832
5833 frame.fixed_ie_mask = 0;
5834
5835 /* copy WPA IE */
5836 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5837 frame.var_ie_len = wpa_ie_len;
5838
5839 /* make sure WPA is enabled */
5840 ipw2100_wpa_enable(priv, 1);
5841 ipw2100_set_wpa_ie(priv, &frame, 0);
5842}
5843
5844#if WIRELESS_EXT < 18
5845static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5846{
5874 struct ipw2100_priv *priv = ieee80211_priv(dev); 5847 struct ipw2100_priv *priv = ieee80211_priv(dev);
5848 struct ieee80211_crypt_data *crypt;
5849 unsigned long flags;
5875 int ret = 0; 5850 int ret = 0;
5876 5851
5877 switch (name) { 5852 switch (name) {
@@ -5880,7 +5855,22 @@ static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
5880 break; 5855 break;
5881 5856
5882 case IPW2100_PARAM_TKIP_COUNTERMEASURES: 5857 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5883 priv->ieee->tkip_countermeasures = value; 5858 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
5859 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
5860 IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
5861 "crypt not set!\n");
5862 break;
5863 }
5864
5865 flags = crypt->ops->get_flags(crypt->priv);
5866
5867 if (value)
5868 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5869 else
5870 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
5871
5872 crypt->ops->set_flags(flags, crypt->priv);
5873
5884 break; 5874 break;
5885 5875
5886 case IPW2100_PARAM_DROP_UNENCRYPTED: 5876 case IPW2100_PARAM_DROP_UNENCRYPTED:
@@ -5932,23 +5922,6 @@ static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
5932 return ret; 5922 return ret;
5933} 5923}
5934 5924
5935void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5936 char *wpa_ie, int wpa_ie_len)
5937{
5938
5939 struct ipw2100_wpa_assoc_frame frame;
5940
5941 frame.fixed_ie_mask = 0;
5942
5943 /* copy WPA IE */
5944 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5945 frame.var_ie_len = wpa_ie_len;
5946
5947 /* make sure WPA is enabled */
5948 ipw2100_wpa_enable(priv, 1);
5949 ipw2100_set_wpa_ie(priv, &frame, 0);
5950}
5951
5952static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, 5925static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5953 struct ipw2100_param *param, int plen) 5926 struct ipw2100_param *param, int plen)
5954{ 5927{
@@ -5992,7 +5965,6 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
5992 struct ipw2100_param *param, 5965 struct ipw2100_param *param,
5993 int param_len) 5966 int param_len)
5994{ 5967{
5995
5996 int ret = 0; 5968 int ret = 0;
5997 struct ipw2100_priv *priv = ieee80211_priv(dev); 5969 struct ipw2100_priv *priv = ieee80211_priv(dev);
5998 struct ieee80211_device *ieee = priv->ieee; 5970 struct ieee80211_device *ieee = priv->ieee;
@@ -6101,8 +6073,8 @@ static int ipw2100_wpa_set_encryption(struct net_device *dev,
6101 if (ops->name != NULL) { 6073 if (ops->name != NULL) {
6102 6074
6103 if (strcmp(ops->name, "WEP") == 0) { 6075 if (strcmp(ops->name, "WEP") == 0) {
6104 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, 6076 memcpy(sec.keys[param->u.crypt.idx],
6105 param->u.crypt.key_len); 6077 param->u.crypt.key, param->u.crypt.key_len);
6106 sec.key_sizes[param->u.crypt.idx] = 6078 sec.key_sizes[param->u.crypt.idx] =
6107 param->u.crypt.key_len; 6079 param->u.crypt.key_len;
6108 sec.flags |= (1 << param->u.crypt.idx); 6080 sec.flags |= (1 << param->u.crypt.idx);
@@ -6190,11 +6162,9 @@ static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
6190 kfree(param); 6162 kfree(param);
6191 return ret; 6163 return ret;
6192} 6164}
6193#endif /* CONFIG_IEEE80211_WPA */
6194 6165
6195static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 6166static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6196{ 6167{
6197#ifdef CONFIG_IEEE80211_WPA
6198 struct iwreq *wrq = (struct iwreq *)rq; 6168 struct iwreq *wrq = (struct iwreq *)rq;
6199 int ret = -1; 6169 int ret = -1;
6200 switch (cmd) { 6170 switch (cmd) {
@@ -6206,10 +6176,9 @@ static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6206 return -EOPNOTSUPP; 6176 return -EOPNOTSUPP;
6207 } 6177 }
6208 6178
6209#endif /* CONFIG_IEEE80211_WPA */
6210
6211 return -EOPNOTSUPP; 6179 return -EOPNOTSUPP;
6212} 6180}
6181#endif /* WIRELESS_EXT < 18 */
6213 6182
6214static void ipw_ethtool_get_drvinfo(struct net_device *dev, 6183static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6215 struct ethtool_drvinfo *info) 6184 struct ethtool_drvinfo *info)
@@ -6333,10 +6302,15 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6333 priv->ieee->hard_start_xmit = ipw2100_tx; 6302 priv->ieee->hard_start_xmit = ipw2100_tx;
6334 priv->ieee->set_security = shim__set_security; 6303 priv->ieee->set_security = shim__set_security;
6335 6304
6305 priv->ieee->perfect_rssi = -20;
6306 priv->ieee->worst_rssi = -85;
6307
6336 dev->open = ipw2100_open; 6308 dev->open = ipw2100_open;
6337 dev->stop = ipw2100_close; 6309 dev->stop = ipw2100_close;
6338 dev->init = ipw2100_net_init; 6310 dev->init = ipw2100_net_init;
6311#if WIRELESS_EXT < 18
6339 dev->do_ioctl = ipw2100_ioctl; 6312 dev->do_ioctl = ipw2100_ioctl;
6313#endif
6340 dev->get_stats = ipw2100_stats; 6314 dev->get_stats = ipw2100_stats;
6341 dev->ethtool_ops = &ipw2100_ethtool_ops; 6315 dev->ethtool_ops = &ipw2100_ethtool_ops;
6342 dev->tx_timeout = ipw2100_tx_timeout; 6316 dev->tx_timeout = ipw2100_tx_timeout;
@@ -6362,13 +6336,13 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6362 /* If power management is turned on, default to AUTO mode */ 6336 /* If power management is turned on, default to AUTO mode */
6363 priv->power_mode = IPW_POWER_AUTO; 6337 priv->power_mode = IPW_POWER_AUTO;
6364 6338
6365#ifdef CONFIG_IEEE80211_WPA 6339#ifdef CONFIG_IPW2100_MONITOR
6340 priv->config |= CFG_CRC_CHECK;
6341#endif
6366 priv->ieee->wpa_enabled = 0; 6342 priv->ieee->wpa_enabled = 0;
6367 priv->ieee->tkip_countermeasures = 0;
6368 priv->ieee->drop_unencrypted = 0; 6343 priv->ieee->drop_unencrypted = 0;
6369 priv->ieee->privacy_invoked = 0; 6344 priv->ieee->privacy_invoked = 0;
6370 priv->ieee->ieee802_1x = 1; 6345 priv->ieee->ieee802_1x = 1;
6371#endif /* CONFIG_IEEE80211_WPA */
6372 6346
6373 /* Set module parameters */ 6347 /* Set module parameters */
6374 switch (mode) { 6348 switch (mode) {
@@ -6429,7 +6403,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6429 INIT_LIST_HEAD(&priv->fw_pend_list); 6403 INIT_LIST_HEAD(&priv->fw_pend_list);
6430 INIT_STAT(&priv->fw_pend_stat); 6404 INIT_STAT(&priv->fw_pend_stat);
6431 6405
6432#ifdef CONFIG_SOFTWARE_SUSPEND2 6406#ifdef PF_SYNCTHREAD
6433 priv->workqueue = create_workqueue(DRV_NAME, 0); 6407 priv->workqueue = create_workqueue(DRV_NAME, 0);
6434#else 6408#else
6435 priv->workqueue = create_workqueue(DRV_NAME); 6409 priv->workqueue = create_workqueue(DRV_NAME);
@@ -6591,7 +6565,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6591 6565
6592 /* perform this after register_netdev so that dev->name is set */ 6566 /* perform this after register_netdev so that dev->name is set */
6593 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group); 6567 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6594 netif_carrier_off(dev);
6595 6568
6596 /* If the RF Kill switch is disabled, go ahead and complete the 6569 /* If the RF Kill switch is disabled, go ahead and complete the
6597 * startup sequence */ 6570 * startup sequence */
@@ -6860,10 +6833,6 @@ static int __init ipw2100_init(void)
6860 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); 6833 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6861 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); 6834 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6862 6835
6863#ifdef CONFIG_IEEE80211_NOWEP
6864 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6865#endif
6866
6867 ret = pci_module_init(&ipw2100_pci_driver); 6836 ret = pci_module_init(&ipw2100_pci_driver);
6868 6837
6869#ifdef CONFIG_IPW_DEBUG 6838#ifdef CONFIG_IPW_DEBUG
@@ -6963,9 +6932,10 @@ static int ipw2100_wx_set_freq(struct net_device *dev,
6963 } 6932 }
6964 } 6933 }
6965 6934
6966 if (fwrq->e > 0 || fwrq->m > 1000) 6935 if (fwrq->e > 0 || fwrq->m > 1000) {
6967 return -EOPNOTSUPP; 6936 err = -EOPNOTSUPP;
6968 else { /* Set the channel */ 6937 goto done;
6938 } else { /* Set the channel */
6969 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m); 6939 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6970 err = ipw2100_set_channel(priv, fwrq->m, 0); 6940 err = ipw2100_set_channel(priv, fwrq->m, 0);
6971 } 6941 }
@@ -7256,7 +7226,7 @@ static int ipw2100_wx_get_wap(struct net_device *dev,
7256 * configured BSSID then return that; otherwise return ANY */ 7226 * configured BSSID then return that; otherwise return ANY */
7257 if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) { 7227 if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
7258 wrqu->ap_addr.sa_family = ARPHRD_ETHER; 7228 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7259 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN); 7229 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
7260 } else 7230 } else
7261 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); 7231 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7262 7232
@@ -7711,13 +7681,13 @@ static int ipw2100_wx_get_retry(struct net_device *dev,
7711 return -EINVAL; 7681 return -EINVAL;
7712 7682
7713 if (wrqu->retry.flags & IW_RETRY_MAX) { 7683 if (wrqu->retry.flags & IW_RETRY_MAX) {
7714 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; 7684 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
7715 wrqu->retry.value = priv->long_retry_limit; 7685 wrqu->retry.value = priv->long_retry_limit;
7716 } else { 7686 } else {
7717 wrqu->retry.flags = 7687 wrqu->retry.flags =
7718 (priv->short_retry_limit != 7688 (priv->short_retry_limit !=
7719 priv->long_retry_limit) ? 7689 priv->long_retry_limit) ?
7720 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT; 7690 IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
7721 7691
7722 wrqu->retry.value = priv->short_retry_limit; 7692 wrqu->retry.value = priv->short_retry_limit;
7723 } 7693 }
@@ -7847,9 +7817,9 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7847 7817
7848 struct ipw2100_priv *priv = ieee80211_priv(dev); 7818 struct ipw2100_priv *priv = ieee80211_priv(dev);
7849 7819
7850 if (!(priv->power_mode & IPW_POWER_ENABLED)) { 7820 if (!(priv->power_mode & IPW_POWER_ENABLED))
7851 wrqu->power.disabled = 1; 7821 wrqu->power.disabled = 1;
7852 } else { 7822 else {
7853 wrqu->power.disabled = 0; 7823 wrqu->power.disabled = 0;
7854 wrqu->power.flags = 0; 7824 wrqu->power.flags = 0;
7855 } 7825 }
@@ -7859,6 +7829,273 @@ static int ipw2100_wx_get_power(struct net_device *dev,
7859 return 0; 7829 return 0;
7860} 7830}
7861 7831
7832#if WIRELESS_EXT > 17
7833/*
7834 * WE-18 WPA support
7835 */
7836
7837/* SIOCSIWGENIE */
7838static int ipw2100_wx_set_genie(struct net_device *dev,
7839 struct iw_request_info *info,
7840 union iwreq_data *wrqu, char *extra)
7841{
7842
7843 struct ipw2100_priv *priv = ieee80211_priv(dev);
7844 struct ieee80211_device *ieee = priv->ieee;
7845 u8 *buf;
7846
7847 if (!ieee->wpa_enabled)
7848 return -EOPNOTSUPP;
7849
7850 if (wrqu->data.length > MAX_WPA_IE_LEN ||
7851 (wrqu->data.length && extra == NULL))
7852 return -EINVAL;
7853
7854 if (wrqu->data.length) {
7855 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
7856 if (buf == NULL)
7857 return -ENOMEM;
7858
7859 memcpy(buf, extra, wrqu->data.length);
7860 kfree(ieee->wpa_ie);
7861 ieee->wpa_ie = buf;
7862 ieee->wpa_ie_len = wrqu->data.length;
7863 } else {
7864 kfree(ieee->wpa_ie);
7865 ieee->wpa_ie = NULL;
7866 ieee->wpa_ie_len = 0;
7867 }
7868
7869 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
7870
7871 return 0;
7872}
7873
7874/* SIOCGIWGENIE */
7875static int ipw2100_wx_get_genie(struct net_device *dev,
7876 struct iw_request_info *info,
7877 union iwreq_data *wrqu, char *extra)
7878{
7879 struct ipw2100_priv *priv = ieee80211_priv(dev);
7880 struct ieee80211_device *ieee = priv->ieee;
7881
7882 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
7883 wrqu->data.length = 0;
7884 return 0;
7885 }
7886
7887 if (wrqu->data.length < ieee->wpa_ie_len)
7888 return -E2BIG;
7889
7890 wrqu->data.length = ieee->wpa_ie_len;
7891 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
7892
7893 return 0;
7894}
7895
7896/* SIOCSIWAUTH */
7897static int ipw2100_wx_set_auth(struct net_device *dev,
7898 struct iw_request_info *info,
7899 union iwreq_data *wrqu, char *extra)
7900{
7901 struct ipw2100_priv *priv = ieee80211_priv(dev);
7902 struct ieee80211_device *ieee = priv->ieee;
7903 struct iw_param *param = &wrqu->param;
7904 struct ieee80211_crypt_data *crypt;
7905 unsigned long flags;
7906 int ret = 0;
7907
7908 switch (param->flags & IW_AUTH_INDEX) {
7909 case IW_AUTH_WPA_VERSION:
7910 case IW_AUTH_CIPHER_PAIRWISE:
7911 case IW_AUTH_CIPHER_GROUP:
7912 case IW_AUTH_KEY_MGMT:
7913 /*
7914 * ipw2200 does not use these parameters
7915 */
7916 break;
7917
7918 case IW_AUTH_TKIP_COUNTERMEASURES:
7919 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
7920 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
7921 IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
7922 "crypt not set!\n");
7923 break;
7924 }
7925
7926 flags = crypt->ops->get_flags(crypt->priv);
7927
7928 if (param->value)
7929 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7930 else
7931 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
7932
7933 crypt->ops->set_flags(flags, crypt->priv);
7934
7935 break;
7936
7937 case IW_AUTH_DROP_UNENCRYPTED:{
7938 /* HACK:
7939 *
7940 * wpa_supplicant calls set_wpa_enabled when the driver
7941 * is loaded and unloaded, regardless of if WPA is being
7942 * used. No other calls are made which can be used to
7943 * determine if encryption will be used or not prior to
7944 * association being expected. If encryption is not being
7945 * used, drop_unencrypted is set to false, else true -- we
7946 * can use this to determine if the CAP_PRIVACY_ON bit should
7947 * be set.
7948 */
7949 struct ieee80211_security sec = {
7950 .flags = SEC_ENABLED,
7951 .enabled = param->value,
7952 };
7953 priv->ieee->drop_unencrypted = param->value;
7954 /* We only change SEC_LEVEL for open mode. Others
7955 * are set by ipw_wpa_set_encryption.
7956 */
7957 if (!param->value) {
7958 sec.flags |= SEC_LEVEL;
7959 sec.level = SEC_LEVEL_0;
7960 } else {
7961 sec.flags |= SEC_LEVEL;
7962 sec.level = SEC_LEVEL_1;
7963 }
7964 if (priv->ieee->set_security)
7965 priv->ieee->set_security(priv->ieee->dev, &sec);
7966 break;
7967 }
7968
7969 case IW_AUTH_80211_AUTH_ALG:
7970 ret = ipw2100_wpa_set_auth_algs(priv, param->value);
7971 break;
7972
7973 case IW_AUTH_WPA_ENABLED:
7974 ret = ipw2100_wpa_enable(priv, param->value);
7975 break;
7976
7977 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
7978 ieee->ieee802_1x = param->value;
7979 break;
7980
7981 //case IW_AUTH_ROAMING_CONTROL:
7982 case IW_AUTH_PRIVACY_INVOKED:
7983 ieee->privacy_invoked = param->value;
7984 break;
7985
7986 default:
7987 return -EOPNOTSUPP;
7988 }
7989 return ret;
7990}
7991
7992/* SIOCGIWAUTH */
7993static int ipw2100_wx_get_auth(struct net_device *dev,
7994 struct iw_request_info *info,
7995 union iwreq_data *wrqu, char *extra)
7996{
7997 struct ipw2100_priv *priv = ieee80211_priv(dev);
7998 struct ieee80211_device *ieee = priv->ieee;
7999 struct ieee80211_crypt_data *crypt;
8000 struct iw_param *param = &wrqu->param;
8001 int ret = 0;
8002
8003 switch (param->flags & IW_AUTH_INDEX) {
8004 case IW_AUTH_WPA_VERSION:
8005 case IW_AUTH_CIPHER_PAIRWISE:
8006 case IW_AUTH_CIPHER_GROUP:
8007 case IW_AUTH_KEY_MGMT:
8008 /*
8009 * wpa_supplicant will control these internally
8010 */
8011 ret = -EOPNOTSUPP;
8012 break;
8013
8014 case IW_AUTH_TKIP_COUNTERMEASURES:
8015 crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
8016 if (!crypt || !crypt->ops->get_flags) {
8017 IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
8018 "crypt not set!\n");
8019 break;
8020 }
8021
8022 param->value = (crypt->ops->get_flags(crypt->priv) &
8023 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
8024
8025 break;
8026
8027 case IW_AUTH_DROP_UNENCRYPTED:
8028 param->value = ieee->drop_unencrypted;
8029 break;
8030
8031 case IW_AUTH_80211_AUTH_ALG:
8032 param->value = priv->sec.auth_mode;
8033 break;
8034
8035 case IW_AUTH_WPA_ENABLED:
8036 param->value = ieee->wpa_enabled;
8037 break;
8038
8039 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
8040 param->value = ieee->ieee802_1x;
8041 break;
8042
8043 case IW_AUTH_ROAMING_CONTROL:
8044 case IW_AUTH_PRIVACY_INVOKED:
8045 param->value = ieee->privacy_invoked;
8046 break;
8047
8048 default:
8049 return -EOPNOTSUPP;
8050 }
8051 return 0;
8052}
8053
8054/* SIOCSIWENCODEEXT */
8055static int ipw2100_wx_set_encodeext(struct net_device *dev,
8056 struct iw_request_info *info,
8057 union iwreq_data *wrqu, char *extra)
8058{
8059 struct ipw2100_priv *priv = ieee80211_priv(dev);
8060 return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
8061}
8062
8063/* SIOCGIWENCODEEXT */
8064static int ipw2100_wx_get_encodeext(struct net_device *dev,
8065 struct iw_request_info *info,
8066 union iwreq_data *wrqu, char *extra)
8067{
8068 struct ipw2100_priv *priv = ieee80211_priv(dev);
8069 return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
8070}
8071
8072/* SIOCSIWMLME */
8073static int ipw2100_wx_set_mlme(struct net_device *dev,
8074 struct iw_request_info *info,
8075 union iwreq_data *wrqu, char *extra)
8076{
8077 struct ipw2100_priv *priv = ieee80211_priv(dev);
8078 struct iw_mlme *mlme = (struct iw_mlme *)extra;
8079 u16 reason;
8080
8081 reason = cpu_to_le16(mlme->reason_code);
8082
8083 switch (mlme->cmd) {
8084 case IW_MLME_DEAUTH:
8085 // silently ignore
8086 break;
8087
8088 case IW_MLME_DISASSOC:
8089 ipw2100_disassociate_bssid(priv);
8090 break;
8091
8092 default:
8093 return -EOPNOTSUPP;
8094 }
8095 return 0;
8096}
8097#endif /* WIRELESS_EXT > 17 */
8098
7862/* 8099/*
7863 * 8100 *
7864 * IWPRIV handlers 8101 * IWPRIV handlers
@@ -8019,6 +8256,54 @@ static int ipw2100_wx_get_preamble(struct net_device *dev,
8019 return 0; 8256 return 0;
8020} 8257}
8021 8258
8259#ifdef CONFIG_IPW2100_MONITOR
8260static int ipw2100_wx_set_crc_check(struct net_device *dev,
8261 struct iw_request_info *info,
8262 union iwreq_data *wrqu, char *extra)
8263{
8264 struct ipw2100_priv *priv = ieee80211_priv(dev);
8265 int err, mode = *(int *)extra;
8266
8267 down(&priv->action_sem);
8268 if (!(priv->status & STATUS_INITIALIZED)) {
8269 err = -EIO;
8270 goto done;
8271 }
8272
8273 if (mode == 1)
8274 priv->config |= CFG_CRC_CHECK;
8275 else if (mode == 0)
8276 priv->config &= ~CFG_CRC_CHECK;
8277 else {
8278 err = -EINVAL;
8279 goto done;
8280 }
8281 err = 0;
8282
8283 done:
8284 up(&priv->action_sem);
8285 return err;
8286}
8287
8288static int ipw2100_wx_get_crc_check(struct net_device *dev,
8289 struct iw_request_info *info,
8290 union iwreq_data *wrqu, char *extra)
8291{
8292 /*
8293 * This can be called at any time. No action lock required
8294 */
8295
8296 struct ipw2100_priv *priv = ieee80211_priv(dev);
8297
8298 if (priv->config & CFG_CRC_CHECK)
8299 snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
8300 else
8301 snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
8302
8303 return 0;
8304}
8305#endif /* CONFIG_IPW2100_MONITOR */
8306
8022static iw_handler ipw2100_wx_handlers[] = { 8307static iw_handler ipw2100_wx_handlers[] = {
8023 NULL, /* SIOCSIWCOMMIT */ 8308 NULL, /* SIOCSIWCOMMIT */
8024 ipw2100_wx_get_name, /* SIOCGIWNAME */ 8309 ipw2100_wx_get_name, /* SIOCGIWNAME */
@@ -8042,7 +8327,11 @@ static iw_handler ipw2100_wx_handlers[] = {
8042 NULL, /* SIOCWIWTHRSPY */ 8327 NULL, /* SIOCWIWTHRSPY */
8043 ipw2100_wx_set_wap, /* SIOCSIWAP */ 8328 ipw2100_wx_set_wap, /* SIOCSIWAP */
8044 ipw2100_wx_get_wap, /* SIOCGIWAP */ 8329 ipw2100_wx_get_wap, /* SIOCGIWAP */
8330#if WIRELESS_EXT > 17
8331 ipw2100_wx_set_mlme, /* SIOCSIWMLME */
8332#else
8045 NULL, /* -- hole -- */ 8333 NULL, /* -- hole -- */
8334#endif
8046 NULL, /* SIOCGIWAPLIST -- deprecated */ 8335 NULL, /* SIOCGIWAPLIST -- deprecated */
8047 ipw2100_wx_set_scan, /* SIOCSIWSCAN */ 8336 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8048 ipw2100_wx_get_scan, /* SIOCGIWSCAN */ 8337 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
@@ -8066,6 +8355,17 @@ static iw_handler ipw2100_wx_handlers[] = {
8066 ipw2100_wx_get_encode, /* SIOCGIWENCODE */ 8355 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8067 ipw2100_wx_set_power, /* SIOCSIWPOWER */ 8356 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8068 ipw2100_wx_get_power, /* SIOCGIWPOWER */ 8357 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8358#if WIRELESS_EXT > 17
8359 NULL, /* -- hole -- */
8360 NULL, /* -- hole -- */
8361 ipw2100_wx_set_genie, /* SIOCSIWGENIE */
8362 ipw2100_wx_get_genie, /* SIOCGIWGENIE */
8363 ipw2100_wx_set_auth, /* SIOCSIWAUTH */
8364 ipw2100_wx_get_auth, /* SIOCGIWAUTH */
8365 ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
8366 ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
8367 NULL, /* SIOCSIWPMKSA */
8368#endif
8069}; 8369};
8070 8370
8071#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV 8371#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
@@ -8074,6 +8374,8 @@ static iw_handler ipw2100_wx_handlers[] = {
8074#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3 8374#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8075#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4 8375#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8076#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5 8376#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8377#define IPW2100_PRIV_SET_CRC_CHECK SIOCIWFIRSTPRIV+6
8378#define IPW2100_PRIV_GET_CRC_CHECK SIOCIWFIRSTPRIV+7
8077 8379
8078static const struct iw_priv_args ipw2100_private_args[] = { 8380static const struct iw_priv_args ipw2100_private_args[] = {
8079 8381
@@ -8099,6 +8401,14 @@ static const struct iw_priv_args ipw2100_private_args[] = {
8099 { 8401 {
8100 IPW2100_PRIV_GET_LONGPREAMBLE, 8402 IPW2100_PRIV_GET_LONGPREAMBLE,
8101 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"}, 8403 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
8404#ifdef CONFIG_IPW2100_MONITOR
8405 {
8406 IPW2100_PRIV_SET_CRC_CHECK,
8407 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
8408 {
8409 IPW2100_PRIV_GET_CRC_CHECK,
8410 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
8411#endif /* CONFIG_IPW2100_MONITOR */
8102}; 8412};
8103 8413
8104static iw_handler ipw2100_private_handler[] = { 8414static iw_handler ipw2100_private_handler[] = {
@@ -8113,6 +8423,13 @@ static iw_handler ipw2100_private_handler[] = {
8113 ipw2100_wx_get_powermode, 8423 ipw2100_wx_get_powermode,
8114 ipw2100_wx_set_preamble, 8424 ipw2100_wx_set_preamble,
8115 ipw2100_wx_get_preamble, 8425 ipw2100_wx_get_preamble,
8426#ifdef CONFIG_IPW2100_MONITOR
8427 ipw2100_wx_set_crc_check,
8428 ipw2100_wx_get_crc_check,
8429#else /* CONFIG_IPW2100_MONITOR */
8430 NULL,
8431 NULL,
8432#endif /* CONFIG_IPW2100_MONITOR */
8116}; 8433};
8117 8434
8118static struct iw_handler_def ipw2100_wx_handler_def = { 8435static struct iw_handler_def ipw2100_wx_handler_def = {
@@ -8292,17 +8609,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
8292 /* We now have the BSSID, so can finish setting to the full 8609 /* We now have the BSSID, so can finish setting to the full
8293 * associated state */ 8610 * associated state */
8294 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN); 8611 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8295 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN); 8612 memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
8296 priv->status &= ~STATUS_ASSOCIATING; 8613 priv->status &= ~STATUS_ASSOCIATING;
8297 priv->status |= STATUS_ASSOCIATED; 8614 priv->status |= STATUS_ASSOCIATED;
8298 netif_carrier_on(priv->net_dev); 8615 netif_carrier_on(priv->net_dev);
8299 if (netif_queue_stopped(priv->net_dev)) { 8616 netif_wake_queue(priv->net_dev);
8300 IPW_DEBUG_INFO("Waking net queue.\n");
8301 netif_wake_queue(priv->net_dev);
8302 } else {
8303 IPW_DEBUG_INFO("Starting net queue.\n");
8304 netif_start_queue(priv->net_dev);
8305 }
8306 } 8617 }
8307 8618
8308 if (!(priv->status & STATUS_ASSOCIATED)) { 8619 if (!(priv->status & STATUS_ASSOCIATED)) {
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 3eb5c384eaab..99fce99b701a 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. 3 Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
4 4
5 This program is free software; you can redistribute it and/or modify it 5 This program is free software; you can redistribute it and/or modify it
6 under the terms of version 2 of the GNU General Public License as 6 under the terms of version 2 of the GNU General Public License as
@@ -475,6 +475,9 @@ enum {
475#define CFG_ADHOC_CREATE (1<<8) 475#define CFG_ADHOC_CREATE (1<<8)
476#define CFG_C3_DISABLED (1<<9) 476#define CFG_C3_DISABLED (1<<9)
477#define CFG_PASSIVE_SCAN (1<<10) 477#define CFG_PASSIVE_SCAN (1<<10)
478#ifdef CONFIG_IPW2100_MONITOR
479#define CFG_CRC_CHECK (1<<11)
480#endif
478 481
479#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */ 482#define CAP_SHARED_KEY (1<<0) /* Off = OPEN */
480#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */ 483#define CAP_PRIVACY_ON (1<<1) /* Off = No privacy */
@@ -858,9 +861,9 @@ struct ipw2100_rx {
858#define TYPE_ASSOCIATION_REQUEST 0x0013 861#define TYPE_ASSOCIATION_REQUEST 0x0013
859#define TYPE_REASSOCIATION_REQUEST 0x0014 862#define TYPE_REASSOCIATION_REQUEST 0x0014
860 863
861#define HW_FEATURE_RFKILL (0x0001) 864#define HW_FEATURE_RFKILL 0x0001
862#define RF_KILLSWITCH_OFF (1) 865#define RF_KILLSWITCH_OFF 1
863#define RF_KILLSWITCH_ON (0) 866#define RF_KILLSWITCH_ON 0
864 867
865#define IPW_COMMAND_POOL_SIZE 40 868#define IPW_COMMAND_POOL_SIZE 40
866 869