aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2009-08-25 14:12:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-11-23 17:05:26 -0500
commita3caa99e6c68f466c13cfea74097f6fb01b45e25 (patch)
treee5dae94b31a4ab78abb505a4fd26329e690d177b /drivers/net
parent9f13084d52d40dcce5a5f00586410acdb5a3fbff (diff)
libipw: initiate cfg80211 API conversion (v2)
Initiate the conversion of libipw to the new cfg80211 configuration API. For now, leave CONFIG_IPW2200_PROMISCUOUS stuff alone. Eventually migrate it to cfg80211 when the add/del/change_virtual_intf methods are implemented. (v2: Fix unconditional wiphy_unregister in libipw which was causing problems for ipw2100, somewhat based on prior attempted fix by Zhu Yi <yi.zhu@intel.com>. Previously both original version of this patch and Zhu Yi's fix attempt were reverted due to discovery of regressions. -- JWL) Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c6
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c145
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h8
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c38
4 files changed, 161 insertions, 36 deletions
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index b7408370cf82..a9bc8a97c4e1 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6029 struct ipw2100_priv *priv; 6029 struct ipw2100_priv *priv;
6030 struct net_device *dev; 6030 struct net_device *dev;
6031 6031
6032 dev = alloc_ieee80211(sizeof(struct ipw2100_priv)); 6032 dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0);
6033 if (!dev) 6033 if (!dev)
6034 return NULL; 6034 return NULL;
6035 priv = libipw_priv(dev); 6035 priv = libipw_priv(dev);
@@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6342 sysfs_remove_group(&pci_dev->dev.kobj, 6342 sysfs_remove_group(&pci_dev->dev.kobj,
6343 &ipw2100_attribute_group); 6343 &ipw2100_attribute_group);
6344 6344
6345 free_ieee80211(dev); 6345 free_ieee80211(dev, 0);
6346 pci_set_drvdata(pci_dev, NULL); 6346 pci_set_drvdata(pci_dev, NULL);
6347 } 6347 }
6348 6348
@@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6400 if (dev->base_addr) 6400 if (dev->base_addr)
6401 iounmap((void __iomem *)dev->base_addr); 6401 iounmap((void __iomem *)dev->base_addr);
6402 6402
6403 free_ieee80211(dev); 6403 free_ieee80211(dev, 0);
6404 } 6404 }
6405 6405
6406 pci_release_regions(pci_dev); 6406 pci_release_regions(pci_dev);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 9b398db2d740..2dfe78acda97 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -108,6 +108,25 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
108static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */ 108static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
109#endif 109#endif
110 110
111static struct ieee80211_rate ipw2200_rates[] = {
112 { .bitrate = 10 },
113 { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
114 { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
115 { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
116 { .bitrate = 60 },
117 { .bitrate = 90 },
118 { .bitrate = 120 },
119 { .bitrate = 180 },
120 { .bitrate = 240 },
121 { .bitrate = 360 },
122 { .bitrate = 480 },
123 { .bitrate = 540 }
124};
125
126#define ipw2200_a_rates (ipw2200_rates + 4)
127#define ipw2200_num_a_rates 8
128#define ipw2200_bg_rates (ipw2200_rates + 0)
129#define ipw2200_num_bg_rates 12
111 130
112#ifdef CONFIG_IPW2200_QOS 131#ifdef CONFIG_IPW2200_QOS
113static int qos_enable = 0; 132static int qos_enable = 0;
@@ -8659,24 +8678,6 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
8659 * 8678 *
8660 */ 8679 */
8661 8680
8662static int ipw_wx_get_name(struct net_device *dev,
8663 struct iw_request_info *info,
8664 union iwreq_data *wrqu, char *extra)
8665{
8666 struct ipw_priv *priv = libipw_priv(dev);
8667 mutex_lock(&priv->mutex);
8668 if (priv->status & STATUS_RF_KILL_MASK)
8669 strcpy(wrqu->name, "radio off");
8670 else if (!(priv->status & STATUS_ASSOCIATED))
8671 strcpy(wrqu->name, "unassociated");
8672 else
8673 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
8674 ipw_modes[priv->assoc_request.ieee_mode]);
8675 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
8676 mutex_unlock(&priv->mutex);
8677 return 0;
8678}
8679
8680static int ipw_set_channel(struct ipw_priv *priv, u8 channel) 8681static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
8681{ 8682{
8682 if (channel == 0) { 8683 if (channel == 0) {
@@ -9976,7 +9977,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9976/* Rebase the WE IOCTLs to zero for the handler array */ 9977/* Rebase the WE IOCTLs to zero for the handler array */
9977#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] 9978#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
9978static iw_handler ipw_wx_handlers[] = { 9979static iw_handler ipw_wx_handlers[] = {
9979 IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name, 9980 IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
9980 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 9981 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
9981 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 9982 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
9982 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 9983 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -11421,16 +11422,100 @@ static void ipw_bg_down(struct work_struct *work)
11421/* Called by register_netdev() */ 11422/* Called by register_netdev() */
11422static int ipw_net_init(struct net_device *dev) 11423static int ipw_net_init(struct net_device *dev)
11423{ 11424{
11425 int i, rc = 0;
11424 struct ipw_priv *priv = libipw_priv(dev); 11426 struct ipw_priv *priv = libipw_priv(dev);
11427 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
11428 struct wireless_dev *wdev = &priv->ieee->wdev;
11425 mutex_lock(&priv->mutex); 11429 mutex_lock(&priv->mutex);
11426 11430
11427 if (ipw_up(priv)) { 11431 if (ipw_up(priv)) {
11428 mutex_unlock(&priv->mutex); 11432 rc = -EIO;
11429 return -EIO; 11433 goto out;
11430 } 11434 }
11431 11435
11436 memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
11437
11438 /* fill-out priv->ieee->bg_band */
11439 if (geo->bg_channels) {
11440 struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
11441
11442 bg_band->band = IEEE80211_BAND_2GHZ;
11443 bg_band->n_channels = geo->bg_channels;
11444 bg_band->channels =
11445 kzalloc(geo->bg_channels *
11446 sizeof(struct ieee80211_channel), GFP_KERNEL);
11447 /* translate geo->bg to bg_band.channels */
11448 for (i = 0; i < geo->bg_channels; i++) {
11449 bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
11450 bg_band->channels[i].center_freq = geo->bg[i].freq;
11451 bg_band->channels[i].hw_value = geo->bg[i].channel;
11452 bg_band->channels[i].max_power = geo->bg[i].max_power;
11453 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11454 bg_band->channels[i].flags |=
11455 IEEE80211_CHAN_PASSIVE_SCAN;
11456 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
11457 bg_band->channels[i].flags |=
11458 IEEE80211_CHAN_NO_IBSS;
11459 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
11460 bg_band->channels[i].flags |=
11461 IEEE80211_CHAN_RADAR;
11462 /* No equivalent for LIBIPW_CH_80211H_RULES,
11463 LIBIPW_CH_UNIFORM_SPREADING, or
11464 LIBIPW_CH_B_ONLY... */
11465 }
11466 /* point at bitrate info */
11467 bg_band->bitrates = ipw2200_bg_rates;
11468 bg_band->n_bitrates = ipw2200_num_bg_rates;
11469
11470 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
11471 }
11472
11473 /* fill-out priv->ieee->a_band */
11474 if (geo->a_channels) {
11475 struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
11476
11477 a_band->band = IEEE80211_BAND_5GHZ;
11478 a_band->n_channels = geo->a_channels;
11479 a_band->channels =
11480 kzalloc(geo->a_channels *
11481 sizeof(struct ieee80211_channel), GFP_KERNEL);
11482 /* translate geo->bg to a_band.channels */
11483 for (i = 0; i < geo->a_channels; i++) {
11484 a_band->channels[i].band = IEEE80211_BAND_2GHZ;
11485 a_band->channels[i].center_freq = geo->a[i].freq;
11486 a_band->channels[i].hw_value = geo->a[i].channel;
11487 a_band->channels[i].max_power = geo->a[i].max_power;
11488 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11489 a_band->channels[i].flags |=
11490 IEEE80211_CHAN_PASSIVE_SCAN;
11491 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
11492 a_band->channels[i].flags |=
11493 IEEE80211_CHAN_NO_IBSS;
11494 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
11495 a_band->channels[i].flags |=
11496 IEEE80211_CHAN_RADAR;
11497 /* No equivalent for LIBIPW_CH_80211H_RULES,
11498 LIBIPW_CH_UNIFORM_SPREADING, or
11499 LIBIPW_CH_B_ONLY... */
11500 }
11501 /* point at bitrate info */
11502 a_band->bitrates = ipw2200_a_rates;
11503 a_band->n_bitrates = ipw2200_num_a_rates;
11504
11505 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
11506 }
11507
11508 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
11509
11510 /* With that information in place, we can now register the wiphy... */
11511 if (wiphy_register(wdev->wiphy)) {
11512 rc = -EIO;
11513 goto out;
11514 }
11515
11516out:
11432 mutex_unlock(&priv->mutex); 11517 mutex_unlock(&priv->mutex);
11433 return 0; 11518 return rc;
11434} 11519}
11435 11520
11436/* PCI driver stuff */ 11521/* PCI driver stuff */
@@ -11561,7 +11646,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11561 if (priv->prom_net_dev) 11646 if (priv->prom_net_dev)
11562 return -EPERM; 11647 return -EPERM;
11563 11648
11564 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv)); 11649 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
11565 if (priv->prom_net_dev == NULL) 11650 if (priv->prom_net_dev == NULL)
11566 return -ENOMEM; 11651 return -ENOMEM;
11567 11652
@@ -11580,7 +11665,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
11580 11665
11581 rc = register_netdev(priv->prom_net_dev); 11666 rc = register_netdev(priv->prom_net_dev);
11582 if (rc) { 11667 if (rc) {
11583 free_ieee80211(priv->prom_net_dev); 11668 free_ieee80211(priv->prom_net_dev, 1);
11584 priv->prom_net_dev = NULL; 11669 priv->prom_net_dev = NULL;
11585 return rc; 11670 return rc;
11586 } 11671 }
@@ -11594,7 +11679,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
11594 return; 11679 return;
11595 11680
11596 unregister_netdev(priv->prom_net_dev); 11681 unregister_netdev(priv->prom_net_dev);
11597 free_ieee80211(priv->prom_net_dev); 11682 free_ieee80211(priv->prom_net_dev, 1);
11598 11683
11599 priv->prom_net_dev = NULL; 11684 priv->prom_net_dev = NULL;
11600} 11685}
@@ -11622,7 +11707,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11622 struct ipw_priv *priv; 11707 struct ipw_priv *priv;
11623 int i; 11708 int i;
11624 11709
11625 net_dev = alloc_ieee80211(sizeof(struct ipw_priv)); 11710 net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
11626 if (net_dev == NULL) { 11711 if (net_dev == NULL) {
11627 err = -ENOMEM; 11712 err = -ENOMEM;
11628 goto out; 11713 goto out;
@@ -11770,7 +11855,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11770 pci_disable_device(pdev); 11855 pci_disable_device(pdev);
11771 pci_set_drvdata(pdev, NULL); 11856 pci_set_drvdata(pdev, NULL);
11772 out_free_ieee80211: 11857 out_free_ieee80211:
11773 free_ieee80211(priv->net_dev); 11858 free_ieee80211(priv->net_dev, 0);
11774 out: 11859 out:
11775 return err; 11860 return err;
11776} 11861}
@@ -11837,7 +11922,11 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
11837 pci_release_regions(pdev); 11922 pci_release_regions(pdev);
11838 pci_disable_device(pdev); 11923 pci_disable_device(pdev);
11839 pci_set_drvdata(pdev, NULL); 11924 pci_set_drvdata(pdev, NULL);
11840 free_ieee80211(priv->net_dev); 11925 /* wiphy_unregister needs to be here, before free_ieee80211 */
11926 wiphy_unregister(priv->ieee->wdev.wiphy);
11927 kfree(priv->ieee->a_band.channels);
11928 kfree(priv->ieee->bg_band.channels);
11929 free_ieee80211(priv->net_dev, 0);
11841 free_firmware(); 11930 free_firmware();
11842} 11931}
11843 11932
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index 1e334ff6bd52..bf45391172f3 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -31,6 +31,7 @@
31#include <linux/ieee80211.h> 31#include <linux/ieee80211.h>
32 32
33#include <net/lib80211.h> 33#include <net/lib80211.h>
34#include <net/cfg80211.h>
34 35
35#define LIBIPW_VERSION "git-1.1.13" 36#define LIBIPW_VERSION "git-1.1.13"
36 37
@@ -783,12 +784,15 @@ struct libipw_geo {
783 784
784struct libipw_device { 785struct libipw_device {
785 struct net_device *dev; 786 struct net_device *dev;
787 struct wireless_dev wdev;
786 struct libipw_security sec; 788 struct libipw_security sec;
787 789
788 /* Bookkeeping structures */ 790 /* Bookkeeping structures */
789 struct libipw_stats ieee_stats; 791 struct libipw_stats ieee_stats;
790 792
791 struct libipw_geo geo; 793 struct libipw_geo geo;
794 struct ieee80211_supported_band bg_band;
795 struct ieee80211_supported_band a_band;
792 796
793 /* Probe / Beacon management */ 797 /* Probe / Beacon management */
794 struct list_head network_free_list; 798 struct list_head network_free_list;
@@ -1014,8 +1018,8 @@ static inline int libipw_is_cck_rate(u8 rate)
1014} 1018}
1015 1019
1016/* ieee80211.c */ 1020/* ieee80211.c */
1017extern void free_ieee80211(struct net_device *dev); 1021extern void free_ieee80211(struct net_device *dev, int monitor);
1018extern struct net_device *alloc_ieee80211(int sizeof_priv); 1022extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
1019extern int libipw_change_mtu(struct net_device *dev, int new_mtu); 1023extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
1020 1024
1021extern void libipw_networks_age(struct libipw_device *ieee, 1025extern void libipw_networks_age(struct libipw_device *ieee,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index eb2b60834c17..e8a1ac5f8e11 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -62,6 +62,9 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
62MODULE_AUTHOR(DRV_COPYRIGHT); 62MODULE_AUTHOR(DRV_COPYRIGHT);
63MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
64 64
65struct cfg80211_ops libipw_config_ops = { };
66void *libipw_wiphy_privid = &libipw_wiphy_privid;
67
65static int libipw_networks_allocate(struct libipw_device *ieee) 68static int libipw_networks_allocate(struct libipw_device *ieee)
66{ 69{
67 if (ieee->networks) 70 if (ieee->networks)
@@ -140,7 +143,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
140} 143}
141EXPORT_SYMBOL(libipw_change_mtu); 144EXPORT_SYMBOL(libipw_change_mtu);
142 145
143struct net_device *alloc_ieee80211(int sizeof_priv) 146struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
144{ 147{
145 struct libipw_device *ieee; 148 struct libipw_device *ieee;
146 struct net_device *dev; 149 struct net_device *dev;
@@ -157,10 +160,31 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
157 160
158 ieee->dev = dev; 161 ieee->dev = dev;
159 162
163 if (!monitor) {
164 ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
165 if (!ieee->wdev.wiphy) {
166 LIBIPW_ERROR("Unable to allocate wiphy.\n");
167 goto failed_free_netdev;
168 }
169
170 ieee->dev->ieee80211_ptr = &ieee->wdev;
171 ieee->wdev.iftype = NL80211_IFTYPE_STATION;
172
173 /* Fill-out wiphy structure bits we know... Not enough info
174 here to call set_wiphy_dev or set MAC address or channel info
175 -- have to do that in ->ndo_init... */
176 ieee->wdev.wiphy->privid = libipw_wiphy_privid;
177
178 ieee->wdev.wiphy->max_scan_ssids = 1;
179 ieee->wdev.wiphy->max_scan_ie_len = 0;
180 ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
181 | BIT(NL80211_IFTYPE_ADHOC);
182 }
183
160 err = libipw_networks_allocate(ieee); 184 err = libipw_networks_allocate(ieee);
161 if (err) { 185 if (err) {
162 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err); 186 LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
163 goto failed_free_netdev; 187 goto failed_free_wiphy;
164 } 188 }
165 libipw_networks_initialize(ieee); 189 libipw_networks_initialize(ieee);
166 190
@@ -193,19 +217,27 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
193 217
194 return dev; 218 return dev;
195 219
220failed_free_wiphy:
221 if (!monitor)
222 wiphy_free(ieee->wdev.wiphy);
196failed_free_netdev: 223failed_free_netdev:
197 free_netdev(dev); 224 free_netdev(dev);
198failed: 225failed:
199 return NULL; 226 return NULL;
200} 227}
201 228
202void free_ieee80211(struct net_device *dev) 229void free_ieee80211(struct net_device *dev, int monitor)
203{ 230{
204 struct libipw_device *ieee = netdev_priv(dev); 231 struct libipw_device *ieee = netdev_priv(dev);
205 232
206 lib80211_crypt_info_free(&ieee->crypt_info); 233 lib80211_crypt_info_free(&ieee->crypt_info);
207 234
208 libipw_networks_free(ieee); 235 libipw_networks_free(ieee);
236
237 /* free cfg80211 resources */
238 if (!monitor)
239 wiphy_free(ieee->wdev.wiphy);
240
209 free_netdev(dev); 241 free_netdev(dev);
210} 242}
211 243