All of lore.kernel.org
 help / color / mirror / Atom feed
From: Holger Schurig <holgerschurig@gmail.com>
To: linux-wireless@vger.kernel.org
Cc: "John W. Linville" <linville@tuxdriver.com>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Dan Williams <dcbw@redhat.com>,
	Holger Schurig <holgerschurig@googlemail.com>
Subject: Re: [PATCH] libertas: cfg80211 support
Date: Wed, 3 Feb 2010 10:31:22 +0100	[thread overview]
Message-ID: <201002031031.22805.holgerschurig@gmail.com> (raw)
In-Reply-To: <20100202203643.GD2967@tuxdriver.com>

> I'm happy to have libertas support cfg80211.  But doesn't this
> remove the mesh support that the OLPC guys still use?

yes.


Or maybe not. I have another work-in-progress on top of my
previous v4 patch that should implement mesh. I'll post that
ASAP. Samuel can than rip things out of it :-)  Because it's a
patch on top of v4 (and not a new hs-v5 one), it's easy to see my
changes.


------------------------------------------------------------------



* made "lbs_band_2ghz" non static, re-used that array in mesh code
* twiddled some debug output
* remove unused local variable "nr_sets" in lbs_ret_scan()
* lbs_ret_scan() bails out early if scanresp->nr_sets == 0
* added some "BUG_ON(!priv->scan_req)" sanity checks
* removed carrier up/down changes during scan
* lbs_cfg_scan() schedules the scan worker immediately and
  sets priv->scan_req before that
* added some more comments
* lbs_cfg_ret_disconnect() correctly sets state to LBS_DISCONNECTED
* removed reporting of bitrate, as this is not working
* fixed noise level reporting (broken lbs_get_survey() function)
* monitor will monitor more data
* untested mesh support via nl80211/cfg80211
* lbs_scan_deinit() will now send a scan-abort message to cfg80211
  when priv->scan_req was active
* call lbs_scan_deinit() at "ifconfig wlan0 down" time. This
  also aborts the scan state inside cfg80211 and removes a BUG_ON-
  warning if a scan was active during "ifconfig wlan0 down" time.
* initialize return value in lbs_init_adapter() to avoid a warning

Signed-off-by: Holger Schurig <hs4233@mail.mn-solutions.de>

make C=1 clean, but not run throught scripts/checkpatch.pl

---
 drivers/net/wireless/libertas/cfg.c  |  108 +++++++++++++--------
 drivers/net/wireless/libertas/cfg.h  |    5 -
 drivers/net/wireless/libertas/cmd.c  |    5 -
 drivers/net/wireless/libertas/dev.h  |    3 
 drivers/net/wireless/libertas/main.c |   13 +-
 drivers/net/wireless/libertas/mesh.c |  174 ++++++++++++++++++++++++++++++-----
 drivers/net/wireless/libertas/mesh.h |   16 +--
 7 files changed, 236 insertions(+), 88 deletions(-)

--- linux-wl.orig/drivers/net/wireless/libertas/cfg.c
+++ linux-wl/drivers/net/wireless/libertas/cfg.c
@@ -64,7 +64,7 @@ static struct ieee80211_rate lbs_rates[]
 	RATETAB_ENT(540, 12, 0),
 };
 
