X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fwireless%2Fipw2100.c;h=94aeb23a77298c6c0153ff6d8fa18f6994524790;hb=d6e05edc59ecd79e8badf440c0d295a979bdfa3e;hp=23a74accd50ac63fae67988e153fd6c9f015fcf0;hpb=392d0f6d0752e6a3e25c3e3da95d78c53b0fd7a1;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 23a74ac..94aeb23 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved. + Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -167,15 +167,15 @@ that only one external action is invoked at a time. #include "ipw2100.h" -#define IPW2100_VERSION "1.1.1" +#define IPW2100_VERSION "git-1.2.2" #define DRV_NAME "ipw2100" #define DRV_VERSION IPW2100_VERSION #define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver" -#define DRV_COPYRIGHT "Copyright(c) 2003-2005 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation" /* Debugging stuff */ -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG #define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */ #endif @@ -208,7 +208,7 @@ MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); static u32 ipw2100_debug_level = IPW_DL_NONE; -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG #define IPW_DEBUG(level, message...) \ do { \ if (ipw2100_debug_level & (level)) { \ @@ -219,9 +219,9 @@ do { \ } while (0) #else #define IPW_DEBUG(level, message...) do {} while (0) -#endif /* CONFIG_IPW_DEBUG */ +#endif /* CONFIG_IPW2100_DEBUG */ -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG static const char *command_types[] = { "undefined", "unused", /* HOST_ATTENTION */ @@ -411,7 +411,7 @@ static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val) write_register(dev, IPW_REG_AUTOINCREMENT_DATA, val); } -static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len, +static void write_nic_memory(struct net_device *dev, u32 addr, u32 len, const u8 * buf) { u32 aligned_addr; @@ -449,7 +449,7 @@ static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len, *buf); } -static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len, +static void read_nic_memory(struct net_device *dev, u32 addr, u32 len, u8 * buf) { u32 aligned_addr; @@ -657,7 +657,7 @@ static void printk_buf(int level, const u8 * data, u32 len) #define MAX_RESET_BACKOFF 10 -static inline void schedule_reset(struct ipw2100_priv *priv) +static void schedule_reset(struct ipw2100_priv *priv) { unsigned long now = get_seconds(); @@ -1130,7 +1130,7 @@ static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv) write_register(priv->net_dev, IPW_REG_GPIO, reg); } -static inline int rf_kill_active(struct ipw2100_priv *priv) +static int rf_kill_active(struct ipw2100_priv *priv) { #define MAX_RF_KILL_CHECKS 5 #define RF_KILL_CHECK_DELAY 40 @@ -1418,7 +1418,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv) if (priv->status & STATUS_ENABLED) return 0; - down(&priv->adapter_sem); + mutex_lock(&priv->adapter_mutex); if (rf_kill_active(priv)) { IPW_DEBUG_HC("Command aborted due to RF kill active.\n"); @@ -1444,7 +1444,7 @@ static int ipw2100_enable_adapter(struct ipw2100_priv *priv) } fail_up: - up(&priv->adapter_sem); + mutex_unlock(&priv->adapter_mutex); return err; } @@ -1485,7 +1485,7 @@ static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv) * * Sending the PREPARE_FOR_POWER_DOWN will restrict the * hardware from going into standby mode and will transition - * out of D0-standy if it is already in that state. + * out of D0-standby if it is already in that state. * * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the * driver upon completion. Once received, the driver can @@ -1576,7 +1576,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv) cancel_delayed_work(&priv->hang_check); } - down(&priv->adapter_sem); + mutex_lock(&priv->adapter_mutex); err = ipw2100_hw_send_command(priv, &cmd); if (err) { @@ -1595,7 +1595,7 @@ static int ipw2100_disable_adapter(struct ipw2100_priv *priv) IPW_DEBUG_INFO("TODO: implement scan state machine\n"); fail_up: - up(&priv->adapter_sem); + mutex_unlock(&priv->adapter_mutex); return err; } @@ -1672,6 +1672,18 @@ static int ipw2100_start_scan(struct ipw2100_priv *priv) return err; } +static const struct ieee80211_geo ipw_geos[] = { + { /* Restricted */ + "---", + .bg_channels = 14, + .bg = {{2412, 1}, {2417, 2}, {2422, 3}, + {2427, 4}, {2432, 5}, {2437, 6}, + {2442, 7}, {2447, 8}, {2452, 9}, + {2457, 10}, {2462, 11}, {2467, 12}, + {2472, 13}, {2484, 14}}, + }, +}; + static int ipw2100_up(struct ipw2100_priv *priv, int deferred) { unsigned long flags; @@ -1727,6 +1739,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) goto exit; } + /* Initialize the geo */ + if (ieee80211_set_geo(priv->ieee, &ipw_geos[0])) { + printk(KERN_WARNING DRV_NAME "Could not set geo\n"); + return 0; + } + priv->ieee->freq_band = IEEE80211_24GHZ_BAND; + lock = LOCK_NONE; if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) { printk(KERN_ERR DRV_NAME @@ -1869,7 +1888,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv) priv->status |= STATUS_RESET_PENDING; spin_unlock_irqrestore(&priv->low_lock, flags); - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); /* stop timed checks so that they don't interfere with reset */ priv->stop_hang_check = 1; cancel_delayed_work(&priv->hang_check); @@ -1879,7 +1898,7 @@ static void ipw2100_reset_adapter(struct ipw2100_priv *priv) wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); ipw2100_up(priv, 0); - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); } @@ -2081,7 +2100,7 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status) priv->status &= ~STATUS_SCANNING; } -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG #define IPW2100_HANDLER(v, f) { v, f, # v } struct ipw2100_status_indicator { int status; @@ -2094,7 +2113,7 @@ struct ipw2100_status_indicator { int status; void (*cb) (struct ipw2100_priv * priv, u32 status); }; -#endif /* CONFIG_IPW_DEBUG */ +#endif /* CONFIG_IPW2100_DEBUG */ static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status) { @@ -2149,7 +2168,7 @@ static void isr_status_change(struct ipw2100_priv *priv, int status) static void isr_rx_complete_command(struct ipw2100_priv *priv, struct ipw2100_cmd_header *cmd) { -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG if (cmd->host_command_reg < ARRAY_SIZE(command_types)) { IPW_DEBUG_HC("Command completed '%s (%d)'\n", command_types[cmd->host_command_reg], @@ -2167,7 +2186,7 @@ static void isr_rx_complete_command(struct ipw2100_priv *priv, wake_up_interruptible(&priv->wait_command_queue); } -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG static const char *frame_types[] = { "COMMAND_STATUS_VAL", "STATUS_CHANGE_VAL", @@ -2177,7 +2196,7 @@ static const char *frame_types[] = { }; #endif -static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv, +static int ipw2100_alloc_skb(struct ipw2100_priv *priv, struct ipw2100_rx_packet *packet) { packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx)); @@ -2201,7 +2220,18 @@ static inline int ipw2100_alloc_skb(struct ipw2100_priv *priv, #define SEARCH_SNAPSHOT 1 #define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff)) -static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv) +static void ipw2100_snapshot_free(struct ipw2100_priv *priv) +{ + int i; + if (!priv->snapshot[0]) + return; + for (i = 0; i < 0x30; i++) + kfree(priv->snapshot[i]); + priv->snapshot[0] = NULL; +} + +#ifdef CONFIG_IPW2100_DEBUG_C3 +static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv) { int i; if (priv->snapshot[0]) @@ -2221,17 +2251,7 @@ static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv) return 1; } -static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv) -{ - int i; - if (!priv->snapshot[0]) - return; - for (i = 0; i < 0x30; i++) - kfree(priv->snapshot[i]); - priv->snapshot[0] = NULL; -} - -static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf, +static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf, size_t len, int mode) { u32 i, j; @@ -2269,6 +2289,7 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf, return ret; } +#endif /* * @@ -2288,9 +2309,9 @@ static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf, static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH]; #endif -static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i) +static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i) { -#ifdef CONFIG_IPW_DEBUG_C3 +#ifdef CONFIG_IPW2100_DEBUG_C3 struct ipw2100_status *status = &priv->status_queue.drv[i]; u32 match, reg; int j; @@ -2312,7 +2333,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i) } #endif -#ifdef CONFIG_IPW_DEBUG_C3 +#ifdef CONFIG_IPW2100_DEBUG_C3 /* Halt the fimrware so we can get a good image */ write_register(priv->net_dev, IPW_REG_RESET_REG, IPW_AUX_HOST_RESET_REG_STOP_MASTER); @@ -2346,7 +2367,7 @@ static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i) schedule_reset(priv); } -static inline void isr_rx(struct ipw2100_priv *priv, int i, +static void isr_rx(struct ipw2100_priv *priv, int i, struct ieee80211_rx_stats *stats) { struct ipw2100_status *status = &priv->status_queue.drv[i]; @@ -2369,15 +2390,6 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i, IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); return; } -#ifdef CONFIG_IPW2100_MONITOR - if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR && - priv->config & CFG_CRC_CHECK && - status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { - IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); - priv->ieee->stats.rx_errors++; - return; - } -#endif if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR && !(priv->status & STATUS_ASSOCIATED))) { @@ -2425,7 +2437,90 @@ static inline void isr_rx(struct ipw2100_priv *priv, int i, priv->rx_queue.drv[i].host_addr = packet->dma_addr; } -static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i) +#ifdef CONFIG_IPW2100_MONITOR + +static void isr_rx_monitor(struct ipw2100_priv *priv, int i, + struct ieee80211_rx_stats *stats) +{ + struct ipw2100_status *status = &priv->status_queue.drv[i]; + struct ipw2100_rx_packet *packet = &priv->rx_buffers[i]; + + /* Magic struct that slots into the radiotap header -- no reason + * to build this manually element by element, we can write it much + * more efficiently than we can parse it. ORDER MATTERS HERE */ + struct ipw_rt_hdr { + struct ieee80211_radiotap_header rt_hdr; + s8 rt_dbmsignal; /* signal in dbM, kluged to signed */ + } *ipw_rt; + + IPW_DEBUG_RX("Handler...\n"); + + if (unlikely(status->frame_size > skb_tailroom(packet->skb) - + sizeof(struct ipw_rt_hdr))) { + IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!" + " Dropping.\n", + priv->net_dev->name, + status->frame_size, + skb_tailroom(packet->skb)); + priv->ieee->stats.rx_errors++; + return; + } + + if (unlikely(!netif_running(priv->net_dev))) { + priv->ieee->stats.rx_errors++; + priv->wstats.discard.misc++; + IPW_DEBUG_DROP("Dropping packet while interface is not up.\n"); + return; + } + + if (unlikely(priv->config & CFG_CRC_CHECK && + status->flags & IPW_STATUS_FLAG_CRC_ERROR)) { + IPW_DEBUG_RX("CRC error in packet. Dropping.\n"); + priv->ieee->stats.rx_errors++; + return; + } + + pci_unmap_single(priv->pci_dev, packet->dma_addr, + sizeof(struct ipw2100_rx), PCI_DMA_FROMDEVICE); + memmove(packet->skb->data + sizeof(struct ipw_rt_hdr), + packet->skb->data, status->frame_size); + + ipw_rt = (struct ipw_rt_hdr *) packet->skb->data; + + ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; + ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */ + ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr); /* total hdr+data */ + + ipw_rt->rt_hdr.it_present = 1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL; + + ipw_rt->rt_dbmsignal = status->rssi + IPW2100_RSSI_TO_DBM; + + skb_put(packet->skb, status->frame_size + sizeof(struct ipw_rt_hdr)); + + if (!ieee80211_rx(priv->ieee, packet->skb, stats)) { + priv->ieee->stats.rx_errors++; + + /* ieee80211_rx failed, so it didn't free the SKB */ + dev_kfree_skb_any(packet->skb); + packet->skb = NULL; + } + + /* We need to allocate a new SKB and attach it to the RDB. */ + if (unlikely(ipw2100_alloc_skb(priv, packet))) { + IPW_DEBUG_WARNING( + "%s: Unable to allocate SKB onto RBD ring - disabling " + "adapter.\n", priv->net_dev->name); + /* TODO: schedule adapter shutdown */ + IPW_DEBUG_INFO("TODO: Shutdown adapter...\n"); + } + + /* Update the RDB entry */ + priv->rx_queue.drv[i].host_addr = packet->dma_addr; +} + +#endif + +static int ipw2100_corruption_check(struct ipw2100_priv *priv, int i) { struct ipw2100_status *status = &priv->status_queue.drv[i]; struct ipw2100_rx *u = priv->rx_buffers[i].rxp; @@ -2481,7 +2576,7 @@ static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i) * The WRITE index is cached in the variable 'priv->rx_queue.next'. * */ -static inline void __ipw2100_rx_process(struct ipw2100_priv *priv) +static void __ipw2100_rx_process(struct ipw2100_priv *priv) { struct ipw2100_bd_queue *rxq = &priv->rx_queue; struct ipw2100_status_queue *sq = &priv->status_queue; @@ -2556,7 +2651,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv) case P8023_DATA_VAL: #ifdef CONFIG_IPW2100_MONITOR if (priv->ieee->iw_mode == IW_MODE_MONITOR) { - isr_rx(priv, i, &stats); + isr_rx_monitor(priv, i, &stats); break; } #endif @@ -2634,7 +2729,7 @@ static inline void __ipw2100_rx_process(struct ipw2100_priv *priv) * for use by future command and data packets. * */ -static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) +static int __ipw2100_tx_process(struct ipw2100_priv *priv) { struct ipw2100_bd_queue *txq = &priv->tx_queue; struct ipw2100_bd *tbd; @@ -2716,7 +2811,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) list_del(element); DEC_STAT(&priv->fw_pend_stat); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG { int i = txq->oldest; IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i, @@ -2782,7 +2877,7 @@ static inline int __ipw2100_tx_process(struct ipw2100_priv *priv) "something else: ids %d=%d.\n", priv->net_dev->name, txq->oldest, packet->index); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG if (packet->info.c_struct.cmd->host_command_reg < sizeof(command_types) / sizeof(*command_types)) IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n", @@ -2975,7 +3070,7 @@ static void ipw2100_tx_send_data(struct ipw2100_priv *priv) IPW_DEBUG_TX("data header tbd TX%d P=%08x L=%d\n", packet->index, tbd->host_addr, tbd->buf_length); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG if (packet->info.d_struct.txb->nr_frags > 1) IPW_DEBUG_FRAG("fragment Tx: %d frames\n", packet->info.d_struct.txb->nr_frags); @@ -3748,6 +3843,8 @@ static ssize_t store_memory(struct device *d, struct device_attribute *attr, struct net_device *dev = priv->net_dev; const char *p = buf; + (void)dev; /* kill unused-var warning for debug-only code */ + if (count < 1) return count; @@ -3825,7 +3922,7 @@ static ssize_t show_stats(struct device *d, struct device_attribute *attr, priv->rx_interrupts, priv->inta_other); out += sprintf(out, "firmware resets: %d\n", priv->resets); out += sprintf(out, "firmware hangs: %d\n", priv->hangs); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG out += sprintf(out, "packet mismatch image: %s\n", priv->snapshot[0] ? "YES" : "NO"); #endif @@ -3859,7 +3956,7 @@ static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode) #ifdef CONFIG_IPW2100_MONITOR case IW_MODE_MONITOR: priv->last_mode = priv->ieee->iw_mode; - priv->net_dev->type = ARPHRD_IEEE80211; + priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP; break; #endif /* CONFIG_IPW2100_MONITOR */ } @@ -3980,7 +4077,7 @@ static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr, static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG static ssize_t show_debug_level(struct device_driver *d, char *buf) { return sprintf(buf, "0x%08X\n", ipw2100_debug_level); @@ -4009,7 +4106,7 @@ static ssize_t store_debug_level(struct device_driver *d, static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, store_debug_level); -#endif /* CONFIG_IPW_DEBUG */ +#endif /* CONFIG_IPW2100_DEBUG */ static ssize_t show_fatal_error(struct device *d, struct device_attribute *attr, char *buf) @@ -4066,6 +4163,8 @@ static ssize_t store_scan_age(struct device *d, struct device_attribute *attr, unsigned long val; char *p = buffer; + (void)dev; /* kill unused-var warning for debug-only code */ + IPW_DEBUG_INFO("enter\n"); strncpy(buffer, buf, len); @@ -4113,7 +4212,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n", disable_radio ? "OFF" : "ON"); - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (disable_radio) { priv->status |= STATUS_RF_KILL_SW; @@ -4131,7 +4230,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio) schedule_reset(priv); } - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return 1; } @@ -4933,7 +5032,7 @@ static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 * bssid, }; int err; -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG if (bssid != NULL) IPW_DEBUG_HC("MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], @@ -5101,12 +5200,13 @@ static int ipw2100_set_tx_power(struct ipw2100_priv *priv, u32 tx_power) .host_command_length = 4 }; int err = 0; + u32 tmp = tx_power; if (tx_power != IPW_TX_POWER_DEFAULT) - tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 / - (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM); + tmp = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 / + (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM); - cmd.host_command_parameters[0] = tx_power; + cmd.host_command_parameters[0] = tmp; if (priv->ieee->iw_mode == IW_MODE_ADHOC) err = ipw2100_hw_send_command(priv, &cmd); @@ -5359,9 +5459,12 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode) SEC_LEVEL_0, 0, 1); } else { auth_mode = IPW_AUTH_OPEN; - if ((priv->ieee->sec.flags & SEC_AUTH_MODE) && - (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) - auth_mode = IPW_AUTH_SHARED; + if (priv->ieee->sec.flags & SEC_AUTH_MODE) { + if (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY) + auth_mode = IPW_AUTH_SHARED; + else if (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP) + auth_mode = IPW_AUTH_LEAP_CISCO_ID; + } sec_level = SEC_LEVEL_0; if (priv->ieee->sec.flags & SEC_LEVEL) @@ -5431,7 +5534,7 @@ static void shim__set_security(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int i, force_update = 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) goto done; @@ -5504,7 +5607,7 @@ static void shim__set_security(struct net_device *dev, if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) ipw2100_configure_security(priv, 0); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); } static int ipw2100_adapter_setup(struct ipw2100_priv *priv) @@ -5628,7 +5731,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); priv->config |= CFG_CUSTOM_MAC; memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN); @@ -5638,12 +5741,12 @@ static int ipw2100_set_address(struct net_device *dev, void *p) goto done; priv->reset_backoff = 0; - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); ipw2100_reset_adapter(priv); return 0; done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -5731,70 +5834,6 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev) return &priv->ieee->stats; } -#if WIRELESS_EXT < 18 -/* Support for wpa_supplicant before WE-18, deprecated. */ - -/* following definitions must match definitions in driver_ipw.c */ - -#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 - -#define IPW2100_CMD_SET_WPA_PARAM 1 -#define IPW2100_CMD_SET_WPA_IE 2 -#define IPW2100_CMD_SET_ENCRYPTION 3 -#define IPW2100_CMD_MLME 4 - -#define IPW2100_PARAM_WPA_ENABLED 1 -#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2 -#define IPW2100_PARAM_DROP_UNENCRYPTED 3 -#define IPW2100_PARAM_PRIVACY_INVOKED 4 -#define IPW2100_PARAM_AUTH_ALGS 5 -#define IPW2100_PARAM_IEEE_802_1X 6 - -#define IPW2100_MLME_STA_DEAUTH 1 -#define IPW2100_MLME_STA_DISASSOC 2 - -#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2 -#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5 -#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7 - -#define IPW2100_CRYPT_ALG_NAME_LEN 16 - -struct ipw2100_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[0]; - } wpa_ie; - struct { - u32 command; - u32 reason_code; - } mlme; - struct { - u8 alg[IPW2100_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[0]; - } crypt; - - } u; -}; - -/* end of driver_ipw.c code */ -#endif /* WIRELESS_EXT < 18 */ - static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) { /* This is called when wpa_supplicant loads and closes the driver @@ -5803,11 +5842,6 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) return 0; } -#if WIRELESS_EXT < 18 -#define IW_AUTH_ALG_OPEN_SYSTEM 0x1 -#define IW_AUTH_ALG_SHARED_KEY 0x2 -#endif - static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) { @@ -5823,6 +5857,9 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) { sec.auth_mode = WLAN_AUTH_OPEN; ieee->open_wep = 1; + } else if (value & IW_AUTH_ALG_LEAP) { + sec.auth_mode = WLAN_AUTH_LEAP; + ieee->open_wep = 1; } else return -EINVAL; @@ -5834,8 +5871,8 @@ static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value) return ret; } -void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, - char *wpa_ie, int wpa_ie_len) +static void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, + char *wpa_ie, int wpa_ie_len) { struct ipw2100_wpa_assoc_frame frame; @@ -5851,365 +5888,6 @@ void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, ipw2100_set_wpa_ie(priv, &frame, 0); } -#if WIRELESS_EXT < 18 -static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value) -{ - struct ipw2100_priv *priv = ieee80211_priv(dev); - struct ieee80211_crypt_data *crypt; - unsigned long flags; - int ret = 0; - - switch (name) { - case IPW2100_PARAM_WPA_ENABLED: - ret = ipw2100_wpa_enable(priv, value); - break; - - case IPW2100_PARAM_TKIP_COUNTERMEASURES: - crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; - if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) { - IPW_DEBUG_WARNING("Can't set TKIP countermeasures: " - "crypt not set!\n"); - break; - } - - flags = crypt->ops->get_flags(crypt->priv); - - if (value) - flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; - else - flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES; - - crypt->ops->set_flags(flags, crypt->priv); - - break; - - case IPW2100_PARAM_DROP_UNENCRYPTED:{ - /* See IW_AUTH_DROP_UNENCRYPTED handling for details */ - struct ieee80211_security sec = { - .flags = SEC_ENABLED, - .enabled = value, - }; - priv->ieee->drop_unencrypted = value; - /* We only change SEC_LEVEL for open mode. Others - * are set by ipw_wpa_set_encryption. - */ - if (!value) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_0; - } else { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } - if (priv->ieee->set_security) - priv->ieee->set_security(priv->ieee->dev, &sec); - break; - } - - case IPW2100_PARAM_PRIVACY_INVOKED: - priv->ieee->privacy_invoked = value; - break; - - case IPW2100_PARAM_AUTH_ALGS: - ret = ipw2100_wpa_set_auth_algs(priv, value); - break; - - case IPW2100_PARAM_IEEE_802_1X: - priv->ieee->ieee802_1x = value; - break; - - default: - printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n", - dev->name, name); - ret = -EOPNOTSUPP; - } - - return ret; -} - -static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason) -{ - - struct ipw2100_priv *priv = ieee80211_priv(dev); - int ret = 0; - - switch (command) { - case IPW2100_MLME_STA_DEAUTH: - // silently ignore - break; - - case IPW2100_MLME_STA_DISASSOC: - ipw2100_disassociate_bssid(priv); - break; - - default: - printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n", - dev->name, command); - ret = -EOPNOTSUPP; - } - - return ret; -} - -static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, - struct ipw2100_param *param, int plen) -{ - - struct ipw2100_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee; - u8 *buf; - - if (!ieee->wpa_enabled) - return -EOPNOTSUPP; - - if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || - (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) - return -EINVAL; - - if (param->u.wpa_ie.len) { - buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); - - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = param->u.wpa_ie.len; - - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - - ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); - - return 0; -} - -/* implementation borrowed from hostap driver */ - -static int ipw2100_wpa_set_encryption(struct net_device *dev, - struct ipw2100_param *param, - int param_len) -{ - int ret = 0; - struct ipw2100_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee; - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - - param->u.crypt.err = 0; - param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0'; - - if (param_len != - (int)((char *)param->u.crypt.key - (char *)param) + - param->u.crypt.key_len) { - IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, - param->u.crypt.key_len); - return -EINVAL; - } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - if (param->u.crypt.idx >= WEP_KEYS) - return -EINVAL; - crypt = &ieee->crypt[param->u.crypt.idx]; - } else { - return -EINVAL; - } - - sec.flags |= SEC_ENABLED | SEC_ENCRYPT; - if (strcmp(param->u.crypt.alg, "none") == 0) { - if (crypt) { - sec.enabled = 0; - sec.encrypt = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_LEVEL; - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - goto done; - } - sec.enabled = 1; - sec.encrypt = 1; - - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { - request_module("ieee80211_crypt_wep"); - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { - request_module("ieee80211_crypt_tkip"); - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { - request_module("ieee80211_crypt_ccmp"); - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - } - if (ops == NULL) { - IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n", - dev->name, param->u.crypt.alg); - param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG; - ret = -EINVAL; - goto done; - } - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - - new_crypt = (struct ieee80211_crypt_data *) - kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); - new_crypt->ops = ops; - if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) - new_crypt->priv = - new_crypt->ops->init(param->u.crypt.idx); - - if (new_crypt->priv == NULL) { - kfree(new_crypt); - param->u.crypt.err = - IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED; - ret = -EINVAL; - goto done; - } - - *crypt = new_crypt; - } - - if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(param->u.crypt.key, - param->u.crypt.key_len, param->u.crypt.seq, - (*crypt)->priv) < 0) { - IPW_DEBUG_INFO("%s: key setting failed\n", dev->name); - param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED; - ret = -EINVAL; - goto done; - } - - if (param->u.crypt.set_tx) { - ieee->tx_keyidx = param->u.crypt.idx; - sec.active_key = param->u.crypt.idx; - sec.flags |= SEC_ACTIVE_KEY; - } - - if (ops->name != NULL) { - - if (strcmp(ops->name, "WEP") == 0) { - memcpy(sec.keys[param->u.crypt.idx], - param->u.crypt.key, param->u.crypt.key_len); - sec.key_sizes[param->u.crypt.idx] = - param->u.crypt.key_len; - sec.flags |= (1 << param->u.crypt.idx); - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (strcmp(ops->name, "TKIP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (strcmp(ops->name, "CCMP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - } - done: - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name); - param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED; - return -EINVAL; - } - - return ret; -} - -static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p) -{ - - struct ipw2100_param *param; - int ret = 0; - - IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length); - - if (p->length < sizeof(struct ipw2100_param) || !p->pointer) - return -EINVAL; - - param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - kfree(param); - return -EFAULT; - } - - switch (param->cmd) { - - case IPW2100_CMD_SET_WPA_PARAM: - ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name, - param->u.wpa_param.value); - break; - - case IPW2100_CMD_SET_WPA_IE: - ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length); - break; - - case IPW2100_CMD_SET_ENCRYPTION: - ret = ipw2100_wpa_set_encryption(dev, param, p->length); - break; - - case IPW2100_CMD_MLME: - ret = ipw2100_wpa_mlme(dev, param->u.mlme.command, - param->u.mlme.reason_code); - break; - - default: - printk(KERN_ERR DRV_NAME - ": %s: Unknown WPA supplicant request: %d\n", dev->name, - param->cmd); - ret = -EOPNOTSUPP; - - } - - if (ret == 0 && copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - - kfree(param); - return ret; -} - -static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct iwreq *wrq = (struct iwreq *)rq; - int ret = -1; - switch (cmd) { - case IPW2100_IOCTL_WPA_SUPPLICANT: - ret = ipw2100_wpa_supplicant(dev, &wrq->u.data); - return ret; - - default: - return -EOPNOTSUPP; - } - - return -EOPNOTSUPP; -} -#endif /* WIRELESS_EXT < 18 */ - static void ipw_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -6338,14 +6016,12 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, dev->open = ipw2100_open; dev->stop = ipw2100_close; dev->init = ipw2100_net_init; -#if WIRELESS_EXT < 18 - dev->do_ioctl = ipw2100_ioctl; -#endif dev->get_stats = ipw2100_stats; dev->ethtool_ops = &ipw2100_ethtool_ops; dev->tx_timeout = ipw2100_tx_timeout; dev->wireless_handlers = &ipw2100_wx_handler_def; - dev->get_wireless_stats = ipw2100_wx_wireless_stats; + priv->wireless_data.ieee80211 = priv->ieee; + dev->wireless_data = &priv->wireless_data; dev->set_mac_address = ipw2100_set_address; dev->watchdog_timeo = 3 * HZ; dev->irq = 0; @@ -6413,8 +6089,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, strcpy(priv->nick, "ipw2100"); spin_lock_init(&priv->low_lock); - sema_init(&priv->action_sem, 1); - sema_init(&priv->adapter_sem, 1); + mutex_init(&priv->action_mutex); + mutex_init(&priv->adapter_mutex); init_waitqueue_head(&priv->wait_command_queue); @@ -6579,7 +6255,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, * member to call a function that then just turns and calls ipw2100_up. * net_dev->init is called after name allocation but before the * notifier chain is called */ - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); err = register_netdev(dev); if (err) { printk(KERN_WARNING DRV_NAME @@ -6615,12 +6291,12 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev, priv->status |= STATUS_INITIALIZED; - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return 0; fail_unlock: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); fail: if (dev) { @@ -6660,7 +6336,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) struct net_device *dev; if (priv) { - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); priv->status &= ~STATUS_INITIALIZED; @@ -6675,9 +6351,9 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) /* Take down the hardware */ ipw2100_down(priv); - /* Release the semaphore so that the network subsystem can + /* Release the mutex so that the network subsystem can * complete any needed calls into the driver... */ - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); /* Unregister the device first - this results in close() * being called if the device is open. If we free storage @@ -6709,18 +6385,14 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) } #ifdef CONFIG_PM -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) -static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state) -#else static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) -#endif { struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); struct net_device *dev = priv->net_dev; IPW_DEBUG_INFO("%s: Going into suspend...\n", dev->name); - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (priv->status & STATUS_INITIALIZED) { /* Take down the device; powers it off, etc. */ ipw2100_down(priv); @@ -6733,7 +6405,7 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state) pci_disable_device(pci_dev); pci_set_power_state(pci_dev, PCI_D3hot); - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return 0; } @@ -6747,7 +6419,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev) if (IPW2100_PM_DISABLED) return 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); IPW_DEBUG_INFO("%s: Coming out of suspend...\n", dev->name); @@ -6773,7 +6445,7 @@ static int ipw2100_resume(struct pci_dev *pci_dev) if (!(priv->status & STATUS_RF_KILL_SW)) ipw2100_up(priv, 0); - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return 0; } @@ -6862,7 +6534,7 @@ static int __init ipw2100_init(void) ret = pci_module_init(&ipw2100_pci_driver); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG ipw2100_debug_level = debug; driver_create_file(&ipw2100_pci_driver.driver, &driver_attr_debug_level); @@ -6877,7 +6549,7 @@ static int __init ipw2100_init(void) static void __exit ipw2100_exit(void) { /* FIXME: IPG: check that we have no instances of the devices open */ -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG driver_remove_file(&ipw2100_pci_driver.driver, &driver_attr_debug_level); #endif @@ -6937,7 +6609,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev, if (priv->ieee->iw_mode == IW_MODE_INFRA) return -EOPNOTSUPP; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -6968,7 +6640,7 @@ static int ipw2100_wx_set_freq(struct net_device *dev, } done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7009,7 +6681,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev, if (wrqu->mode == priv->ieee->iw_mode) return 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7032,7 +6704,7 @@ static int ipw2100_wx_set_mode(struct net_device *dev, } done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7157,7 +6829,7 @@ static int ipw2100_wx_get_range(struct net_device *dev, /* Set the Wireless Extension versions */ range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; + range->we_version_source = 18; // range->retry_capa; /* What retry options are supported */ // range->retry_flags; /* How to decode max/min retry limit */ @@ -7183,6 +6855,14 @@ static int ipw2100_wx_get_range(struct net_device *dev, } range->num_frequency = val; + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWAP)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; + IPW_DEBUG_WX("GET Range\n"); return 0; @@ -7206,7 +6886,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev, if (wrqu->ap_addr.sa_family != ARPHRD_ETHER) return -EINVAL; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7235,7 +6915,7 @@ static int ipw2100_wx_set_wap(struct net_device *dev, wrqu->ap_addr.sa_data[5] & 0xff); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7271,7 +6951,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, int length = 0; int err = 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7308,7 +6988,7 @@ static int ipw2100_wx_set_essid(struct net_device *dev, err = ipw2100_set_essid(priv, essid, length, 0); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7389,7 +7069,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev, u32 rate; int err = 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7416,7 +7096,7 @@ static int ipw2100_wx_set_rate(struct net_device *dev, IPW_DEBUG_WX("SET Rate -> %04X \n", rate); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7436,7 +7116,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev, return 0; } - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7468,7 +7148,7 @@ static int ipw2100_wx_get_rate(struct net_device *dev, IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7483,7 +7163,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev, if (wrqu->rts.fixed == 0) return -EINVAL; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7503,7 +7183,7 @@ static int ipw2100_wx_set_rts(struct net_device *dev, IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7534,11 +7214,17 @@ static int ipw2100_wx_set_txpow(struct net_device *dev, { struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0, value; + + if (ipw_radio_kill_sw(priv, wrqu->txpower.disabled)) + return -EINPROGRESS; if (priv->ieee->iw_mode != IW_MODE_ADHOC) + return 0; + + if ((wrqu->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) return -EINVAL; - if (wrqu->txpower.disabled == 1 || wrqu->txpower.fixed == 0) + if (wrqu->txpower.fixed == 0) value = IPW_TX_POWER_DEFAULT; else { if (wrqu->txpower.value < IPW_TX_POWER_MIN_DBM || @@ -7548,7 +7234,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev, value = wrqu->txpower.value; } - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7559,7 +7245,7 @@ static int ipw2100_wx_set_txpow(struct net_device *dev, IPW_DEBUG_WX("SET TX Power -> %d \n", value); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7573,24 +7259,19 @@ static int ipw2100_wx_get_txpow(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); - if (priv->ieee->iw_mode != IW_MODE_ADHOC) { - wrqu->power.disabled = 1; - return 0; - } + wrqu->txpower.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0; if (priv->tx_power == IPW_TX_POWER_DEFAULT) { - wrqu->power.fixed = 0; - wrqu->power.value = IPW_TX_POWER_MAX_DBM; - wrqu->power.disabled = 1; + wrqu->txpower.fixed = 0; + wrqu->txpower.value = IPW_TX_POWER_MAX_DBM; } else { - wrqu->power.disabled = 0; - wrqu->power.fixed = 1; - wrqu->power.value = priv->tx_power; + wrqu->txpower.fixed = 1; + wrqu->txpower.value = priv->tx_power; } - wrqu->power.flags = IW_TXPOW_DBM; + wrqu->txpower.flags = IW_TXPOW_DBM; - IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->power.value); + IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->txpower.value); return 0; } @@ -7656,7 +7337,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev, if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) return 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7683,7 +7364,7 @@ static int ipw2100_wx_set_retry(struct net_device *dev, IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7726,7 +7407,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7741,7 +7422,7 @@ static int ipw2100_wx_set_scan(struct net_device *dev, } done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7791,7 +7472,7 @@ static int ipw2100_wx_set_power(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -7824,7 +7505,7 @@ static int ipw2100_wx_set_power(struct net_device *dev, IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -7851,7 +7532,6 @@ static int ipw2100_wx_get_power(struct net_device *dev, return 0; } -#if WIRELESS_EXT > 17 /* * WE-18 WPA support */ @@ -7939,11 +7619,8 @@ static int ipw2100_wx_set_auth(struct net_device *dev, case IW_AUTH_TKIP_COUNTERMEASURES: crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; - if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) { - IPW_DEBUG_WARNING("Can't set TKIP countermeasures: " - "crypt not set!\n"); + if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) break; - } flags = crypt->ops->get_flags(crypt->priv); @@ -8116,7 +7793,6 @@ static int ipw2100_wx_set_mlme(struct net_device *dev, } return 0; } -#endif /* WIRELESS_EXT > 17 */ /* * @@ -8133,7 +7809,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev, int enable = (parms[0] > 0); int err = 0; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -8151,7 +7827,7 @@ static int ipw2100_wx_set_promisc(struct net_device *dev, err = ipw2100_switch_mode(priv, priv->last_mode); } done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -8174,7 +7850,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err = 0, mode = *(int *)extra; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -8186,7 +7862,7 @@ static int ipw2100_wx_set_powermode(struct net_device *dev, if (priv->power_mode != mode) err = ipw2100_set_power_mode(priv, mode); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -8238,7 +7914,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err, mode = *(int *)extra; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -8256,7 +7932,7 @@ static int ipw2100_wx_set_preamble(struct net_device *dev, err = ipw2100_system_config(priv, 0); done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -8286,7 +7962,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev, struct ipw2100_priv *priv = ieee80211_priv(dev); int err, mode = *(int *)extra; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); if (!(priv->status & STATUS_INITIALIZED)) { err = -EIO; goto done; @@ -8303,7 +7979,7 @@ static int ipw2100_wx_set_crc_check(struct net_device *dev, err = 0; done: - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); return err; } @@ -8349,11 +8025,7 @@ static iw_handler ipw2100_wx_handlers[] = { NULL, /* SIOCWIWTHRSPY */ ipw2100_wx_set_wap, /* SIOCSIWAP */ ipw2100_wx_get_wap, /* SIOCGIWAP */ -#if WIRELESS_EXT > 17 ipw2100_wx_set_mlme, /* SIOCSIWMLME */ -#else - NULL, /* -- hole -- */ -#endif NULL, /* SIOCGIWAPLIST -- deprecated */ ipw2100_wx_set_scan, /* SIOCSIWSCAN */ ipw2100_wx_get_scan, /* SIOCGIWSCAN */ @@ -8377,7 +8049,6 @@ static iw_handler ipw2100_wx_handlers[] = { ipw2100_wx_get_encode, /* SIOCGIWENCODE */ ipw2100_wx_set_power, /* SIOCSIWPOWER */ ipw2100_wx_get_power, /* SIOCGIWPOWER */ -#if WIRELESS_EXT > 17 NULL, /* -- hole -- */ NULL, /* -- hole -- */ ipw2100_wx_set_genie, /* SIOCSIWGENIE */ @@ -8387,7 +8058,6 @@ static iw_handler ipw2100_wx_handlers[] = { ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */ ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */ NULL, /* SIOCSIWPMKSA */ -#endif }; #define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV @@ -8454,16 +8124,6 @@ static iw_handler ipw2100_private_handler[] = { #endif /* CONFIG_IPW2100_MONITOR */ }; -static struct iw_handler_def ipw2100_wx_handler_def = { - .standard = ipw2100_wx_handlers, - .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler), - .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(ipw2100_private_args) / - sizeof(struct iw_priv_args), - .private = (iw_handler *) ipw2100_private_handler, - .private_args = (struct iw_priv_args *)ipw2100_private_args, -}; - /* * Get wireless statistics. * Called by /proc/net/wireless @@ -8570,7 +8230,7 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev) quality = min(beacon_qual, min(tx_qual, rssi_qual)); -#ifdef CONFIG_IPW_DEBUG +#ifdef CONFIG_IPW2100_DEBUG if (beacon_qual == quality) IPW_DEBUG_WX("Quality clamped by Missed Beacons\n"); else if (tx_qual == quality) @@ -8605,6 +8265,17 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev) return (struct iw_statistics *)NULL; } +static struct iw_handler_def ipw2100_wx_handler_def = { + .standard = ipw2100_wx_handlers, + .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler), + .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(ipw2100_private_args) / + sizeof(struct iw_priv_args), + .private = (iw_handler *) ipw2100_private_handler, + .private_args = (struct iw_priv_args *)ipw2100_private_args, + .get_wireless_stats = ipw2100_wx_wireless_stats, +}; + static void ipw2100_wx_event_work(struct ipw2100_priv *priv) { union iwreq_data wrqu; @@ -8613,11 +8284,11 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv) if (priv->status & STATUS_STOPPING) return; - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); IPW_DEBUG_WX("enter\n"); - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -8640,7 +8311,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv) if (!(priv->status & STATUS_ASSOCIATED)) { IPW_DEBUG_WX("Configuring ESSID\n"); - down(&priv->action_sem); + mutex_lock(&priv->action_mutex); /* This is a disassociation event, so kick the firmware to * look for another AP */ if (priv->config & CFG_STATIC_ESSID) @@ -8648,7 +8319,7 @@ static void ipw2100_wx_event_work(struct ipw2100_priv *priv) 0); else ipw2100_set_essid(priv, NULL, 0, 0); - up(&priv->action_sem); + mutex_unlock(&priv->action_mutex); } wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);