Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8ecd988 authored by John W. Linville's avatar John W. Linville
Browse files

libipw: initiate cfg80211 API conversion



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.

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 73f57f83
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
	struct ipw2100_priv *priv;
	struct net_device *dev;

	dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
	dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0);
	if (!dev)
		return NULL;
	priv = libipw_priv(dev);
@@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
		sysfs_remove_group(&pci_dev->dev.kobj,
				   &ipw2100_attribute_group);

		free_ieee80211(dev);
		free_ieee80211(dev, 0);
		pci_set_drvdata(pci_dev, NULL);
	}

@@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
		if (dev->base_addr)
			iounmap((void __iomem *)dev->base_addr);

		free_ieee80211(dev);
		free_ieee80211(dev, 0);
	}

	pci_release_regions(pci_dev);
+113 −28
Original line number Diff line number Diff line
@@ -103,6 +103,25 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
static int rtap_iface = 0;     /* def: 0 -- do not create rtap interface */
#endif

static struct ieee80211_rate ipw2200_rates[] = {
	{ .bitrate = 10 },
	{ .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60 },
	{ .bitrate = 90 },
	{ .bitrate = 120 },
	{ .bitrate = 180 },
	{ .bitrate = 240 },
	{ .bitrate = 360 },
	{ .bitrate = 480 },
	{ .bitrate = 540 }
};

#define ipw2200_a_rates		(ipw2200_rates + 4)
#define ipw2200_num_a_rates	8
#define ipw2200_bg_rates	(ipw2200_rates + 0)
#define ipw2200_num_bg_rates	12

#ifdef CONFIG_IPW2200_QOS
static int qos_enable = 0;
@@ -8640,24 +8659,6 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
 *
 */

static int ipw_wx_get_name(struct net_device *dev,
			   struct iw_request_info *info,
			   union iwreq_data *wrqu, char *extra)
{
	struct ipw_priv *priv = libipw_priv(dev);
	mutex_lock(&priv->mutex);
	if (priv->status & STATUS_RF_KILL_MASK)
		strcpy(wrqu->name, "radio off");
	else if (!(priv->status & STATUS_ASSOCIATED))
		strcpy(wrqu->name, "unassociated");
	else
		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
			 ipw_modes[priv->assoc_request.ieee_mode]);
	IPW_DEBUG_WX("Name: %s\n", wrqu->name);
	mutex_unlock(&priv->mutex);
	return 0;
}

static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
{
	if (channel == 0) {
@@ -9957,7 +9958,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
/* Rebase the WE IOCTLs to zero for the handler array */
#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
static iw_handler ipw_wx_handlers[] = {
	IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
	IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
	IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
	IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
	IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -11401,16 +11402,100 @@ static void ipw_bg_down(struct work_struct *work)
/* Called by register_netdev() */
static int ipw_net_init(struct net_device *dev)
{
	int i, rc = 0;
	struct ipw_priv *priv = libipw_priv(dev);
	const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
	struct wireless_dev *wdev = &priv->ieee->wdev;
	mutex_lock(&priv->mutex);

	if (ipw_up(priv)) {
		mutex_unlock(&priv->mutex);
		return -EIO;
		rc = -EIO;
		goto out;
	}

	memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);

	/* fill-out priv->ieee->bg_band */
	if (geo->bg_channels) {
		struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;

		bg_band->band = IEEE80211_BAND_2GHZ;
		bg_band->n_channels = geo->bg_channels;
		bg_band->channels =
			kzalloc(geo->bg_channels *
				sizeof(struct ieee80211_channel), GFP_KERNEL);
		/* translate geo->bg to bg_band.channels */
		for (i = 0; i < geo->bg_channels; i++) {
			bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
			bg_band->channels[i].center_freq = geo->bg[i].freq;
			bg_band->channels[i].hw_value = geo->bg[i].channel;
			bg_band->channels[i].max_power = geo->bg[i].max_power;
			if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
				bg_band->channels[i].flags |=
					IEEE80211_CHAN_PASSIVE_SCAN;
			if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
				bg_band->channels[i].flags |=
					IEEE80211_CHAN_NO_IBSS;
			if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
				bg_band->channels[i].flags |=
					IEEE80211_CHAN_RADAR;
			/* No equivalent for LIBIPW_CH_80211H_RULES,
			   LIBIPW_CH_UNIFORM_SPREADING, or
			   LIBIPW_CH_B_ONLY... */
		}
		/* point at bitrate info */
		bg_band->bitrates = ipw2200_bg_rates;
		bg_band->n_bitrates = ipw2200_num_bg_rates;

		wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
	}

	/* fill-out priv->ieee->a_band */
	if (geo->a_channels) {
		struct ieee80211_supported_band *a_band = &priv->ieee->a_band;

		a_band->band = IEEE80211_BAND_5GHZ;
		a_band->n_channels = geo->a_channels;
		a_band->channels =
			kzalloc(geo->a_channels *
				sizeof(struct ieee80211_channel), GFP_KERNEL);
		/* translate geo->bg to a_band.channels */
		for (i = 0; i < geo->a_channels; i++) {
			a_band->channels[i].band = IEEE80211_BAND_2GHZ;
			a_band->channels[i].center_freq = geo->a[i].freq;
			a_band->channels[i].hw_value = geo->a[i].channel;
			a_band->channels[i].max_power = geo->a[i].max_power;
			if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
				a_band->channels[i].flags |=
					IEEE80211_CHAN_PASSIVE_SCAN;
			if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
				a_band->channels[i].flags |=
					IEEE80211_CHAN_NO_IBSS;
			if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
				a_band->channels[i].flags |=
					IEEE80211_CHAN_RADAR;
			/* No equivalent for LIBIPW_CH_80211H_RULES,
			   LIBIPW_CH_UNIFORM_SPREADING, or
			   LIBIPW_CH_B_ONLY... */
		}
		/* point at bitrate info */
		a_band->bitrates = ipw2200_a_rates;
		a_band->n_bitrates = ipw2200_num_a_rates;

		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
	}

	set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);

	/* With that information in place, we can now register the wiphy... */
	if (wiphy_register(wdev->wiphy)) {
		rc = -EIO;
		goto out;
	}

out:
	mutex_unlock(&priv->mutex);
	return 0;
	return rc;
}

/* PCI driver stuff */
@@ -11540,7 +11625,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
	if (priv->prom_net_dev)
		return -EPERM;

	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
	priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
	if (priv->prom_net_dev == NULL)
		return -ENOMEM;

@@ -11559,7 +11644,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)

	rc = register_netdev(priv->prom_net_dev);
	if (rc) {
		free_ieee80211(priv->prom_net_dev);
		free_ieee80211(priv->prom_net_dev, 1);
		priv->prom_net_dev = NULL;
		return rc;
	}
