aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2x00/ipw2200.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/ipw2x00/ipw2200.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/ipw2x00/ipw2200.c')
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c189
1 files changed, 152 insertions, 37 deletions
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index a6ca536e44f8..8d72e3d19586 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -31,6 +31,7 @@
31******************************************************************************/ 31******************************************************************************/
32 32
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/slab.h>
34#include "ipw2200.h" 35#include "ipw2200.h"
35 36
36 37
@@ -81,6 +82,11 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
81MODULE_VERSION(DRV_VERSION); 82MODULE_VERSION(DRV_VERSION);
82MODULE_AUTHOR(DRV_COPYRIGHT); 83MODULE_AUTHOR(DRV_COPYRIGHT);
83MODULE_LICENSE("GPL"); 84MODULE_LICENSE("GPL");
85MODULE_FIRMWARE("ipw2200-ibss.fw");
86#ifdef CONFIG_IPW2200_MONITOR
87MODULE_FIRMWARE("ipw2200-sniffer.fw");
88#endif
89MODULE_FIRMWARE("ipw2200-bss.fw");
84 90
85static int cmdlog = 0; 91static int cmdlog = 0;
86static int debug = 0; 92static int debug = 0;
@@ -104,6 +110,25 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
104static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ 110static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
105#endif 111#endif
106 112
113static struct ieee80211_rate ipw2200_rates[] = {
114 { .bitrate = 10 },
115 { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
116 { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
117 { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
118 { .bitrate = 60 },
119 { .bitrate = 90 },
120 { .bitrate = 120 },
121 { .bitrate = 180 },
122 { .bitrate = 240 },
123 { .bitrate = 360 },
124 { .bitrate = 480 },
125 { .bitrate = 540 }
126};
127
128#define ipw2200_a_rates (ipw2200_rates + 4)
129#define ipw2200_num_a_rates 8
130#define ipw2200_bg_rates (ipw2200_rates + 0)
131#define ipw2200_num_bg_rates 12
107 132
108#ifdef CONFIG_IPW2200_QOS 133#ifdef CONFIG_IPW2200_QOS
109static int qos_enable = 0; 134static int qos_enable = 0;
@@ -768,7 +793,7 @@ static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
768 /* get number of entries */ 793 /* get number of entries */
769 field_count = *(((u16 *) & field_info) + 1); 794 field_count = *(((u16 *) & field_info) + 1);
770 795
771 /* abort if not enought memory */ 796 /* abort if not enough memory */
772 total_len = field_len * field_count; 797 total_len = field_len * field_count;
773 if (total_len > *len) { 798 if (total_len > *len) {
774 *len = total_len; 799 *len = total_len;
@@ -1734,10 +1759,13 @@ static DEVICE_ATTR(direct_dword, S_IWUSR | S_IRUGO,
1734 1759
1735static int rf_kill_active(struct ipw_priv *priv) 1760static int rf_kill_active(struct ipw_priv *priv)
1736{ 1761{
1737 if (0 == (ipw_read32(priv, 0x30) & 0x10000)) 1762 if (0 == (ipw_read32(priv, 0x30) & 0x10000)) {
1738 priv->status |= STATUS_RF_KILL_HW; 1763 priv->status |= STATUS_RF_KILL_HW;
1739 else 1764 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
1765 } else {
1740 priv->status &= ~STATUS_RF_KILL_HW; 1766 priv->status &= ~STATUS_RF_KILL_HW;
1767 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);
1768 }
1741 1769
1742 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0; 1770 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;
1743} 1771}
@@ -2020,6 +2048,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv)
2020 if (inta & IPW_INTA_BIT_RF_KILL_DONE) { 2048 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {
2021 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n"); 2049 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
2022 priv->status |= STATUS_RF_KILL_HW; 2050 priv->status |= STATUS_RF_KILL_HW;
2051 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);
2023 wake_up_interruptible(&priv->wait_command_queue); 2052 wake_up_interruptible(&priv->wait_command_queue);
2024 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); 2053 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
2025 cancel_delayed_work(&priv->request_scan); 2054 cancel_delayed_work(&priv->request_scan);
@@ -3149,14 +3178,27 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
3149 int total_nr = 0; 3178 int total_nr = 0;
3150 int i; 3179 int i;
3151 struct pci_pool *pool; 3180 struct pci_pool *pool;
3152 u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL]; 3181 void **virts;
3153 dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL]; 3182 dma_addr_t *phys;
3154 3183
3155 IPW_DEBUG_TRACE("<< : \n"); 3184 IPW_DEBUG_TRACE("<< : \n");
3156 3185
3186 virts = kmalloc(sizeof(void *) * CB_NUMBER_OF_ELEMENTS_SMALL,
3187 GFP_KERNEL);
3188 if (!virts)
3189 return -ENOMEM;
3190
3191 phys = kmalloc(sizeof(dma_addr_t) * CB_NUMBER_OF_ELEMENTS_SMALL,
3192 GFP_KERNEL);
3193 if (!phys) {
3194 kfree(virts);
3195 return -ENOMEM;
3196 }
3157 pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0); 3197 pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
3158 if (!pool) { 3198 if (!pool) {
3159 IPW_ERROR("pci_pool_create failed\n"); 3199 IPW_ERROR("pci_pool_create failed\n");
3200 kfree(phys);
3201 kfree(virts);
3160 return -ENOMEM; 3202 return -ENOMEM;
3161 } 3203 }
3162 3204
@@ -3226,6 +3268,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
3226 pci_pool_free(pool, virts[i], phys[i]); 3268 pci_pool_free(pool, virts[i], phys[i]);
3227 3269
3228 pci_pool_destroy(pool); 3270 pci_pool_destroy(pool);
3271 kfree(phys);
3272 kfree(virts);
3229 3273
3230 return ret; 3274 return ret;
3231} 3275}
@@ -7732,7 +7776,7 @@ static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,
7732 case SEC_LEVEL_0: 7776 case SEC_LEVEL_0:
7733 break; 7777 break;
7734 default: 7778 default:
7735 printk(KERN_ERR "Unknow security level %d\n", 7779 printk(KERN_ERR "Unknown security level %d\n",
7736 priv->ieee->sec.level); 7780 priv->ieee->sec.level);
7737 break; 7781 break;
7738 } 7782 }
@@ -8655,24 +8699,6 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
8655 * 8699 *
8656 */ 8700 */
8657 8701
8658static int ipw_wx_get_name(struct net_device *dev,
8659 struct iw_request_info *info,
8660 union iwreq_data *wrqu, char *extra)
8661{
8662 struct ipw_priv *priv = libipw_priv(dev);
8663 mutex_lock(&priv->mutex);
8664 if (priv->status & STATUS_RF_KILL_MASK)
8665 strcpy(wrqu->name, "radio off");
8666 else if (!(priv->status & STATUS_ASSOCIATED))
8667 strcpy(wrqu->name, "unassociated");
8668 else
8669 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
8670 ipw_modes[priv->assoc_request.ieee_mode]);
8671 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8672 mutex_unlock(&priv->mutex);
8673 return 0;
8674}
8675
8676static int ipw_set_channel(struct ipw_priv *priv, u8 channel) 8702static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
8677{ 8703{
8678 if (channel == 0) { 8704 if (channel == 0) {
@@ -8916,7 +8942,7 @@ static int ipw_wx_get_range(struct net_device *dev,
8916 range->max_qual.updated = 7; /* Updated all three */ 8942 range->max_qual.updated = 7; /* Updated all three */
8917 8943
8918 range->avg_qual.qual = 70; 8944 range->avg_qual.qual = 70;
8919 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */ 8945 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
8920 range->avg_qual.level = 0; /* FIXME to real average level */ 8946 range->avg_qual.level = 0; /* FIXME to real average level */
8921 range->avg_qual.noise = 0; 8947 range->avg_qual.noise = 0;
8922 range->avg_qual.updated = 7; /* Updated all three */ 8948 range->avg_qual.updated = 7; /* Updated all three */
@@ -9972,7 +9998,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9972/* Rebase the WE IOCTLs to zero for the handler array */ 9998/* Rebase the WE IOCTLs to zero for the handler array */
9973#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 9999#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
9974static iw_handler ipw_wx_handlers[] = { 10000static iw_handler ipw_wx_handlers[] = {
9975 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 10001 IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
9976 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 10002 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
9977 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 10003 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
9978 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 10004 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -10289,7 +10315,7 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,
10289 case SEC_LEVEL_0: 10315 case SEC_LEVEL_0:
10290 break; 10316 break;
10291 default: 10317 default:
10292 printk(KERN_ERR "Unknow security level %d\n", 10318 printk(KERN_ERR "Unknown security level %d\n",
10293 priv->ieee->sec.level); 10319 priv->ieee->sec.level);
10294 break; 10320 break;
10295 } 10321 }
@@ -11275,6 +11301,7 @@ static int ipw_up(struct ipw_priv *priv)
11275 if (!(priv->config & CFG_CUSTOM_MAC)) 11301 if (!(priv->config & CFG_CUSTOM_MAC))
11276 eeprom_parse_mac(priv, priv->mac_addr); 11302 eeprom_parse_mac(priv, priv->mac_addr);
11277 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); 11303 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
11304 memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN);
11278 11305
11279 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { 11306 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
11280 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], 11307 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
@@ -11416,20 +11443,104 @@ static void ipw_bg_down(struct work_struct *work)
11416/* Called by register_netdev() */ 11443/* Called by register_netdev() */
11417static int ipw_net_init(struct net_device *dev) 11444static int ipw_net_init(struct net_device *dev)
11418{ 11445{
11446 int i, rc = 0;
11419 struct ipw_priv *priv = libipw_priv(dev); 11447 struct ipw_priv *priv = libipw_priv(dev);
11448 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
11449 struct wireless_dev *wdev = &priv->ieee->wdev;
11420 mutex_lock(&priv->mutex); 11450 mutex_lock(&priv->mutex);
11421 11451
11422 if (ipw_up(priv)) { 11452 if (ipw_up(priv)) {
11423 mutex_unlock(&priv->mutex); 11453 rc = -EIO;
11424 return -EIO; 11454 goto out;
11455 }
11456
11457 memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
11458
11459 /* fill-out priv->ieee->bg_band */
11460 if (geo->bg_channels) {
11461 struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
11462
11463 bg_band->band = IEEE80211_BAND_2GHZ;
11464 bg_band->n_channels = geo->bg_channels;
11465 bg_band->channels =
11466 kzalloc(geo->bg_channels *
11467 sizeof(struct ieee80211_channel), GFP_KERNEL);
11468 /* translate geo->bg to bg_band.channels */
11469 for (i = 0; i < geo->bg_channels; i++) {
11470 bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
11471 bg_band->channels[i].center_freq = geo->bg[i].freq;
11472 bg_band->channels[i].hw_value = geo->bg[i].channel;
11473 bg_band->channels[i].max_power = geo->bg[i].max_power;
11474 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11475 bg_band->channels[i].flags |=
11476 IEEE80211_CHAN_PASSIVE_SCAN;
11477 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
11478 bg_band->channels[i].flags |=
11479 IEEE80211_CHAN_NO_IBSS;
11480 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
11481 bg_band->channels[i].flags |=
11482 IEEE80211_CHAN_RADAR;
11483 /* No equivalent for LIBIPW_CH_80211H_RULES,
11484 LIBIPW_CH_UNIFORM_SPREADING, or
11485 LIBIPW_CH_B_ONLY... */
11486 }
11487 /* point at bitrate info */
11488 bg_band->bitrates = ipw2200_bg_rates;
11489 bg_band->n_bitrates = ipw2200_num_bg_rates;
11490
11491 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
11492 }
11493
11494 /* fill-out priv->ieee->a_band */
11495 if (geo->a_channels) {
11496 struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
11497
11498 a_band->band = IEEE80211_BAND_5GHZ;
11499 a_band->n_channels = geo->a_channels;
11500 a_band->channels =
11501 kzalloc(geo->a_channels *
11502 sizeof(struct ieee80211_channel), GFP_KERNEL);
11503 /* translate geo->bg to a_band.channels */
11504 for (i = 0; i < geo->a_channels; i++) {
11505 a_band->channels[i].band = IEEE80211_BAND_2GHZ;
11506 a_band->channels[i].center_freq = geo->a[i].freq;
11507 a_band->channels[i].hw_value = geo->a[i].channel;
11508 a_band->channels[i].max_power = geo->a[i].max_power;
11509 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11510 a_band->channels[i].flags |=
11511 IEEE80211_CHAN_PASSIVE_SCAN;
11512 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
11513 a_band->channels[i].flags |=
11514 IEEE80211_CHAN_NO_IBSS;
11515 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
11516 a_band->channels[i].flags |=
11517 IEEE80211_CHAN_RADAR;
11518 /* No equivalent for LIBIPW_CH_80211H_RULES,
11519 LIBIPW_CH_UNIFORM_SPREADING, or
11520 LIBIPW_CH_B_ONLY... */
11521 }
11522 /* point at bitrate info */
11523 a_band->bitrates = ipw2200_a_rates;
11524 a_band->n_bitrates = ipw2200_num_a_rates;
11525
11526 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
11425 } 11527 }
11426 11528
11529 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
11530
11531 /* With that information in place, we can now register the wiphy... */
11532 if (wiphy_register(wdev->wiphy)) {
11533 rc = -EIO;
11534 goto out;
11535 }
11536
11537out:
11427 mutex_unlock(&priv->mutex); 11538 mutex_unlock(&priv->mutex);
11428 return 0; 11539 return rc;
11429} 11540}
11430 11541
11431/* PCI driver stuff */ 11542/* PCI driver stuff */
11432static struct pci_device_id card_ids[] = { 11543static DEFINE_PCI_DEVICE_TABLE(card_ids) = {
11433 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0}, 11544 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},
11434 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0}, 11545 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},
11435 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0}, 11546 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},
@@ -11556,7 +11667,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11556 if (priv->prom_net_dev) 11667 if (priv->prom_net_dev)
11557 return -EPERM; 11668 return -EPERM;
11558 11669
11559 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv)); 11670 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
11560 if (priv->prom_net_dev == NULL) 11671 if (priv->prom_net_dev == NULL)
11561 return -ENOMEM; 11672 return -ENOMEM;
11562 11673
@@ -11575,7 +11686,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11575 11686
11576 rc = register_netdev(priv->prom_net_dev); 11687 rc = register_netdev(priv->prom_net_dev);
11577 if (rc) { 11688 if (rc) {
11578 free_ieee80211(priv->prom_net_dev); 11689 free_ieee80211(priv->prom_net_dev, 1);
11579 priv->prom_net_dev = NULL; 11690 priv->prom_net_dev = NULL;
11580 return rc; 11691 return rc;
11581 } 11692 }
@@ -11589,7 +11700,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
11589 return; 11700 return;
11590 11701
11591 unregister_netdev(priv->prom_net_dev); 11702 unregister_netdev(priv->prom_net_dev);
11592 free_ieee80211(priv->prom_net_dev); 11703 free_ieee80211(priv->prom_net_dev, 1);
11593 11704
11594 priv->prom_net_dev = NULL; 11705 priv->prom_net_dev = NULL;
11595} 11706}
@@ -11617,7 +11728,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11617 struct ipw_priv *priv; 11728 struct ipw_priv *priv;
11618 int i; 11729 int i;
11619 11730
11620 net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); 11731 net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
11621 if (net_dev == NULL) { 11732 if (net_dev == NULL) {
11622 err = -ENOMEM; 11733 err = -ENOMEM;
11623 goto out; 11734 goto out;
@@ -11765,7 +11876,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11765 pci_disable_device(pdev); 11876 pci_disable_device(pdev);
11766 pci_set_drvdata(pdev, NULL); 11877 pci_set_drvdata(pdev, NULL);
11767 out_free_ieee80211: 11878 out_free_ieee80211:
11768 free_ieee80211(priv->net_dev); 11879 free_ieee80211(priv->net_dev, 0);
11769 out: 11880 out:
11770 return err; 11881 return err;
11771} 11882}
@@ -11832,7 +11943,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
11832 pci_release_regions(pdev); 11943 pci_release_regions(pdev);
11833 pci_disable_device(pdev); 11944 pci_disable_device(pdev);
11834 pci_set_drvdata(pdev, NULL); 11945 pci_set_drvdata(pdev, NULL);
11835 free_ieee80211(priv->net_dev); 11946 /* wiphy_unregister needs to be here, before free_ieee80211 */
11947 wiphy_unregister(priv->ieee->wdev.wiphy);
11948 kfree(priv->ieee->a_band.channels);
11949 kfree(priv->ieee->bg_band.channels);
11950 free_ieee80211(priv->net_dev, 0);
11836 free_firmware(); 11951 free_firmware();
11837} 11952}
11838 11953