-static struct ieee80211_supported_band lbs_band_2ghz = {
+struct ieee80211_supported_band lbs_band_2ghz = {
 	.channels = lbs_2ghz_channels,
 	.n_channels = ARRAY_SIZE(lbs_2ghz_channels),
 	.bitrates = lbs_rates,
@@ -203,7 +203,7 @@ static int lbs_add_channel_list_tlv(stru
 	header->len  = cpu_to_le16(chanscanparamsize);
 	tlv += sizeof(struct mrvl_ie_header);
 
-	/* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel,
+	/* lbs_deb_scan("channels %d to %d\n", priv->scan_channel,
 		     last_channel); */
 	memset(tlv, 0, chanscanparamsize);
 
@@ -457,7 +457,6 @@ static int lbs_ret_scan(struct lbs_priva
 	struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
 	int bsssize;
 	const u8 *pos;
-	u16 nr_sets;
 	const u8 *tsfdesc;
 	int tsfsize;
 	int i;
@@ -465,8 +464,14 @@ static int lbs_ret_scan(struct lbs_priva
 
 	lbs_deb_enter(LBS_DEB_CFG80211);
 
+	/* Bail out early out if we didn't get BSS entries */
+	if (scanresp->nr_sets == 0) {
+		ret = 0;
+		goto done;
+	}
 	bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
-	nr_sets = le16_to_cpu(resp->size);
+
+	BUG_ON(!priv->scan_req);
 
 	/*
 	 * The general layout of the scan response is described in chapter
@@ -476,7 +481,7 @@ static int lbs_ret_scan(struct lbs_priva
 	 *
 	 * cmd_ds_802_11_scan_rsp
 	 *   cmd_header
-	 *   pos_size
+	 *   bssdescriptsize
 	 *   nr_sets
 	 *   bssdesc 1
 	 *     bssid
@@ -569,11 +574,11 @@ static int lbs_ret_scan(struct lbs_priva
 			struct ieee80211_channel *channel =
 				ieee80211_get_channel(wiphy, freq);
 
-			lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, "
-				     "%d dBm\n",
+			lbs_deb_scan("%pM, capa %04x, chan %2d, "
+				     "%d dBm, %s\n",
 				     bssid, capa, chan_no,
-				     print_ssid(ssid_buf, ssid, ssid_len),
-				     LBS_SCAN_RSSI_TO_MBM(rssi)/100);
+				     LBS_SCAN_RSSI_TO_MBM(rssi)/100,
+				     print_ssid(ssid_buf, ssid, ssid_len));
 
 			if (channel ||
 			    !(channel->flags & IEEE80211_CHAN_DISABLED))
@@ -614,24 +619,23 @@ static void lbs_scan_worker(struct work_
 	struct cmd_ds_802_11_scan *scan_cmd;
 	u8 *tlv; /* pointer into our current, growing TLV storage area */
 	int last_channel;
-	int running, carrier;
+	int running;
 
 	lbs_deb_enter(LBS_DEB_SCAN);
 
+	BUG_ON(!priv->scan_req);
+
 	scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
 	if (scan_cmd == NULL)
-		goto out_no_scan_cmd;
+		goto done;
 
 	/* prepare fixed part of scan command */
 	scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
 
 	/* stop network while we're away from our main channel */
 	running = !netif_queue_stopped(priv->dev);
-	carrier = netif_carrier_ok(priv->dev);
 	if (running)
 		netif_stop_queue(priv->dev);
-	if (carrier)
-		netif_carrier_off(priv->dev);
 
 	/* prepare fixed part of scan command */
 	tlv = scan_cmd->tlvbuffer;
@@ -669,6 +673,10 @@ static void lbs_scan_worker(struct work_
 		le16_to_cpu(scan_cmd->hdr.size),
 		lbs_ret_scan, 0);
 
+	/* __lbs_cmd() can possibly schedule, so make sure things are
+	 * still sane */
+	BUG_ON(!priv->scan_req);
+
 	if (priv->scan_channel >= priv->scan_req->n_channels) {
 		/* Mark scan done */
 		cfg80211_scan_done(priv->scan_req, false);
@@ -676,14 +684,11 @@ static void lbs_scan_worker(struct work_
 	}
 
 	/* Restart network */
-	if (carrier)
-		netif_carrier_on(priv->dev);
 	if (running && !priv->tx_pending_len)
 		netif_wake_queue(priv->dev);
 
 	kfree(scan_cmd);
-
- out_no_scan_cmd:
+ done:
 	lbs_deb_leave(LBS_DEB_SCAN);
 }
 
@@ -703,18 +708,16 @@ static int lbs_cfg_scan(struct wiphy *wi
 		goto out;
 	}
 
-	lbs_deb_scan("scan: ssids %d, channels %d, ie_len %d\n",
+	lbs_deb_scan("ssids %d, channels %d, ie_len %d\n",
 		request->n_ssids, request->n_channels, request->ie_len);
 
 	priv->scan_channel = 0;
-	queue_delayed_work(priv->work_thread, &priv->scan_work,
-		msecs_to_jiffies(50));
+	priv->scan_req = request;
+	queue_delayed_work(priv->work_thread, &priv->scan_work, 0);
 
 	if (priv->surpriseremoved)
 		ret = -EIO;
 
-	priv->scan_req = request;
-
  out:
 	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
 	return ret;
@@ -901,7 +904,7 @@ static int lbs_set_key_material(struct l
 	struct cmd_key_material cmd;
 	int ret;
 
-	lbs_deb_enter(LBS_DEB_CFG80211);
+	lbs_deb_enter_args(LBS_DEB_CFG80211, "len %d", key_len);
 
 	/*
 	 * Example for WPA (TKIP):
@@ -910,8 +913,8 @@ static int lbs_set_key_material(struct l
 	 * size      34 00
 	 * sequence  xx xx
 	 * result    00 00
-	 * action    01 00
-	 * TLV type  00 01    key param
+	 * action    01 00    CMD_ACT_SET
+	 * TLV type  00 01    TLV_TYPE_KEY_MATERIAL
 	 * length    00 26
 	 * key type  01 00    TKIP
 	 * key info  06 00    UNICAST | ENABLED
@@ -948,7 +951,7 @@ static int lbs_set_authtype(struct lbs_p
 	struct cmd_ds_802_11_authenticate cmd;
 	int ret;
 
-	lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type);
+	lbs_deb_enter_args(LBS_DEB_ASSOC, "%d", sme->auth_type);
 
 	/*
 	 * cmd        11 00
@@ -972,7 +975,7 @@ static int lbs_set_authtype(struct lbs_p
 	ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
 
  done:
-	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
 	return ret;
 }
 
@@ -1002,7 +1005,7 @@ static int lbs_associate(struct lbs_priv
 	int ret;
 	u8 *pos = &(cmd->iebuf[0]);
 
-	lbs_deb_enter(LBS_DEB_CFG80211);
+	lbs_deb_enter(LBS_DEB_ASSOC);
 
 	if (!cmd) {
 		ret = -ENOMEM;
@@ -1121,7 +1124,7 @@ static int lbs_associate(struct lbs_priv
 
 
 done:
-	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
 	return ret;
 }
 
@@ -1162,7 +1165,7 @@ static int lbs_cfg_connect(struct wiphy 
 
 
 	if (!bss) {
-		lbs_pr_err("assicate: bss %pM not in scan results\n",
+		lbs_pr_err("associate: BSS %pM not in scan results\n",
 			   sme->bssid);
 		ret = -ENOENT;
 		goto done;
@@ -1185,10 +1188,14 @@ static int lbs_cfg_connect(struct wiphy 
 		priv->wep_tx_key = sme->key_idx;
 		priv->wep_key_len[sme->key_idx] = sme->key_len;
 		memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len);
+
 		/* Set WEP keys and WEP mode */
 		lbs_set_wep_keys(priv);
+
+		/* Enable WEP mode in the MAC */
 		priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
 		lbs_set_mac_control(priv);
+
 		/* No RSN mode for WEP */
 		lbs_enable_rsn(priv, 0);
 		break;
@@ -1204,6 +1211,8 @@ static int lbs_cfg_connect(struct wiphy 
 	case WLAN_CIPHER_SUITE_CCMP:
 		/* Remove WEP keys and WEP mode */
 		lbs_remove_wep_keys(priv);
+
+		/* Disable WEP mode in MAC */
 		priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
 		lbs_set_mac_control(priv);
 
@@ -1216,6 +1225,7 @@ static int lbs_cfg_connect(struct wiphy 
 			KEY_TYPE_ID_WEP, /* doesn't matter */
 			KEY_INFO_WPA_MCAST,
 			NULL, 0);
+
 		/* RSN mode for WPA/WPA2 */
 		lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
 		break;
@@ -1246,7 +1256,7 @@ static int lbs_cfg_connect(struct wiphy 
 static int lbs_cfg_ret_disconnect(struct lbs_private *priv, unsigned long dummy,
 			      struct cmd_header *resp)
 {
-	lbs_deb_enter(LBS_DEB_CFG80211);
+	lbs_deb_enter(LBS_DEB_ASSOC);
 
 	cfg80211_disconnected(priv->dev,
 			      priv->disassoc_reason,
@@ -1254,9 +1264,10 @@ static int lbs_cfg_ret_disconnect(struct
 			      GFP_KERNEL);
 
 	/* TODO: get rid of priv->connect_status */
-	priv->connect_status = LBS_CONNECTED;
+	priv->connect_status = LBS_DISCONNECTED;
+	netif_carrier_off(priv->dev);
 
-	lbs_deb_leave(LBS_DEB_CFG80211);
+	lbs_deb_leave(LBS_DEB_ASSOC);
 	return 0;
 }
 
@@ -1427,7 +1438,7 @@ static int lbs_enable_monitor_mode(struc
 	 * sequence  xx xx
 	 * result    00 00
 	 * action    01 00    ACT_SET
-	 * enable    01 00
+	 * enable    01 00    bitmask (1=data, 2=ctrl, 4=beacon)
 	 */
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
@@ -1493,7 +1504,6 @@ static int lbs_cfg_get_station(struct wi
 	struct lbs_private *priv = wiphy_priv(wiphy);
 	s8 signal, noise;
 	int ret;
-	size_t i;
 
 	lbs_deb_enter(LBS_DEB_CFG80211);
 
@@ -1513,14 +1523,20 @@ static int lbs_cfg_get_station(struct wi
 		sinfo->filled |= STATION_INFO_SIGNAL;
 	}
 
+#ifdef TODO
+	size_t i;
+
+	/* "iw wlan link" says "failed to parse nested attributes!" */
+
 	/* Convert priv->cur_rate from hw_value to NL80211 value */
 	for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
-		if (priv->cur_rate == lbs_rates[i].hw_value) {
-			sinfo->txrate.legacy = lbs_rates[i].bitrate;
+		if (priv->cur_rate == lbs_rates[i].bitrate) {
+			sinfo->txrate.legacy = lbs_rates[i].bitrate * 10;
 			sinfo->filled |= STATION_INFO_TX_BITRATE;
 			break;
 		}
 	}
+#endif
 
 	return 0;
 }
@@ -1539,8 +1555,10 @@ static int lbs_get_survey(struct wiphy *
 	s8 signal, noise;
 	int ret;
 
-	if (idx != 0)
+	if (idx != 0) {
 		ret = -ENOENT;
+		goto out;
+	}
 
 	lbs_deb_enter(LBS_DEB_CFG80211);
 
@@ -1554,6 +1572,7 @@ static int lbs_get_survey(struct wiphy *
 	}
 
 	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+out:
 	return ret;
 }
 
@@ -1575,7 +1594,7 @@ static int lbs_change_intf(struct wiphy 
 
 	switch (type) {
 	case NL80211_IFTYPE_MONITOR:
-		ret = lbs_enable_monitor_mode(priv, 1);
+		ret = lbs_enable_monitor_mode(priv, 0x07);
 		break;
 	case NL80211_IFTYPE_STATION:
 		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
@@ -2076,8 +2095,15 @@ int lbs_cfg_register(struct lbs_private 
 
 void lbs_scan_deinit(struct lbs_private *priv)
 {
-	lbs_deb_enter(LBS_DEB_CFG80211);
+	lbs_deb_enter(LBS_DEB_SCAN);
+
 	cancel_delayed_work_sync(&priv->scan_work);
+	if (priv->scan_req) {
+		cfg80211_scan_done(priv->scan_req, true);
+		priv->scan_req = NULL;
+	}
+
+	lbs_deb_leave(LBS_DEB_SCAN);
 }
 
 
--- linux-wl.orig/drivers/net/wireless/libertas/mesh.c
+++ linux-wl/drivers/net/wireless/libertas/mesh.c
@@ -5,13 +5,130 @@
 #include <linux/if_arp.h>
 #include <linux/kthread.h>
 #include <linux/kfifo.h>
+#include <net/cfg80211.h>
 
 #include "mesh.h"
+#include "cfg.h"
 #include "decl.h"
 #include "cmd.h"
 
 
 /***************************************************************************
+ * Mesh cfg80211 support
+ */
+
+static int lbs_join_mesh(struct wiphy *wiphy, struct net_device *dev,
+		struct cfg80211_ibss_params *params)
+{
+	struct lbs_private *priv = wiphy_priv(wiphy);
+	int ret = 0;
+	DECLARE_SSID_BUF(ssid_buf);
+
+	lbs_deb_enter(LBS_DEB_CFG80211);
+
+	if (!params->channel) {
+		ret = -ENOTSUPP;
+		goto out;
+	}
+
+	/* If channel != current channel AND if we're connected, then this
+	 * won't work */
+
+	ret = lbs_set_channel(priv, params->channel->hw_value);
+	if (ret)
+		goto out;
+
+	//TODO
+	// CMD_ACT_MESH_CONFIG_START
+ out:
+	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	return ret;
+}
+
+
+static int lbs_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
+{
+	//struct lbs_private *priv = wiphy_priv(wiphy);
+	//struct cmd_ds_802_11_ad_hoc_stop cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CFG80211);
+
+	//TODO
+
+	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
+	return ret;
+}
+
+
+static struct cfg80211_ops lbs_cfg80211_mesh_ops = {
+	.join_ibss = lbs_join_mesh,
+	.leave_ibss = lbs_leave_mesh,
+};
+
+
+static struct wireless_dev *lbs_cfg_alloc_mesh(struct lbs_private *priv)
+{
+	int ret = 0;
+	struct wireless_dev *wdev;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+
+	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+	if (!wdev) {
+		lbs_pr_err("cannot allocate mesh wireless device\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	wdev->wiphy = wiphy_new(&lbs_cfg80211_mesh_ops, 0);
+	if (!wdev->wiphy) {
+		lbs_pr_err("cannot allocate mesh wiphy\n");
+		ret = -ENOMEM;
+		goto err_wiphy_new;
+	}
+	wdev->iftype = NL80211_IFTYPE_ADHOC; //TODO: is this right?
+
+	lbs_deb_leave(LBS_DEB_MESH);
+	return wdev;
+
+ err_wiphy_new:
+	kfree(wdev);
+	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+	return ERR_PTR(ret);
+}
+
+static int lbs_mesh_register(struct lbs_private *priv)
+{
+	struct wireless_dev *wdev = priv->mesh_wdev;
+	int ret;
+
+	lbs_deb_enter(LBS_DEB_MESH);
+
+	wdev->wiphy->max_scan_ssids = 1;
+	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+	wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_ADHOC);
+
+	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
+
+	/*
+	 * We could check priv->fwcapinfo && FW_CAPINFO_WPA, but I have
+	 * never seen a firmware without WPA
+	 */
+	//wdev->wiphy->cipher_suites = cipher_suites;
+	//wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+	ret = wiphy_register(wdev->wiphy);
+	if (ret < 0)
+		lbs_pr_err("cannot register mesh wiphy device\n");
+
+	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
+	return ret;
+}
+
+
+
+/***************************************************************************
  * Mesh sysfs support
  */
 
@@ -185,14 +302,14 @@ static struct attribute_group lbs_mesh_a
  * Initializing and starting, stopping mesh
  */
 
+
 /*
  * Check mesh FW version and appropriately send the mesh start
  * command
  */
-int lbs_init_mesh(struct lbs_private *priv)
+void lbs_init_mesh(struct lbs_private *priv)
 {
 	struct net_device *dev = priv->dev;
-	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_MESH);
 
@@ -237,31 +354,41 @@ int lbs_init_mesh(struct lbs_private *pr
 			priv->mesh_tlv = 0;
 	}
 
+	if (!priv->mesh_tlv)
+		goto out;
 
-	if (priv->mesh_tlv) {
-		sprintf(priv->mesh_ssid, "mesh");
-		priv->mesh_ssid_len = 4;
-
-		lbs_add_mesh(priv);
-
-		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-			lbs_pr_err("cannot register lbs_mesh attribute\n");
+	lbs_deb_mesh("using %s mesh commands\n",
+		     priv->mesh_tlv == TLV_TYPE_OLD_MESH_ID
+		     ? "old" : "new");
+	sprintf(priv->mesh_ssid, "mesh");
+	priv->mesh_ssid_len = 4;
+
+	priv->mesh_wdev = lbs_cfg_alloc_mesh(priv);
+	lbs_add_mesh(priv);
+	lbs_mesh_register(priv);
 
-		ret = 1;
-	}
+	if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+		lbs_pr_err("cannot register lbs_mesh attribute\n");
 
-	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-	return ret;
+out:
+	lbs_deb_leave(LBS_DEB_MESH);
 }
 
 
 int lbs_deinit_mesh(struct lbs_private *priv)
 {
 	struct net_device *dev = priv->dev;
+	struct wireless_dev *mesh_wdev = priv->mesh_wdev;
 	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_MESH);
 
+	if (mesh_wdev) {
+		if (mesh_wdev->wiphy)
+			wiphy_unregister(mesh_wdev->wiphy);
+		wiphy_free(mesh_wdev->wiphy);
+	}
+
 	if (priv->mesh_tlv) {
 		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
 		ret = 1;
@@ -283,6 +410,7 @@ static int lbs_mesh_stop(struct net_devi
 	struct lbs_private *priv = dev->ml_priv;
 
 	lbs_deb_enter(LBS_DEB_MESH);
+
 	spin_lock_irq(&priv->driver_lock);
 
 	priv->mesh_open = 0;
@@ -310,16 +438,14 @@ static int lbs_mesh_dev_open(struct net_
 	struct lbs_private *priv = dev->ml_priv;
 	int ret = 0;
 
-	lbs_deb_enter(LBS_DEB_NET);
+	lbs_deb_enter(LBS_DEB_MESH);
 
 	spin_lock_irq(&priv->driver_lock);
 
-#ifdef TODO
-	if (priv->monitormode) {
+ 	if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) {
 		ret = -EBUSY;
 		goto out;
 	}
-#endif
 
 	priv->mesh_open = 1;
 	priv->mesh_connect_status = LBS_CONNECTED;
@@ -329,7 +455,7 @@ static int lbs_mesh_dev_open(struct net_
 		netif_wake_queue(dev);
 
 	spin_unlock_irq(&priv->driver_lock);
-	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);
+	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
 	return ret;
 }
 
@@ -364,16 +490,15 @@ int lbs_add_mesh(struct lbs_private *pri
 	mesh_dev->ml_priv = priv;
 	priv->mesh_dev = mesh_dev;
 
+	//TODO mesh_dev->ieee80211_ptr = priv->mesh_wdev;
 	mesh_dev->netdev_ops = &mesh_netdev_ops;
 	mesh_dev->ethtool_ops = &lbs_ethtool_ops;
 	memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, ETH_ALEN);
 
 	SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
 
-#ifdef	WIRELESS_EXT
-	mesh_dev->wireless_handlers = &mesh_handler_def;
-#endif
 	mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+
 	/* Register virtual mesh interface */
 	ret = register_netdev(mesh_dev);
 	if (ret) {
@@ -404,13 +529,13 @@ done:
 
 void lbs_remove_mesh(struct lbs_private *priv)
 {
-	struct net_device *mesh_dev;
+	struct net_device *mesh_dev = priv->mesh_dev;
 
-	mesh_dev = priv->mesh_dev;
 	if (!mesh_dev)
 		return;
 
 	lbs_deb_enter(LBS_DEB_MESH);
+
 	netif_stop_queue(mesh_dev);
 	netif_carrier_off(mesh_dev);
 	sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
@@ -418,6 +543,7 @@ void lbs_remove_mesh(struct lbs_private 
 	unregister_netdev(mesh_dev);
 	priv->mesh_dev = NULL;
 	free_netdev(mesh_dev);
+
 	lbs_deb_leave(LBS_DEB_MESH);
 }
 
--- linux-wl.orig/drivers/net/wireless/libertas/cfg.h
+++ linux-wl/drivers/net/wireless/libertas/cfg.h
@@ -1,9 +1,12 @@
 #ifndef __LBS_CFG80211_H__
 #define __LBS_CFG80211_H__
 
-struct device;
+#include <net/cfg80211.h>
+
 struct lbs_private;
 
+extern struct ieee80211_supported_band lbs_band_2ghz;
+
 struct wireless_dev *lbs_cfg_alloc(struct device *dev);
 int lbs_cfg_register(struct lbs_private *priv);
 void lbs_cfg_free(struct lbs_private *priv);
--- linux-wl.orig/drivers/net/wireless/libertas/dev.h
+++ linux-wl/drivers/net/wireless/libertas/dev.h
@@ -40,8 +40,9 @@ struct lbs_private {
 	u8 disassoc_reason;
 
 	/* Mesh */
-	struct net_device *mesh_dev; /* Virtual device */
+	struct net_device *mesh_dev;
 #ifdef CONFIG_LIBERTAS_MESH
+	struct wireless_dev *mesh_wdev;
 	u32 mesh_connect_status;
 	struct lbs_mesh_stats mstats;
 	int mesh_open;
--- linux-wl.orig/drivers/net/wireless/libertas/main.c
+++ linux-wl/drivers/net/wireless/libertas/main.c
@@ -129,6 +129,8 @@ static int lbs_eth_stop(struct net_devic
 
 	lbs_deb_enter(LBS_DEB_NET);
 
+	lbs_scan_deinit(priv);
+
 	spin_lock_irq(&priv->driver_lock);
 	netif_stop_queue(dev);
 	spin_unlock_irq(&priv->driver_lock);
@@ -730,7 +732,7 @@ int lbs_exit_auto_deep_sleep(struct lbs_
 
 static int lbs_init_adapter(struct lbs_private *priv)
 {
-	int ret;
+	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_MAIN);
 
@@ -899,17 +901,12 @@ void lbs_remove_card(struct lbs_private 
 
 	lbs_remove_mesh(priv);
 	lbs_scan_deinit(priv);
-
-	dev = priv->dev;
-
 	cancel_work_sync(&priv->mcast_work);
 
 	/* worker thread destruction blocks on the in-flight command which
 	 * should have been cleared already in lbs_stop_card().
 	 */
-	lbs_deb_main("destroying worker thread\n");
 	destroy_workqueue(priv->work_thread);
-	lbs_deb_main("done destroying worker thread\n");
 
 	if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
 		priv->psmode = LBS802_11POWERMODECAM;
@@ -1036,7 +1033,7 @@ void lbs_queue_event(struct lbs_private 
 {
 	unsigned long flags;
 
-	lbs_deb_enter(LBS_DEB_THREAD);
+	lbs_deb_enter_args(LBS_DEB_CMD, "event %d", event);
 	spin_lock_irqsave(&priv->driver_lock, flags);
 
 	if (priv->psstate == PS_STATE_SLEEP)
@@ -1047,7 +1044,7 @@ void lbs_queue_event(struct lbs_private 
 	wake_up_interruptible(&priv->waitq);
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
-	lbs_deb_leave(LBS_DEB_THREAD);
+	lbs_deb_leave(LBS_DEB_CMD);
 }
 EXPORT_SYMBOL_GPL(lbs_queue_event);
 
--- linux-wl.orig/drivers/net/wireless/libertas/mesh.h
+++ linux-wl/drivers/net/wireless/libertas/mesh.h
@@ -11,6 +11,11 @@
 
 #ifdef CONFIG_LIBERTAS_MESH
 
+
+struct net_device;
+struct lbs_private;
+
+
 /* Mesh statistics */
 struct lbs_mesh_stats {
 	u32	fwd_bcast_cnt;		/* Fwd: Broadcast counter */
@@ -24,10 +29,8 @@ struct lbs_mesh_stats {
 };
 
 
-struct net_device;
-struct lbs_private;
-
-int lbs_init_mesh(struct lbs_private *priv);
+/* Initialization */
+void lbs_init_mesh(struct lbs_private *priv);
 int lbs_deinit_mesh(struct lbs_private *priv);
 
 int lbs_add_mesh(struct lbs_private *priv);
@@ -70,11 +73,6 @@ void lbs_persist_config_init(struct net_
 void lbs_persist_config_remove(struct net_device *net);
 
 
-/* WEXT handler */
-
-extern struct iw_handler_def mesh_handler_def;
-
-
 /* Ethtool statistics */
 
 struct ethtool_stats;
--- linux-wl.orig/drivers/net/wireless/libertas/cmd.c
+++ linux-wl/drivers/net/wireless/libertas/cmd.c
@@ -81,8 +81,6 @@ static int lbs_is_cmd_allowed(struct lbs
 {
 	int ret = 1;
 
-	lbs_deb_enter(LBS_DEB_CMD);
-
 	if (!priv->is_auto_deep_sleep_enabled) {
 		if (priv->is_deep_sleep) {
 			lbs_deb_cmd("command not allowed in deep sleep\n");
@@ -90,7 +88,6 @@ static int lbs_is_cmd_allowed(struct lbs
 		}
 	}
 
-	lbs_deb_leave(LBS_DEB_CMD);
 	return ret;
 }
 
@@ -864,7 +861,7 @@ void lbs_set_mac_control(struct lbs_priv
 {
 	struct cmd_ds_mac_control cmd;
 
-	lbs_deb_enter(LBS_DEB_CMD);
+	lbs_deb_enter_args(LBS_DEB_CMD, "0x%04x", priv->mac_control);
 
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	cmd.action = cpu_to_le16(priv->mac_control);

-- 
http://www.holgerschurig.de

  reply	other threads:[~2010-02-03  9:32 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-02  0:09 [PATCH] libertas: cfg80211 support Samuel Ortiz
2010-02-02 20:36 ` John W. Linville
2010-02-03  9:31   ` Holger Schurig [this message]
2010-02-03 12:04     ` Samuel Ortiz
2010-02-03 15:32       ` Holger Schurig
2010-02-03 20:30         ` Dan Williams
2010-02-04  7:28           ` Holger Schurig
2010-02-04 21:49             ` Dan Williams
2010-02-04  9:52 ` Holger Schurig
2010-02-11 12:01   ` Samuel Ortiz
2010-02-11 12:24     ` Holger Schurig
2010-02-04 10:11 ` Holger Schurig
2010-02-11 12:03   ` Samuel Ortiz
2010-02-04 13:44 ` [PATCH] libertas+cfg80211: better disconnect support Holger Schurig
2010-02-15 10:46 ` [PATCH] libertas: cfg80211 support Holger Schurig
     [not found]   ` <cdd918981002240005o1fa50956yfb2a692716c06a55@mail.gmail.com>
2010-02-24 23:35     ` Dan Williams
2010-02-25  8:42       ` David MOUSSAUD
2010-02-25  8:48         ` Johannes Berg
2010-02-25 18:05           ` Andrey Yurovsky
2010-03-07 17:32             ` Kalle Valo
2010-03-07 17:52               ` Gábor Stefanik
2010-02-24  8:22 ` David MOUSSAUD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201002031031.22805.holgerschurig@gmail.com \
    --to=holgerschurig@gmail.com \
    --cc=dcbw@redhat.com \
    --cc=holgerschurig@googlemail.com \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=sameo@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.