@@ -11573,7 +11658,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
		return;

	unregister_netdev(priv->prom_net_dev);
	free_ieee80211(priv->prom_net_dev);
	free_ieee80211(priv->prom_net_dev, 1);

	priv->prom_net_dev = NULL;
}
@@ -11601,7 +11686,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
	struct ipw_priv *priv;
	int i;

	net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
	net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
	if (net_dev == NULL) {
		err = -ENOMEM;
		goto out;
@@ -11749,7 +11834,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
      out_free_ieee80211:
	free_ieee80211(priv->net_dev);
	free_ieee80211(priv->net_dev, 0);
      out:
	return err;
}
@@ -11816,7 +11901,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);
	free_ieee80211(priv->net_dev);
	free_ieee80211(priv->net_dev, 0);
	free_firmware();
}

+6 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/ieee80211.h>

#include <net/lib80211.h>
#include <net/cfg80211.h>

#define LIBIPW_VERSION "git-1.1.13"

@@ -783,12 +784,15 @@ struct libipw_geo {

struct libipw_device {
	struct net_device *dev;
	struct wireless_dev wdev;
	struct libipw_security sec;

	/* Bookkeeping structures */
	struct libipw_stats ieee_stats;

	struct libipw_geo geo;
	struct ieee80211_supported_band bg_band;
	struct ieee80211_supported_band a_band;

	/* Probe / Beacon management */
	struct list_head network_free_list;
@@ -1014,8 +1018,8 @@ static inline int libipw_is_cck_rate(u8 rate)
}

/* ieee80211.c */
extern void free_ieee80211(struct net_device *dev);
extern struct net_device *alloc_ieee80211(int sizeof_priv);
extern void free_ieee80211(struct net_device *dev, int monitor);
extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
extern int libipw_change_mtu(struct net_device *dev, int new_mtu);

extern void libipw_networks_age(struct libipw_device *ieee,
+39 −3
Original line number Diff line number Diff line
@@ -62,6 +62,9 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_AUTHOR(DRV_COPYRIGHT);
MODULE_LICENSE("GPL");

struct cfg80211_ops libipw_config_ops = { };
void *libipw_wiphy_privid = &libipw_wiphy_privid;

static int libipw_networks_allocate(struct libipw_device *ieee)
{
	if (ieee->networks)
@@ -140,7 +143,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
}
EXPORT_SYMBOL(libipw_change_mtu);

struct net_device *alloc_ieee80211(int sizeof_priv)
struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
{
	struct libipw_device *ieee;
	struct net_device *dev;
@@ -157,10 +160,31 @@ struct net_device *alloc_ieee80211(int sizeof_priv)

	ieee->dev = dev;

	if (!monitor) {
		ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
		if (!ieee->wdev.wiphy) {
			LIBIPW_ERROR("Unable to allocate wiphy.\n");
			goto failed_free_netdev;
		}

		ieee->dev->ieee80211_ptr = &ieee->wdev;
		ieee->wdev.iftype = NL80211_IFTYPE_STATION;

		/* Fill-out wiphy structure bits we know...  Not enough info
		   here to call set_wiphy_dev or set MAC address or channel info
		   -- have to do that in ->ndo_init... */
		ieee->wdev.wiphy->privid = libipw_wiphy_privid;

		ieee->wdev.wiphy->max_scan_ssids = 1;
		ieee->wdev.wiphy->max_scan_ie_len = 0;
		ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
						| BIT(NL80211_IFTYPE_ADHOC);
	}

	err = libipw_networks_allocate(ieee);
	if (err) {
		LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
		goto failed_free_netdev;
		goto failed_free_wiphy;
	}
	libipw_networks_initialize(ieee);

@@ -193,19 +217,31 @@ struct net_device *alloc_ieee80211(int sizeof_priv)

	return dev;

failed_free_wiphy:
	if (!monitor)
		wiphy_free(ieee->wdev.wiphy);
failed_free_netdev:
	free_netdev(dev);
failed:
	return NULL;
}

void free_ieee80211(struct net_device *dev)
void free_ieee80211(struct net_device *dev, int monitor)
{
	struct libipw_device *ieee = netdev_priv(dev);

	lib80211_crypt_info_free(&ieee->crypt_info);

	libipw_networks_free(ieee);

	/* free cfg80211 resources */
	if (!monitor) {
		wiphy_unregister(ieee->wdev.wiphy);
		kfree(ieee->a_band.channels);
		kfree(ieee->bg_band.channels);
		wiphy_free(ieee->wdev.wiphy);
	}

	free_netdev(dev);
}