Skip to contentSkip to conversation

libertas update

PATCH In review David Woodhouse 4 participants 141 messages Dec 10, 2007 – Dec 19, 2007 Networking drivers (wireless) Page 1 of 2

lore
Share & tools
lore
#0 lore raw

cover libertas update

This is the first set of patches to clean up the libertas driver, from the tree at git://git.infradead.org/libertas-2.6.git

It removes the 'struct lbs_adapter' data structure, merging it into 'struct lbs_private', and removes a bunch of pointless unused fields from it.

It collapses the pointless nest of functions in the transmit path, which used to go pre_start_xmit->hard_start_xmit->lbs_process_tx->SendSinglePacket and now can be handled entirely in libertas_hard_start_xmit() -- thus removing the need to store information about which netdevice the packet belongs to, so the whole IS_MESH_FRAME / {UN,}SET_MESH_FRAME thing can go away too.

It slightly cleans up the RX code path too, along similar lines. There's more to be done here.

It fixes radiotap mode so that you can query it without crashing, and can even enable it and see packets, which is a shiny new feature. As an added bonus, you can even disable it again without crashing, too.

It also fixes a bunch of other things which offended me along the way, and makes a start at addressing the locking issues with command and data transmission to the device, partly by moving the actual TX packet submission to the context of the main worker thread.

There's more to be done, but it seems to make sense to merge at this point before I embark on the next batch...

Dan Williams (1):
libertas: select WIRELESS_EXT

David Woodhouse (39):
libertas: Fix memory leak of RX skbs
libertas: Remove cmd_oid from struct cmd_ctrl_node
libertas: Consolidate lbs_host_to_card_done() function.
libertas: Don't claim to have checksummed incoming packets.
libertas: Move SET_BOOT2_VER command to if_usb where it belongs
libertas: Zero 'pdata_size' field in cmd_ctrl_node reliably.
libertas: Byteswap cmdptr->size in lbs_cmd()
libertas: Use lbs_cmd() for setting Boot2 version
libertas: Remove SET_BOOT2_VER support from the Big Switch Statement.
libertas: Fix endianness in boot2_version handling.
libertas: when usb_submit_usb fails, include the error code in the printk
libertas: Switch to using a callback function pointer for commands
libertas: Don't set IW_ENCODE_NOKEY when returning WEP keys.
libertas: Fix up error handling in lbs_setuserscan()
libertas: kill adapter->nr_cmd_pending
libertas: switch lbs_cmd() to take a callback function pointer
libertas: clean up lbs_thread() to make it slightly more readable
libertas: fix lbs_rtap attribute in sysfs
libertas: kill TxLockFlag
libertas: kill struct lbs_adapter
libertas: use lbs_host_to_card_done() in lbs_tx_timeout()
libertas: cope with device which already has firmware loaded
libertas: stop debugfs code looking at cmdpendingq
libertas: kill internal tx queue for PS mode
libertas: kill SendSinglePacket() function.
libertas: move lbs_hard_start_xmit() into tx.c
libertas: kill lbs_process_tx() by merging it into lbs_hard_start_xmit()
libertas: clean up lbs_hard_start_xmit()
libertas: kill lbs_pre_start_xmit(), lib_mesh_pre_start_xmit()
libertas: stop using ieee80211 for radiotap device
libertas: set dev_addr on rtap device
libertas: TX packet is radiotap iff it comes from rtap_dev
libertas: free successfully transmitted skbs again
libertas: refactor the 'should I sleep?' decision in lbs_thread()
libertas: Move actual transmission to main thread
libertas: remove unreachable code from process_rxed_802_11_packet()
libertas: fix error cases in lbs_process_rxed_802_11_packet()
libertas: kill lbs_upload_tx_packet()
libertas: kill (IS,SET,UNSET)_MESH_FRAME.

Holger Schurig (7):
libertas: remove cmd_ctrl_node->cmdflags
libertas: remove cmd_ctrl_node->status
libertas: make more functions static
libertas: handy function to call firmware commands
libertas: fix data packet size errors
libertas: implement new scanning logic
libertas: endianness fixes

Li Zefan (1):
libertas: don't cast a pointer to pointer of

---

23 files changed, 1809 insertions(+), 2189 deletions(-)
Signature · 1 line
dwmw2
#1 lore raw

PATCH 1/48 libertas: Fix memory leak of RX skbs

Date: Wed, 28 Nov 2007 16:20:51 +0000

---
 drivers/net/wireless/libertas/if_usb.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/if_usb.c +5 -1
index 4fce0ba..c27ffcf 100644
@@ -460,6 +460,8 @@ static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
 	if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
 		/* handle failure conditions */
 		lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
+		kfree_skb(skb);
+		rinfo->skb = NULL;
 		ret = -1;
 	} else {
 		/* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
@@ -667,8 +669,10 @@ static void if_usb_receive(struct urb *urb)
 		lbs_deb_usbd(&cardp->udev->dev,
 			    "Recv length = 0x%x, Recv type = 0x%X\n",
 			    recvlength, recvtype);
-	} else if (urb->status)
+	} else if (urb->status) {
+		kfree_skb(skb);
 		goto rx_exit;
+	}
 
 	switch (recvtype) {
 	case CMD_TYPE_DATA:
Signature · 1 line
1.5.3.4
#2 lore raw

PATCH 2/48 libertas: Remove cmd_oid from struct cmd_ctrl_node

In reply to David Woodhouse

Date: Sat, 1 Dec 2007 15:15:41 +0000

This is only needed for SNMP and key operations; it doesn't need to be preserved outside that context.

---
 drivers/net/wireless/libertas/cmd.c     |    9 +++------
 drivers/net/wireless/libertas/decl.h    |    2 +-
 drivers/net/wireless/libertas/hostcmd.h |    2 --
 3 files changed, 4 insertions(+), 9 deletions(-)
drivers/net/wireless/libertas/cmd.c +3 -6
index d98bec9..6658590 100644
@@ -1231,7 +1231,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		goto done;
 	}
 
-	lbs_set_cmd_ctrl_node(priv, cmdnode, cmd_oid, wait_option, pdata_buf);
+	lbs_set_cmd_ctrl_node(priv, cmdnode, wait_option, pdata_buf);
 
 	cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
 
@@ -1404,7 +1404,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 	case CMD_802_11_INACTIVITY_TIMEOUT:
 		ret = lbs_cmd_802_11_inactivity_timeout(priv, cmdptr,
 							 cmd_action, pdata_buf);
-		lbs_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf);
+		lbs_set_cmd_ctrl_node(priv, cmdnode, 0, pdata_buf);
 		break;
 
 	case CMD_802_11_TPC_CFG:
@@ -1668,7 +1668,6 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
 	ptempnode->cmdwaitqwoken = 1;
 	wake_up_interruptible(&ptempnode->cmdwait_q);
 	ptempnode->status = 0;
-	ptempnode->cmd_oid = (u32) 0;
 	ptempnode->wait_option = 0;
 	ptempnode->pdata_buf = NULL;
 
@@ -1683,21 +1682,19 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
  *
  *  @param priv		A pointer to struct lbs_private structure
  *  @param ptempnode	A pointer to cmd_ctrl_node structure
- *  @param cmd_oid	cmd oid: treated as sub command
  *  @param wait_option	wait option: wait response or not
  *  @param pdata_buf	A pointer to informaion buffer
  *  @return 		0 or -1
  */
 void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 		    struct cmd_ctrl_node *ptempnode,
-		    u32 cmd_oid, u16 wait_option, void *pdata_buf)
+		    u16 wait_option, void *pdata_buf)
 {
 	lbs_deb_enter(LBS_DEB_HOST);
 
 	if (!ptempnode)
 		return;
 
-	ptempnode->cmd_oid = cmd_oid;
 	ptempnode->wait_option = wait_option;
 	ptempnode->pdata_buf = pdata_buf;
 
drivers/net/wireless/libertas/decl.h +1 -1
index 74187f3..447297a 100644
@@ -26,7 +26,7 @@ struct cmd_ctrl_node *lbs_get_free_cmd_ctrl_node(struct lbs_private *priv);
 
 void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 	struct cmd_ctrl_node *ptempnode,
-	u32 cmd_oid, u16 wait_option, void *pdata_buf);
+	u16 wait_option, void *pdata_buf);
 
 int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_no,
drivers/net/wireless/libertas/hostcmd.h +0 -2
index 614db6c..c029149 100644
@@ -69,8 +69,6 @@ struct cmd_ctrl_node {
 	/* CMD link list */
 	struct list_head list;
 	u32 status;
-	/* CMD ID */
-	u32 cmd_oid;
 	/*CMD wait option: wait for finish or no wait */
 	u16 wait_option;
 	/* command parameter */
Signature · 1 line
1.5.3.4
#3 lore raw

PATCH 3/48 libertas: Consolidate lbs_host_to_card_done() function.

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 14:36:11 +0000

As we move towards having this done by a state machine, start by having a single 'stuff sent' function, which is called by if_usb/if_sdio/if_cs after sending both data and commands.

---
 drivers/net/wireless/libertas/decl.h    |    1 +
 drivers/net/wireless/libertas/if_cs.c   |   12 +++---------
 drivers/net/wireless/libertas/if_sdio.c |    9 +++------
 drivers/net/wireless/libertas/if_usb.c  |   18 ++----------------
 drivers/net/wireless/libertas/main.c    |   18 ++++++++++++++++++
 5 files changed, 27 insertions(+), 31 deletions(-)
drivers/net/wireless/libertas/decl.h +1 -0
index 447297a..201ec60 100644
@@ -86,5 +86,6 @@ int lbs_stop_card(struct lbs_private *priv);
 int lbs_add_mesh(struct lbs_private *priv, struct device *dev);
 void lbs_remove_mesh(struct lbs_private *priv);
 int lbs_reset_device(struct lbs_private *priv);
+void lbs_host_to_card_done(struct lbs_private *priv);
 
 #endif
drivers/net/wireless/libertas/if_cs.c +3 -9
index 5fadcc0..54b1ba3 100644
@@ -253,19 +253,13 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
 		/* Not for us */
 		return IRQ_NONE;
 
-	} else if(int_cause == 0xffff) {
+	} else if (int_cause == 0xffff) {
 		/* Read in junk, the card has probably been removed */
 		card->priv->adapter->surpriseremoved = 1;
 
 	} else {
-		if(int_cause & IF_CS_H_IC_TX_OVER) {
-			card->priv->dnld_sent = DNLD_RES_RECEIVED;
-			if (!card->priv->adapter->cur_cmd)
-				wake_up_interruptible(&card->priv->waitq);
-
-			if (card->priv->adapter->connect_status == LBS_CONNECTED)
-				netif_wake_queue(card->priv->dev);
-		}
+		if (int_cause & IF_CS_H_IC_TX_OVER)
+			lbs_host_to_card_done(card->priv);
 
 		/* clear interrupt */
 		if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause & IF_CS_C_IC_MASK);
drivers/net/wireless/libertas/if_sdio.c +3 -6
index 437f3dd..0f0296b 100644
@@ -835,12 +835,9 @@ static void if_sdio_interrupt(struct sdio_func *func)
 	 * Ignore the define name, this really means the card has
 	 * successfully received the command.
 	 */
-	if (cause & IF_SDIO_H_INT_DNLD) {
-		if ((card->priv->dnld_sent == DNLD_DATA_SENT) &&
-			(card->priv->adapter->connect_status == LBS_CONNECTED))
-			netif_wake_queue(card->priv->dev);
-		card->priv->dnld_sent = DNLD_RES_RECEIVED;
-	}
+	if (cause & IF_SDIO_H_INT_DNLD)
+		lbs_host_to_card_done(card->priv);
+
 
 	if (cause & IF_SDIO_H_INT_UPLD) {
 		ret = if_sdio_card_to_host(card);
drivers/net/wireless/libertas/if_usb.c +2 -16
index c27ffcf..418dcab 100644
@@ -66,22 +66,8 @@ static void if_usb_write_bulk_callback(struct urb *urb)
 		/* Used for both firmware TX and regular TX.  priv isn't
 		 * valid at firmware load time.
 		 */
-		if (priv) {
-			struct lbs_adapter *adapter = priv->adapter;
-			struct net_device *dev = priv->dev;
-
-			priv->dnld_sent = DNLD_RES_RECEIVED;
-
-			/* Wake main thread if commands are pending */
-			if (!adapter->cur_cmd)
-				wake_up_interruptible(&priv->waitq);
-
-			if (adapter->connect_status == LBS_CONNECTED)
-				netif_wake_queue(dev);
-
-			if (priv->mesh_dev && (adapter->mesh_connect_status == LBS_CONNECTED))
-				netif_wake_queue(priv->mesh_dev);
-		}
+		if (priv)
+			lbs_host_to_card_done(priv);
 	} else {
 		/* print the failure status number for debug */
 		lbs_pr_info("URB in failure status: %d\n", urb->status);
drivers/net/wireless/libertas/main.c +18 -0
index 67b6d79..ed02c02 100644
@@ -616,6 +616,24 @@ static void lbs_tx_timeout(struct net_device *dev)
 	lbs_deb_leave(LBS_DEB_TX);
 }
 
+void lbs_host_to_card_done(struct lbs_private *priv)
+{
+	struct lbs_adapter *adapter = priv->adapter;
+
+	priv->dnld_sent = DNLD_RES_RECEIVED;
+
+	/* Wake main thread if commands are pending */
+	if (!adapter->cur_cmd)
+		wake_up_interruptible(&priv->waitq);
+
+	if (priv->dev && adapter->connect_status == LBS_CONNECTED)
+		netif_wake_queue(priv->dev);
+
+	if (priv->mesh_dev && adapter->mesh_connect_status == LBS_CONNECTED)
+		netif_wake_queue(priv->mesh_dev);
+}
+EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
+
 /**
  *  @brief This function returns the network statistics
  *
Signature · 1 line
1.5.3.4
#4 lore raw

PATCH 4/48 libertas: select WIRELESS_EXT

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 4 Dec 2007 12:17:54 -0500

---
 drivers/net/wireless/Kconfig |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/net/wireless/Kconfig +1 -0
index 2b733c5..5583719 100644
@@ -264,6 +264,7 @@ config IPW2200_DEBUG
 config LIBERTAS
 	tristate "Marvell 8xxx Libertas WLAN driver support"
 	depends on WLAN_80211
+	select WIRELESS_EXT
 	select IEEE80211
 	select FW_LOADER
 	---help---
Signature · 1 line
1.5.3.4
#5 lore raw

PATCH 5/48 libertas: remove cmd_ctrl_node->cmdflags

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Wed, 5 Dec 2007 17:57:56 +0100

There was no code that ever did set this flag.

---
 drivers/net/wireless/libertas/cmdresp.c |    7 -------
 drivers/net/wireless/libertas/hostcmd.h |    1 -
 2 files changed, 0 insertions(+), 8 deletions(-)
drivers/net/wireless/libertas/cmdresp.c +0 -7
index 90f1c49..cbd28ee 100644
@@ -856,13 +856,6 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		goto done;
 	}
 
-	if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) {
-		/* Copy the response back to response buffer */
-		memcpy(adapter->cur_cmd->pdata_buf, resp,
-		       le16_to_cpu(resp->size));
-		adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD;
-	}
-
 	/* If the command is not successful, cleanup and return failure */
 	if ((result != 0 || !(respcmd & 0x8000))) {
 		lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
drivers/net/wireless/libertas/hostcmd.h +0 -1
index c029149..217ae12 100644
@@ -75,7 +75,6 @@ struct cmd_ctrl_node {
 	void *pdata_buf;
 	/*command data */
 	u8 *bufvirtualaddr;
-	u16 cmdflags;
 	/* wait queue */
 	u16 cmdwaitqwoken;
 	wait_queue_head_t cmdwait_q;
Signature · 1 line
1.5.3.4
#6 lore raw

PATCH 6/48 libertas: remove cmd_ctrl_node->status

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Wed, 5 Dec 2007 17:57:58 +0100

There was no code that ever did set this variable.

---
 drivers/net/wireless/libertas/cmd.c     |    1 -
 drivers/net/wireless/libertas/hostcmd.h |    1 -
 2 files changed, 0 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/cmd.c +0 -1
index 6658590..43dde7e 100644
@@ -1667,7 +1667,6 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
 		return;
 	ptempnode->cmdwaitqwoken = 1;
 	wake_up_interruptible(&ptempnode->cmdwait_q);
-	ptempnode->status = 0;
 	ptempnode->wait_option = 0;
 	ptempnode->pdata_buf = NULL;
 
drivers/net/wireless/libertas/hostcmd.h +0 -1
index 217ae12..f096d99 100644
@@ -68,7 +68,6 @@ struct rxpd {
 struct cmd_ctrl_node {
 	/* CMD link list */
 	struct list_head list;
-	u32 status;
 	/*CMD wait option: wait for finish or no wait */
 	u16 wait_option;
 	/* command parameter */
Signature · 1 line
1.5.3.4
#7 lore raw

PATCH 7/48 libertas: make more functions static

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Wed, 5 Dec 2007 17:58:06 +0100

These functions were used in the old debugfs code for events, but as this code is now gone, there's no need to export those functions.

---
 drivers/net/wireless/libertas/cmd.c  |    9 +++++++--
 drivers/net/wireless/libertas/decl.h |    7 +------
 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/libertas/cmd.c +7 -2
index 43dde7e..54ef990 100644
@@ -13,6 +13,11 @@
 #include "wext.h"
 
 static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
+struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
+void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
+		    struct cmd_ctrl_node *ptempnode,
+		    u16 wait_option, void *pdata_buf);
+
 
 static u16 commands_allowed_in_ps[] = {
 	CMD_802_11_RSSI,
@@ -1220,7 +1225,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		goto done;
 	}
 
-	cmdnode = lbs_get_free_cmd_ctrl_node(priv);
+	cmdnode = lbs_get_cmd_ctrl_node(priv);
 
 	if (cmdnode == NULL) {
 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
@@ -1623,7 +1628,7 @@ done:
  *  @param priv		A pointer to struct lbs_private structure
  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
  */
-struct cmd_ctrl_node *lbs_get_free_cmd_ctrl_node(struct lbs_private *priv)
+struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
 {
 	struct cmd_ctrl_node *tempnode;
 	struct lbs_adapter *adapter = priv->adapter;
drivers/net/wireless/libertas/decl.h +1 -6
index 201ec60..0856cc9 100644
@@ -15,18 +15,13 @@ struct lbs_private;
 struct lbs_adapter;
 struct sk_buff;
 struct net_device;
+struct cmd_ctrl_node;
 
 int lbs_set_mac_packet_filter(struct lbs_private *priv);
 
 void lbs_send_tx_feedback(struct lbs_private *priv);
 
 int lbs_free_cmd_buffer(struct lbs_private *priv);
-struct cmd_ctrl_node;
-struct cmd_ctrl_node *lbs_get_free_cmd_ctrl_node(struct lbs_private *priv);
-
-void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
-	struct cmd_ctrl_node *ptempnode,
-	u16 wait_option, void *pdata_buf);
 
 int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_no,
Signature · 1 line
1.5.3.4
#8 lore raw

Re: [PATCH 07/48] libertas: make more functions static

Quoted 7 lines · David Woodhouse
drivers/net/wireless/libertas/cmd.c +0 -0
@@ -13,6 +13,11 @@

=A0#include "wext.h"
=A0
=A0static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode); +struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv=

);

Quoted 2 lines

+void lbs_set_cmd_ctrl_node(struct lbs_private *priv, +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0 =A0struct cmd_ctrl=

_node *ptempnode,

Quoted 1 line

+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0 =A0u16 wait_option=

, void *pdata_buf);

Quoted 1 line

+

You should never need forward declarations for global functions in a C = file,
it is error prone in any case:

* if the functions are only used in one file, make them static.
* Better, avoid forward declarations entirely by ordering the functions= in the
way they are called.
* If they are used in one file and defined in another, declare them in a common header, and only there, in order to avoid the prototypes from = diverging.

	Arnd <><

-
To unsubscribe from this list: send the line "unsubscribe linux-wireles= s" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

Re: [PATCH 07/48] libertas: make more functions static

Quoted 2 lines

* Better, avoid forward declarations entirely by ordering the functions in the way they are called.

Right.

I wanted to keep the patch small, as I knew that David might create patches in the same area.

But libertas can easily take another 200 cleanup-patches ... :-)

#10 lore raw

Re: [PATCH 07/48] libertas: make more functions static

Quoted 7 lines · Holger Schurig
Quoted 2 lines

* Better, avoid forward declarations entirely by ordering the functions in the way they are called.

Right.

I wanted to keep the patch small, as I knew that David might create patches in the same area.

The whole command queueing stuff is my primary focus... I just had to clean it all up a bit before I could really get on with that.

This function will be the subject of another commit with 'kill' in the title, fairly soon now...

Although I suspect that given the title of Holger's commit, he actually meant to make it static. It really is only used in that one file.

Signature · 1 line
dwmw2
#11 lore raw

PATCH 8/48 libertas: handy function to call firmware commands

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Wed, 5 Dec 2007 17:58:11 +0100

Using an arbitrary firmware command was actually very painful. One had to change big switch() statements in cmd.c, cmdresp.c, add structs to the big union in "struct cmd_ds_command" and add the define for the CMD_802_11_xxx to the proper place.

With this function, this is now much easier. For now, it implements a blocking (a.k.a. CMD_OPTION_WAITFORRSP) way where one deals directly with command requests and response buffers. You can do everything in one place:

---
 drivers/net/wireless/libertas/cmd.c     |   96 +++++++++++++++++++++++++++++++
 drivers/net/wireless/libertas/cmdresp.c |   23 ++++++--
 drivers/net/wireless/libertas/decl.h    |    6 ++
 drivers/net/wireless/libertas/hostcmd.h |   11 ++-
 4 files changed, 126 insertions(+), 10 deletions(-)
drivers/net/wireless/libertas/cmd.c +96 -0
index 54ef990..9064513 100644
@@ -2007,3 +2007,99 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
+
+
+/**
+ *  @brief Simple way to call firmware functions
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param psmode  	one of the many CMD_802_11_xxxx
+ *  @param cmd          pointer to the parameters structure for above command
+ *                      (this should not include the command, size, sequence
+ *                      and result fields from struct cmd_ds_gen)
+ *  @param cmd_size     size structure pointed to by cmd
+ *  @param rsp          pointer to an area where the result should be placed
+ *  @param rsp_size     pointer to the size of the rsp area. If the firmware
+ *                      returns fewer bytes, then this *rsp_size will be
+ *                      changed to the actual size.
+ *  @return 	   	-1 in case of a higher level error, otherwise
+ *                      the result code from the firmware
+ */
+int lbs_cmd(struct lbs_private *priv,
+	u16 command,
+	void *cmd, int cmd_size,
+	void *rsp, int *rsp_size)
+{
+	struct lbs_adapter *adapter = priv->adapter;
+	struct cmd_ctrl_node *cmdnode;
+	struct cmd_ds_gen *cmdptr;
+	unsigned long flags;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_HOST);
+	lbs_deb_host("rsp at %p, rsp_size at %p\n", rsp, rsp_size);
+
+	if (!adapter || !rsp_size) {
+		lbs_deb_host("PREP_CMD: adapter is NULL\n");
+		ret = -1;
+		goto done;
+	}
+
+	if (adapter->surpriseremoved) {
+		lbs_deb_host("PREP_CMD: card removed\n");
+		ret = -1;
+		goto done;
+	}
+
+	cmdnode = lbs_get_cmd_ctrl_node(priv);
+
+	if (cmdnode == NULL) {
+		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
+
+		/* Wake up main thread to execute next command */
+		wake_up_interruptible(&priv->waitq);
+		ret = -1;
+		goto done;
+	}
+
+	cmdptr = (struct cmd_ds_gen *)cmdnode->bufvirtualaddr;
+	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
+	cmdnode->pdata_buf = rsp;
+	cmdnode->pdata_size = rsp_size;
+
+	/* Set sequence number, clean result, move to buffer */
+	adapter->seqnum++;
+	cmdptr->command = cpu_to_le16(command);
+	cmdptr->size    = cmd_size + S_DS_GEN;
+	cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
+	cmdptr->result = 0;
+	memcpy(cmdptr->cmdresp, cmd, cmd_size);
+
+	lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
+
+	/* here was the big old switch() statement, which is now obsolete,
+	 * because the caller of lbs_cmd() sets up all of *cmd for us. */
+
+	cmdnode->cmdwaitqwoken = 0;
+	lbs_queue_cmd(adapter, cmdnode, 1);
+	wake_up_interruptible(&priv->waitq);
+
+	might_sleep();
+	wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
+
+	spin_lock_irqsave(&adapter->driver_lock, flags);
+	if (adapter->cur_cmd_retcode) {
+		lbs_deb_host("PREP_CMD: command failed with return code %d\n",
+		       adapter->cur_cmd_retcode);
+		adapter->cur_cmd_retcode = 0;
+		ret = -1;
+	}
+	spin_unlock_irqrestore(&adapter->driver_lock, flags);
+
+done:
+	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(lbs_cmd);
+
+
drivers/net/wireless/libertas/cmdresp.c +17 -6
index cbd28ee..6a43de7 100644
@@ -799,7 +799,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 	}
 
 	/* Store the response code to cur_cmd_retcode. */
-	adapter->cur_cmd_retcode = result;;
+	adapter->cur_cmd_retcode = result;
 
 	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
 		struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
@@ -880,11 +880,22 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		goto done;
 	}
 
-	spin_unlock_irqrestore(&adapter->driver_lock, flags);
-
-	ret = handle_cmd_response(respcmd, resp, priv);
-
-	spin_lock_irqsave(&adapter->driver_lock, flags);
+	if (adapter->cur_cmd->pdata_size) {
+		struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
+		u16 sz = cpu_to_le16(resp->size);
+		if (sz > *adapter->cur_cmd->pdata_size) {
+			lbs_pr_err("response 0x%04x doesn't fit into "
+				"buffer (%d > %d)\n", respcmd,
+				sz, *adapter->cur_cmd->pdata_size);
+			sz = *adapter->cur_cmd->pdata_size;
+		}
+		memcpy(adapter->cur_cmd->pdata_buf, r->cmdresp, sz);
+		*adapter->cur_cmd->pdata_size = sz;
+	} else {
+		spin_unlock_irqrestore(&adapter->driver_lock, flags);
+		ret = handle_cmd_response(respcmd, resp, priv);
+		spin_lock_irqsave(&adapter->driver_lock, flags);
+	}
 	if (adapter->cur_cmd) {
 		/* Clean up and Put current command back to cmdfreeq */
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
drivers/net/wireless/libertas/decl.h +6 -0
index 0856cc9..6f47ff0 100644
@@ -16,6 +16,7 @@ struct lbs_adapter;
 struct sk_buff;
 struct net_device;
 struct cmd_ctrl_node;
+struct cmd_ds_command;
 
 int lbs_set_mac_packet_filter(struct lbs_private *priv);
 
@@ -23,6 +24,11 @@ void lbs_send_tx_feedback(struct lbs_private *priv);
 
 int lbs_free_cmd_buffer(struct lbs_private *priv);
 
+int lbs_cmd(struct lbs_private *priv,
+	u16 command,
+	void *cmd, int cmd_size,
+	void *resp, int *resp_size);
+
 int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_no,
 	u16 cmd_action,
drivers/net/wireless/libertas/hostcmd.h +7 -4
index f096d99..be69ae6 100644
@@ -66,13 +66,13 @@ struct rxpd {
 };
 
 struct cmd_ctrl_node {
-	/* CMD link list */
 	struct list_head list;
-	/*CMD wait option: wait for finish or no wait */
+	/* wait for finish or not */
 	u16 wait_option;
-	/* command parameter */
+	/* command response */
 	void *pdata_buf;
-	/*command data */
+	int *pdata_size;
+	/* command data */
 	u8 *bufvirtualaddr;
 	/* wait queue */
 	u16 cmdwaitqwoken;
@@ -100,9 +100,12 @@ struct cmd_ds_gen {
 	__le16 size;
 	__le16 seqnum;
 	__le16 result;
+	void *cmdresp[0];
 };
 
 #define S_DS_GEN sizeof(struct cmd_ds_gen)
+
+
 /*
  * Define data structure for CMD_GET_HW_SPEC
  * This structure defines the response for the GET_HW_SPEC command
Signature · 1 line
1.5.3.4
#12 lore raw

PATCH 9/48 libertas: Don't claim to have checksummed incoming packets.

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 10:36:08 +0000

This explains why we never noticed the corruption of checksums on outgoing packets... we weren't actually checking them either.

---
 drivers/net/wireless/libertas/rx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/rx.c +1 -1
index fa467df..a252a8f 100644
@@ -147,7 +147,7 @@ void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb)
 		else
 			skb->protocol = eth_type_trans(skb, priv->dev);
 	}
-	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->ip_summed = CHECKSUM_NONE;
 	netif_rx(skb);
 }
 
Signature · 1 line
1.5.3.4
#13 lore raw

PATCH 10/48 libertas: Move SET_BOOT2_VER command to if_usb where it belongs

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 14:41:08 +0000

This is meaningless for non-USB devices and unimplemented in their firmware. It's somewhat dubious for USB devices too, but that's a different story.

---
 drivers/net/wireless/libertas/if_usb.c |    5 +++++
 drivers/net/wireless/libertas/main.c   |    4 ----
 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/if_usb.c +5 -0
index 418dcab..f858928 100644
@@ -222,6 +222,11 @@ static int if_usb_probe(struct usb_interface *intf,
 	if (lbs_start_card(priv))
 		goto err_start_card;
 
+	/* Set the boot2 version in firmware, ignoring errors. */
+	(void)lbs_prepare_and_send_command(priv, CMD_SET_BOOT2_VER,
+					   0, CMD_OPTION_WAITFORRSP, 0, NULL);
+
+
 	usb_get_dev(udev);
 	usb_set_intfdata(intf, cardp);
 
drivers/net/wireless/libertas/main.c +0 -4
index ed02c02..a5b573c 100644
@@ -999,10 +999,6 @@ static int lbs_setup_firmware(struct lbs_private *priv)
 		priv->mesh_autostart_enabled = 0;
 	}
 
-       /* Set the boot2 version in firmware */
-       ret = lbs_prepare_and_send_command(priv, CMD_SET_BOOT2_VER,
-                                   0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
 	ret = 0;
 done:
 	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
Signature · 1 line
1.5.3.4
#14 lore raw

PATCH 11/48 libertas: Zero 'pdata_size' field in cmd_ctrl_node reliably.

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 12:37:31 +0000

Otherwise, lbs_process_rx_command() will take the new path for lbs_cmd() responses, when it shouldn't.

---
 drivers/net/wireless/libertas/cmd.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/net/wireless/libertas/cmd.c +2 -0
index 9064513..4fc3e4b 100644
@@ -1674,6 +1674,7 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
 	wake_up_interruptible(&ptempnode->cmdwait_q);
 	ptempnode->wait_option = 0;
 	ptempnode->pdata_buf = NULL;
+	ptempnode->pdata_size = 0;
 
 	if (ptempnode->bufvirtualaddr != NULL)
 		memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
@@ -1701,6 +1702,7 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 
 	ptempnode->wait_option = wait_option;
 	ptempnode->pdata_buf = pdata_buf;
+	ptempnode->pdata_size = 0;
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
Signature · 1 line
1.5.3.4
#15 lore raw

PATCH 12/48 libertas: Byteswap cmdptr->size in lbs_cmd()

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 12:38:31 +0000

Bad Holger. Always test on big-endian machines, if it's little-endian you need to be swapping to/from.

---
 drivers/net/wireless/libertas/cmd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmd.c +1 -1
index 4fc3e4b..7097dcf 100644
@@ -2072,7 +2072,7 @@ int lbs_cmd(struct lbs_private *priv,
 	/* Set sequence number, clean result, move to buffer */
 	adapter->seqnum++;
 	cmdptr->command = cpu_to_le16(command);
-	cmdptr->size    = cmd_size + S_DS_GEN;
+	cmdptr->size    = cpu_to_le16(cmd_size + S_DS_GEN);
 	cmdptr->seqnum = cpu_to_le16(adapter->seqnum);
 	cmdptr->result = 0;
 	memcpy(cmdptr->cmdresp, cmd, cmd_size);
Signature · 1 line
1.5.3.4
#16 lore raw

PATCH 13/48 libertas: don't cast a pointer to pointer of

In reply to David Woodhouse

From: Li Zefan <[email protected]>
Date: Thu, 6 Dec 2007 13:01:21 +0100

Don't cast struct foo * to struct list_head *, it's safe only when the list member is the first member of struct foo.

Also don't cast struct list_head * to struct foo *.

---
 drivers/net/wireless/libertas/cmd.c |   22 +++++++++++-----------
 1 files changed, 11 insertions(+), 11 deletions(-)
drivers/net/wireless/libertas/cmd.c +11 -11
index 7097dcf..851eb3c 100644
@@ -1021,11 +1021,10 @@ void lbs_queue_cmd(struct lbs_adapter *adapter,
 	spin_lock_irqsave(&adapter->driver_lock, flags);
 
 	if (addtail) {
-		list_add_tail((struct list_head *)cmdnode,
-			      &adapter->cmdpendingq);
+		list_add_tail(&cmdnode->list, &adapter->cmdpendingq);
 		adapter->nr_cmd_pending++;
 	} else
-		list_add((struct list_head *)cmdnode, &adapter->cmdpendingq);
+		list_add(&cmdnode->list, &adapter->cmdpendingq);
 
 	spin_unlock_irqrestore(&adapter->driver_lock, flags);
 
@@ -1144,7 +1143,7 @@ void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
 		return;
 
 	cleanup_cmdnode(ptempcmd);
-	list_add_tail((struct list_head *)ptempcmd, &adapter->cmdfreeq);
+	list_add_tail(&ptempcmd->list, &adapter->cmdfreeq);
 }
 
 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
@@ -1642,8 +1641,9 @@ struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
 	spin_lock_irqsave(&adapter->driver_lock, flags);
 
 	if (!list_empty(&adapter->cmdfreeq)) {
-		tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;
-		list_del((struct list_head *)tempnode);
+		tempnode = list_first_entry(&adapter->cmdfreeq,
+					    struct cmd_ctrl_node, list);
+		list_del(&tempnode->list);
 	} else {
 		lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
 		tempnode = NULL;
@@ -1738,8 +1738,8 @@ int lbs_execute_next_command(struct lbs_private *priv)
 	}
 
 	if (!list_empty(&adapter->cmdpendingq)) {
-		cmdnode = (struct cmd_ctrl_node *)
-		    adapter->cmdpendingq.next;
+		cmdnode = list_first_entry(&adapter->cmdpendingq,
+					   struct cmd_ctrl_node, list);
 	}
 
 	spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -1803,7 +1803,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				    cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
-					list_del((struct list_head *)cmdnode);
+					list_del(&cmdnode->list);
 					lbs_cleanup_and_insert_cmd(priv, cmdnode);
 
 					ret = 0;
@@ -1814,7 +1814,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				    (adapter->psstate == PS_STATE_PRE_SLEEP)) {
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
-					list_del((struct list_head *)cmdnode);
+					list_del(&cmdnode->list);
 					lbs_cleanup_and_insert_cmd(priv, cmdnode);
 					adapter->needtowakeup = 1;
 
@@ -1826,7 +1826,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				       "EXEC_NEXT_CMD: sending EXIT_PS\n");
 			}
 		}
-		list_del((struct list_head *)cmdnode);
+		list_del(&cmdnode->list);
 		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
 			    le16_to_cpu(cmdptr->command));
 		DownloadcommandToStation(priv, cmdnode);
Signature · 1 line
1.5.3.4
#17 lore raw

PATCH 14/48 libertas: fix data packet size errors

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Thu, 6 Dec 2007 13:50:30 +0100

I wondered about junk bytes at the end when using "lbsdebug +hex +host" until I noticed that firmware for the CF card sends my extranous bytes. It says "I have 20 bytes", I take 20 bytes, but the last 8 bytes of this are just data junk.

Also, in the new lbs_cmd() where was a size miscalulation that made itself clear after fixing this bug.

---
 drivers/net/wireless/libertas/cmdresp.c |    2 +-
 drivers/net/wireless/libertas/if_cs.c   |    3 +++
 2 files changed, 4 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmdresp.c +1 -1
index 6a43de7..22a6973 100644
@@ -882,7 +882,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 
 	if (adapter->cur_cmd->pdata_size) {
 		struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
-		u16 sz = cpu_to_le16(resp->size);
+		u16 sz = cpu_to_le16(resp->size) - S_DS_GEN;
 		if (sz > *adapter->cur_cmd->pdata_size) {
 			lbs_pr_err("response 0x%04x doesn't fit into "
 				"buffer (%d > %d)\n", respcmd,
drivers/net/wireless/libertas/if_cs.c +3 -0
index 54b1ba3..8508260 100644
@@ -373,6 +373,9 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
 	if (*len & 1)
 		data[*len-1] = if_cs_read8(priv->card, IF_CS_C_CMD);
 
+	/* This is a workaround for a firmware that reports too much
+	 * bytes */
+	*len -= 8;
 	ret = 0;
 out:
 	lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len);
Signature · 1 line
1.5.3.4
#18 lore raw

Re: [PATCH 14/48] libertas: fix data packet size errors

Quoted 23 lines · On Monday 10 December 2007 16:45:48 David Woodhouse wrote:

From: Holger Schurig <[email protected]>
Date: Thu, 6 Dec 2007 13:50:30 +0100

I wondered about junk bytes at the end when using "lbsdebug +hex +host" until I noticed that firmware for the CF card sends my extranous bytes. It says "I have 20 bytes", I take 20 bytes, but the last 8 bytes of this are just data junk.

Also, in the new lbs_cmd() where was a size miscalulation that made itself clear after fixing this bug.

---
 drivers/net/wireless/libertas/cmdresp.c |    2 +-
 drivers/net/wireless/libertas/if_cs.c   |    3 +++
 2 files changed, 4 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmdresp.c +0 -0
index 6a43de7..22a6973 100644

drivers/net/wireless/libertas/cmdresp.c int lbs_process_rx_command(struct lbs_private *priv) · line 885

Quoted 5 lines
drivers/net/wireless/libertas/cmdresp.c +1 -1
@@ -882,7 +882,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 
 	if (adapter->cur_cmd->pdata_size) {
 		struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
-		u16 sz = cpu_to_le16(resp->size);
+		u16 sz = cpu_to_le16(resp->size) - S_DS_GEN;

Whoops, something's wrong here.
You are subtracting from a LE value.

Quoted 17 lines
drivers/net/wireless/libertas/cmdresp.c +0 -0
 		if (sz > *adapter->cur_cmd->pdata_size) {
 			lbs_pr_err("response 0x%04x doesn't fit into "
 				"buffer (%d > %d)\n", respcmd,
drivers/net/wireless/libertas/if_cs.c +3 -0
index 54b1ba3..8508260 100644
@@ -373,6 +373,9 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
 	if (*len & 1)
 		data[*len-1] = if_cs_read8(priv->card, IF_CS_C_CMD);
 
+	/* This is a workaround for a firmware that reports too much
+	 * bytes */
+	*len -= 8;
 	ret = 0;
 out:
 	lbs_deb_leave_args(LBS_DEB_CS, "ret %d, len %d", ret, *len);
Signature · 1 line
Greetings Michael.
#19 lore raw

Re: [PATCH 14/48] libertas: fix data packet size errors

Quoted 2 lines

Whoops, something's wrong here.
You are subtracting from a LE value.

You're right. Sparse detected that and I later sent a patch that fixed it. See Patch 21/48.

#20 lore raw

Re: [PATCH 14/48] libertas: fix data packet size errors

In reply to Michael Buesch
Quoted 4 lines · Michael Buesch
Quoted 1 line

+ u16 sz = cpu_to_le16(resp->size) - S_DS_GEN;

Whoops, something's wrong here.
You are subtracting from a LE value.

It should have been le16_to_cpu(), not cpu_to_le16(). It works as it is on all real hardware, although it makes sparse unhappy. Holger later fixed a bunch of such things (including this one along with some _real_ errors) in patch #21.

Signature · 1 line
dwmw2
#21 lore raw

PATCH 15/48 libertas: Use lbs_cmd() for setting Boot2 version

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 12:51:00 +0000

---
 drivers/net/wireless/libertas/if_usb.c |   20 ++++++++++++++++----
 1 files changed, 16 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/if_usb.c +16 -4
index f858928..4d89fd0 100644
@@ -101,6 +101,21 @@ static void if_usb_free(struct usb_card_rec *cardp)
 	lbs_deb_leave(LBS_DEB_USB);
 }
 
+static void if_usb_set_boot2_ver(struct lbs_private *priv)
+{
+	struct cmd_ds_set_boot2_ver b2_cmd;
+	int rsp_len = sizeof(b2_cmd);
+
+	b2_cmd.action = 0;
+	b2_cmd.version = cpu_to_le16(priv->boot2_version);
+
+	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd),
+		    &b2_cmd, &rsp_len)) {
+		lbs_deb_usb("Setting boot2 version failed\n");
+	}
+}
+
+
 /**
  *  @brief sets the configuration values
  *  @param ifnum	interface number
@@ -222,10 +237,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	if (lbs_start_card(priv))
 		goto err_start_card;
 
-	/* Set the boot2 version in firmware, ignoring errors. */
-	(void)lbs_prepare_and_send_command(priv, CMD_SET_BOOT2_VER,
-					   0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
+	if_usb_set_boot2_ver(priv);
 
 	usb_get_dev(udev);
 	usb_set_intfdata(intf, cardp);
Signature · 1 line
1.5.3.4
#22 lore raw

PATCH 16/48 libertas: Remove SET_BOOT2_VER support from the Big Switch Statement.

In reply to David Woodhouse

Date: Thu, 6 Dec 2007 14:44:21 +0000

And the death of libertas_prepare_and_send_command() starts...

---
 drivers/net/wireless/libertas/cmd.c |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)
drivers/net/wireless/libertas/cmd.c +0 -15
index 851eb3c..b1ea878 100644
@@ -974,17 +974,6 @@ static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
 	return 0;
 }
 
-static int lbs_cmd_set_boot2_ver(struct lbs_private *priv,
-				struct cmd_ds_command *cmd,
-				u16 cmd_action, void *pdata_buf)
-{
-	struct cmd_ds_set_boot2_ver *boot2_ver = &cmd->params.boot2_ver;
-	cmd->command = cpu_to_le16(CMD_SET_BOOT2_VER);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_set_boot2_ver) + S_DS_GEN);
-	boot2_ver->version = priv->boot2_version;
-	return 0;
-}
-
 /*
  * Note: NEVER use lbs_queue_cmd() with addtail==0 other than for
  * the command timer, because it does not account for queued commands.
@@ -1470,10 +1459,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		ret = lbs_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf);
 		break;
 
-	case CMD_SET_BOOT2_VER:
-		ret = lbs_cmd_set_boot2_ver(priv, cmdptr, cmd_action, pdata_buf);
-		break;
-
 	case CMD_GET_TSF:
 		cmdptr->command = cpu_to_le16(CMD_GET_TSF);
 		cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
Signature · 1 line
1.5.3.4
#23 lore raw

PATCH 17/48 libertas: Fix endianness in boot2_version handling.

In reply to David Woodhouse

Date: Fri, 7 Dec 2007 12:56:45 +0000

We read it from the card. We byte-swap it. We write it back to the card. D'oh.

---
 drivers/net/wireless/libertas/if_usb.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/if_usb.c +1 -1
index 4d89fd0..d5fc7d7 100644
@@ -227,7 +227,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	priv->hw_host_to_card = if_usb_host_to_card;
 	priv->hw_get_int_status = if_usb_get_int_status;
 	priv->hw_read_event_cause = if_usb_read_event_cause;
-	priv->boot2_version = udev->descriptor.bcdDevice;
+	priv->boot2_version = le16_to_cpu(udev->descriptor.bcdDevice);
 
 	/* Delay 200 ms to waiting for the FW ready */
 	if_usb_submit_rx_urb(cardp);
Signature · 1 line
1.5.3.4
#24 lore raw

PATCH 18/48 libertas: implement new scanning logic

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Fri, 7 Dec 2007 16:52:10 +0100

This changes the code that is used for scanning and makes it hopefully easier to understand:

* move function into logical blocks
* create a bunch of lbs_scan_add_XXXX_tlv() functions, that help to create the TLV parameter of CMD_802_11_SCAN
* all of them are now called from the much simpler lbs_do_scan()
* no **puserscancfg double-pointers :-)

---
 drivers/net/wireless/libertas/dev.h  |    3 +-
 drivers/net/wireless/libertas/scan.c |  871 ++++++++++++++--------------------
 2 files changed, 361 insertions(+), 513 deletions(-)
drivers/net/wireless/libertas/dev.h +1 -2
index 1efea63..96a34c5 100644
@@ -366,9 +366,8 @@ struct lbs_adapter {
 	struct cmd_ds_802_11_get_log logmsg;
 
 	u32 monitormode;
+	int last_scanned_channel;
 	u8 fw_ready;
-
-	u8 last_scanned_channel;
 };
 
 #endif
drivers/net/wireless/libertas/scan.c +360 -511

1,206 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#25 lore raw

PATCH 19/48 libertas: when usb_submit_usb fails, include the error code in the printk

In reply to David Woodhouse

Date: Fri, 7 Dec 2007 15:12:26 +0000

---
 drivers/net/wireless/libertas/if_usb.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/if_usb.c +2 -2
index d5fc7d7..e9190a6 100644
@@ -424,7 +424,7 @@ static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
 
 	if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
 		/*  transfer failed */
-		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed\n");
+		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
 		ret = -1;
 	} else {
 		/* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
@@ -462,7 +462,7 @@ static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
 	/* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
 	if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
 		/* handle failure conditions */
-		lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed\n");
+		lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
 		kfree_skb(skb);
 		rinfo->skb = NULL;
 		ret = -1;
Signature · 1 line
1.5.3.4
#26 lore raw

PATCH 20/48 libertas: Switch to using a callback function pointer for commands

In reply to David Woodhouse

Date: Fri, 7 Dec 2007 15:13:05 +0000

---
 drivers/net/wireless/libertas/cmd.c     |   31 +++++++++++++++++++++++++------
 drivers/net/wireless/libertas/cmdresp.c |   23 ++++++++---------------
 drivers/net/wireless/libertas/hostcmd.h |    1 +
 3 files changed, 34 insertions(+), 21 deletions(-)
drivers/net/wireless/libertas/cmd.c +25 -6
index b1ea878..ebfcb7b 100644
@@ -1659,7 +1659,8 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
 	wake_up_interruptible(&ptempnode->cmdwait_q);
 	ptempnode->wait_option = 0;
 	ptempnode->pdata_buf = NULL;
-	ptempnode->pdata_size = 0;
+	ptempnode->pdata_size = NULL;
+	ptempnode->callback = NULL;
 
 	if (ptempnode->bufvirtualaddr != NULL)
 		memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
@@ -1687,7 +1688,8 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 
 	ptempnode->wait_option = wait_option;
 	ptempnode->pdata_buf = pdata_buf;
-	ptempnode->pdata_size = 0;
+	ptempnode->pdata_size = NULL;
+	ptempnode->callback = NULL;
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
@@ -2012,10 +2014,26 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  *  @return 	   	-1 in case of a higher level error, otherwise
  *                      the result code from the firmware
  */
-int lbs_cmd(struct lbs_private *priv,
-	u16 command,
-	void *cmd, int cmd_size,
-	void *rsp, int *rsp_size)
+
+static int lbs_cmd_callback(uint16_t respcmd, struct cmd_ds_command *resp, struct lbs_private *priv)
+{ 
+	struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
+	struct lbs_adapter *adapter = priv->adapter;
+	u16 sz = cpu_to_le16(resp->size) - S_DS_GEN;
+
+	if (sz > *adapter->cur_cmd->pdata_size) {
+		lbs_pr_err("response 0x%04x doesn't fit into buffer (%d > %d)\n",
+			   respcmd, sz, *adapter->cur_cmd->pdata_size);
+		sz = *adapter->cur_cmd->pdata_size;
+	}
+	memcpy(adapter->cur_cmd->pdata_buf, r->cmdresp, sz);
+	*adapter->cur_cmd->pdata_size = sz;
+
+	return 0;
+}
+
+int lbs_cmd(struct lbs_private *priv, u16 command, void *cmd, int cmd_size,
+	    void *rsp, int *rsp_size)
 {
 	struct lbs_adapter *adapter = priv->adapter;
 	struct cmd_ctrl_node *cmdnode;
@@ -2053,6 +2071,7 @@ int lbs_cmd(struct lbs_private *priv,
 	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
 	cmdnode->pdata_buf = rsp;
 	cmdnode->pdata_size = rsp_size;
+	cmdnode->callback = lbs_cmd_callback;
 
 	/* Set sequence number, clean result, move to buffer */
 	adapter->seqnum++;
drivers/net/wireless/libertas/cmdresp.c +8 -15
index 22a6973..20ca38c 100644
@@ -880,22 +880,15 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		goto done;
 	}
 
-	if (adapter->cur_cmd->pdata_size) {
-		struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
-		u16 sz = cpu_to_le16(resp->size) - S_DS_GEN;
-		if (sz > *adapter->cur_cmd->pdata_size) {
-			lbs_pr_err("response 0x%04x doesn't fit into "
-				"buffer (%d > %d)\n", respcmd,
-				sz, *adapter->cur_cmd->pdata_size);
-			sz = *adapter->cur_cmd->pdata_size;
-		}
-		memcpy(adapter->cur_cmd->pdata_buf, r->cmdresp, sz);
-		*adapter->cur_cmd->pdata_size = sz;
-	} else {
-		spin_unlock_irqrestore(&adapter->driver_lock, flags);
+	spin_unlock_irqrestore(&adapter->driver_lock, flags);
+
+	if (adapter->cur_cmd && adapter->cur_cmd->callback)
+		ret = adapter->cur_cmd->callback(respcmd, resp, priv);
+	else
 		ret = handle_cmd_response(respcmd, resp, priv);
-		spin_lock_irqsave(&adapter->driver_lock, flags);
-	}
+
+	spin_lock_irqsave(&adapter->driver_lock, flags);
+
 	if (adapter->cur_cmd) {
 		/* Clean up and Put current command back to cmdfreeq */
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
drivers/net/wireless/libertas/hostcmd.h +1 -0
index be69ae6..5ef65ae 100644
@@ -72,6 +72,7 @@ struct cmd_ctrl_node {
 	/* command response */
 	void *pdata_buf;
 	int *pdata_size;
+	int (*callback)(uint16_t respcmd, struct cmd_ds_command *resp, struct lbs_private *priv);
 	/* command data */
 	u8 *bufvirtualaddr;
 	/* wait queue */
Signature · 1 line
1.5.3.4
#27 lore raw

PATCH 21/48 libertas: endianness fixes

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Fri, 7 Dec 2007 15:30:44 +0000

Recently I found that that sparse by default doesn't endianness checks. So I changed my compilation habit to be

make modules C=1 SUBDIRS=drivers/net/wireless/libertas CHECKFLAGS="-D__CHECK_ENDIAN__"

so that I get the little-endian checks from sparse as well. That showed up a good bunch of problems.

---
 drivers/net/wireless/libertas/11d.c     |    2 +-
 drivers/net/wireless/libertas/cmd.c     |   28 ++++++++++++++--------------
 drivers/net/wireless/libertas/cmdresp.c |    2 +-
 drivers/net/wireless/libertas/hostcmd.h |    8 ++++----
 drivers/net/wireless/libertas/if_sdio.c |    2 +-
 drivers/net/wireless/libertas/if_usb.c  |    4 ++--
 6 files changed, 23 insertions(+), 23 deletions(-)
drivers/net/wireless/libertas/11d.c +1 -1
index 377dcb5..013965d 100644
@@ -518,7 +518,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
 		cmd->size =
 		    cpu_to_le16(sizeof(pdomaininfo->action) + S_DS_GEN);
 		lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
-			(int)(cmd->size));
+			le16_to_cpu(cmd->size));
 		goto done;
 	}
 
drivers/net/wireless/libertas/cmd.c +14 -14
index ebfcb7b..cf1ab8a 100644
@@ -431,7 +431,7 @@ static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
 		u8 mode = (u8) (size_t) pdata_buf;
 		pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
 		pSNMPMIB->oid = cpu_to_le16((u16) DESIRED_BSSTYPE_I);
-		pSNMPMIB->bufsize = sizeof(u8);
+		pSNMPMIB->bufsize = cpu_to_le16(sizeof(u8));
 		if (mode == IW_MODE_ADHOC) {
 			ucTemp = SNMP_MIB_VALUE_ADHOC;
 		} else {
@@ -451,8 +451,8 @@ static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
 			pSNMPMIB->oid = cpu_to_le16((u16) DOT11D_I);
 
 			if (cmd_action == CMD_ACT_SET) {
-				pSNMPMIB->querytype = CMD_ACT_SET;
-				pSNMPMIB->bufsize = sizeof(u16);
+				pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_SET);
+				pSNMPMIB->bufsize = cpu_to_le16(sizeof(u16));
 				ulTemp = *(u32 *)pdata_buf;
 				*((__le16 *)(pSNMPMIB->value)) =
 				    cpu_to_le16((u16) ulTemp);
@@ -484,7 +484,7 @@ static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv,
 		{
 
 			u32 ulTemp;
-			pSNMPMIB->oid = le16_to_cpu((u16) RTSTHRESH_I);
+			pSNMPMIB->oid = cpu_to_le16(RTSTHRESH_I);
 
 			if (cmd_action == CMD_ACT_GET) {
 				pSNMPMIB->querytype = cpu_to_le16(CMD_ACT_GET);
@@ -759,7 +759,7 @@ static int lbs_cmd_reg_access(struct lbs_private *priv,
 
 	offval = (struct lbs_offset_value *)pdata_buf;
 
-	switch (cmdptr->command) {
+	switch (le16_to_cpu(cmdptr->command)) {
 	case CMD_MAC_REG_ACCESS:
 		{
 			struct cmd_ds_mac_reg_access *macreg;
@@ -999,7 +999,7 @@ void lbs_queue_cmd(struct lbs_adapter *adapter,
 	}
 
 	/* Exit_PS command needs to be queued in the header always. */
-	if (cmdptr->command == CMD_802_11_PS_MODE) {
+	if (le16_to_cpu(cmdptr->command) == CMD_802_11_PS_MODE) {
 		struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
 		if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
 			if (adapter->psstate != PS_STATE_FULL_POWER)
@@ -1062,15 +1062,14 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 	adapter->cur_cmd_retcode = 0;
 	spin_unlock_irqrestore(&adapter->driver_lock, flags);
 
-	cmdsize = cmdptr->size;
-	command = cpu_to_le16(cmdptr->command);
+	cmdsize = le16_to_cpu(cmdptr->size);
+	command = le16_to_cpu(cmdptr->command);
 
 	lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n",
-		    command, le16_to_cpu(cmdptr->size), jiffies);
+		    command, cmdsize, jiffies);
 	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", cmdnode->bufvirtualaddr, cmdsize);
 
 	cmdnode->cmdwaitqwoken = 0;
-	cmdsize = cpu_to_le16(cmdsize);
 
 	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
 
@@ -1426,9 +1425,10 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 
 #define ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN 8
 			cmdptr->size =
-			    cpu_to_le16(gpio->header.len + S_DS_GEN +
-					     ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
-			gpio->header.len = cpu_to_le16(gpio->header.len);
+			    cpu_to_le16(le16_to_cpu(gpio->header.len)
+				+ S_DS_GEN
+				+ ACTION_NUMLED_TLVTYPE_LEN_FIELDS_LEN);
+			gpio->header.len = gpio->header.len;
 
 			ret = 0;
 			break;
@@ -2019,7 +2019,7 @@ static int lbs_cmd_callback(uint16_t respcmd, struct cmd_ds_command *resp, struc
 { 
 	struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
 	struct lbs_adapter *adapter = priv->adapter;
-	u16 sz = cpu_to_le16(resp->size) - S_DS_GEN;
+	u16 sz = le16_to_cpu(resp->size) - S_DS_GEN;
 
 	if (sz > *adapter->cur_cmd->pdata_size) {
 		lbs_pr_err("response 0x%04x doesn't fit into buffer (%d > %d)\n",
drivers/net/wireless/libertas/cmdresp.c +1 -1
index 20ca38c..f6c1016 100644
@@ -561,7 +561,7 @@ static int lbs_ret_802_11_subscribe_event(struct lbs_private *priv,
 	lbs_deb_enter(LBS_DEB_CMD);
 
 	if (dst_event->action == cpu_to_le16(CMD_ACT_GET)) {
-		dst_event->events = le16_to_cpu(cmd_event->events);
+		dst_event->events = cmd_event->events;
 		memcpy(dst_event->tlv, cmd_event->tlv, sizeof(dst_event->tlv));
 	}
 
drivers/net/wireless/libertas/hostcmd.h +4 -4
index 5ef65ae..efdb720 100644
@@ -419,13 +419,13 @@ struct cmd_ds_802_11_rf_antenna {
 };
 
 struct cmd_ds_802_11_monitor_mode {
-	u16 action;
-	u16 mode;
+	__le16 action;
+	__le16 mode;
 };
 
 struct cmd_ds_set_boot2_ver {
-	u16 action;
-	u16 version;
+	__le16 action;
+	__le16 version;
 };
 
 struct cmd_ds_802_11_ps_mode {
drivers/net/wireless/libertas/if_sdio.c +1 -1
index 0f0296b..6f5a517 100644
@@ -454,7 +454,7 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
 
 		chunk_size = min(size, (size_t)60);
 
-		*((u32*)chunk_buffer) = cpu_to_le32(chunk_size);
+		*((__le32*)chunk_buffer) = cpu_to_le32(chunk_size);
 		memcpy(chunk_buffer + 4, firmware, chunk_size);
 /*
 		lbs_deb_sdio("sending %d bytes chunk\n", chunk_size);
drivers/net/wireless/libertas/if_usb.c +2 -2
index e9190a6..a17371f 100644
@@ -107,7 +107,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 	int rsp_len = sizeof(b2_cmd);
 
 	b2_cmd.action = 0;
-	b2_cmd.version = cpu_to_le16(priv->boot2_version);
+	b2_cmd.version = priv->boot2_version;
 
 	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd),
 		    &b2_cmd, &rsp_len)) {
@@ -227,7 +227,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	priv->hw_host_to_card = if_usb_host_to_card;
 	priv->hw_get_int_status = if_usb_get_int_status;
 	priv->hw_read_event_cause = if_usb_read_event_cause;
-	priv->boot2_version = le16_to_cpu(udev->descriptor.bcdDevice);
+	priv->boot2_version = udev->descriptor.bcdDevice;
 
 	/* Delay 200 ms to waiting for the FW ready */
 	if_usb_submit_rx_urb(cardp);
Signature · 1 line
1.5.3.4
#28 lore raw

PATCH 22/48 libertas: Don't set IW_ENCODE_NOKEY when returning WEP keys.

In reply to David Woodhouse

Date: Fri, 7 Dec 2007 19:32:12 +0000

Also clean up the double setting/clearing of IW_ENCODE_DISABLED.

---
 drivers/net/wireless/libertas/wext.c |   11 +----------
 1 files changed, 1 insertions(+), 10 deletions(-)
drivers/net/wireless/libertas/wext.c +1 -10
index b8c93c0..1af140b 100644
@@ -1122,14 +1122,6 @@ static int lbs_get_encode(struct net_device *dev,
 		break;
 	}
 
-	if (   adapter->secinfo.wep_enabled
-	    || adapter->secinfo.WPAenabled
-	    || adapter->secinfo.WPA2enabled) {
-		dwrq->flags &= ~IW_ENCODE_DISABLED;
-	} else {
-		dwrq->flags |= IW_ENCODE_DISABLED;
-	}
-
 	memset(extra, 0, 16);
 
 	mutex_lock(&adapter->lock);
@@ -1150,14 +1142,13 @@ static int lbs_get_encode(struct net_device *dev,
 		   || (adapter->secinfo.WPA2enabled)) {
 		/* return WPA enabled */
 		dwrq->flags &= ~IW_ENCODE_DISABLED;
+		dwrq->flags |= IW_ENCODE_NOKEY;
 	} else {
 		dwrq->flags |= IW_ENCODE_DISABLED;
 	}
 
 	mutex_unlock(&adapter->lock);
 
-	dwrq->flags |= IW_ENCODE_NOKEY;
-
 	lbs_deb_wext("key: %02x:%02x:%02x:%02x:%02x:%02x, keylen %d\n",
 	       extra[0], extra[1], extra[2],
 	       extra[3], extra[4], extra[5], dwrq->length);
Signature · 1 line
1.5.3.4
#29 lore raw

PATCH 23/48 libertas: Fix up error handling in lbs_setuserscan()

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 00:23:55 +0000

---
 drivers/net/wireless/libertas/debugfs.c |   29 +++++++++++++++++++----------
 1 files changed, 19 insertions(+), 10 deletions(-)
drivers/net/wireless/libertas/debugfs.c +19 -10
index 1d881ae..dde0c37 100644
@@ -292,18 +292,23 @@ static ssize_t lbs_setuserscan(struct file *file,
 	struct lbs_ioctl_user_scan_cfg *scan_cfg;
 	union iwreq_data wrqu;
 	int dur;
-	unsigned long addr = get_zeroed_page(GFP_KERNEL);
-	char *buf = (char *)addr;
+	char *buf = (char *)get_zeroed_page(GFP_KERNEL);
 
-	scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL);
-	if (!scan_cfg)
+	if (!buf)
 		return -ENOMEM;
-
+		
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
 		res = -EFAULT;
-		goto out_unlock;
+		goto out_buf;
+	}
+
+	scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL);
+	if (!scan_cfg) {
+		res = -ENOMEM;
+		goto out_buf;
 	}
+	res = count;
 
 	scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY;
 
@@ -316,15 +321,19 @@ static ssize_t lbs_setuserscan(struct file *file,
 
 	lbs_scan_networks(priv, scan_cfg, 1);
 	wait_event_interruptible(priv->adapter->cmd_pending,
-				 !priv->adapter->nr_cmd_pending);
+				 priv->adapter->surpriseremoved || !priv->adapter->nr_cmd_pending);
+
+	if (priv->adapter->surpriseremoved)
+		goto out_scan_cfg;
 
 	memset(&wrqu, 0x00, sizeof(union iwreq_data));
 	wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
 
-out_unlock:
-	free_page(addr);
+ out_scan_cfg:
 	kfree(scan_cfg);
-	return count;
+ out_buf:
+	free_page((unsigned long)buf);
+	return res;
 }
 
 
Signature · 1 line
1.5.3.4
#30 lore raw

PATCH 24/48 libertas: kill adapter->nr_cmd_pending

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 00:35:00 +0000

---
 drivers/net/wireless/libertas/cmd.c     |    6 ++----
 drivers/net/wireless/libertas/cmdresp.c |    5 -----
 drivers/net/wireless/libertas/debugfs.c |    3 ++-
 drivers/net/wireless/libertas/dev.h     |    1 -
 drivers/net/wireless/libertas/main.c    |    4 +---
 5 files changed, 5 insertions(+), 14 deletions(-)
drivers/net/wireless/libertas/cmd.c +2 -4
index cf1ab8a..092c295 100644
@@ -1009,10 +1009,9 @@ void lbs_queue_cmd(struct lbs_adapter *adapter,
 
 	spin_lock_irqsave(&adapter->driver_lock, flags);
 
-	if (addtail) {
+	if (addtail)
 		list_add_tail(&cmdnode->list, &adapter->cmdpendingq);
-		adapter->nr_cmd_pending++;
-	} else
+	else
 		list_add(&cmdnode->list, &adapter->cmdpendingq);
 
 	spin_unlock_irqrestore(&adapter->driver_lock, flags);
@@ -1078,7 +1077,6 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 		spin_lock_irqsave(&adapter->driver_lock, flags);
 		adapter->cur_cmd_retcode = ret;
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-		adapter->nr_cmd_pending--;
 		adapter->cur_cmd = NULL;
 		spin_unlock_irqrestore(&adapter->driver_lock, flags);
 		goto done;
drivers/net/wireless/libertas/cmdresp.c +0 -5
index f6c1016..44865bf 100644
@@ -791,7 +791,6 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		lbs_deb_host("invalid response!\n");
 		adapter->cur_cmd_retcode = -1;
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-		adapter->nr_cmd_pending--;
 		adapter->cur_cmd = NULL;
 		spin_unlock_irqrestore(&adapter->driver_lock, flags);
 		ret = -1;
@@ -848,7 +847,6 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		}
 
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-		adapter->nr_cmd_pending--;
 		adapter->cur_cmd = NULL;
 		spin_unlock_irqrestore(&adapter->driver_lock, flags);
 
@@ -872,7 +870,6 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		}
 
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-		adapter->nr_cmd_pending--;
 		adapter->cur_cmd = NULL;
 		spin_unlock_irqrestore(&adapter->driver_lock, flags);
 
@@ -892,8 +889,6 @@ int lbs_process_rx_command(struct lbs_private *priv)
 	if (adapter->cur_cmd) {
 		/* Clean up and Put current command back to cmdfreeq */
 		__lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
-		adapter->nr_cmd_pending--;
-		WARN_ON(adapter->nr_cmd_pending > 128);
 		adapter->cur_cmd = NULL;
 	}
 	spin_unlock_irqrestore(&adapter->driver_lock, flags);
drivers/net/wireless/libertas/debugfs.c +2 -1
index dde0c37..341ef67 100644
@@ -321,7 +321,8 @@ static ssize_t lbs_setuserscan(struct file *file,
 
 	lbs_scan_networks(priv, scan_cfg, 1);
 	wait_event_interruptible(priv->adapter->cmd_pending,
-				 priv->adapter->surpriseremoved || !priv->adapter->nr_cmd_pending);
+				 priv->adapter->surpriseremoved || 
+				 (!priv->adapter->cur_cmd && list_empty(&priv->adapter->cmdpendingq)));
 
 	if (priv->adapter->surpriseremoved)
 		goto out_scan_cfg;
drivers/net/wireless/libertas/dev.h +0 -1
index 96a34c5..fb26f18 100644
@@ -231,7 +231,6 @@ struct lbs_adapter {
 	struct list_head cmdpendingq;
 
 	wait_queue_head_t cmd_pending;
-	u8 nr_cmd_pending;
 	/* command related variables protected by adapter->driver_lock */
 
 	/** Async and Sync Event variables */
drivers/net/wireless/libertas/main.c +1 -3
index a5b573c..500357b 100644
@@ -929,14 +929,13 @@ static int lbs_thread(void *data)
 		/* Wake-up command waiters which can't sleep in
 		 * lbs_prepare_and_send_command
 		 */
-		if (!adapter->nr_cmd_pending)
+		if (!list_empty(&adapter->cmdpendingq))
 			wake_up_all(&adapter->cmd_pending);
 
 		lbs_tx_runqueue(priv);
 	}
 
 	del_timer(&adapter->command_timer);
-	adapter->nr_cmd_pending = 0;
 	wake_up_all(&adapter->cmd_pending);
 
 	lbs_deb_leave(LBS_DEB_THREAD);
@@ -1105,7 +1104,6 @@ static int lbs_init_adapter(struct lbs_private *priv)
 
 	spin_lock_init(&adapter->driver_lock);
 	init_waitqueue_head(&adapter->cmd_pending);
-	adapter->nr_cmd_pending = 0;
 
 	/* Allocate the command buffers */
 	if (lbs_allocate_cmd_buffer(priv)) {
Signature · 1 line
1.5.3.4
#31 lore raw

PATCH 25/48 libertas: switch lbs_cmd() to take a callback function pointer

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 00:59:54 +0000

All existing code which sends commands is set up to have some function called with the results, not to get data back. It's more versatile this way, and providing it with a callback function which involves memcpy() is hardly difficult.

---
 drivers/net/wireless/libertas/cmd.c     |   30 ++++--------------------------
 drivers/net/wireless/libertas/decl.h    |    6 ++----
 drivers/net/wireless/libertas/hostcmd.h |    1 -
 drivers/net/wireless/libertas/if_usb.c  |    5 +----
 4 files changed, 7 insertions(+), 35 deletions(-)
drivers/net/wireless/libertas/cmd.c +4 -26
index 092c295..6838c9c 100644
@@ -1657,7 +1657,6 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
 	wake_up_interruptible(&ptempnode->cmdwait_q);
 	ptempnode->wait_option = 0;
 	ptempnode->pdata_buf = NULL;
-	ptempnode->pdata_size = NULL;
 	ptempnode->callback = NULL;
 
 	if (ptempnode->bufvirtualaddr != NULL)
@@ -1686,7 +1685,6 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 
 	ptempnode->wait_option = wait_option;
 	ptempnode->pdata_buf = pdata_buf;
-	ptempnode->pdata_size = NULL;
 	ptempnode->callback = NULL;
 
 	lbs_deb_leave(LBS_DEB_HOST);
@@ -2013,25 +2011,8 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  *                      the result code from the firmware
  */
 
-static int lbs_cmd_callback(uint16_t respcmd, struct cmd_ds_command *resp, struct lbs_private *priv)
-{ 
-	struct cmd_ds_gen *r = (struct cmd_ds_gen *)resp;
-	struct lbs_adapter *adapter = priv->adapter;
-	u16 sz = le16_to_cpu(resp->size) - S_DS_GEN;
-
-	if (sz > *adapter->cur_cmd->pdata_size) {
-		lbs_pr_err("response 0x%04x doesn't fit into buffer (%d > %d)\n",
-			   respcmd, sz, *adapter->cur_cmd->pdata_size);
-		sz = *adapter->cur_cmd->pdata_size;
-	}
-	memcpy(adapter->cur_cmd->pdata_buf, r->cmdresp, sz);
-	*adapter->cur_cmd->pdata_size = sz;
-
-	return 0;
-}
-
-int lbs_cmd(struct lbs_private *priv, u16 command, void *cmd, int cmd_size,
-	    void *rsp, int *rsp_size)
+int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size,
+	    int (*callback)(uint16_t, struct cmd_ds_command *, struct lbs_private *))
 {
 	struct lbs_adapter *adapter = priv->adapter;
 	struct cmd_ctrl_node *cmdnode;
@@ -2040,9 +2021,8 @@ int lbs_cmd(struct lbs_private *priv, u16 command, void *cmd, int cmd_size,
 	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_HOST);
-	lbs_deb_host("rsp at %p, rsp_size at %p\n", rsp, rsp_size);
 
-	if (!adapter || !rsp_size) {
+	if (!adapter) {
 		lbs_deb_host("PREP_CMD: adapter is NULL\n");
 		ret = -1;
 		goto done;
@@ -2067,9 +2047,7 @@ int lbs_cmd(struct lbs_private *priv, u16 command, void *cmd, int cmd_size,
 
 	cmdptr = (struct cmd_ds_gen *)cmdnode->bufvirtualaddr;
 	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
-	cmdnode->pdata_buf = rsp;
-	cmdnode->pdata_size = rsp_size;
-	cmdnode->callback = lbs_cmd_callback;
+	cmdnode->callback = callback;
 
 	/* Set sequence number, clean result, move to buffer */
 	adapter->seqnum++;
drivers/net/wireless/libertas/decl.h +2 -4
index 6f47ff0..1a8fdaa 100644
@@ -24,10 +24,8 @@ void lbs_send_tx_feedback(struct lbs_private *priv);
 
 int lbs_free_cmd_buffer(struct lbs_private *priv);
 
-int lbs_cmd(struct lbs_private *priv,
-	u16 command,
-	void *cmd, int cmd_size,
-	void *resp, int *resp_size);
+int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size, 
+	    int (*callback)(uint16_t, struct cmd_ds_command *, struct lbs_private *));
 
 int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_no,
drivers/net/wireless/libertas/hostcmd.h +0 -1
index efdb720..f1c1d3f 100644
@@ -71,7 +71,6 @@ struct cmd_ctrl_node {
 	u16 wait_option;
 	/* command response */
 	void *pdata_buf;
-	int *pdata_size;
 	int (*callback)(uint16_t respcmd, struct cmd_ds_command *resp, struct lbs_private *priv);
 	/* command data */
 	u8 *bufvirtualaddr;
drivers/net/wireless/libertas/if_usb.c +1 -4
index a17371f..7c4bd8d 100644
@@ -104,15 +104,12 @@ static void if_usb_free(struct usb_card_rec *cardp)
 static void if_usb_set_boot2_ver(struct lbs_private *priv)
 {
 	struct cmd_ds_set_boot2_ver b2_cmd;
-	int rsp_len = sizeof(b2_cmd);
 
 	b2_cmd.action = 0;
 	b2_cmd.version = priv->boot2_version;
 
-	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd),
-		    &b2_cmd, &rsp_len)) {
+	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd), NULL))
 		lbs_deb_usb("Setting boot2 version failed\n");
-	}
 }
 
 
Signature · 1 line
1.5.3.4
#32 lore raw

PATCH 26/48 libertas: clean up lbs_thread() to make it slightly more readable

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 17:42:59 +0000

No semantic changes.

---
 drivers/net/wireless/libertas/main.c |   92 +++++++++++++--------------------
 1 files changed, 36 insertions(+), 56 deletions(-)
drivers/net/wireless/libertas/main.c +36 -56
index 500357b..f595664 100644
@@ -795,70 +795,60 @@ static int lbs_thread(void *data)
 	init_waitqueue_entry(&wait, current);
 
 	set_freezable();
+
 	for (;;) {
-		lbs_deb_thread( "main-thread 111: intcounter=%d "
-		       "currenttxskb=%p dnld_sent=%d\n",
-		       adapter->intcounter,
-		       adapter->currenttxskb, priv->dnld_sent);
+		lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+				adapter->intcounter, adapter->currenttxskb, priv->dnld_sent);
 
 		add_wait_queue(&priv->waitq, &wait);
 		set_current_state(TASK_INTERRUPTIBLE);
 		spin_lock_irq(&adapter->driver_lock);
+
 		if ((adapter->psstate == PS_STATE_SLEEP) ||
-		    (!adapter->intcounter
-		     && (priv->dnld_sent || adapter->cur_cmd ||
-			 list_empty(&adapter->cmdpendingq)))) {
-			lbs_deb_thread(
-			       "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
-			       adapter->connect_status, adapter->intcounter,
-			       adapter->psmode, adapter->psstate);
+		    (!adapter->intcounter && (priv->dnld_sent || adapter->cur_cmd || list_empty(&adapter->cmdpendingq)))) {
+			lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
+				       adapter->connect_status, adapter->intcounter,
+				       adapter->psmode, adapter->psstate);
 			spin_unlock_irq(&adapter->driver_lock);
 			schedule();
 		} else
 			spin_unlock_irq(&adapter->driver_lock);
 
-		lbs_deb_thread(
-		       "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
-		       "dnld_sent=%d\n", adapter->intcounter,
-		       adapter->currenttxskb, priv->dnld_sent);
+		lbs_deb_thread("main-thread 222 (waking up): intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+			       adapter->intcounter, adapter->currenttxskb, priv->dnld_sent);
 
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(&priv->waitq, &wait);
 		try_to_freeze();
 
-		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "
-		       "dnld_sent=%d\n",
-		       adapter->intcounter,
-		       adapter->currenttxskb, priv->dnld_sent);
+		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+			       adapter->intcounter, adapter->currenttxskb, priv->dnld_sent);
 
-		if (kthread_should_stop()
-		    || adapter->surpriseremoved) {
-			lbs_deb_thread(
-			       "main-thread: break from main thread: surpriseremoved=0x%x\n",
-			       adapter->surpriseremoved);
+		if (kthread_should_stop() || adapter->surpriseremoved) {
+			lbs_deb_thread("main-thread: break from main thread: surpriseremoved=0x%x\n",
+				       adapter->surpriseremoved);
 			break;
 		}
 
 
 		spin_lock_irq(&adapter->driver_lock);
+
 		if (adapter->intcounter) {
 			u8 int_status;
+
 			adapter->intcounter = 0;
 			int_status = priv->hw_get_int_status(priv, &ireg);
 
 			if (int_status) {
-				lbs_deb_thread(
-				       "main-thread: reading HOST_INT_STATUS_REG failed\n");
+				lbs_deb_thread("main-thread: reading HOST_INT_STATUS_REG failed\n");
 				spin_unlock_irq(&adapter->driver_lock);
 				continue;
 			}
 			adapter->hisregcpy |= ireg;
 		}
 
-		lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "
-		       "dnld_sent=%d\n",
-		       adapter->intcounter,
-		       adapter->currenttxskb, priv->dnld_sent);
+		lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
+			       adapter->intcounter, adapter->currenttxskb, priv->dnld_sent);
 
 		/* command response? */
 		if (adapter->hisregcpy & MRVDRV_CMD_UPLD_RDY) {
@@ -877,8 +867,7 @@ static int lbs_thread(void *data)
 			adapter->hisregcpy &= ~MRVDRV_CARDEVENT;
 
 			if (priv->hw_read_event_cause(priv)) {
-				lbs_pr_alert(
-				       "main-thread: hw_read_event_cause failed\n");
+				lbs_pr_alert("main-thread: hw_read_event_cause failed\n");
 				spin_unlock_irq(&adapter->driver_lock);
 				continue;
 			}
@@ -888,30 +877,21 @@ static int lbs_thread(void *data)
 			spin_unlock_irq(&adapter->driver_lock);
 
 		/* Check if we need to confirm Sleep Request received previously */
-		if (adapter->psstate == PS_STATE_PRE_SLEEP) {
-			if (!priv->dnld_sent && !adapter->cur_cmd) {
-				if (adapter->connect_status ==
-				    LBS_CONNECTED) {
-					lbs_deb_thread(
-					       "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "
-					       "dnld_sent=%d cur_cmd=%p, confirm now\n",
-					       adapter->intcounter,
-					       adapter->currenttxskb,
-					       priv->dnld_sent,
-					       adapter->cur_cmd);
-
-					lbs_ps_confirm_sleep(priv,
-						       (u16) adapter->psmode);
-				} else {
-					/* workaround for firmware sending
-					 * deauth/linkloss event immediately
-					 * after sleep request, remove this
-					 * after firmware fixes it
-					 */
-					adapter->psstate = PS_STATE_AWAKE;
-					lbs_pr_alert(
-					       "main-thread: ignore PS_SleepConfirm in non-connected state\n");
-				}
+		if (adapter->psstate == PS_STATE_PRE_SLEEP &&
+		    !priv->dnld_sent && !adapter->cur_cmd) {
+			if (adapter->connect_status == LBS_CONNECTED) {
+				lbs_deb_thread("main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p dnld_sent=%d cur_cmd=%p, confirm now\n",
+					       adapter->intcounter, adapter->currenttxskb, priv->dnld_sent, adapter->cur_cmd);
+
+				lbs_ps_confirm_sleep(priv, (u16) adapter->psmode);
+			} else {
+				/* workaround for firmware sending
+				 * deauth/linkloss event immediately
+				 * after sleep request; remove this
+				 * after firmware fixes it
+				 */
+				adapter->psstate = PS_STATE_AWAKE;
+				lbs_pr_alert("main-thread: ignore PS_SleepConfirm in non-connected state\n");
 			}
 		}
 
Signature · 1 line
1.5.3.4
#33 lore raw

PATCH 27/48 libertas: fix lbs_rtap attribute in sysfs

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 18:29:16 +0000

At least it doesn't oops when you attempt to read or write it now. Only when you enable it and then later turn it off. And when it's enabled I don't see how it actually works.

But one fewer oops is good, for now...

---
 drivers/net/wireless/libertas/dev.h  |    2 --
 drivers/net/wireless/libertas/main.c |   18 ++++++------------
 2 files changed, 6 insertions(+), 14 deletions(-)
drivers/net/wireless/libertas/dev.h +0 -2
index fb26f18..5cb2923 100644
@@ -143,8 +143,6 @@ struct lbs_private {
 	   all other bits reserved 0 */
 	u8 dnld_sent;
 
-	struct device *hotplug_device;
-
 	/** thread to service interrupts */
 	struct task_struct *main_thread;
 	wait_queue_head_t waitq;
drivers/net/wireless/libertas/main.c +6 -12
index f595664..d03a2f8 100644
@@ -256,8 +256,7 @@ void lbs_remove_rtap(struct lbs_private *priv);
 static ssize_t lbs_rtap_get(struct device *dev,
 		struct device_attribute *attr, char * buf)
 {
-	struct lbs_private *priv = (struct lbs_private *)
-		(to_net_dev(dev))->priv;
+	struct lbs_private *priv = to_net_dev(dev)->priv;
 	struct lbs_adapter *adapter = priv->adapter;
 	return snprintf(buf, 5, "0x%X\n", adapter->monitormode);
 }
@@ -269,8 +268,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
 		struct device_attribute *attr, const char * buf, size_t count)
 {
 	int monitor_mode;
-	struct lbs_private *priv = (struct lbs_private *)
-		(to_net_dev(dev))->priv;
+	struct lbs_private *priv = to_net_dev(dev)->priv;
 	struct lbs_adapter *adapter = priv->adapter;
 
 	sscanf(buf, "%x", &monitor_mode);
@@ -1158,7 +1156,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 	priv->card = card;
 	priv->mesh_open = 0;
 	priv->infra_open = 0;
-	priv->hotplug_device = dmdev;
 
 	/* Setup the OS Interface to our functions */
 	dev->open = lbs_open;
@@ -1178,15 +1175,13 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 	SET_NETDEV_DEV(dev, dmdev);
 
 	priv->rtap_net_dev = NULL;
-	if (device_create_file(dmdev, &dev_attr_lbs_rtap))
-		goto err_init_adapter;
 
 	lbs_deb_thread("Starting main thread...\n");
 	init_waitqueue_head(&priv->waitq);
 	priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
 	if (IS_ERR(priv->main_thread)) {
 		lbs_deb_thread("Error creating main thread.\n");
-		goto err_kthread_run;
+		goto err_init_adapter;
 	}
 
 	priv->work_thread = create_singlethread_workqueue("lbs_worker");
@@ -1196,9 +1191,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 
 	goto done;
 
-err_kthread_run:
-	device_remove_file(dmdev, &dev_attr_lbs_rtap);
-
 err_init_adapter:
 	lbs_free_adapter(priv);
 
@@ -1224,7 +1216,7 @@ int lbs_remove_card(struct lbs_private *priv)
 	lbs_remove_rtap(priv);
 
 	dev = priv->dev;
-	device_remove_file(priv->hotplug_device, &dev_attr_lbs_rtap);
+	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
 
 	cancel_delayed_work(&priv->scan_work);
 	cancel_delayed_work(&priv->assoc_work);
@@ -1273,6 +1265,8 @@ int lbs_start_card(struct lbs_private *priv)
 		lbs_pr_err("cannot register ethX device\n");
 		goto done;
 	}
+	if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
+		lbs_pr_err("cannot register lbs_rtap attribute\n");
 
 	lbs_debugfs_init_one(priv, dev);
 
Signature · 1 line
1.5.3.4
#34 lore raw

PATCH 28/48 libertas: kill TxLockFlag

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 19:46:19 +0000

We don't need this. We can use adapter->currenttxskb instead.

---
 drivers/net/wireless/libertas/dev.h  |    1 -
 drivers/net/wireless/libertas/main.c |   25 ++++++++++++++++++++++---
 drivers/net/wireless/libertas/tx.c   |    9 +++------
 3 files changed, 25 insertions(+), 10 deletions(-)
drivers/net/wireless/libertas/dev.h +0 -1
index 5cb2923..eaa45d4 100644
@@ -285,7 +285,6 @@ struct lbs_adapter {
 
 	/** Tx-related variables (for single packet tx) */
 	struct sk_buff *currenttxskb;
-	u16 TxLockFlag;
 
 	/** NIC Operation characteristics */
 	u16 currentpacketfilter;
drivers/net/wireless/libertas/main.c +22 -3
index d03a2f8..7155f48 100644
@@ -290,8 +290,14 @@ static ssize_t lbs_rtap_set(struct device *dev,
 			return strlen(buf);
 		adapter->monitormode = LBS_MONITOR_OFF;
 		lbs_remove_rtap(priv);
-		netif_wake_queue(priv->dev);
-		netif_wake_queue(priv->mesh_dev);
+
+		if (adapter->currenttxskb) {
+			dev_kfree_skb_any(adapter->currenttxskb);
+			adapter->currenttxskb = NULL;
+		}
+
+		/* Wake queues, command thread, etc. */
+		lbs_host_to_card_done(priv);
 	}
 
 	lbs_prepare_and_send_command(priv,
@@ -521,7 +527,15 @@ static int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	lbs_deb_enter(LBS_DEB_TX);
 
-	if (priv->dnld_sent || priv->adapter->TxLockFlag) {
+	/* We could return NETDEV_TX_BUSY here, but I'd actually 
+	   like to get the point where we can BUG() */
+	if (priv->dnld_sent) {
+		lbs_pr_err("%s while dnld_sent\n", __func__);
+		priv->stats.tx_dropped++;
+		goto done;
+	}
+	if (priv->adapter->currenttxskb) {
+		lbs_pr_err("%s while TX skb pending\n", __func__);
 		priv->stats.tx_dropped++;
 		goto done;
 	}
@@ -624,6 +638,11 @@ void lbs_host_to_card_done(struct lbs_private *priv)
 	if (!adapter->cur_cmd)
 		wake_up_interruptible(&priv->waitq);
 
+	/* Don't wake netif queues if we're in monitor mode and
+	   a TX packet is already pending. */
+	if (priv->adapter->currenttxskb)
+		return;
+
 	if (priv->dev && adapter->connect_status == LBS_CONNECTED)
 		netif_wake_queue(priv->dev);
 
drivers/net/wireless/libertas/tx.c +3 -6
index b423ce1..131ef3f 100644
@@ -152,11 +152,11 @@ done:
 		netif_stop_queue(priv->dev);
 		if (priv->mesh_dev)
 			netif_stop_queue(priv->mesh_dev);
-		/* freeze any packets already in our queues */
-		priv->adapter->TxLockFlag = 1;
+
+		/* Keep the skb around for when we get feedback */
+		priv->adapter->currenttxskb = skb;
 	} else {
 		dev_kfree_skb_any(skb);
-		priv->adapter->currenttxskb = NULL;
 	}
 
 	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
@@ -227,8 +227,6 @@ int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
 		return ret;
 	}
 
-	priv->adapter->currenttxskb = skb;
-
 	ret = SendSinglePacket(priv, skb);
 done:
 	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
@@ -272,7 +270,6 @@ void lbs_send_tx_feedback(struct lbs_private *priv)
 	    (1 + adapter->txretrycount - try_count) : 0;
 	lbs_upload_rx_packet(priv, adapter->currenttxskb);
 	adapter->currenttxskb = NULL;
-	priv->adapter->TxLockFlag = 0;
 
 	if (adapter->connect_status == LBS_CONNECTED)
 		netif_wake_queue(priv->dev);
Signature · 1 line
1.5.3.4
#35 lore raw

PATCH 29/48 libertas: kill struct lbs_adapter

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 20:04:36 +0000

There seems to be no reason for a separate structure; move it all into struct lbs_private.

---
 drivers/net/wireless/libertas/11d.c     |   68 +++---
 drivers/net/wireless/libertas/assoc.c   |  136 ++++++------
 drivers/net/wireless/libertas/assoc.h   |    2 +-
 drivers/net/wireless/libertas/cmd.c     |  278 +++++++++++------------
 drivers/net/wireless/libertas/cmdresp.c |  336 +++++++++++++---------------
 drivers/net/wireless/libertas/debugfs.c |   56 +++---
 drivers/net/wireless/libertas/decl.h    |    7 +-
 drivers/net/wireless/libertas/dev.h     |   97 ++++----
 drivers/net/wireless/libertas/ethtool.c |   19 +-
 drivers/net/wireless/libertas/if_cs.c   |   21 +-
 drivers/net/wireless/libertas/if_sdio.c |   20 +-
 drivers/net/wireless/libertas/if_usb.c  |   27 +--
 drivers/net/wireless/libertas/join.c    |  150 ++++++-------
 drivers/net/wireless/libertas/main.c    |  326 ++++++++++++---------------
 drivers/net/wireless/libertas/rx.c      |   78 +++----
 drivers/net/wireless/libertas/scan.c    |  188 ++++++++--------
 drivers/net/wireless/libertas/scan.h    |    6 +-
 drivers/net/wireless/libertas/tx.c      |   63 +++---
 drivers/net/wireless/libertas/wext.c    |  372 ++++++++++++++-----------------
 19 files changed, 1046 insertions(+), 1204 deletions(-)
drivers/net/wireless/libertas/11d.c +32 -36
index 013965d..5e10ce0 100644
@@ -432,8 +432,8 @@ u8 lbs_get_scan_type_11d(u8 chan,
 
 void lbs_init_11d(struct lbs_private *priv)
 {
-	priv->adapter->enable11d = 0;
-	memset(&(priv->adapter->parsed_region_chan), 0,
+	priv->enable11d = 0;
+	memset(&(priv->parsed_region_chan), 0,
 	       sizeof(struct parsed_region_chan_11d));
 	return;
 }
@@ -447,7 +447,7 @@ static int set_domain_info_11d(struct lbs_private *priv)
 {
 	int ret;
 
-	if (!priv->adapter->enable11d) {
+	if (!priv->enable11d) {
 		lbs_deb_11d("dnld domain Info with 11d disabled\n");
 		return 0;
 	}
@@ -469,22 +469,21 @@ static int set_domain_info_11d(struct lbs_private *priv)
 */
 int lbs_set_universaltable(struct lbs_private *priv, u8 band)
 {
-	struct lbs_adapter *adapter = priv->adapter;
 	u16 size = sizeof(struct chan_freq_power);
 	u16 i = 0;
 
-	memset(adapter->universal_channel, 0,
-	       sizeof(adapter->universal_channel));
+	memset(priv->universal_channel, 0,
+	       sizeof(priv->universal_channel));
 
-	adapter->universal_channel[i].nrcfp =
+	priv->universal_channel[i].nrcfp =
 	    sizeof(channel_freq_power_UN_BG) / size;
 	lbs_deb_11d("BG-band nrcfp %d\n",
-	       adapter->universal_channel[i].nrcfp);
+	       priv->universal_channel[i].nrcfp);
 
-	adapter->universal_channel[i].CFP = channel_freq_power_UN_BG;
-	adapter->universal_channel[i].valid = 1;
-	adapter->universal_channel[i].region = UNIVERSAL_REGION_CODE;
-	adapter->universal_channel[i].band = band;
+	priv->universal_channel[i].CFP = channel_freq_power_UN_BG;
+	priv->universal_channel[i].valid = 1;
+	priv->universal_channel[i].region = UNIVERSAL_REGION_CODE;
+	priv->universal_channel[i].band = band;
 	i++;
 
 	return 0;
@@ -505,8 +504,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
 	struct cmd_ds_802_11d_domain_info *pdomaininfo =
 	    &cmd->params.domaininfo;
 	struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain;
-	struct lbs_adapter *adapter = priv->adapter;
-	u8 nr_subband = adapter->domainreg.nr_subband;
+	u8 nr_subband = priv->domainreg.nr_subband;
 
 	lbs_deb_enter(LBS_DEB_11D);
 
@@ -523,7 +521,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
 	}
 
 	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
-	memcpy(domain->countrycode, adapter->domainreg.countrycode,
+	memcpy(domain->countrycode, priv->domainreg.countrycode,
 	       sizeof(domain->countrycode));
 
 	domain->header.len =
@@ -531,7 +529,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
 			     sizeof(domain->countrycode));
 
 	if (nr_subband) {
-		memcpy(domain->subband, adapter->domainreg.subband,
+		memcpy(domain->subband, priv->domainreg.subband,
 		       nr_subband * sizeof(struct ieeetypes_subbandset));
 
 		cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
@@ -605,24 +603,23 @@ int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv,
                                         struct bss_descriptor * bss)
 {
 	int ret;
-	struct lbs_adapter *adapter = priv->adapter;
 
 	lbs_deb_enter(LBS_DEB_11D);
-	if (priv->adapter->enable11d) {
-		memset(&adapter->parsed_region_chan, 0,
+	if (priv->enable11d) {
+		memset(&priv->parsed_region_chan, 0,
 		       sizeof(struct parsed_region_chan_11d));
 		ret = parse_domain_info_11d(&bss->countryinfo, 0,
-					       &adapter->parsed_region_chan);
+					       &priv->parsed_region_chan);
 
 		if (ret == -1) {
 			lbs_deb_11d("error parsing domain_info from AP\n");
 			goto done;
 		}
 
-		memset(&adapter->domainreg, 0,
+		memset(&priv->domainreg, 0,
 		       sizeof(struct lbs_802_11d_domain_reg));
-		generate_domain_info_11d(&adapter->parsed_region_chan,
-				      &adapter->domainreg);
+		generate_domain_info_11d(&priv->parsed_region_chan,
+				      &priv->domainreg);
 
 		ret = set_domain_info_11d(priv);
 
@@ -646,18 +643,17 @@ done:
 int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv)
 {
 	int ret;
-	struct lbs_adapter *adapter = priv->adapter;
 	struct region_channel *region_chan;
 	u8 j;
 
 	lbs_deb_enter(LBS_DEB_11D);
-	lbs_deb_11d("curbssparams.band %d\n", adapter->curbssparams.band);
+	lbs_deb_11d("curbssparams.band %d\n", priv->curbssparams.band);
 
-	if (priv->adapter->enable11d) {
+	if (priv->enable11d) {
 		/* update parsed_region_chan_11; dnld domaininf to FW */
 
-		for (j = 0; j < ARRAY_SIZE(adapter->region_channel); j++) {
-			region_chan = &adapter->region_channel[j];
+		for (j = 0; j < ARRAY_SIZE(priv->region_channel); j++) {
+			region_chan = &priv->region_channel[j];
 
 			lbs_deb_11d("%d region_chan->band %d\n", j,
 			       region_chan->band);
@@ -665,28 +661,28 @@ int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv)
 			if (!region_chan || !region_chan->valid
 			    || !region_chan->CFP)
 				continue;
-			if (region_chan->band != adapter->curbssparams.band)
+			if (region_chan->band != priv->curbssparams.band)
 				continue;
 			break;
 		}
 
-		if (j >= ARRAY_SIZE(adapter->region_channel)) {
+		if (j >= ARRAY_SIZE(priv->region_channel)) {
 			lbs_deb_11d("region_chan not found, band %d\n",
-			       adapter->curbssparams.band);
+			       priv->curbssparams.band);
 			ret = -1;
 			goto done;
 		}
 
-		memset(&adapter->parsed_region_chan, 0,
+		memset(&priv->parsed_region_chan, 0,
 		       sizeof(struct parsed_region_chan_11d));
 		lbs_generate_parsed_region_chan_11d(region_chan,
-						     &adapter->
+						     &priv->
 						     parsed_region_chan);
 
-		memset(&adapter->domainreg, 0,
+		memset(&priv->domainreg, 0,
 		       sizeof(struct lbs_802_11d_domain_reg));
-		generate_domain_info_11d(&adapter->parsed_region_chan,
-					 &adapter->domainreg);
+		generate_domain_info_11d(&priv->parsed_region_chan,
+					 &priv->domainreg);
 
 		ret = set_domain_info_11d(priv);
 
drivers/net/wireless/libertas/assoc.c +64 -72

381 lines not on this page · raw message

drivers/net/wireless/libertas/assoc.h +1 -1
index fad00ae..08372bb 100644
@@ -6,7 +6,7 @@
 #include "dev.h"
 
 void lbs_association_worker(struct work_struct *work);
-struct assoc_request *lbs_get_association_request(struct lbs_adapter *adapter);
+struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
 void lbs_sync_channel(struct work_struct *work);
 
 #endif /* _LBS_ASSOC_H */
drivers/net/wireless/libertas/cmd.c +129 -149

734 lines not on this page · raw message

drivers/net/wireless/libertas/cmdresp.c +158 -178

760 lines not on this page · raw message

drivers/net/wireless/libertas/debugfs.c +26 -30

154 lines not on this page · raw message

drivers/net/wireless/libertas/decl.h +3 -4
index 1a8fdaa..e255b19 100644
@@ -12,7 +12,6 @@
 
 /** Function Prototype Declaration */
 struct lbs_private;
-struct lbs_adapter;
 struct sk_buff;
 struct net_device;
 struct cmd_ctrl_node;
@@ -32,7 +31,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_action,
 	u16 wait_option, u32 cmd_oid, void *pdata_buf);
 
-void lbs_queue_cmd(struct lbs_adapter *adapter,
+void lbs_queue_cmd(struct lbs_private *priv,
 	struct cmd_ctrl_node *cmdnode,
 	u8 addtail);
 
@@ -43,7 +42,7 @@ void lbs_interrupt(struct net_device *);
 int lbs_set_radio_control(struct lbs_private *priv);
 u32 lbs_fw_index_to_data_rate(u8 index);
 u8 lbs_data_rate_to_fw_index(u32 rate);
-void lbs_get_fwversion(struct lbs_adapter *adapter,
+void lbs_get_fwversion(struct lbs_private *priv,
 	char *fwversion,
 	int maxlen);
 
@@ -66,7 +65,7 @@ void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
 void lbs_tx_runqueue(struct lbs_private *priv);
 
 struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
-	struct lbs_adapter *adapter,
+	struct lbs_private *priv,
 	u8 band,
 	u16 channel);
 
drivers/net/wireless/libertas/dev.h +48 -49

127 lines not on this page · raw message

drivers/net/wireless/libertas/ethtool.c +9 -10
index f32fb00..a54b4f4 100644
@@ -25,7 +25,7 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev,
 	struct lbs_private *priv = (struct lbs_private *) dev->priv;
 	char fwver[32];
 
-	lbs_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1);
+	lbs_get_fwversion(priv, fwver, sizeof(fwver) - 1);
 
 	strcpy(info->driver, "libertas");
 	strcpy(info->version, lbs_driver_version);
@@ -46,7 +46,6 @@ static int lbs_ethtool_get_eeprom(struct net_device *dev,
                                   struct ethtool_eeprom *eeprom, u8 * bytes)
 {
 	struct lbs_private *priv = (struct lbs_private *) dev->priv;
-	struct lbs_adapter *adapter = priv->adapter;
 	struct lbs_ioctl_regrdwr regctrl;
 	char *ptr;
 	int ret;
@@ -60,10 +59,10 @@ static int lbs_ethtool_get_eeprom(struct net_device *dev,
 
 //      mutex_lock(&priv->mutex);
 
-	adapter->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
-	if (!adapter->prdeeprom)
+	priv->prdeeprom = kmalloc(eeprom->len+sizeof(regctrl), GFP_KERNEL);
+	if (!priv->prdeeprom)
 		return -ENOMEM;
-	memcpy(adapter->prdeeprom, &regctrl, sizeof(regctrl));
+	memcpy(priv->prdeeprom, &regctrl, sizeof(regctrl));
 
 	/* +14 is for action, offset, and NOB in
 	 * response */
@@ -77,14 +76,14 @@ static int lbs_ethtool_get_eeprom(struct net_device *dev,
 				    &regctrl);
 
 	if (ret) {
-		if (adapter->prdeeprom)
-			kfree(adapter->prdeeprom);
+		if (priv->prdeeprom)
+			kfree(priv->prdeeprom);
 		goto done;
 	}
 
 	mdelay(10);
 
-	ptr = (char *)adapter->prdeeprom;
+	ptr = (char *)priv->prdeeprom;
 
 	/* skip the command header, but include the "value" u32 variable */
 	ptr = ptr + sizeof(struct lbs_ioctl_regrdwr) - 4;
@@ -94,8 +93,8 @@ static int lbs_ethtool_get_eeprom(struct net_device *dev,
 	 */
 	memcpy(bytes, ptr, eeprom->len);
 
-	if (adapter->prdeeprom)
-		kfree(adapter->prdeeprom);
+	if (priv->prdeeprom)
+		kfree(priv->prdeeprom);
 //	mutex_unlock(&priv->mutex);
 
 	ret = 0;
drivers/net/wireless/libertas/if_cs.c +10 -11
index 8508260..49a0178 100644
@@ -255,7 +255,7 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
 
 	} else if (int_cause == 0xffff) {
 		/* Read in junk, the card has probably been removed */
-		card->priv->adapter->surpriseremoved = 1;
+		card->priv->surpriseremoved = 1;
 
 	} else {
 		if (int_cause & IF_CS_H_IC_TX_OVER)
@@ -644,7 +644,6 @@ static int if_cs_host_to_card(struct lbs_private *priv,
 static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg)
 {
 	struct if_cs_card *card = (struct if_cs_card *)priv->card;
-	/* struct lbs_adapter *adapter = priv->adapter; */
 	int ret = 0;
 	u16 int_cause;
 	u8 *cmdbuf;
@@ -652,7 +651,7 @@ static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg)
 
 	lbs_deb_enter(LBS_DEB_CS);
 
-	if (priv->adapter->surpriseremoved)
+	if (priv->surpriseremoved)
 		goto out;
 
 	int_cause = if_cs_read16(card, IF_CS_C_INT_CAUSE) & IF_CS_C_IC_MASK;
@@ -678,22 +677,22 @@ sbi_get_int_status_exit:
 
 	/* Card has a command result for us */
 	if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
-		spin_lock(&priv->adapter->driver_lock);
-		if (!priv->adapter->cur_cmd) {
+		spin_lock(&priv->driver_lock);
+		if (!priv->cur_cmd) {
 			cmdbuf = priv->upld_buf;
-			priv->adapter->hisregcpy &= ~IF_CS_C_S_RX_UPLD_RDY;
+			priv->hisregcpy &= ~IF_CS_C_S_RX_UPLD_RDY;
 		} else {
-			cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
+			cmdbuf = priv->cur_cmd->bufvirtualaddr;
 		}
 
 		ret = if_cs_receive_cmdres(priv, cmdbuf, &priv->upld_len);
-		spin_unlock(&priv->adapter->driver_lock);
+		spin_unlock(&priv->driver_lock);
 		if (ret < 0)
 			lbs_pr_err("could not receive cmd from card\n");
 	}
 
 out:
-	lbs_deb_leave_args(LBS_DEB_CS, "ret %d, ireg 0x%x, hisregcpy 0x%x", ret, *ireg, priv->adapter->hisregcpy);
+	lbs_deb_leave_args(LBS_DEB_CS, "ret %d, ireg 0x%x, hisregcpy 0x%x", ret, *ireg, priv->hisregcpy);
 	return ret;
 }
 
@@ -702,7 +701,7 @@ static int if_cs_read_event_cause(struct lbs_private *priv)
 {
 	lbs_deb_enter(LBS_DEB_CS);
 
-	priv->adapter->eventcause = (if_cs_read16(priv->card, IF_CS_C_STATUS) & IF_CS_C_S_STATUS_MASK) >> 5;
+	priv->eventcause = (if_cs_read16(priv->card, IF_CS_C_STATUS) & IF_CS_C_S_STATUS_MASK) >> 5;
 	if_cs_write16(priv->card, IF_CS_H_INT_CAUSE, IF_CS_H_IC_HOST_EVENT);
 
 	return 0;
@@ -869,7 +868,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
 	priv->hw_get_int_status   = if_cs_get_int_status;
 	priv->hw_read_event_cause = if_cs_read_event_cause;
 
-	priv->adapter->fw_ready = 1;
+	priv->fw_ready = 1;
 
 	/* Now actually get the IRQ */
 	ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt,
drivers/net/wireless/libertas/if_sdio.c +10 -10
index 6f5a517..6456613 100644
@@ -134,9 +134,9 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 
 	lbs_deb_enter(LBS_DEB_SDIO);
 
-	spin_lock_irqsave(&card->priv->adapter->driver_lock, flags);
+	spin_lock_irqsave(&card->priv->driver_lock, flags);
 
-	if (!card->priv->adapter->cur_cmd) {
+	if (!card->priv->cur_cmd) {
 		lbs_deb_sdio("discarding spurious response\n");
 		ret = 0;
 		goto out;
@@ -149,7 +149,7 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 		goto out;
 	}
 
-	memcpy(card->priv->adapter->cur_cmd->bufvirtualaddr, buffer, size);
+	memcpy(card->priv->cur_cmd->bufvirtualaddr, buffer, size);
 	card->priv->upld_len = size;
 
 	card->int_cause |= MRVDRV_CMD_UPLD_RDY;
@@ -159,7 +159,7 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 	ret = 0;
 
 out:
-	spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags);
+	spin_unlock_irqrestore(&card->priv->driver_lock, flags);
 
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
@@ -231,14 +231,14 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
 		event <<= SBI_EVENT_CAUSE_SHIFT;
 	}
 
-	spin_lock_irqsave(&card->priv->adapter->driver_lock, flags);
+	spin_lock_irqsave(&card->priv->driver_lock, flags);
 
 	card->event = event;
 	card->int_cause |= MRVDRV_CARDEVENT;
 
 	lbs_interrupt(card->priv->dev);
 
-	spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags);
+	spin_unlock_irqrestore(&card->priv->driver_lock, flags);
 
 	ret = 0;
 
@@ -800,7 +800,7 @@ static int if_sdio_read_event_cause(struct lbs_private *priv)
 
 	card = priv->card;
 
-	priv->adapter->eventcause = card->event;
+	priv->eventcause = card->event;
 
 	lbs_deb_leave(LBS_DEB_SDIO);
 
@@ -958,7 +958,7 @@ static int if_sdio_probe(struct sdio_func *func,
 	priv->hw_get_int_status = if_sdio_get_int_status;
 	priv->hw_read_event_cause = if_sdio_read_event_cause;
 
-	priv->adapter->fw_ready = 1;
+	priv->fw_ready = 1;
 
 	/*
 	 * Enable interrupts now that everything is set up
@@ -981,7 +981,7 @@ out:
 err_activate_card:
 	flush_scheduled_work();
 	free_netdev(priv->dev);
-	kfree(priv->adapter);
+	kfree(priv);
 reclaim:
 	sdio_claim_host(func);
 release_int:
@@ -1011,7 +1011,7 @@ static void if_sdio_remove(struct sdio_func *func)
 
 	card = sdio_get_drvdata(func);
 
-	card->priv->adapter->surpriseremoved = 1;
+	card->priv->surpriseremoved = 1;
 
 	lbs_deb_sdio("call remove card\n");
 	lbs_stop_card(card->priv);
drivers/net/wireless/libertas/if_usb.c +13 -14
index 7c4bd8d..87bed4a 100644
@@ -229,7 +229,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	/* Delay 200 ms to waiting for the FW ready */
 	if_usb_submit_rx_urb(cardp);
 	msleep_interruptible(200);
-	priv->adapter->fw_ready = 1;
+	priv->fw_ready = 1;
 
 	if (lbs_start_card(priv))
 		goto err_start_card;
@@ -270,9 +270,8 @@ static void if_usb_disconnect(struct usb_interface *intf)
 	cardp->surprise_removed = 1;
 
 	if (priv) {
-		struct lbs_adapter *adapter = priv->adapter;
 
-		adapter->surpriseremoved = 1;
+		priv->surpriseremoved = 1;
 		lbs_stop_card(priv);
 		lbs_remove_mesh(priv);
 		lbs_remove_card(priv);
@@ -609,14 +608,14 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 	if (!in_interrupt())
 		BUG();
 
-	spin_lock(&priv->adapter->driver_lock);
+	spin_lock(&priv->driver_lock);
 	/* take care of cur_cmd = NULL case by reading the
 	 * data to clear the interrupt */
-	if (!priv->adapter->cur_cmd) {
+	if (!priv->cur_cmd) {
 		cmdbuf = priv->upld_buf;
-		priv->adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
+		priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
 	} else
-		cmdbuf = priv->adapter->cur_cmd->bufvirtualaddr;
+		cmdbuf = priv->cur_cmd->bufvirtualaddr;
 
 	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
 	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
@@ -625,7 +624,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 
 	kfree_skb(skb);
 	lbs_interrupt(priv->dev);
-	spin_unlock(&priv->adapter->driver_lock);
+	spin_unlock(&priv->driver_lock);
 
 	lbs_deb_usbd(&cardp->udev->dev,
 		    "Wake up main thread to handle cmd response\n");
@@ -685,20 +684,20 @@ static void if_usb_receive(struct urb *urb)
 
 	case CMD_TYPE_INDICATION:
 		/* Event cause handling */
-		spin_lock(&priv->adapter->driver_lock);
+		spin_lock(&priv->driver_lock);
 		cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
 		lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
 			    cardp->usb_event_cause);
 		if (cardp->usb_event_cause & 0xffff0000) {
 			lbs_send_tx_feedback(priv);
-			spin_unlock(&priv->adapter->driver_lock);
+			spin_unlock(&priv->driver_lock);
 			break;
 		}
 		cardp->usb_event_cause <<= 3;
 		cardp->usb_int_cause |= MRVDRV_CARDEVENT;
 		kfree_skb(skb);
 		lbs_interrupt(priv->dev);
-		spin_unlock(&priv->adapter->driver_lock);
+		spin_unlock(&priv->driver_lock);
 		goto rx_exit;
 	default:
 		lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
@@ -750,7 +749,7 @@ static int if_usb_host_to_card(struct lbs_private *priv,
 	                    nb + MESSAGE_HEADER_LEN);
 }
 
-/* called with adapter->driver_lock held */
+/* called with priv->driver_lock held */
 static int if_usb_get_int_status(struct lbs_private *priv, u8 *ireg)
 {
 	struct usb_card_rec *cardp = priv->card;
@@ -767,7 +766,7 @@ static int if_usb_read_event_cause(struct lbs_private *priv)
 {
 	struct usb_card_rec *cardp = priv->card;
 
-	priv->adapter->eventcause = cardp->usb_event_cause;
+	priv->eventcause = cardp->usb_event_cause;
 	/* Re-submit rx urb here to avoid event lost issue */
 	if_usb_submit_rx_urb(cardp);
 	return 0;
@@ -942,7 +941,7 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 
 	lbs_deb_enter(LBS_DEB_USB);
 
-	if (priv->adapter->psstate != PS_STATE_FULL_POWER)
+	if (priv->psstate != PS_STATE_FULL_POWER)
 		return -1;
 
 	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
drivers/net/wireless/libertas/join.c +70 -80

356 lines not on this page · raw message

drivers/net/wireless/libertas/main.c +146 -180

326 lines not on this page · raw message

drivers/net/wireless/libertas/rx.c +36 -42

78 lines not on this page · raw message

drivers/net/wireless/libertas/scan.c +90 -98

188 lines not on this page · raw message

drivers/net/wireless/libertas/scan.h +2 -4
index 9b62e2b..319f70d 100644

Lines of this file are not shown. View the raw message.

drivers/net/wireless/libertas/tx.c +30 -33

63 lines not on this page · raw message

drivers/net/wireless/libertas/wext.c +169 -203

372 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.5.3.4

Part of the diff is not shown here. View the raw message.

#36 lore raw

PATCH 30/48 libertas: use lbs_host_to_card_done() in lbs_tx_timeout()

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 20:56:44 +0000

Also attempt some locking in lbs_host_to_card_done()

---
 drivers/net/wireless/libertas/main.c |   40 ++++++++++++++-------------------
 1 files changed, 17 insertions(+), 23 deletions(-)
drivers/net/wireless/libertas/main.c +17 -23
index 243cdea..2ff5f1b 100644
@@ -601,31 +601,24 @@ static void lbs_tx_timeout(struct net_device *dev)
 
 	lbs_pr_err("tx watch dog timeout\n");
 
-	priv->dnld_sent = DNLD_RES_RECEIVED;
 	dev->trans_start = jiffies;
 
 	if (priv->currenttxskb) {
-		if (priv->monitormode != LBS_MONITOR_OFF) {
-			/* If we are here, we have not received feedback from
-			   the previous packet.  Assume TX_FAIL and move on. */
-			priv->eventcause = 0x01000000;
-			lbs_send_tx_feedback(priv);
-		} else
-			wake_up_interruptible(&priv->waitq);
-	} else if (dev == priv->dev) {
-		if (priv->connect_status == LBS_CONNECTED)
-			netif_wake_queue(priv->dev);
-
-	} else if (dev == priv->mesh_dev) {
-		if (priv->mesh_connect_status == LBS_CONNECTED)
-			netif_wake_queue(priv->mesh_dev);
+		priv->eventcause = 0x01000000;
+		lbs_send_tx_feedback(priv);
 	}
+	/* XX: Shouldn't we also call into the hw-specific driver
+	   to kick it somehow? */
+	lbs_host_to_card_done(priv);
 
 	lbs_deb_leave(LBS_DEB_TX);
 }
 
 void lbs_host_to_card_done(struct lbs_private *priv)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->driver_lock, flags);
 
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
@@ -634,15 +627,16 @@ void lbs_host_to_card_done(struct lbs_private *priv)
 		wake_up_interruptible(&priv->waitq);
 
 	/* Don't wake netif queues if we're in monitor mode and
-	   a TX packet is already pending. */
-	if (priv->currenttxskb)
-		return;
-
-	if (priv->dev && priv->connect_status == LBS_CONNECTED)
-		netif_wake_queue(priv->dev);
+	   a TX packet is already pending, or if there are commands
+	   queued to be sent. */
+	if (!priv->currenttxskb && list_empty(&priv->cmdpendingq)) {
+		if (priv->dev && priv->connect_status == LBS_CONNECTED)
+			netif_wake_queue(priv->dev);
 
-	if (priv->mesh_dev && priv->mesh_connect_status == LBS_CONNECTED)
-		netif_wake_queue(priv->mesh_dev);
+		if (priv->mesh_dev && priv->mesh_connect_status == LBS_CONNECTED)
+			netif_wake_queue(priv->mesh_dev);
+	}
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
 
Signature · 1 line
1.5.3.4
#37 lore raw

PATCH 31/48 libertas: cope with device which already has firmware loaded

In reply to David Woodhouse

Date: Sat, 8 Dec 2007 23:49:06 +0000

---
 drivers/net/wireless/libertas/if_usb.c |   35 ++++++++++++++++++++-----------
 drivers/net/wireless/libertas/if_usb.h |    2 +-
 2 files changed, 23 insertions(+), 14 deletions(-)
drivers/net/wireless/libertas/if_usb.c +22 -13
index 87bed4a..141d185 100644
@@ -374,20 +374,23 @@ static int if_prog_firmware(struct usb_card_rec *cardp)
 
 static int if_usb_reset_device(struct usb_card_rec *cardp)
 {
+	struct cmd_ds_command *cmd = (void *)&cardp->bulk_out_buffer[4];
 	int ret;
-	struct lbs_private *priv = cardp->priv;
 
 	lbs_deb_enter(LBS_DEB_USB);
 
-	/* Try a USB port reset first, if that fails send the reset
-	 * command to the firmware.
-	 */
+	*(__le32 *)cardp->bulk_out_buffer = cpu_to_le32(CMD_TYPE_REQUEST);
+
+	cmd->command = cpu_to_le16(CMD_802_11_RESET);
+	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
+	cmd->result = cpu_to_le16(0);
+	cmd->seqnum = cpu_to_le16(0x5a5a);
+	cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
+	usb_tx_block(cardp, cardp->bulk_out_buffer, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
+
+	msleep(10);
 	ret = usb_reset_device(cardp->udev);
-	if (!ret && priv) {
-		msleep(10);
-		ret = lbs_reset_device(priv);
-		msleep(10);
-	}
+	msleep(10);
 
 	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
 
@@ -508,9 +511,15 @@ static void if_usb_receive_fwload(struct urb *urb)
 			return;
 		}
 		if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
-			lbs_pr_info(
-				"boot cmd response wrong magic number (0x%x)\n",
-				le32_to_cpu(bootcmdresp.u32magicnumber));
+			if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) ||
+			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) ||
+			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) {
+				lbs_pr_info("Firmware already seems alive; resetting\n");
+				cardp->bootcmdresp = -1;
+			} else {
+				lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
+					    le32_to_cpu(bootcmdresp.u32magicnumber));
+			}
 		} else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
 			lbs_pr_info(
 				"boot cmd response cmd_tag error (%d)\n",
@@ -883,7 +892,7 @@ restart:
 		} while (cardp->bootcmdresp == 0 && j < 10);
 	} while (cardp->bootcmdresp == 0 && i < 5);
 
-	if (cardp->bootcmdresp == 0) {
+	if (cardp->bootcmdresp <= 0) {
 		if (--reset_count >= 0) {
 			if_usb_reset_device(cardp);
 			goto restart;
drivers/net/wireless/libertas/if_usb.h +1 -1
index f53ddb2..940a369 100644
@@ -70,7 +70,7 @@ struct usb_card_rec {
 
 	u8 rx_urb_recall;
 
-	u8 bootcmdresp;
+	s8 bootcmdresp;
 };
 
 /** fwheader */
Signature · 1 line
1.5.3.4
#38 lore raw

PATCH 32/48 libertas: stop debugfs code looking at cmdpendingq

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 11:08:25 -0500

It doesn't need to wait until no commands are pending anyway -- it only needs to wait until the scan is finished.

We can hopefully find it something else to wait on too -- it's the only user of the cmd_pending waitqueue.

---
 drivers/net/wireless/libertas/debugfs.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/debugfs.c +1 -2
index 9917a18..e8a24d7 100644
@@ -320,8 +320,7 @@ static ssize_t lbs_setuserscan(struct file *file,
 
 	lbs_scan_networks(priv, scan_cfg, 1);
 	wait_event_interruptible(priv->cmd_pending,
-				 priv->surpriseremoved || 
-				 (!priv->cur_cmd && list_empty(&priv->cmdpendingq)));
+				 priv->surpriseremoved || !priv->last_scanned_channel);
 
 	if (priv->surpriseremoved)
 		goto out_scan_cfg;
Signature · 1 line
1.5.3.4
#39 lore raw

PATCH 33/48 libertas: kill internal tx queue for PS mode

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 12:37:27 -0500

It was buggy as hell anyway, since it was just spewing packets at the device when it wasn't necessarily ready for them (in the USB case, while the URB was still busy).

We could probably do with a better way of flushing packets to the device _immediately_, before we stick it back into sleep mode. But we can no longer just dequeue packets directly, it seems.

---
 drivers/net/wireless/libertas/decl.h |    2 -
 drivers/net/wireless/libertas/dev.h  |    5 ----
 drivers/net/wireless/libertas/main.c |    6 -----
 drivers/net/wireless/libertas/tx.c   |   40 ++-------------------------------
 4 files changed, 3 insertions(+), 50 deletions(-)
drivers/net/wireless/libertas/decl.h +0 -2
index e255b19..b094514 100644
@@ -62,8 +62,6 @@ void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
 void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode);
 void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
 
-void lbs_tx_runqueue(struct lbs_private *priv);
-
 struct chan_freq_power *lbs_find_cfp_by_band_and_channel(
 	struct lbs_private *priv,
 	u8 band,
drivers/net/wireless/libertas/dev.h +0 -5
index 21b0d38..a9c3adc 100644
@@ -197,11 +197,6 @@ struct lbs_private {
 	/** Timers */
 	struct timer_list command_timer;
 
-	/* TX queue used in PS mode */
-	spinlock_t txqueue_lock;
-	struct sk_buff *tx_queue_ps[NR_TX_QUEUE];
-	unsigned int tx_queue_idx;
-
 	u8 hisregcpy;
 
 	/** current ssid/bssid related parameters*/
drivers/net/wireless/libertas/main.c +0 -6
index 2ff5f1b..c638995 100644
@@ -914,8 +914,6 @@ static int lbs_thread(void *data)
 		 */
 		if (!list_empty(&priv->cmdpendingq))
 			wake_up_all(&priv->cmd_pending);
-
-		lbs_tx_runqueue(priv);
 	}
 
 	del_timer(&priv->command_timer);
@@ -1072,10 +1070,6 @@ static int lbs_init_adapter(struct lbs_private *priv)
 
 	mutex_init(&priv->lock);
 
-	memset(&priv->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));
-	priv->tx_queue_idx = 0;
-	spin_lock_init(&priv->txqueue_lock);
-
 	setup_timer(&priv->command_timer, command_timer_fn,
 	            (unsigned long)priv);
 
drivers/net/wireless/libertas/tx.c +3 -37
index 4cb39d3..749535e 100644
@@ -164,41 +164,6 @@ done:
 }
 
 
-void lbs_tx_runqueue(struct lbs_private *priv)
-{
-	int i;
-
-	spin_lock(&priv->txqueue_lock);
-	for (i = 0; i < priv->tx_queue_idx; i++) {
-		struct sk_buff *skb = priv->tx_queue_ps[i];
-		spin_unlock(&priv->txqueue_lock);
-		SendSinglePacket(priv, skb);
-		spin_lock(&priv->txqueue_lock);
-	}
-	priv->tx_queue_idx = 0;
-	spin_unlock(&priv->txqueue_lock);
-}
-
-static void lbs_tx_queue(struct lbs_private *priv, struct sk_buff *skb)
-{
-
-	spin_lock(&priv->txqueue_lock);
-
-	WARN_ON(priv->tx_queue_idx >= NR_TX_QUEUE);
-	priv->tx_queue_ps[priv->tx_queue_idx++] = skb;
-	if (priv->tx_queue_idx == NR_TX_QUEUE) {
-		netif_stop_queue(priv->dev);
-		if (priv->mesh_dev)
-			netif_stop_queue(priv->mesh_dev);
-	} else {
-		netif_start_queue(priv->dev);
-		if (priv->mesh_dev)
-			netif_start_queue(priv->mesh_dev);
-	}
-
-	spin_unlock(&priv->txqueue_lock);
-}
-
 /**
  *  @brief This function checks the conditions and sends packet to IF
  *  layer if everything is ok.
@@ -221,8 +186,9 @@ int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
 
 	if ((priv->psstate == PS_STATE_SLEEP) ||
 	    (priv->psstate == PS_STATE_PRE_SLEEP)) {
-		lbs_tx_queue(priv, skb);
-		return ret;
+		lbs_pr_alert("TX error: packet xmit in %ssleep mode\n",
+			     priv->psstate == PS_STATE_SLEEP?"":"pre-");
+		goto done;
 	}
 
 	ret = SendSinglePacket(priv, skb);
Signature · 1 line
1.5.3.4
#40 lore raw

PATCH 34/48 libertas: kill SendSinglePacket() function.

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 12:48:10 -0500

Make a start on reducing the number of pointless nested functions, starting with the StudlyCaps. No semantic changes (yet) -- we can sort out the now-obvious discrepancy in the failure paths in a separate commit.

---
 drivers/net/wireless/libertas/tx.c |   66 +++++++++++++-----------------------
 1 files changed, 24 insertions(+), 42 deletions(-)
drivers/net/wireless/libertas/tx.c +24 -42
index 749535e..10596f3 100644
@@ -49,16 +49,16 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
 }
 
 /**
- *  @brief This function processes a single packet and sends
- *  to IF layer
+ *  @brief This function checks the conditions and sends packet to IF
+ *  layer if everything is ok.
  *
  *  @param priv    A pointer to struct lbs_private structure
  *  @param skb     A pointer to skb which includes TX packet
  *  @return 	   0 or -1
  */
-static int SendSinglePacket(struct lbs_private *priv, struct sk_buff *skb)
+int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
 {
-	int ret = 0;
+	int ret = -1;
 	struct txpd localtxpd;
 	struct txpd *plocaltxpd = &localtxpd;
 	u8 *p802x_hdr;
@@ -68,16 +68,31 @@ static int SendSinglePacket(struct lbs_private *priv, struct sk_buff *skb)
 
 	lbs_deb_enter(LBS_DEB_TX);
 
+	lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
+
+	if (priv->dnld_sent) {
+		lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
+		       priv->dnld_sent);
+		goto done;
+	}
+
+	if ((priv->psstate == PS_STATE_SLEEP) ||
+	    (priv->psstate == PS_STATE_PRE_SLEEP)) {
+		lbs_pr_alert("TX error: packet xmit in %ssleep mode\n",
+			     priv->psstate == PS_STATE_SLEEP?"":"pre-");
+		goto done;
+	}
+
 	if (priv->surpriseremoved)
 		return -1;
 
 	if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
 		lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
 		       skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
-		ret = -1;
-		goto done;
+		goto done_tx;
 	}
 
+	ret = 0;
 	memset(plocaltxpd, 0, sizeof(struct txpd));
 
 	plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
@@ -130,12 +145,12 @@ static int SendSinglePacket(struct lbs_private *priv, struct sk_buff *skb)
 
 	if (ret) {
 		lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
-		goto done;
+		goto done_tx;
 	}
 
-	lbs_deb_tx("SendSinglePacket succeeds\n");
+	lbs_deb_tx("%s succeeds\n", __func__);
 
-done:
+done_tx:
 	if (!ret) {
 		priv->stats.tx_packets++;
 		priv->stats.tx_bytes += skb->len;
@@ -159,39 +174,6 @@ done:
 		dev_kfree_skb_any(skb);
 	}
 
-	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
-	return ret;
-}
-
-
-/**
- *  @brief This function checks the conditions and sends packet to IF
- *  layer if everything is ok.
- *
- *  @param priv    A pointer to struct lbs_private structure
- *  @return 	   n/a
- */
-int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
-{
-	int ret = -1;
-
-	lbs_deb_enter(LBS_DEB_TX);
-	lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
-
-	if (priv->dnld_sent) {
-		lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
-		       priv->dnld_sent);
-		goto done;
-	}
-
-	if ((priv->psstate == PS_STATE_SLEEP) ||
-	    (priv->psstate == PS_STATE_PRE_SLEEP)) {
-		lbs_pr_alert("TX error: packet xmit in %ssleep mode\n",
-			     priv->psstate == PS_STATE_SLEEP?"":"pre-");
-		goto done;
-	}
-
-	ret = SendSinglePacket(priv, skb);
 done:
 	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
 	return ret;
Signature · 1 line
1.5.3.4
#41 lore raw

PATCH 35/48 libertas: move lbs_hard_start_xmit() into tx.c

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 12:52:19 -0500

... where it can shortly be merged with lbs_process_tx()...

---
 drivers/net/wireless/libertas/decl.h |    2 +-
 drivers/net/wireless/libertas/main.c |   32 --------------------------------
 drivers/net/wireless/libertas/tx.c   |   33 ++++++++++++++++++++++++++++++++-
 3 files changed, 33 insertions(+), 34 deletions(-)
drivers/net/wireless/libertas/decl.h +1 -1
index b094514..fcb5a85 100644
@@ -50,10 +50,10 @@ void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb);
 
 /** The proc fs interface */
 int lbs_process_rx_command(struct lbs_private *priv);
-int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb);
 void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
 	struct cmd_ctrl_node *ptempcmd);
 
+int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
 
 int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *);
drivers/net/wireless/libertas/main.c +0 -32
index c638995..d311d57 100644
@@ -515,38 +515,6 @@ static int lbs_close(struct net_device *dev)
 		return 0;
 }
 
-
-static int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	int ret = 0;
-	struct lbs_private *priv = dev->priv;
-
-	lbs_deb_enter(LBS_DEB_TX);
-
-	/* We could return NETDEV_TX_BUSY here, but I'd actually 
-	   like to get the point where we can BUG() */
-	if (priv->dnld_sent) {
-		lbs_pr_err("%s while dnld_sent\n", __func__);
-		priv->stats.tx_dropped++;
-		goto done;
-	}
-	if (priv->currenttxskb) {
-		lbs_pr_err("%s while TX skb pending\n", __func__);
-		priv->stats.tx_dropped++;
-		goto done;
-	}
-
-	netif_stop_queue(priv->dev);
-	if (priv->mesh_dev)
-		netif_stop_queue(priv->mesh_dev);
-
-	if (lbs_process_tx(priv, skb) == 0)
-		dev->trans_start = jiffies;
-done:
-	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
-	return ret;
-}
-
 /**
  * @brief Mark mesh packets and handover them to lbs_hard_start_xmit
  *
drivers/net/wireless/libertas/tx.c +32 -1
index 10596f3..336544c 100644
@@ -56,7 +56,7 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
  *  @param skb     A pointer to skb which includes TX packet
  *  @return 	   0 or -1
  */
-int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
+static int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
 {
 	int ret = -1;
 	struct txpd localtxpd;
@@ -179,6 +179,37 @@ done:
 	return ret;
 }
 
+int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	int ret = 0;
+	struct lbs_private *priv = dev->priv;
+
+	lbs_deb_enter(LBS_DEB_TX);
+
+	/* We could return NETDEV_TX_BUSY here, but I'd actually 
+	   like to get the point where we can BUG() */
+	if (priv->dnld_sent) {
+		lbs_pr_err("%s while dnld_sent\n", __func__);
+		priv->stats.tx_dropped++;
+		goto done;
+	}
+	if (priv->currenttxskb) {
+		lbs_pr_err("%s while TX skb pending\n", __func__);
+		priv->stats.tx_dropped++;
+		goto done;
+	}
+
+	netif_stop_queue(priv->dev);
+	if (priv->mesh_dev)
+		netif_stop_queue(priv->mesh_dev);
+
+	if (lbs_process_tx(priv, skb) == 0)
+		dev->trans_start = jiffies;
+done:
+	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
+	return ret;
+}
+
 /**
  *  @brief This function sends to the host the last transmitted packet,
  *  filling the radiotap headers with transmission information.
Signature · 1 line
1.5.3.4
#42 lore raw

PATCH 36/48 libertas: kill lbs_process_tx() by merging it into lbs_hard_start_xmit()

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 12:57:14 -0500

---
 drivers/net/wireless/libertas/tx.c |   45 ++++++++++-------------------------
 1 files changed, 13 insertions(+), 32 deletions(-)
drivers/net/wireless/libertas/tx.c +13 -32
index 336544c..7bc2124 100644
@@ -56,8 +56,9 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
  *  @param skb     A pointer to skb which includes TX packet
  *  @return 	   0 or -1
  */
-static int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
+int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	struct lbs_private *priv = dev->priv;
 	int ret = -1;
 	struct txpd localtxpd;
 	struct txpd *plocaltxpd = &localtxpd;
@@ -70,12 +71,21 @@ static int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb)
 
 	lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
 
+	netif_stop_queue(priv->dev);
+	if (priv->mesh_dev)
+		netif_stop_queue(priv->mesh_dev);
+
 	if (priv->dnld_sent) {
 		lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
 		       priv->dnld_sent);
 		goto done;
 	}
 
+	if (priv->currenttxskb) {
+		lbs_pr_err("%s while TX skb pending\n", __func__);
+		goto done;
+	}
+
 	if ((priv->psstate == PS_STATE_SLEEP) ||
 	    (priv->psstate == PS_STATE_PRE_SLEEP)) {
 		lbs_pr_alert("TX error: packet xmit in %ssleep mode\n",
@@ -154,6 +164,8 @@ done_tx:
 	if (!ret) {
 		priv->stats.tx_packets++;
 		priv->stats.tx_bytes += skb->len;
+
+ 		dev->trans_start = jiffies;
 	} else {
 		priv->stats.tx_dropped++;
 		priv->stats.tx_errors++;
@@ -179,37 +191,6 @@ done:
 	return ret;
 }
 
-int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	int ret = 0;
-	struct lbs_private *priv = dev->priv;
-
-	lbs_deb_enter(LBS_DEB_TX);
-
-	/* We could return NETDEV_TX_BUSY here, but I'd actually 
-	   like to get the point where we can BUG() */
-	if (priv->dnld_sent) {
-		lbs_pr_err("%s while dnld_sent\n", __func__);
-		priv->stats.tx_dropped++;
-		goto done;
-	}
-	if (priv->currenttxskb) {
-		lbs_pr_err("%s while TX skb pending\n", __func__);
-		priv->stats.tx_dropped++;
-		goto done;
-	}
-
-	netif_stop_queue(priv->dev);
-	if (priv->mesh_dev)
-		netif_stop_queue(priv->mesh_dev);
-
-	if (lbs_process_tx(priv, skb) == 0)
-		dev->trans_start = jiffies;
-done:
-	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
-	return ret;
-}
-
 /**
  *  @brief This function sends to the host the last transmitted packet,
  *  filling the radiotap headers with transmission information.
Signature · 1 line
1.5.3.4
#43 lore raw

PATCH 37/48 libertas: clean up lbs_hard_start_xmit()

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 14:37:59 -0500

Having merged the nest of functions into one, now we can clean it up and fix the error handling, and the duplication -- and at least make a start on the locking.

---
 drivers/net/wireless/libertas/tx.c |  133 +++++++++++++++++-------------------
 1 files changed, 63 insertions(+), 70 deletions(-)
drivers/net/wireless/libertas/tx.c +63 -70
index 7bc2124..aefe524 100644
@@ -58,22 +58,16 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
  */
 int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+	unsigned long flags;
 	struct lbs_private *priv = dev->priv;
-	int ret = -1;
-	struct txpd localtxpd;
-	struct txpd *plocaltxpd = &localtxpd;
-	u8 *p802x_hdr;
-	struct tx_radiotap_hdr *pradiotap_hdr;
-	u32 new_rate;
-	u8 *ptr = priv->tmptxbuf;
+	struct txpd *txpd;
+	char *p802x_hdr;
+	uint16_t pkt_len;
+	int ret;
 
 	lbs_deb_enter(LBS_DEB_TX);
 
-	lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
-
-	netif_stop_queue(priv->dev);
-	if (priv->mesh_dev)
-		netif_stop_queue(priv->mesh_dev);
+	ret = NETDEV_TX_BUSY;
 
 	if (priv->dnld_sent) {
 		lbs_pr_alert( "TX error: dnld_sent = %d, not sending\n",
@@ -94,98 +88,97 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	if (priv->surpriseremoved)
-		return -1;
+		goto drop;
 
 	if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
 		lbs_deb_tx("tx err: skb length %d 0 or > %zd\n",
 		       skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
-		goto done_tx;
+		/* We'll never manage to send this one; drop it and return 'OK' */
+		goto drop;
 	}
 
-	ret = 0;
-	memset(plocaltxpd, 0, sizeof(struct txpd));
-
-	plocaltxpd->tx_packet_length = cpu_to_le16(skb->len);
+	lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100));
 
-	/* offset of actual data */
-	plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
+	txpd = (void *)priv->tmptxbuf;
+	memset(txpd, 0, sizeof(struct txpd));
 
 	p802x_hdr = skb->data;
-	if (priv->monitormode != LBS_MONITOR_OFF) {
+	pkt_len = skb->len;
 
-		/* locate radiotap header */
-		pradiotap_hdr = (struct tx_radiotap_hdr *)skb->data;
+	if (priv->monitormode != LBS_MONITOR_OFF) {
+		struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
 
 		/* set txpd fields from the radiotap header */
-		new_rate = convert_radiotap_rate_to_mv(pradiotap_hdr->rate);
-		if (new_rate != 0) {
-			/* use new tx_control[4:0] */
-			plocaltxpd->tx_control = cpu_to_le32(new_rate);
-		}
+		txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate));
 
 		/* skip the radiotap header */
-		p802x_hdr += sizeof(struct tx_radiotap_hdr);
-		plocaltxpd->tx_packet_length =
-			cpu_to_le16(le16_to_cpu(plocaltxpd->tx_packet_length)
-				    - sizeof(struct tx_radiotap_hdr));
+		p802x_hdr += sizeof(*rtap_hdr);
+		pkt_len -= sizeof(*rtap_hdr);
 
+		/* copy destination address from 802.11 header */
+		memcpy(txpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
+	} else {
+		/* copy destination address from 802.3 header */
+		memcpy(txpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
 	}
-	/* copy destination address from 802.3 or 802.11 header */
-	if (priv->monitormode != LBS_MONITOR_OFF)
-		memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN);
-	else
-		memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN);
 
-	lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) plocaltxpd, sizeof(struct txpd));
+	txpd->tx_packet_length = cpu_to_le16(pkt_len);
+	txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
 
-	if (IS_MESH_FRAME(skb)) {
-		plocaltxpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
-	}
+	if (dev == priv->mesh_dev)
+		txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
 
-	memcpy(ptr, plocaltxpd, sizeof(struct txpd));
+	lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
 
-	ptr += sizeof(struct txpd);
+	lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, le16_to_cpu(txpd->tx_packet_length));
 
-	lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
-	memcpy(ptr, p802x_hdr, le16_to_cpu(plocaltxpd->tx_packet_length));
-	ret = priv->hw_host_to_card(priv, MVMS_DAT,
-				    priv->tmptxbuf,
-				    le16_to_cpu(plocaltxpd->tx_packet_length) +
-				    sizeof(struct txpd));
+	memcpy(&txpd[1], p802x_hdr, le16_to_cpu(txpd->tx_packet_length));
 
-	if (ret) {
-		lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
-		goto done_tx;
-	}
+	/* We need to protect against the queues being restarted before
+	   we get round to stopping them */
+	spin_lock_irqsave(&priv->driver_lock, flags);
 
-	lbs_deb_tx("%s succeeds\n", __func__);
+	ret = priv->hw_host_to_card(priv, MVMS_DAT, priv->tmptxbuf,
+				    pkt_len + sizeof(struct txpd));
 
-done_tx:
 	if (!ret) {
+		lbs_deb_tx("%s succeeds\n", __func__);
+
+		/* Stop processing outgoing pkts before submitting */
+		netif_stop_queue(priv->dev);
+		if (priv->mesh_dev)
+			netif_stop_queue(priv->mesh_dev);
+
 		priv->stats.tx_packets++;
 		priv->stats.tx_bytes += skb->len;
 
- 		dev->trans_start = jiffies;
-	} else {
-		priv->stats.tx_dropped++;
-		priv->stats.tx_errors++;
+		dev->trans_start = jiffies;
+
+		if (priv->monitormode != LBS_MONITOR_OFF) {
+			/* Keep the skb to echo it back once Tx feedback is
+			   received from FW */
+			skb_orphan(skb);
+
+			/* Keep the skb around for when we get feedback */
+			priv->currenttxskb = skb;
+		}
 	}
+	
+	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-	if (!ret && priv->monitormode != LBS_MONITOR_OFF) {
-		/* Keep the skb to echo it back once Tx feedback is
-		   received from FW */
-		skb_orphan(skb);
-		/* stop processing outgoing pkts */
-		netif_stop_queue(priv->dev);
-		if (priv->mesh_dev)
-			netif_stop_queue(priv->mesh_dev);
+	if (ret) {
+		lbs_deb_tx("tx err: hw_host_to_card returned 0x%X\n", ret);
+drop:
+		priv->stats.tx_dropped++;
+		priv->stats.tx_errors++;
 
-		/* Keep the skb around for when we get feedback */
-		priv->currenttxskb = skb;
-	} else {
 		dev_kfree_skb_any(skb);
 	}
 
+	/* Even if we dropped the packet, return OK. Otherwise the
+	   packet gets requeued. */
+	ret = NETDEV_TX_OK;
+
 done:
 	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
 	return ret;
Signature · 1 line
1.5.3.4
#44 lore raw

PATCH 38/48 libertas: kill lbs_pre_start_xmit(), lib_mesh_pre_start_xmit()

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 15:04:19 -0500

These wrappers only do two things.

Firstly, they set the frame type, which isn't necessary since lbs_hard_start_xmit() gets to see which device it belongs to anyway.

Secondly, they return -EOPNOTSUPP if the device is in monitor mode. Which is a strange thing to do and will provide nasty warnings from qdisc_restart(). And lbs_hard_start_xmit() seems to have code to cope with monitor mode anyway.

---
 drivers/net/wireless/libertas/main.c |   50 +--------------------------------
 1 files changed, 2 insertions(+), 48 deletions(-)
drivers/net/wireless/libertas/main.c +2 -48
index d311d57..5c8cb00 100644
@@ -515,52 +515,6 @@ static int lbs_close(struct net_device *dev)
 		return 0;
 }
 
-/**
- * @brief Mark mesh packets and handover them to lbs_hard_start_xmit
- *
- */
-static int lbs_mesh_pre_start_xmit(struct sk_buff *skb,
-		struct net_device *dev)
-{
-	struct lbs_private *priv = dev->priv;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_MESH);
-	if (priv->monitormode != LBS_MONITOR_OFF) {
-		netif_stop_queue(dev);
-		return -EOPNOTSUPP;
-	}
-
-	SET_MESH_FRAME(skb);
-
-	ret = lbs_hard_start_xmit(skb, priv->mesh_dev);
-	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
-	return ret;
-}
-
-/**
- * @brief Mark non-mesh packets and handover them to lbs_hard_start_xmit
- *
- */
-static int lbs_pre_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct lbs_private *priv = dev->priv;
-	int ret;
-
-	lbs_deb_enter(LBS_DEB_TX);
-
-	if (priv->monitormode != LBS_MONITOR_OFF) {
-		netif_stop_queue(dev);
-		return -EOPNOTSUPP;
-	}
-
-	UNSET_MESH_FRAME(skb);
-
-	ret = lbs_hard_start_xmit(skb, dev);
-	lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret);
-	return ret;
-}
-
 static void lbs_tx_timeout(struct net_device *dev)
 {
 	struct lbs_private *priv = (struct lbs_private *) dev->priv;
@@ -1104,7 +1058,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 
 	/* Setup the OS Interface to our functions */
 	dev->open = lbs_open;
-	dev->hard_start_xmit = lbs_pre_start_xmit;
+	dev->hard_start_xmit = lbs_hard_start_xmit;
 	dev->stop = lbs_close;
 	dev->set_mac_address = lbs_set_mac_address;
 	dev->tx_timeout = lbs_tx_timeout;
@@ -1276,7 +1230,7 @@ int lbs_add_mesh(struct lbs_private *priv, struct device *dev)
 	priv->mesh_dev = mesh_dev;
 
 	mesh_dev->open = lbs_mesh_open;
-	mesh_dev->hard_start_xmit = lbs_mesh_pre_start_xmit;
+	mesh_dev->hard_start_xmit = lbs_hard_start_xmit;
 	mesh_dev->stop = lbs_mesh_close;
 	mesh_dev->get_stats = lbs_get_stats;
 	mesh_dev->set_mac_address = lbs_set_mac_address;
Signature · 1 line
1.5.3.4
#45 lore raw

PATCH 39/48 libertas: stop using ieee80211 for radiotap device

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 16:22:21 -0500

There seems to be no point in doing it as an ieee80211 device instead of a normal netdev, and when we override its ->priv and then call free_ieee80211() it has a distressing tendency to crash horribly.

---
 drivers/net/wireless/libertas/dev.h  |    2 -
 drivers/net/wireless/libertas/main.c |   36 ++++++++++++++-------------------
 2 files changed, 15 insertions(+), 23 deletions(-)
drivers/net/wireless/libertas/dev.h +0 -2
index a9c3adc..04cf33d 100644
@@ -10,7 +10,6 @@
 #include <linux/wireless.h>
 #include <linux/ethtool.h>
 #include <linux/debugfs.h>
-#include <net/ieee80211.h>
 
 #include "defs.h"
 #include "scan.h"
@@ -114,7 +113,6 @@ struct lbs_private {
 	struct net_device_stats stats;
 	struct net_device *mesh_dev; /* Virtual device */
 	struct net_device *rtap_net_dev;
-	struct ieee80211_device *ieee;
 
 	struct iw_statistics wstats;
 	struct lbs_mesh_stats mstats;
drivers/net/wireless/libertas/main.c +15 -21
index 5c8cb00..55dce8d 100644
@@ -1448,7 +1448,7 @@ static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
 {
 	struct lbs_private *priv = dev->priv;
-	return &priv->ieee->stats;
+	return &priv->stats;
 }
 
 
@@ -1457,42 +1457,36 @@ void lbs_remove_rtap(struct lbs_private *priv)
 	if (priv->rtap_net_dev == NULL)
 		return;
 	unregister_netdev(priv->rtap_net_dev);
-	free_ieee80211(priv->rtap_net_dev);
+	free_netdev(priv->rtap_net_dev);
 	priv->rtap_net_dev = NULL;
 }
 
 int lbs_add_rtap(struct lbs_private *priv)
 {
 	int rc = 0;
+	struct net_device *rtap_dev;
 
 	if (priv->rtap_net_dev)
 		return -EPERM;
 
-	priv->rtap_net_dev = alloc_ieee80211(0);
-	if (priv->rtap_net_dev == NULL)
+	rtap_dev = alloc_netdev(0, "rtap%d", ether_setup);
+	if (rtap_dev == NULL)
 		return -ENOMEM;
 
+	rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+	rtap_dev->open = lbs_rtap_open;
+	rtap_dev->stop = lbs_rtap_stop;
+	rtap_dev->get_stats = lbs_rtap_get_stats;
+	rtap_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
+	rtap_dev->set_multicast_list = lbs_set_multicast_list;
+	rtap_dev->priv = priv;
 
-	priv->ieee = netdev_priv(priv->rtap_net_dev);
-
-	strcpy(priv->rtap_net_dev->name, "rtap%d");
-
-	priv->rtap_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
-	priv->rtap_net_dev->open = lbs_rtap_open;
-	priv->rtap_net_dev->stop = lbs_rtap_stop;
-	priv->rtap_net_dev->get_stats = lbs_rtap_get_stats;
-	priv->rtap_net_dev->hard_start_xmit = lbs_rtap_hard_start_xmit;
-	priv->rtap_net_dev->set_multicast_list = lbs_set_multicast_list;
-	priv->rtap_net_dev->priv = priv;
-
-	priv->ieee->iw_mode = IW_MODE_MONITOR;
-
-	rc = register_netdev(priv->rtap_net_dev);
+	rc = register_netdev(rtap_dev);
 	if (rc) {
-		free_ieee80211(priv->rtap_net_dev);
-		priv->rtap_net_dev = NULL;
+		free_netdev(rtap_dev);
 		return rc;
 	}
+	priv->rtap_net_dev = rtap_dev;
 
 	return 0;
 }
Signature · 1 line
1.5.3.4
#46 lore raw

PATCH 40/48 libertas: set dev_addr on rtap device

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 19:54:11 -0500

This lets us bring it up, because eth_validate_addr() succeeds instead of returning -EINVAL. And finally monitor mode seems to (mostly) work.

---
 drivers/net/wireless/libertas/main.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/net/wireless/libertas/main.c +1 -0
index 55dce8d..e9c6b4f 100644
@@ -1473,6 +1473,7 @@ int lbs_add_rtap(struct lbs_private *priv)
 	if (rtap_dev == NULL)
 		return -ENOMEM;
 
+	memcpy(rtap_dev->dev_addr, priv->current_addr, ETH_ALEN);
 	rtap_dev->type = ARPHRD_IEEE80211_RADIOTAP;
 	rtap_dev->open = lbs_rtap_open;
 	rtap_dev->stop = lbs_rtap_stop;
Signature · 1 line
1.5.3.4
#47 lore raw

PATCH 41/48 libertas: TX packet is radiotap iff it comes from rtap_dev

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 22:00:55 -0500

Fix one of the barriers to simultaneous radiotap and normal operation -- stop misinterpreting the TX packets on the normal devices. We're also going to have to clone the incoming skbs and feed them into both devices, and there seem to be firmware problems with staying associated too. But this is a reasonable start...

---
 drivers/net/wireless/libertas/tx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/tx.c +1 -1
index aefe524..c2881a9 100644
@@ -105,7 +105,7 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	p802x_hdr = skb->data;
 	pkt_len = skb->len;
 
-	if (priv->monitormode != LBS_MONITOR_OFF) {
+	if (dev == priv->rtap_net_dev) {
 		struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data;
 
 		/* set txpd fields from the radiotap header */
Signature · 1 line
1.5.3.4
#48 lore raw

PATCH 42/48 libertas: free successfully transmitted skbs again

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 22:02:46 -0500

I was so busy cleaning up the failure modes that I accidentally forgot to make sure we still free them in the success case. Oops.

---
 drivers/net/wireless/libertas/tx.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/tx.c +3 -1
index c2881a9..300aa05 100644
@@ -161,7 +161,9 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 			/* Keep the skb around for when we get feedback */
 			priv->currenttxskb = skb;
-		}
+		} else
+			dev_kfree_skb_any(skb);
+		
 	}
 	
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
Signature · 1 line
1.5.3.4
#49 lore raw

PATCH 43/48 libertas: refactor the 'should I sleep?' decision in lbs_thread()

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 23:44:43 -0500

This was making my brain hurt.

---
 drivers/net/wireless/libertas/main.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/main.c +18 -2
index e9c6b4f..42b64b5 100644
@@ -722,6 +722,8 @@ static int lbs_thread(void *data)
 	set_freezable();
 
 	for (;;) {
+		int shouldsleep;
+
 		lbs_deb_thread( "main-thread 111: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
 				priv->intcounter, priv->currenttxskb, priv->dnld_sent);
 
@@ -729,8 +731,22 @@ static int lbs_thread(void *data)
 		set_current_state(TASK_INTERRUPTIBLE);
 		spin_lock_irq(&priv->driver_lock);
 
-		if ((priv->psstate == PS_STATE_SLEEP) ||
-		    (!priv->intcounter && (priv->dnld_sent || priv->cur_cmd || list_empty(&priv->cmdpendingq)))) {
+		if (priv->surpriseremoved)
+			shouldsleep = 0;	/* Bye */
+		else if (priv->psstate == PS_STATE_SLEEP)
+			shouldsleep = 1;	/* Sleep mode. Nothing we can do till it wakes */
+		else if (priv->intcounter)
+			shouldsleep = 0;	/* Interrupt pending. Deal with it now */
+		else if (priv->dnld_sent)
+			shouldsleep = 1;	/* Something is en route to the device already */
+		else if (priv->cur_cmd)
+			shouldsleep = 1;	/* Can't send a command; one already running */
+		else if (!list_empty(&priv->cmdpendingq))
+			shouldsleep = 0;	/* We have a command to send */
+		else
+			shouldsleep = 1;	/* No command */
+
+		if (shouldsleep) {
 			lbs_deb_thread("main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",
 				       priv->connect_status, priv->intcounter,
 				       priv->psmode, priv->psstate);
Signature · 1 line
1.5.3.4
#50 lore raw

PATCH 44/48 libertas: Move actual transmission to main thread

In reply to David Woodhouse

Date: Sun, 9 Dec 2007 23:54:27 -0500

The locking issues with TX, especially TX from multiple netdevs, get _so_ much easier if you do it like this.

---
 drivers/net/wireless/libertas/dev.h  |    5 +-
 drivers/net/wireless/libertas/main.c |   24 ++++++++
 drivers/net/wireless/libertas/tx.c   |  103 ++++++++++++++--------------------
 3 files changed, 71 insertions(+), 61 deletions(-)
drivers/net/wireless/libertas/dev.h +4 -1
index 04cf33d..4681405 100644
@@ -164,7 +164,10 @@ struct lbs_private {
 
 	struct mutex lock;
 
-	u8 tmptxbuf[LBS_UPLD_SIZE];
+	/* TX packet ready to be sent... */
+	int tx_pending_len;		/* -1 while building packet */
+
+	u8 tx_pending_buf[LBS_UPLD_SIZE];
 	/* protected by hard_start_xmit serialization */
 
 	/** command-related variables */
drivers/net/wireless/libertas/main.c +24 -0
index 42b64b5..f16c93b 100644
@@ -739,6 +739,8 @@ static int lbs_thread(void *data)
 			shouldsleep = 0;	/* Interrupt pending. Deal with it now */
 		else if (priv->dnld_sent)
 			shouldsleep = 1;	/* Something is en route to the device already */
+		else if (priv->tx_pending_len > 0)
+			shouldsleep = 0;	/* We've a packet to send */
 		else if (priv->cur_cmd)
 			shouldsleep = 1;	/* Can't send a command; one already running */
 		else if (!list_empty(&priv->cmdpendingq))
@@ -852,6 +854,28 @@ static int lbs_thread(void *data)
 		 */
 		if (!list_empty(&priv->cmdpendingq))
 			wake_up_all(&priv->cmd_pending);
+
+		spin_lock_irq(&priv->driver_lock);
+		if (!priv->dnld_sent && priv->tx_pending_len > 0) {
+			int ret = priv->hw_host_to_card(priv, MVMS_DAT,
+							priv->tx_pending_buf,
+							priv->tx_pending_len);
+			if (ret) {
+				lbs_deb_tx("host_to_card failed %d\n", ret);
+				priv->dnld_sent = DNLD_RES_RECEIVED;
+			}
+			priv->tx_pending_len = 0;
+			if (!priv->currenttxskb) {
+				/* We can wake the queues immediately if we aren't
+				   waiting for TX feedback */
+				if (priv->connect_status == LBS_CONNECTED)
+					netif_wake_queue(priv->dev);
+				if (priv->mesh_dev &&
+				    priv->mesh_connect_status == LBS_CONNECTED)
+					netif_wake_queue(priv->mesh_dev);
+			}
+		}
+		spin_unlock_irq(&priv->driver_lock);
 	}
 
 	del_timer(&priv->command_timer);
drivers/net/wireless/libertas/tx.c +43 -60

136 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#51 lore raw

PATCH 45/48 libertas: remove unreachable code from process_rxed_802_11_packet()

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 00:05:37 -0500

The function is only ever called if we're in rtap mode. So the bit in it which is conditional on rtap mode seems a little superfluous.

---
 drivers/net/wireless/libertas/rx.c |   75 +++++++++++++++--------------------
 1 files changed, 32 insertions(+), 43 deletions(-)
drivers/net/wireless/libertas/rx.c +32 -43
index 58e8311..90a2199 100644
@@ -355,52 +355,41 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
 	       skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
 	/* create the exported radio header */
-	if (priv->monitormode == LBS_MONITOR_OFF) {
-		/* no radio header */
-		/* chop the rxpd */
-		skb_pull(skb, sizeof(struct rxpd));
-	}
 
-	else {
-		/* radiotap header */
-		radiotap_hdr.hdr.it_version = 0;
-		/* XXX must check this value for pad */
-		radiotap_hdr.hdr.it_pad = 0;
-		radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
-		radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
-		/* unknown values */
-		radiotap_hdr.flags = 0;
-		radiotap_hdr.chan_freq = 0;
-		radiotap_hdr.chan_flags = 0;
-		radiotap_hdr.antenna = 0;
-		/* known values */
-		radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
-		/* XXX must check no carryout */
-		radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
-		radiotap_hdr.rx_flags = 0;
-		if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
-			radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
-		//memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
-
-		/* chop the rxpd */
-		skb_pull(skb, sizeof(struct rxpd));
-
-		/* add space for the new radio header */
-		if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
-		    pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
-				     GFP_ATOMIC)) {
-			lbs_pr_alert("%s: couldn't pskb_expand_head\n",
-			       __func__);
-		}
-
-		pradiotap_hdr =
-		    (struct rx_radiotap_hdr *)skb_push(skb,
-						     sizeof(struct
-							    rx_radiotap_hdr));
-		memcpy(pradiotap_hdr, &radiotap_hdr,
-		       sizeof(struct rx_radiotap_hdr));
+	/* radiotap header */
+	radiotap_hdr.hdr.it_version = 0;
+	/* XXX must check this value for pad */
+	radiotap_hdr.hdr.it_pad = 0;
+	radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
+	radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
+	/* unknown values */
+	radiotap_hdr.flags = 0;
+	radiotap_hdr.chan_freq = 0;
+	radiotap_hdr.chan_flags = 0;
+	radiotap_hdr.antenna = 0;
+	/* known values */
+	radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
+	/* XXX must check no carryout */
+	radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
+	radiotap_hdr.rx_flags = 0;
+	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
+		radiotap_hdr.rx_flags |= IEEE80211_RADIOTAP_F_RX_BADFCS;
+	//memset(radiotap_hdr.pad, 0x11, IEEE80211_RADIOTAP_HDRLEN - 18);
+
+	/* chop the rxpd */
+	skb_pull(skb, sizeof(struct rxpd));
+
+	/* add space for the new radio header */
+	if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
+	    pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
+			     GFP_ATOMIC)) {
+		lbs_pr_alert("%s: couldn't pskb_expand_head\n",
+			     __func__);
 	}
 
+	pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
+	memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr));
+
 	/* Take the data rate from the rxpd structure
 	 * only if the rate is auto
 	 */
Signature · 1 line
1.5.3.4
#52 lore raw

PATCH 46/48 libertas: fix error cases in lbs_process_rxed_802_11_packet()

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 00:17:28 -0500

---
 drivers/net/wireless/libertas/rx.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/libertas/rx.c +8 -6
index 90a2199..141069f 100644
@@ -337,9 +337,10 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
 	// lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100));
 
 	if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
-		lbs_deb_rx("rx err: frame received wit bad length\n");
+		lbs_deb_rx("rx err: frame received with bad length\n");
 		priv->stats.rx_length_errors++;
-		ret = 0;
+		ret = -EINVAL;
+		kfree(skb);
 		goto done;
 	}
 
@@ -381,10 +382,11 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
 
 	/* add space for the new radio header */
 	if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
-	    pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0,
-			     GFP_ATOMIC)) {
-		lbs_pr_alert("%s: couldn't pskb_expand_head\n",
-			     __func__);
+	    pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
+		lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__);
+		ret = -ENOMEM;
+		kfree_skb(skb);
+		goto done;
 	}
 
 	pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
Signature · 1 line
1.5.3.4
#53 lore raw

PATCH 47/48 libertas: kill lbs_upload_tx_packet()

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 00:49:26 -0500

It replaces two lines of code. And even for those it has to make inferences about things (i.e. which device) which the caller would have just known.

---
 drivers/net/wireless/libertas/decl.h |    2 --
 drivers/net/wireless/libertas/rx.c   |   32 +++++++++-----------------------
 drivers/net/wireless/libertas/tx.c   |    8 +++++++-
 3 files changed, 16 insertions(+), 26 deletions(-)
drivers/net/wireless/libertas/decl.h +0 -2
index fcb5a85..e8387c7 100644
@@ -46,8 +46,6 @@ void lbs_get_fwversion(struct lbs_private *priv,
 	char *fwversion,
 	int maxlen);
 
-void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb);
-
 /** The proc fs interface */
 int lbs_process_rx_command(struct lbs_private *priv);
 void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
drivers/net/wireless/libertas/rx.c +9 -23
index 141069f..6332fd4 100644
@@ -131,22 +131,6 @@ static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd)
 	lbs_deb_leave(LBS_DEB_RX);
 }
 
-void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb)
-{
-	lbs_deb_rx("skb->data %p\n", skb->data);
-
-	if (priv->monitormode != LBS_MONITOR_OFF) {
-		skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
-	} else {
-		if (priv->mesh_dev && IS_MESH_FRAME(skb))
-			skb->protocol = eth_type_trans(skb, priv->mesh_dev);
-		else
-			skb->protocol = eth_type_trans(skb, priv->dev);
-	}
-	skb->ip_summed = CHECKSUM_NONE;
-	netif_rx(skb);
-}
-
 /**
  *  @brief This function processes received packet and forwards it
  *  to kernel/upper layer
@@ -158,7 +142,7 @@ void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb)
 int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 {
 	int ret = 0;
-
+	struct net_device *dev = priv->dev;
 	struct rxpackethdr *p_rx_pkt;
 	struct rxpd *p_rx_pd;
 
@@ -169,15 +153,15 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 
 	lbs_deb_enter(LBS_DEB_RX);
 
+	skb->ip_summed = CHECKSUM_NONE;
+
 	if (priv->monitormode != LBS_MONITOR_OFF)
 		return process_rxed_802_11_packet(priv, skb);
 
 	p_rx_pkt = (struct rxpackethdr *) skb->data;
 	p_rx_pd = &p_rx_pkt->rx_pd;
-	if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
-		SET_MESH_FRAME(skb);
-	else
-		UNSET_MESH_FRAME(skb);
+	if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
+		dev = priv->mesh_dev;
 
 	lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
 		 min_t(unsigned int, skb->len, 100));
@@ -262,7 +246,8 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 	priv->stats.rx_bytes += skb->len;
 	priv->stats.rx_packets++;
 
-	lbs_upload_rx_packet(priv, skb);
+	skb->protocol = eth_type_trans(skb, dev);
+	netif_rx(skb);
 
 	ret = 0;
 done:
@@ -404,7 +389,8 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
 	priv->stats.rx_bytes += skb->len;
 	priv->stats.rx_packets++;
 
-	lbs_upload_rx_packet(priv, skb);
+	skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
+	netif_rx(skb);
 
 	ret = 0;
 
drivers/net/wireless/libertas/tx.c +7 -1
index e2141f0..8a1a396 100644
@@ -2,6 +2,7 @@
   * This file contains the handling of TX in wlan driver.
   */
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 
 #include "hostcmd.h"
 #include "radiotap.h"
@@ -203,7 +204,12 @@ void lbs_send_tx_feedback(struct lbs_private *priv)
 	try_count = (status >> 16) & 0xff;
 	radiotap_hdr->data_retries = (try_count) ?
 	    (1 + priv->txretrycount - try_count) : 0;
-	lbs_upload_rx_packet(priv, priv->currenttxskb);
+
+
+	priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb,
+						      priv->rtap_net_dev);
+	netif_rx(priv->currenttxskb);
+
 	priv->currenttxskb = NULL;
 
 	if (priv->connect_status == LBS_CONNECTED)
Signature · 1 line
1.5.3.4
#54 lore raw

PATCH 48/48 libertas: kill (IS,SET,UNSET)_MESH_FRAME.

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 00:51:35 -0500

No need for these any more. We've collapsed all the unneeded nests of functions which needed to keep track of which device the skb belonged to.

---
 drivers/net/wireless/libertas/defs.h |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/defs.h +0 -4
index 8242384..04db6af 100644
@@ -257,10 +257,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 
 #define	MAX_LEDS			8
 
-#define IS_MESH_FRAME(x) (x->cb[6])
-#define SET_MESH_FRAME(x) (x->cb[6]=1)
-#define UNSET_MESH_FRAME(x) (x->cb[6]=0)
-
 /** Global Variable Declaration */
 extern const char lbs_driver_version[];
 extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
Signature · 1 line
1.5.3.4
#55 lore raw

[PATCH 49/48] libertas: fix use-after-free error

In reply to David Woodhouse

From: Holger Schurig <[email protected]>
Date: Mon, 10 Dec 2007 12:19:55 +0100

Previously, the display of subscribed events could be wrong.

---
 drivers/net/wireless/libertas/debugfs.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/libertas/debugfs.c +8 -6
index e8a24d7..f4858bd 100644
@@ -409,30 +409,32 @@ static ssize_t lbs_threshold_read(
 	char *buf = (char *)addr;
 	u8 value;
 	u8 freq;
+	int events = 0;
 
-	struct cmd_ds_802_11_subscribe_event *events = kzalloc(
+	struct cmd_ds_802_11_subscribe_event *subscribed = kzalloc(
 		sizeof(struct cmd_ds_802_11_subscribe_event),
 		GFP_KERNEL);
 	struct mrvlietypes_thresholds *got;
 
 	res = lbs_prepare_and_send_command(priv,
 			CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET,
-			CMD_OPTION_WAITFORRSP, 0, events);
+			CMD_OPTION_WAITFORRSP, 0, subscribed);
 	if (res) {
-		kfree(events);
+		kfree(subscribed);
 		return res;
 	}
 
-	got = lbs_tlv_find(tlv_type, events->tlv, sizeof(events->tlv));
+	got = lbs_tlv_find(tlv_type, subscribed->tlv, sizeof(subscribed->tlv));
 	if (got) {
 		value = got->value;
 		freq  = got->freq;
+		events = le16_to_cpu(subscribed->events);
 	}
-	kfree(events);
+	kfree(subscribed);
 
 	if (got)
 		pos += snprintf(buf, len, "%d %d %d\n", value, freq,
-			!!(le16_to_cpu(events->events) & event_mask));
+			!!(events & event_mask));
 
 	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
 
Signature · 1 line
1.5.3.4
#56 lore raw

[PATCH 52/48] libertas: make lbs_cmd() usage nicer

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Mon, 10 Dec 2007 15:11:23 -0500

Define a macro that relieves the caller from having to use sizeof on the command structure when calling lbs_cmd(), and move the prototype of __lbs_cmd() to a new cmd.h file.

---
 drivers/net/wireless/libertas/cmd.c    |    8 ++++----
 drivers/net/wireless/libertas/cmd.h    |   16 ++++++++++++++++
 drivers/net/wireless/libertas/decl.h   |    4 ----
 drivers/net/wireless/libertas/if_usb.c |    3 ++-
 4 files changed, 22 insertions(+), 9 deletions(-)
 create mode 100644 drivers/net/wireless/libertas/cmd.h
drivers/net/wireless/libertas/cmd.c +4 -4
index 228e3fe..c7c226c 100644
@@ -1994,9 +1994,9 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  *                      the result code from the firmware
  */
 
-int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size,
-	    int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
-	    unsigned long callback_arg)
+int __lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size,
+	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
+	      unsigned long callback_arg)
 {
 	struct cmd_ctrl_node *cmdnode;
 	struct cmd_ds_gen *cmdptr;
@@ -2066,6 +2066,6 @@ done:
 	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(lbs_cmd);
+EXPORT_SYMBOL_GPL(__lbs_cmd);
 
 
drivers/net/wireless/libertas/cmd.h new file +16 -0
new file mode 100644
index 0000000..546db49
@@ -0,0 +1,16 @@
+/* Copyright (C) 2007, Red Hat, Inc. */
+
+#ifndef _LBS_CMD_H_
+#define _LBS_CMD_H_
+
+#include "hostcmd.h"
+#include "dev.h"
+
+#define lbs_cmd(priv, cmdnr, cmd, callback, callback_arg) \
+	__lbs_cmd(priv, cmdnr, &cmd, sizeof(cmd), callback, callback_arg)
+
+int __lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size, 
+	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
+	      unsigned long callback_arg);
+
+#endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/decl.h +0 -4
index 82727a8..33c8305 100644
@@ -23,10 +23,6 @@ void lbs_send_tx_feedback(struct lbs_private *priv);
 
 int lbs_free_cmd_buffer(struct lbs_private *priv);
 
-int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size, 
-	    int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
-	    unsigned long callback_arg);
-
 int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_no,
 	u16 cmd_action,
drivers/net/wireless/libertas/if_usb.c +2 -1
index 1c23166..8ff57a6 100644
@@ -13,6 +13,7 @@
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
+#include "cmd.h"
 #include "if_usb.h"
 
 #define MESSAGE_HEADER_LEN	4
@@ -108,7 +109,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 	b2_cmd.action = 0;
 	b2_cmd.version = priv->boot2_version;
 
-	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd), NULL, 0))
+	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, b2_cmd, NULL, 0))
 		lbs_deb_usb("Setting boot2 version failed\n");
 }
 
Signature · 1 line
1.5.3.4
#57 lore raw

[PATCH 53/48] libertas: remove pre_open_check()

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 15:25:42 -0500

The firmware is always initialised before we register the netdevices. It's not possible for pre_open_check() to fail.

One day we might try loading firmware in ->open(), but still it won't be just a _check_, like this.

---
 drivers/net/wireless/libertas/main.c |   32 --------------------------------
 1 files changed, 0 insertions(+), 32 deletions(-)
drivers/net/wireless/libertas/main.c +0 -32
index 2797149..3d9de7a 100644
@@ -367,34 +367,6 @@ static struct attribute_group lbs_mesh_attr_group = {
 };
 
 /**
- *  @brief Check if the device can be open and wait if necessary.
- *
- *  @param dev     A pointer to net_device structure
- *  @return 	   0
- *
- * For USB adapter, on some systems the device open handler will be
- * called before FW ready. Use the following flag check and wait
- * function to work around the issue.
- *
- */
-static int pre_open_check(struct net_device *dev)
-{
-	struct lbs_private *priv = (struct lbs_private *) dev->priv;
-	int i = 0;
-
-	while (!priv->fw_ready && i < 20) {
-		i++;
-		msleep_interruptible(100);
-	}
-	if (!priv->fw_ready) {
-		lbs_pr_err("firmware not ready\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-/**
  *  @brief This function opens the device
  *
  *  @param dev     A pointer to net_device structure
@@ -433,8 +405,6 @@ static int lbs_mesh_open(struct net_device *dev)
 {
 	struct lbs_private *priv = (struct lbs_private *) dev->priv ;
 
-	if (pre_open_check(dev) == -1)
-		return -1;
 	priv->mesh_open = 1 ;
 	netif_wake_queue(priv->mesh_dev);
 
@@ -457,8 +427,6 @@ static int lbs_open(struct net_device *dev)
 {
 	struct lbs_private *priv = (struct lbs_private *) dev->priv ;
 
-	if(pre_open_check(dev) == -1)
-		return -1;
 	priv->infra_open = 1 ;
 	netif_wake_queue(priv->dev);
 	if (priv->open == 0)
Signature · 1 line
1.5.3.4
#58 lore raw

[PATCH 50/48] libertas: add opaque extra argument to cmd callback function

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 13:36:10 -0500

This will be useful for letting callbacks do stuff like copying the response into a buffer provided by the caller of lbs_cmd()

---
 drivers/net/wireless/libertas/cmd.c     |    6 +++++-
 drivers/net/wireless/libertas/cmdresp.c |   11 ++++++-----
 drivers/net/wireless/libertas/decl.h    |    3 ++-
 drivers/net/wireless/libertas/hostcmd.h |    3 ++-
 drivers/net/wireless/libertas/if_usb.c  |    2 +-
 5 files changed, 16 insertions(+), 9 deletions(-)
drivers/net/wireless/libertas/cmd.c +5 -1
index 49a9aee..228e3fe 100644
@@ -1642,6 +1642,7 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
 	ptempnode->wait_option = 0;
 	ptempnode->pdata_buf = NULL;
 	ptempnode->callback = NULL;
+	ptempnode->callback_arg = 0;
 
 	if (ptempnode->bufvirtualaddr != NULL)
 		memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
@@ -1670,6 +1671,7 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 	ptempnode->wait_option = wait_option;
 	ptempnode->pdata_buf = pdata_buf;
 	ptempnode->callback = NULL;
+	ptempnode->callback_arg = 0;
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
@@ -1993,7 +1995,8 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  */
 
 int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size,
-	    int (*callback)(uint16_t, struct cmd_ds_command *, struct lbs_private *))
+	    int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
+	    unsigned long callback_arg)
 {
 	struct cmd_ctrl_node *cmdnode;
 	struct cmd_ds_gen *cmdptr;
@@ -2028,6 +2031,7 @@ int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size,
 	cmdptr = (struct cmd_ds_gen *)cmdnode->bufvirtualaddr;
 	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
 	cmdnode->callback = callback;
+	cmdnode->callback_arg = callback_arg;
 
 	/* Set sequence number, clean result, move to buffer */
 	priv->seqnum++;
drivers/net/wireless/libertas/cmdresp.c +6 -5
index ab6e729..7bad257 100644
@@ -552,12 +552,13 @@ static int lbs_ret_802_11_subscribe_event(struct lbs_private *priv,
 	return 0;
 }
 
-static inline int handle_cmd_response(u16 respcmd,
-				      struct cmd_ds_command *resp,
-				      struct lbs_private *priv)
+static inline int handle_cmd_response(struct lbs_private *priv,
+				      unsigned long dummy,
+				      struct cmd_ds_command *resp)
 {
 	int ret = 0;
 	unsigned long flags;
+	uint16_t respcmd = le16_to_cpu(resp->command);
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
@@ -861,9 +862,9 @@ int lbs_process_rx_command(struct lbs_private *priv)
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 	if (priv->cur_cmd && priv->cur_cmd->callback)
-		ret = priv->cur_cmd->callback(respcmd, resp, priv);
+		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, resp);
 	else
-		ret = handle_cmd_response(respcmd, resp, priv);
+		ret = handle_cmd_response(priv, 0, resp);
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 
drivers/net/wireless/libertas/decl.h +2 -1
index e8387c7..a086d0c 100644
@@ -24,7 +24,8 @@ void lbs_send_tx_feedback(struct lbs_private *priv);
 int lbs_free_cmd_buffer(struct lbs_private *priv);
 
 int lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size, 
-	    int (*callback)(uint16_t, struct cmd_ds_command *, struct lbs_private *));
+	    int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
+	    unsigned long callback_arg);
 
 int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_no,
drivers/net/wireless/libertas/hostcmd.h +2 -1
index f1c1d3f..ed502b7 100644
@@ -71,7 +71,8 @@ struct cmd_ctrl_node {
 	u16 wait_option;
 	/* command response */
 	void *pdata_buf;
-	int (*callback)(uint16_t respcmd, struct cmd_ds_command *resp, struct lbs_private *priv);
+	int (*callback)(struct lbs_private *priv, unsigned long arg, struct cmd_ds_command *resp);
+	unsigned long callback_arg;
 	/* command data */
 	u8 *bufvirtualaddr;
 	/* wait queue */
drivers/net/wireless/libertas/if_usb.c +1 -1
index 141d185..f59fd73 100644
@@ -108,7 +108,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 	b2_cmd.action = 0;
 	b2_cmd.version = priv->boot2_version;
 
-	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd), NULL))
+	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, sizeof(b2_cmd), NULL, 0))
 		lbs_deb_usb("Setting boot2 version failed\n");
 }
 
Signature · 1 line
1.5.3.4
#59 lore raw

[PATCH 51/48] libertas: clean up lbs_interrupt()

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 14:58:37 -0500

Make it take struct lbs_private as argument; that's all it wants anyway, and all callers were starting off from that. Don't wake the netif queues, because those should be handled elsewhere. And sort out the locking, with a big nasty warning for those who don't have the driver_lock locked when they call it.

Oh, and fix if_cs.c to lock the driver_lock before calling it.

---
 drivers/net/wireless/libertas/decl.h    |    2 +-
 drivers/net/wireless/libertas/if_cs.c   |    5 +++--
 drivers/net/wireless/libertas/if_sdio.c |    4 ++--
 drivers/net/wireless/libertas/if_usb.c  |    4 ++--
 drivers/net/wireless/libertas/main.c    |   19 +++++++++----------
 5 files changed, 17 insertions(+), 17 deletions(-)
drivers/net/wireless/libertas/decl.h +1 -1
index a086d0c..82727a8 100644
@@ -39,7 +39,7 @@ void lbs_queue_cmd(struct lbs_private *priv,
 int lbs_allocate_cmd_buffer(struct lbs_private *priv);
 int lbs_execute_next_command(struct lbs_private *priv);
 int lbs_process_event(struct lbs_private *priv);
-void lbs_interrupt(struct net_device *);
+void lbs_interrupt(struct lbs_private *priv);
 int lbs_set_radio_control(struct lbs_private *priv);
 u32 lbs_fw_index_to_data_rate(u8 index);
 u8 lbs_data_rate_to_fw_index(u32 rate);
drivers/net/wireless/libertas/if_cs.c +3 -2
index 49a0178..2acbe5d 100644
@@ -264,8 +264,9 @@ static irqreturn_t if_cs_interrupt(int irq, void *data)
 		/* clear interrupt */
 		if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause & IF_CS_C_IC_MASK);
 	}
-
-	lbs_interrupt(card->priv->dev);
+	spin_lock(&card->priv->driver_lock);
+	lbs_interrupt(card->priv);
+	spin_unlock(&card->priv->driver_lock);
 
 	return IRQ_HANDLED;
 }
drivers/net/wireless/libertas/if_sdio.c +2 -2
index 6456613..94060da 100644
@@ -154,7 +154,7 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 
 	card->int_cause |= MRVDRV_CMD_UPLD_RDY;
 
-	lbs_interrupt(card->priv->dev);
+	lbs_interrupt(card->priv);
 
 	ret = 0;
 
@@ -236,7 +236,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
 	card->event = event;
 	card->int_cause |= MRVDRV_CARDEVENT;
 
-	lbs_interrupt(card->priv->dev);
+	lbs_interrupt(card->priv);
 
 	spin_unlock_irqrestore(&card->priv->driver_lock, flags);
 
drivers/net/wireless/libertas/if_usb.c +2 -2
index f59fd73..1c23166 100644
@@ -632,7 +632,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 	       priv->upld_len);
 
 	kfree_skb(skb);
-	lbs_interrupt(priv->dev);
+	lbs_interrupt(priv);
 	spin_unlock(&priv->driver_lock);
 
 	lbs_deb_usbd(&cardp->udev->dev,
@@ -705,7 +705,7 @@ static void if_usb_receive(struct urb *urb)
 		cardp->usb_event_cause <<= 3;
 		cardp->usb_int_cause |= MRVDRV_CARDEVENT;
 		kfree_skb(skb);
-		lbs_interrupt(priv->dev);
+		lbs_interrupt(priv);
 		spin_unlock(&priv->driver_lock);
 		goto rx_exit;
 	default:
drivers/net/wireless/libertas/main.c +9 -10
index f16c93b..2797149 100644
@@ -1408,23 +1408,22 @@ out:
  *  @param dev     A pointer to net_device structure
  *  @return 	   n/a
  */
-void lbs_interrupt(struct net_device *dev)
+void lbs_interrupt(struct lbs_private *priv)
 {
-	struct lbs_private *priv = dev->priv;
-
 	lbs_deb_enter(LBS_DEB_THREAD);
 
-	lbs_deb_thread("lbs_interrupt: intcounter=%d\n",
-	       priv->intcounter);
+	lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);
+
+	if (spin_trylock(&priv->driver_lock)) {
+		spin_unlock(&priv->driver_lock);
+		printk(KERN_CRIT "%s called without driver_lock held\n", __func__);
+		WARN_ON(1);
+	}
 
 	priv->intcounter++;
 
-	if (priv->psstate == PS_STATE_SLEEP) {
+	if (priv->psstate == PS_STATE_SLEEP)
 		priv->psstate = PS_STATE_AWAKE;
-		netif_wake_queue(dev);
-		if (priv->mesh_dev)
-			netif_wake_queue(priv->mesh_dev);
-	}
 
 	wake_up_interruptible(&priv->waitq);
 
Signature · 1 line
1.5.3.4
#60 lore raw

[PATCH 54/48] libertas: clean up is_command_allowed_in_ps()

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Mon, 10 Dec 2007 15:24:47 -0500

Total overkill to have an array when there's only one command in it.

---
 drivers/net/wireless/libertas/cmd.c |   24 +++++++++---------------
 1 files changed, 9 insertions(+), 15 deletions(-)
drivers/net/wireless/libertas/cmd.c +9 -15
index c7c226c..2efba57 100644
@@ -19,26 +19,20 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 		    u16 wait_option, void *pdata_buf);
 
 
-static u16 commands_allowed_in_ps[] = {
-	CMD_802_11_RSSI,
-};
-
 /**
- *  @brief This function checks if the commans is allowed
- *  in PS mode not.
+ *  @brief Checks whether a command is allowed in Power Save mode
  *
  *  @param command the command ID
- *  @return 	   TRUE or FALSE
+ *  @return 	   1 if allowed, 0 if not allowed
  */
-static u8 is_command_allowed_in_ps(__le16 command)
+static u8 is_command_allowed_in_ps(u16 cmd)
 {
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(commands_allowed_in_ps); i++) {
-		if (command == cpu_to_le16(commands_allowed_in_ps[i]))
-			return 1;
+	switch (cmd) {
+	case CMD_802_11_RSSI:
+		return 1;
+	default:
+		break;
 	}
-
 	return 0;
 }
 
@@ -1715,7 +1709,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 	if (cmdnode) {
 		cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
 
-		if (is_command_allowed_in_ps(cmdptr->command)) {
+		if (is_command_allowed_in_ps(le16_to_cpu(cmdptr->command))) {
 			if ((priv->psstate == PS_STATE_SLEEP) ||
 			    (priv->psstate == PS_STATE_PRE_SLEEP)) {
 				lbs_deb_host(
Signature · 1 line
1.5.3.4
#61 lore raw

[PATCH 58/48] libertas: don't run thread while firmware not yet ready

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 11:55:37 -0500

---
 drivers/net/wireless/libertas/main.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/net/wireless/libertas/main.c +5 -0
index 8866402..9a23109 100644
@@ -671,6 +671,8 @@ static int lbs_thread(void *data)
 			shouldsleep = 1;	/* Sleep mode. Nothing we can do till it wakes */
 		else if (priv->intcounter)
 			shouldsleep = 0;	/* Interrupt pending. Deal with it now */
+		else if (!priv->fw_ready)
+			shouldsleep = 1;	/* Firmware not ready. We're waiting for it */
 		else if (priv->dnld_sent)
 			shouldsleep = 1;	/* Something is en route to the device already */
 		else if (priv->tx_pending_len > 0)
@@ -753,6 +755,9 @@ static int lbs_thread(void *data)
 		} else
 			spin_unlock_irq(&priv->driver_lock);
 
+		if (!priv->fw_ready)
+			continue;
+
 		/* Check if we need to confirm Sleep Request received previously */
 		if (priv->psstate == PS_STATE_PRE_SLEEP &&
 		    !priv->dnld_sent && !priv->cur_cmd) {
Signature · 1 line
1.5.3.4
#62 lore raw

[PATCH 56/48] libertas: improve reliability of firmware reloading on USB

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 18:53:34 -0500

Increase the delay between issuing the RESET command and the usb reset, and be prepared to discard more than one 'normal' packet from it before it resets.

---
 drivers/net/wireless/libertas/if_usb.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/libertas/if_usb.c +3 -3
index 8ff57a6..0a37950 100644
@@ -389,9 +389,9 @@ static int if_usb_reset_device(struct usb_card_rec *cardp)
 	cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
 	usb_tx_block(cardp, cardp->bulk_out_buffer, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
 
-	msleep(10);
+	msleep(100);
 	ret = usb_reset_device(cardp->udev);
-	msleep(10);
+	msleep(100);
 
 	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
 
@@ -500,7 +500,7 @@ static void if_usb_receive_fwload(struct urb *urb)
 		return;
 	}
 
-	if (cardp->bootcmdresp == 0) {
+	if (cardp->bootcmdresp <= 0) {
 		memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
 			sizeof(bootcmdresp));
 		if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
Signature · 1 line
1.5.3.4
#63 lore raw

[PATCH 55/48] libertas: make rtap and normal modes mutually exclusive, clean up open/stop

In reply to David Woodhouse

Date: Mon, 10 Dec 2007 16:38:18 -0500

---
 drivers/net/wireless/libertas/dev.h  |    1 -
 drivers/net/wireless/libertas/main.c |  133 +++++++++++++---------------------
 2 files changed, 50 insertions(+), 84 deletions(-)
drivers/net/wireless/libertas/dev.h +0 -1
index 4681405..9921d0c 100644
@@ -99,7 +99,6 @@ struct lbs_mesh_stats {
 
 /** Private structure for the MV device */
 struct lbs_private {
-	int open;
 	int mesh_open;
 	int infra_open;
 	int mesh_autostart_enabled;
drivers/net/wireless/libertas/main.c +50 -83

203 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#64 lore raw

[PATCH 57/48] libertas: switch to a waitqueue and timer for handling USB firmware load

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 00:07:58 -0500

No need to busy-wait, even if we did have a 100ms delay in the loop. This makes it easier to support the new 'firmware ready' event which is in the new firmware, too.

---
 drivers/net/wireless/libertas/if_usb.c |   38 +++++++++++++++++++++----------
 drivers/net/wireless/libertas/if_usb.h |    5 ++++
 2 files changed, 31 insertions(+), 12 deletions(-)
drivers/net/wireless/libertas/if_usb.c +26 -12
index 0a37950..a086653 100644
@@ -113,7 +113,18 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 		lbs_deb_usb("Setting boot2 version failed\n");
 }
 
+void if_usb_fw_timeo(unsigned long priv)
+{
+	struct usb_card_rec *cardp = (void *)priv;
 
+	if (cardp->fwdnldover) {
+		lbs_deb_usb("Download complete, no event. Assuming success\n");
+	} else {
+		lbs_pr_err("Download timed out\n");
+		cardp->surprise_removed = 1;
+	}
+	wake_up(&cardp->fw_wq);
+}
 /**
  *  @brief sets the configuration values
  *  @param ifnum	interface number
@@ -138,6 +149,9 @@ static int if_usb_probe(struct usb_interface *intf,
 		goto error;
 	}
 
+	setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
+	init_waitqueue_head(&cardp->fw_wq);
+								     
 	cardp->udev = udev;
 	iface_desc = intf->cur_altsetting;
 
@@ -296,7 +310,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
  *  @param priv		pointer to struct lbs_private
  *  @return 	   	0
  */
-static int if_prog_firmware(struct usb_card_rec *cardp)
+static int if_usb_send_fw_pkt(struct usb_card_rec *cardp)
 {
 	struct FWData *fwdata;
 	struct fwheader *fwheader;
@@ -566,19 +580,21 @@ static void if_usb_receive_fwload(struct urb *urb)
 
 	kfree_skb(skb);
 
+	/* reschedule timer for 200ms hence */
+	mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));
+
 	if (cardp->fwfinalblk) {
 		cardp->fwdnldover = 1;
 		goto exit;
 	}
 
-	if_prog_firmware(cardp);
+	if_usb_send_fw_pkt(cardp);
 
 	if_usb_submit_rx_urb_fwload(cardp);
-exit:
+ exit:
 	kfree(syncfwheader);
 
 	return;
-
 }
 
 #define MRVDRV_MIN_PKT_LEN	30
@@ -911,15 +927,13 @@ restart:
 	cardp->totalbytes = 0;
 	cardp->fwfinalblk = 0;
 
-	if_prog_firmware(cardp);
+	/* Send the first firmware packet... */
+	if_usb_send_fw_pkt(cardp);
 
-	do {
-		lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
-		i++;
-		msleep_interruptible(100);
-		if (cardp->surprise_removed || i >= 20)
-			break;
-	} while (!cardp->fwdnldover);
+	/* ... and wait for the process to complete */
+	wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
+	
+	del_timer_sync(&cardp->fw_timeout);
 
 	if (!cardp->fwdnldover) {
 		lbs_pr_info("failed to load fw, resetting device!\n");
drivers/net/wireless/libertas/if_usb.h +5 -0
index 940a369..224c957 100644
@@ -1,6 +1,9 @@
 #ifndef _LBS_IF_USB_H
 #define _LBS_IF_USB_H
 
+#include <linux/wait.h>
+#include <linux/timer.h>
+
 /**
   * This file contains definition for USB interface.
   */
@@ -56,6 +59,8 @@ struct usb_card_rec {
 	u8 bulk_out_endpointAddr;
 
 	const struct firmware *fw;
+	struct timer_list fw_timeout;
+	wait_queue_head_t fw_wq;
 	u8 CRC_OK;
 	u32 fwseqnum;
 	u32 lastseqnum;
Signature · 1 line
1.5.3.4
#65 lore raw

[PATCH 59/48] libertas: clean up direct command handling

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 12:33:30 -0500

Move direct command handling through __lbs_cmd() over to using the header as the first member of the command structure, and only define the __lbs_cmd() callback in one place rather than 3. Convert boot2 version command to new usage.

---
 drivers/net/wireless/libertas/cmd.c     |   22 ++++++++++++----------
 drivers/net/wireless/libertas/cmd.h     |    8 +++++---
 drivers/net/wireless/libertas/cmdresp.c |    7 ++++---
 drivers/net/wireless/libertas/hostcmd.h |   12 ++++++++++--
 4 files changed, 31 insertions(+), 18 deletions(-)
drivers/net/wireless/libertas/cmd.c +12 -10
index 2efba57..78870c7 100644
@@ -1988,12 +1988,13 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  *                      the result code from the firmware
  */
 
-int __lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size,
-	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
+int __lbs_cmd(struct lbs_private *priv, uint16_t command,
+	      struct cmd_header *in_cmd, int in_cmd_size,
+	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
 	      unsigned long callback_arg)
 {
 	struct cmd_ctrl_node *cmdnode;
-	struct cmd_ds_gen *cmdptr;
+	struct cmd_header *send_cmd;
 	unsigned long flags;
 	int ret = 0;
 
@@ -2012,7 +2013,6 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_siz
 	}
 
 	cmdnode = lbs_get_cmd_ctrl_node(priv);
-
 	if (cmdnode == NULL) {
 		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
 
@@ -2022,18 +2022,20 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_siz
 		goto done;
 	}
 
-	cmdptr = (struct cmd_ds_gen *)cmdnode->bufvirtualaddr;
+	send_cmd = (struct cmd_header *) cmdnode->bufvirtualaddr;
 	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
 	cmdnode->callback = callback;
 	cmdnode->callback_arg = callback_arg;
 
+	/* Copy the incoming command to the buffer */
+	memcpy(send_cmd, in_cmd, in_cmd_size);
+
 	/* Set sequence number, clean result, move to buffer */
 	priv->seqnum++;
-	cmdptr->command = cpu_to_le16(command);
-	cmdptr->size    = cpu_to_le16(cmd_size + S_DS_GEN);
-	cmdptr->seqnum = cpu_to_le16(priv->seqnum);
-	cmdptr->result = 0;
-	memcpy(cmdptr->cmdresp, cmd, cmd_size);
+	send_cmd->command = cpu_to_le16(command);
+	send_cmd->size    = cpu_to_le16(in_cmd_size);
+	send_cmd->seqnum  = cpu_to_le16(priv->seqnum);
+	send_cmd->result  = 0;
 
 	lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
 
drivers/net/wireless/libertas/cmd.h +5 -3
index 546db49..259d3e8 100644
@@ -7,10 +7,12 @@
 #include "dev.h"
 
 #define lbs_cmd(priv, cmdnr, cmd, callback, callback_arg) \
-	__lbs_cmd(priv, cmdnr, &cmd, sizeof(cmd), callback, callback_arg)
+	__lbs_cmd(priv, cmdnr, (struct cmd_header *) &cmd, sizeof(cmd), \
+			callback, callback_arg)
 
-int __lbs_cmd(struct lbs_private *priv, uint16_t command, void *cmd, int cmd_size, 
-	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_ds_command *),
+int __lbs_cmd(struct lbs_private *priv, uint16_t command,
+	      struct cmd_header *in_cmd, int in_cmd_size, 
+	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
 	      unsigned long callback_arg);
 
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/cmdresp.c +4 -3
index 7bad257..9113669 100644
@@ -861,9 +861,10 @@ int lbs_process_rx_command(struct lbs_private *priv)
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-	if (priv->cur_cmd && priv->cur_cmd->callback)
-		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg, resp);
-	else
+	if (priv->cur_cmd && priv->cur_cmd->callback) {
+		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
+				(struct cmd_header *) resp);
+	} else
 		ret = handle_cmd_response(priv, 0, resp);
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
drivers/net/wireless/libertas/hostcmd.h +10 -2
index ed502b7..93ac46a 100644
@@ -65,13 +65,20 @@ struct rxpd {
 	u8 reserved[3];
 };
 
+struct cmd_header {
+	__le16 command;
+	__le16 size;
+	__le16 seqnum;
+	__le16 result;
+} __attribute__ ((packed));
+
 struct cmd_ctrl_node {
 	struct list_head list;
 	/* wait for finish or not */
 	u16 wait_option;
 	/* command response */
 	void *pdata_buf;
-	int (*callback)(struct lbs_private *priv, unsigned long arg, struct cmd_ds_command *resp);
+	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
 	unsigned long callback_arg;
 	/* command data */
 	u8 *bufvirtualaddr;
@@ -424,6 +431,8 @@ struct cmd_ds_802_11_monitor_mode {
 };
 
 struct cmd_ds_set_boot2_ver {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 version;
 };
@@ -678,7 +687,6 @@ struct cmd_ds_command {
 		struct cmd_ds_bt_access bt;
 		struct cmd_ds_fwt_access fwt;
 		struct cmd_ds_mesh_access mesh;
-		struct cmd_ds_set_boot2_ver boot2_ver;
 		struct cmd_ds_get_tsf gettsf;
 		struct cmd_ds_802_11_subscribe_event subscribe_event;
 		struct cmd_ds_802_11_beacon_control bcn_ctrl;
Signature · 1 line
1.5.3.4
#66 lore raw

[PATCH 60/48] libertas: add simple copyback command callback

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 12:40:35 -0500

A simple callback which copies the response back into the command buffer that was used to send the command to the card. Will allow for direct command processing outside the mega-switches in cmd.c and cmdresp.c.

---
 drivers/net/wireless/libertas/cmd.c |   29 ++++++++++++++++++++++++++++-
 drivers/net/wireless/libertas/cmd.h |    7 +++++++
 2 files changed, 35 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmd.c +28 -1
index 78870c7..c4b32a0 100644
@@ -1972,6 +1972,34 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
 
 
 /**
+ *  @brief Simple callback that copies response back into command
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param extra  	A pointer to the original command structure for which
+ *                      'resp' is a response
+ *  @param resp         A pointer to the command response
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
+			struct cmd_header *resp)
+{
+	struct cmd_header *buf = (void *)extra;
+	uint16_t copy_len;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
+	lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, "
+		    "copy back buffer was %u bytes", copy_len, resp->size,
+		    buf->size);
+	memcpy(buf, resp, copy_len);
+
+	lbs_deb_leave(LBS_DEB_CMD);
+	return 0;
+}
+
+/**
  *  @brief Simple way to call firmware functions
  *
  *  @param priv    	A pointer to struct lbs_private structure
@@ -1987,7 +2015,6 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  *  @return 	   	-1 in case of a higher level error, otherwise
  *                      the result code from the firmware
  */
-
 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	      struct cmd_header *in_cmd, int in_cmd_size,
 	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
drivers/net/wireless/libertas/cmd.h +7 -0
index 259d3e8..72857a1 100644
@@ -10,9 +10,16 @@
 	__lbs_cmd(priv, cmdnr, (struct cmd_header *) &cmd, sizeof(cmd), \
 			callback, callback_arg)
 
+#define lbs_cmd_with_response(priv, cmdnr, cmd) \
+	__lbs_cmd(priv, cmdnr, (struct cmd_header *) &cmd, sizeof(cmd), \
+		  lbs_cmd_copyback, (unsigned long) &cmd)
+ 
 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	      struct cmd_header *in_cmd, int in_cmd_size, 
 	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
 	      unsigned long callback_arg);
 
+int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
+		     struct cmd_header *resp);
+
 #endif /* _LBS_CMD_H */
Signature · 1 line
1.5.3.4
#67 lore raw

[PATCH 61/48] libertas: convert GET_HW_SPEC to a direct command

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 12:42:16 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   76 +++++++++++++++++++++++++++----
 drivers/net/wireless/libertas/cmd.h     |    2 +
 drivers/net/wireless/libertas/cmdresp.c |   67 ---------------------------
 drivers/net/wireless/libertas/hostcmd.h |    3 +-
 drivers/net/wireless/libertas/main.c    |    6 +--
 5 files changed, 73 insertions(+), 81 deletions(-)
drivers/net/wireless/libertas/cmd.c +67 -9
index c4b32a0..bb940cc 100644
@@ -11,6 +11,7 @@
 #include "dev.h"
 #include "join.h"
 #include "wext.h"
+#include "cmd.h"
 
 static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
 struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
@@ -36,18 +37,78 @@ static u8 is_command_allowed_in_ps(u16 cmd)
 	return 0;
 }
 
-static int lbs_cmd_hw_spec(struct lbs_private *priv, struct cmd_ds_command *cmd)
+/**
+ *  @brief Updates the hardware details like MAC address and regulatory region
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_update_hw_spec(struct lbs_private *priv)
 {
-	struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec;
+	struct cmd_ds_get_hw_spec cmd;
+	int ret = -1;
+	u32 i;
+	DECLARE_MAC_BUF(mac);
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
-	cmd->command = cpu_to_le16(CMD_GET_HW_SPEC);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_get_hw_spec) + S_DS_GEN);
-	memcpy(hwspec->permanentaddr, priv->current_addr, ETH_ALEN);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
+	ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, cmd);
+	if (ret)
+		goto out;
+
+	priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
+	memcpy(priv->fwreleasenumber, cmd.fwreleasenumber, 4);
+
+	lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
+		    priv->fwreleasenumber[2], priv->fwreleasenumber[1],
+		    priv->fwreleasenumber[0], priv->fwreleasenumber[3]);
+	lbs_deb_cmd("GET_HW_SPEC: MAC addr %s\n",
+		    print_mac(mac, cmd.permanentaddr));
+	lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
+		    cmd.hwifversion, cmd.version);
+
+	/* Clamp region code to 8-bit since FW spec indicates that it should
+	 * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
+	 * returns non-zero high 8 bits here.
+	 */
+	priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
+
+	for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
+		/* use the region code to search for the index */
+		if (priv->regioncode == lbs_region_code_to_index[i])
+			break;
+	}
 
+	/* if it's unidentified region code, use the default (USA) */
+	if (i >= MRVDRV_MAX_REGION_CODE) {
+		priv->regioncode = 0x10;
+		lbs_pr_info("unidentified region code; using the default (USA)\n");
+	}
+
+	if (priv->current_addr[0] == 0xff)
+		memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
+
+	memcpy(priv->dev->dev_addr, priv->current_addr, ETH_ALEN);
+	if (priv->mesh_dev)
+		memcpy(priv->mesh_dev->dev_addr, priv->current_addr, ETH_ALEN);
+
+	if (lbs_set_regiontable(priv, priv->regioncode, 0)) {
+		ret = -1;
+		goto out;
+	}
+
+	if (lbs_set_universaltable(priv, 0)) {
+		ret = -1;
+		goto out;
+	}
+
+out:
 	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
+	return ret;
 }
 
 static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv,
@@ -1223,9 +1284,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 	cmdptr->result = 0;
 
 	switch (cmd_no) {
-	case CMD_GET_HW_SPEC:
-		ret = lbs_cmd_hw_spec(priv, cmdptr);
-		break;
 	case CMD_802_11_PS_MODE:
 		ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action);
 		break;
drivers/net/wireless/libertas/cmd.h +2 -0
index 72857a1..b8e5d21 100644
@@ -22,4 +22,6 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
 		     struct cmd_header *resp);
 
+int lbs_update_hw_spec(struct lbs_private *priv);
+
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/cmdresp.c +0 -67

79 lines not on this page · raw message

drivers/net/wireless/libertas/hostcmd.h +2 -1
index 93ac46a..a87c217 100644
@@ -119,6 +119,8 @@ struct cmd_ds_gen {
  * This structure defines the response for the GET_HW_SPEC command
  */
 struct cmd_ds_get_hw_spec {
+	struct cmd_header hdr;
+
 	/* HW Interface version number */
 	__le16 hwifversion;
 	/* HW version number */
@@ -637,7 +639,6 @@ struct cmd_ds_command {
 
 	/* command Body */
 	union {
-		struct cmd_ds_get_hw_spec hwspec;
 		struct cmd_ds_802_11_ps_mode psmode;
 		struct cmd_ds_802_11_scan scan;
 		struct cmd_ds_802_11_scan_rsp scanresp;
drivers/net/wireless/libertas/main.c +2 -4
index 9a23109..9f6c119 100644
@@ -22,6 +22,7 @@
 #include "debugfs.h"
 #include "assoc.h"
 #include "join.h"
+#include "cmd.h"
 
 #define DRIVER_RELEASE_VERSION "323.p0"
 const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
@@ -843,10 +844,7 @@ static int lbs_setup_firmware(struct lbs_private *priv)
 	 * Read MAC address from HW
 	 */
 	memset(priv->current_addr, 0xff, ETH_ALEN);
-
-	ret = lbs_prepare_and_send_command(priv, CMD_GET_HW_SPEC,
-				    0, CMD_OPTION_WAITFORRSP, 0, NULL);
-
+	ret = lbs_update_hw_spec(priv);
 	if (ret) {
 		ret = -1;
 		goto done;
Signature · 1 line
1.5.3.4
#68 lore raw

[PATCH 63/48] libertas: move removal of lbs_rtap file to lbs_stop_card()

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 12:54:43 -0500

This prevents us from trying to remove it when it didn't exist, in the error case.

---
 drivers/net/wireless/libertas/main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/main.c +1 -1
index 9f6c119..212cce3 100644
@@ -1089,7 +1089,6 @@ int lbs_remove_card(struct lbs_private *priv)
 	lbs_remove_rtap(priv);
 
 	dev = priv->dev;
-	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
 
 	cancel_delayed_work(&priv->scan_work);
 	cancel_delayed_work(&priv->assoc_work);
@@ -1167,6 +1166,7 @@ int lbs_stop_card(struct lbs_private *priv)
 	netif_carrier_off(priv->dev);
 
 	lbs_debugfs_remove_one(priv);
+	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
 
 	/* Flush pending command nodes */
 	spin_lock_irqsave(&priv->driver_lock, flags);
Signature · 1 line
1.5.3.4
#69 lore raw

[PATCH 62/48] libertas: switch USB cardp->priv to 'struct lbs_private *' and resulting fix

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 12:53:43 -0500

Amazing what interesting things the compiler will tell you if you let it know what types you expect to be passing around.

---
 drivers/net/wireless/libertas/if_usb.c |    2 +-
 drivers/net/wireless/libertas/if_usb.h |    4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/if_usb.c +1 -1
index a086653..6cd6c96 100644
@@ -1003,7 +1003,7 @@ static int if_usb_resume(struct usb_interface *intf)
 
 	cardp->rx_urb_recall = 0;
 
-	if_usb_submit_rx_urb(cardp->priv);
+	if_usb_submit_rx_urb(cardp);
 
 	netif_device_attach(cardp->eth_dev);
 	netif_device_attach(priv->mesh_dev);
drivers/net/wireless/libertas/if_usb.h +3 -1
index 224c957..f028df1 100644
@@ -4,6 +4,8 @@
 #include <linux/wait.h>
 #include <linux/timer.h>
 
+struct lbs_private;
+
 /**
   * This file contains definition for USB interface.
   */
@@ -48,7 +50,7 @@ struct usb_card_rec {
 	struct net_device *eth_dev;
 	struct usb_device *udev;
 	struct urb *rx_urb, *tx_urb;
-	void *priv;
+	struct lbs_private *priv;
 	struct read_cb_info rinfo;
 
 	int bulk_in_size;
Signature · 1 line
1.5.3.4
#70 lore raw

[PATCH 64/48] libertas: wait for 'firmware ready' event from firmware after loading

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 13:15:25 -0500

---
 drivers/net/wireless/libertas/host.h   |    1 +
 drivers/net/wireless/libertas/if_usb.c |   26 +++++++++++++++++++++-----
 2 files changed, 22 insertions(+), 5 deletions(-)
drivers/net/wireless/libertas/host.h +1 -0
index 4828bbf..b23af19 100644
@@ -304,5 +304,6 @@ enum cmd_mesh_access_opts {
 #define MACREG_INT_CODE_RSSI_HIGH               28
 #define MACREG_INT_CODE_SNR_HIGH                29
 #define MACREG_INT_CODE_MESH_AUTO_STARTED       35
+#define MACREG_INT_CODE_FIRMWARE_READY          48
 
 #endif
drivers/net/wireless/libertas/if_usb.c +21 -5
index 6cd6c96..c94b6df 100644
@@ -230,6 +230,7 @@ static int if_usb_probe(struct usb_interface *intf,
 		goto err_prog_firmware;
 
 	cardp->priv = priv;
+	cardp->priv->fw_ready = 1;
 
 	if (lbs_add_mesh(priv, &udev->dev))
 		goto err_add_mesh;
@@ -241,10 +242,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	priv->hw_read_event_cause = if_usb_read_event_cause;
 	priv->boot2_version = udev->descriptor.bcdDevice;
 
-	/* Delay 200 ms to waiting for the FW ready */
 	if_usb_submit_rx_urb(cardp);
-	msleep_interruptible(200);
-	priv->fw_ready = 1;
 
 	if (lbs_start_card(priv))
 		goto err_start_card;
@@ -514,6 +512,21 @@ static void if_usb_receive_fwload(struct urb *urb)
 		return;
 	}
 
+	if (cardp->fwdnldover) {
+		__le32 *tmp = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
+
+		if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
+		    tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
+			lbs_pr_info("Firmware ready event received\n");
+			wake_up(&cardp->fw_wq);
+		} else {
+			lbs_deb_usb("Waiting for confirmation; got %x %x\n", le32_to_cpu(tmp[0]),
+				    le32_to_cpu(tmp[1]));
+			if_usb_submit_rx_urb_fwload(cardp);
+		}
+		kfree_skb(skb);
+		return;
+	}
 	if (cardp->bootcmdresp <= 0) {
 		memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
 			sizeof(bootcmdresp));
@@ -529,7 +542,8 @@ static void if_usb_receive_fwload(struct urb *urb)
 			if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) ||
 			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) ||
 			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) {
-				lbs_pr_info("Firmware already seems alive; resetting\n");
+				if (!cardp->bootcmdresp)
+					lbs_pr_info("Firmware already seems alive; resetting\n");
 				cardp->bootcmdresp = -1;
 			} else {
 				lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
@@ -590,8 +604,9 @@ static void if_usb_receive_fwload(struct urb *urb)
 
 	if_usb_send_fw_pkt(cardp);
 
-	if_usb_submit_rx_urb_fwload(cardp);
  exit:
+	if_usb_submit_rx_urb_fwload(cardp);
+
 	kfree(syncfwheader);
 
 	return;
@@ -934,6 +949,7 @@ restart:
 	wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
 	
 	del_timer_sync(&cardp->fw_timeout);
+	usb_kill_urb(cardp->rx_urb);
 
 	if (!cardp->fwdnldover) {
 		lbs_pr_info("failed to load fw, resetting device!\n");
Signature · 1 line
1.5.3.4
#71 lore raw

[PATCH 66/48] libertas: fix debug output in lbs_cmd_copyback() function.

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 15:22:27 -0500

Bad dcbw. Always test on big-endian, or at least use sparse.

---
 drivers/net/wireless/libertas/cmd.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/libertas/cmd.c +3 -3
index 79a8d0d..eeb09e0 100644
@@ -2023,7 +2023,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
  *  @return 	   	0 on success, error on failure
  */
 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
-			struct cmd_header *resp)
+		     struct cmd_header *resp)
 {
 	struct cmd_header *buf = (void *)extra;
 	uint16_t copy_len;
@@ -2032,8 +2032,8 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
 
 	copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
 	lbs_deb_cmd("Copying back %u bytes; command response was %u bytes, "
-		    "copy back buffer was %u bytes", copy_len, resp->size,
-		    buf->size);
+		    "copy back buffer was %u bytes\n", copy_len,
+		    le16_to_cpu(resp->size), le16_to_cpu(buf->size));
 	memcpy(buf, resp, copy_len);
 
 	lbs_deb_leave(LBS_DEB_CMD);
Signature · 1 line
1.5.3.4
#72 lore raw

[PATCH 65/48] libertas: rename and re-type bufvirtualaddr to cmdbuf

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 13:49:39 -0500

Make it a struct cmd_header, since that's what it is, and clean up the places that it's used.

---
 drivers/net/wireless/libertas/cmd.c     |  133 +++++++++++++------------------
 drivers/net/wireless/libertas/cmdresp.c |   14 ++--
 drivers/net/wireless/libertas/defs.h    |    4 +-
 drivers/net/wireless/libertas/hostcmd.h |    2 +-
 drivers/net/wireless/libertas/if_cs.c   |    4 +-
 drivers/net/wireless/libertas/if_sdio.c |    4 +-
 drivers/net/wireless/libertas/if_usb.c  |    4 +-
 drivers/net/wireless/libertas/main.c    |   14 ++--
 8 files changed, 79 insertions(+), 100 deletions(-)
drivers/net/wireless/libertas/cmd.c +57 -76
index bb940cc..79a8d0d 100644
@@ -1028,24 +1028,18 @@ void lbs_queue_cmd(struct lbs_private *priv,
 	u8 addtail)
 {
 	unsigned long flags;
-	struct cmd_ds_command *cmdptr;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	if (!cmdnode) {
-		lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
-		goto done;
-	}
-
-	cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
-	if (!cmdptr) {
-		lbs_deb_host("QUEUE_CMD: cmdptr is NULL\n");
+	if (!cmdnode || !cmdnode->cmdbuf) {
+		lbs_deb_host("QUEUE_CMD: cmdnode or cmdbuf is NULL\n");
 		goto done;
 	}
 
 	/* Exit_PS command needs to be queued in the header always. */
-	if (le16_to_cpu(cmdptr->command) == CMD_802_11_PS_MODE) {
-		struct cmd_ds_802_11_ps_mode *psm = &cmdptr->params.psmode;
+	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
+		struct cmd_ds_802_11_ps_mode *psm = (void *) cmdnode->cmdbuf;
+
 		if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
 			if (priv->psstate != PS_STATE_FULL_POWER)
 				addtail = 0;
@@ -1062,7 +1056,7 @@ void lbs_queue_cmd(struct lbs_private *priv,
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 	lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
-	       le16_to_cpu(((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command));
+	       le16_to_cpu(cmdnode->cmdbuf->command));
 
 done:
 	lbs_deb_leave(LBS_DEB_HOST);
@@ -1079,7 +1073,7 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 				    struct cmd_ctrl_node *cmdnode)
 {
 	unsigned long flags;
-	struct cmd_ds_command *cmdptr;
+	struct cmd_header *cmd;
 	int ret = -1;
 	u16 cmdsize;
 	u16 command;
@@ -1091,10 +1085,10 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 		goto done;
 	}
 
-	cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
+	cmd = cmdnode->cmdbuf;
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
-	if (!cmdptr || !cmdptr->size) {
+	if (!cmd || !cmd->size) {
 		lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n");
 		__lbs_cleanup_and_insert_cmd(priv, cmdnode);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1105,16 +1099,16 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 	priv->cur_cmd_retcode = 0;
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-	cmdsize = le16_to_cpu(cmdptr->size);
-	command = le16_to_cpu(cmdptr->command);
+	cmdsize = le16_to_cpu(cmd->size);
+	command = le16_to_cpu(cmd->command);
 
 	lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n",
 		    command, cmdsize, jiffies);
-	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", cmdnode->bufvirtualaddr, cmdsize);
+	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
 
 	cmdnode->cmdwaitqwoken = 0;
 
-	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmdptr, cmdsize);
+	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
 
 	if (ret != 0) {
 		lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n");
@@ -1265,7 +1259,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 
 	lbs_set_cmd_ctrl_node(priv, cmdnode, wait_option, pdata_buf);
 
-	cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
+	cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
 
 	lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
 
@@ -1556,41 +1550,35 @@ EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command);
 int lbs_allocate_cmd_buffer(struct lbs_private *priv)
 {
 	int ret = 0;
-	u32 ulbufsize;
+	u32 bufsize;
 	u32 i;
-	struct cmd_ctrl_node *tempcmd_array;
-	u8 *ptempvirtualaddr;
+	struct cmd_ctrl_node *cmdarray;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	/* Allocate and initialize cmdCtrlNode */
-	ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;
-
-	if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) {
+	/* Allocate and initialize the command array */
+	bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
+	if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
 		lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
 		ret = -1;
 		goto done;
 	}
-	priv->cmd_array = tempcmd_array;
+	priv->cmd_array = cmdarray;
 
-	/* Allocate and initialize command buffers */
-	ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
-	for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
-		if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) {
+	/* Allocate and initialize each command buffer in the command array */
+	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
+		cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
+		if (!cmdarray[i].cmdbuf) {
 			lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
 			ret = -1;
 			goto done;
 		}
-
-		/* Update command buffer virtual */
-		tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;
 	}
 
-	for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
-		init_waitqueue_head(&tempcmd_array[i].cmdwait_q);
-		lbs_cleanup_and_insert_cmd(priv, &tempcmd_array[i]);
+	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
+		init_waitqueue_head(&cmdarray[i].cmdwait_q);
+		lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
 	}
-
 	ret = 0;
 
 done:
@@ -1606,9 +1594,8 @@ done:
  */
 int lbs_free_cmd_buffer(struct lbs_private *priv)
 {
-	u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */
+	struct cmd_ctrl_node *cmdarray;
 	unsigned int i;
-	struct cmd_ctrl_node *tempcmd_array;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
@@ -1618,14 +1605,13 @@ int lbs_free_cmd_buffer(struct lbs_private *priv)
 		goto done;
 	}
 
-	tempcmd_array = priv->cmd_array;
+	cmdarray = priv->cmd_array;
 
 	/* Release shared memory buffers */
-	ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;
-	for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {
-		if (tempcmd_array[i].bufvirtualaddr) {
-			kfree(tempcmd_array[i].bufvirtualaddr);
-			tempcmd_array[i].bufvirtualaddr = NULL;
+	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
+		if (cmdarray[i].cmdbuf) {
+			kfree(cmdarray[i].cmdbuf);
+			cmdarray[i].cmdbuf = NULL;
 		}
 	}
 
@@ -1683,21 +1669,21 @@ struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
  *  @param ptempnode	A pointer to cmdCtrlNode structure
  *  @return 		n/a
  */
-static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode)
+static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode)
 {
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	if (!ptempnode)
+	if (!cmdnode)
 		return;
-	ptempnode->cmdwaitqwoken = 1;
-	wake_up_interruptible(&ptempnode->cmdwait_q);
-	ptempnode->wait_option = 0;
-	ptempnode->pdata_buf = NULL;
-	ptempnode->callback = NULL;
-	ptempnode->callback_arg = 0;
+	cmdnode->cmdwaitqwoken = 1;
+	wake_up_interruptible(&cmdnode->cmdwait_q);
+	cmdnode->wait_option = 0;
+	cmdnode->pdata_buf = NULL;
+	cmdnode->callback = NULL;
+	cmdnode->callback_arg = 0;
 
-	if (ptempnode->bufvirtualaddr != NULL)
-		memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);
+	if (cmdnode->cmdbuf != NULL)
+		memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
@@ -1739,7 +1725,7 @@ void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 int lbs_execute_next_command(struct lbs_private *priv)
 {
 	struct cmd_ctrl_node *cmdnode = NULL;
-	struct cmd_ds_command *cmdptr;
+	struct cmd_header *cmd;
 	unsigned long flags;
 	int ret = 0;
 
@@ -1765,22 +1751,21 @@ int lbs_execute_next_command(struct lbs_private *priv)
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 	if (cmdnode) {
-		cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
+		cmd = cmdnode->cmdbuf;
 
-		if (is_command_allowed_in_ps(le16_to_cpu(cmdptr->command))) {
+		if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
 			if ((priv->psstate == PS_STATE_SLEEP) ||
 			    (priv->psstate == PS_STATE_PRE_SLEEP)) {
 				lbs_deb_host(
 				       "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
-				       le16_to_cpu(cmdptr->command),
+				       le16_to_cpu(cmd->command),
 				       priv->psstate);
 				ret = -1;
 				goto done;
 			}
 			lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
-			       "0x%04x in psstate %d\n",
-				    le16_to_cpu(cmdptr->command),
-				    priv->psstate);
+				     "0x%04x in psstate %d\n",
+				     le16_to_cpu(cmd->command), priv->psstate);
 		} else if (priv->psstate != PS_STATE_FULL_POWER) {
 			/*
 			 * 1. Non-PS command:
@@ -1793,8 +1778,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 			 * otherwise send this command down to firmware
 			 * immediately.
 			 */
-			if (cmdptr->command !=
-			    cpu_to_le16(CMD_802_11_PS_MODE)) {
+			if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
 				/*  Prepare to send Exit PS,
 				 *  this non PS command will be sent later */
 				if ((priv->psstate == PS_STATE_SLEEP)
@@ -1813,8 +1797,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 				 * PS command. Ignore it if it is not Exit_PS.
 				 * otherwise send it down immediately.
 				 */
-				struct cmd_ds_802_11_ps_mode *psm =
-				    &cmdptr->params.psmode;
+				struct cmd_ds_802_11_ps_mode *psm = (void *)cmd;
 
 				lbs_deb_host(
 				       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
@@ -1848,7 +1831,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 		}
 		list_del(&cmdnode->list);
 		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
-			    le16_to_cpu(cmdptr->command));
+			    le16_to_cpu(cmd->command));
 		DownloadcommandToStation(priv, cmdnode);
 	} else {
 		/*
@@ -2079,7 +2062,6 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	      unsigned long callback_arg)
 {
 	struct cmd_ctrl_node *cmdnode;
-	struct cmd_header *send_cmd;
 	unsigned long flags;
 	int ret = 0;
 
@@ -2107,20 +2089,19 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 		goto done;
 	}
 
-	send_cmd = (struct cmd_header *) cmdnode->bufvirtualaddr;
 	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
 	cmdnode->callback = callback;
 	cmdnode->callback_arg = callback_arg;
 
 	/* Copy the incoming command to the buffer */
-	memcpy(send_cmd, in_cmd, in_cmd_size);
+	memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
 
 	/* Set sequence number, clean result, move to buffer */
 	priv->seqnum++;
-	send_cmd->command = cpu_to_le16(command);
-	send_cmd->size    = cpu_to_le16(in_cmd_size);
-	send_cmd->seqnum  = cpu_to_le16(priv->seqnum);
-	send_cmd->result  = 0;
+	cmdnode->cmdbuf->command = cpu_to_le16(command);
+	cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
+	cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
+	cmdnode->cmdbuf->result  = 0;
 
 	lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
 
drivers/net/wireless/libertas/cmdresp.c +7 -7
index 671e323..b4cd7b7 100644
@@ -491,8 +491,9 @@ static int lbs_ret_802_11_subscribe_event(struct lbs_private *priv,
 
 static inline int handle_cmd_response(struct lbs_private *priv,
 				      unsigned long dummy,
-				      struct cmd_ds_command *resp)
+				      struct cmd_header *cmd_response)
 {
+	struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response;
 	int ret = 0;
 	unsigned long flags;
 	uint16_t respcmd = le16_to_cpu(resp->command);
@@ -673,7 +674,7 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 int lbs_process_rx_command(struct lbs_private *priv)
 {
 	u16 respcmd;
-	struct cmd_ds_command *resp;
+	struct cmd_header *resp;
 	int ret = 0;
 	ulong flags;
 	u16 result;
@@ -692,15 +693,14 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		goto done;
 	}
-	resp = (struct cmd_ds_command *)(priv->cur_cmd->bufvirtualaddr);
+	resp = priv->cur_cmd->cmdbuf;
 
 	respcmd = le16_to_cpu(resp->command);
 	result = le16_to_cpu(resp->result);
 
 	lbs_deb_host("CMD_RESP: response 0x%04x, size %d, jiffies %lu\n",
 		respcmd, priv->upld_len, jiffies);
-	lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", priv->cur_cmd->bufvirtualaddr,
-		    priv->upld_len);
+	lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len);
 
 	if (!(respcmd & 0x8000)) {
 		lbs_deb_host("invalid response!\n");
@@ -716,7 +716,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 	priv->cur_cmd_retcode = result;
 
 	if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
-		struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
+		struct cmd_ds_802_11_ps_mode *psmode = (void *) resp;
 		u16 action = le16_to_cpu(psmode->action);
 
 		lbs_deb_host(
@@ -796,7 +796,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 
 	if (priv->cur_cmd && priv->cur_cmd->callback) {
 		ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
-				(struct cmd_header *) resp);
+				resp);
 	} else
 		ret = handle_cmd_response(priv, 0, resp);
 
drivers/net/wireless/libertas/defs.h +2 -2
index 04db6af..9b98ae7 100644
@@ -132,8 +132,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 */
 
 #define MRVDRV_MAX_MULTICAST_LIST_SIZE	32
-#define MRVDRV_NUM_OF_CMD_BUFFER        10
-#define MRVDRV_SIZE_OF_CMD_BUFFER       (2 * 1024)
+#define LBS_NUM_CMD_BUFFERS             10
+#define LBS_CMD_BUFFER_SIZE             (2 * 1024)
 #define MRVDRV_MAX_CHANNEL_SIZE		14
 #define MRVDRV_ASSOCIATION_TIME_OUT	255
 #define MRVDRV_SNAP_HEADER_LEN          8
drivers/net/wireless/libertas/hostcmd.h +1 -1
index a87c217..e5e2106 100644
@@ -81,7 +81,7 @@ struct cmd_ctrl_node {
 	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
 	unsigned long callback_arg;
 	/* command data */
-	u8 *bufvirtualaddr;
+	struct cmd_header *cmdbuf;
 	/* wait queue */
 	u16 cmdwaitqwoken;
 	wait_queue_head_t cmdwait_q;
drivers/net/wireless/libertas/if_cs.c +2 -2
index 2acbe5d..5814363 100644
@@ -364,7 +364,7 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len)
 	}
 
 	*len = if_cs_read16(priv->card, IF_CS_C_CMD_LEN);
-	if ((*len == 0) || (*len > MRVDRV_SIZE_OF_CMD_BUFFER)) {
+	if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
 		lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
 		goto out;
 	}
@@ -683,7 +683,7 @@ sbi_get_int_status_exit:
 			cmdbuf = priv->upld_buf;
 			priv->hisregcpy &= ~IF_CS_C_S_RX_UPLD_RDY;
 		} else {
-			cmdbuf = priv->cur_cmd->bufvirtualaddr;
+			cmdbuf = (u8 *) priv->cur_cmd->cmdbuf;
 		}
 
 		ret = if_cs_receive_cmdres(priv, cmdbuf, &priv->upld_len);
drivers/net/wireless/libertas/if_sdio.c +2 -2
index 94060da..85675c5 100644
@@ -142,14 +142,14 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 		goto out;
 	}
 
-	if (size > MRVDRV_SIZE_OF_CMD_BUFFER) {
+	if (size > LBS_CMD_BUFFER_SIZE) {
 		lbs_deb_sdio("response packet too large (%d bytes)\n",
 			(int)size);
 		ret = -E2BIG;
 		goto out;
 	}
 
-	memcpy(card->priv->cur_cmd->bufvirtualaddr, buffer, size);
+	memcpy(card->priv->cur_cmd->cmdbuf, buffer, size);
 	card->priv->upld_len = size;
 
 	card->int_cause |= MRVDRV_CMD_UPLD_RDY;
drivers/net/wireless/libertas/if_usb.c +2 -2
index c94b6df..5f2d944 100644
@@ -639,7 +639,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 				      struct lbs_private *priv)
 {
 	u8 *cmdbuf;
-	if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) {
+	if (recvlength > LBS_CMD_BUFFER_SIZE) {
 		lbs_deb_usbd(&cardp->udev->dev,
 			    "The receive buffer is too large\n");
 		kfree_skb(skb);
@@ -656,7 +656,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 		cmdbuf = priv->upld_buf;
 		priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
 	} else
-		cmdbuf = priv->cur_cmd->bufvirtualaddr;
+		cmdbuf = (u8 *) priv->cur_cmd->cmdbuf;
 
 	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
 	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
drivers/net/wireless/libertas/main.c +6 -8
index 212cce3..a081b91 100644
@@ -890,23 +890,21 @@ done:
 static void command_timer_fn(unsigned long data)
 {
 	struct lbs_private *priv = (struct lbs_private *)data;
-	struct cmd_ctrl_node *ptempnode;
-	struct cmd_ds_command *cmd;
+	struct cmd_ctrl_node *node;
 	unsigned long flags;
 
-	ptempnode = priv->cur_cmd;
-	if (ptempnode == NULL) {
+	node = priv->cur_cmd;
+	if (node == NULL) {
 		lbs_deb_fw("ptempnode empty\n");
 		return;
 	}
 
-	cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;
-	if (!cmd) {
+	if (!node->cmdbuf) {
 		lbs_deb_fw("cmd is NULL\n");
 		return;
 	}
 
-	lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command);
+	lbs_deb_fw("command_timer_fn fired, cmd %x\n", node->cmdbuf->command);
 
 	if (!priv->fw_ready)
 		return;
@@ -916,7 +914,7 @@ static void command_timer_fn(unsigned long data)
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 	lbs_deb_fw("re-sending same command because of timeout\n");
-	lbs_queue_cmd(priv, ptempnode, 0);
+	lbs_queue_cmd(priv, node, 0);
 
 	wake_up_interruptible(&priv->waitq);
 
Signature · 1 line
1.5.3.4
#73 lore raw

[PATCH 68/48] libertas: remove casts from lbs_cmd() and lbs_cmd_with_response() macros

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 15:28:18 -0500

If stupid people like me give it arguments with the wrong type (like a pointer to the structure, for example, instead of the structure itself), then we should probably notice that at compile time. Otherwise, much confusion ensues.

---
 drivers/net/wireless/libertas/cmd.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/cmd.h +2 -2
index 716f25b..950acce 100644
@@ -7,11 +7,11 @@
 #include "dev.h"
 
 #define lbs_cmd(priv, cmdnr, cmd, callback, callback_arg) \
-	__lbs_cmd(priv, cmdnr, (struct cmd_header *) &cmd, sizeof(cmd), \
+	__lbs_cmd(priv, cmdnr, &(cmd).hdr, sizeof(cmd),	  \
 			callback, callback_arg)
 
 #define lbs_cmd_with_response(priv, cmdnr, cmd) \
-	__lbs_cmd(priv, cmdnr, (struct cmd_header *) &cmd, sizeof(cmd), \
+	__lbs_cmd(priv, cmdnr, &(cmd).hdr, sizeof(cmd), \
 		  lbs_cmd_copyback, (unsigned long) &cmd)
  
 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
Signature · 1 line
1.5.3.4
#74 lore raw

[PATCH 69/48] libertas: fix case of FWT_ACCESS_LIST_ROUTE and FWT_ACCESS_LIST_NEIGHBOR commands

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 15:29:10 -0500

---
 drivers/net/wireless/libertas/host.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/host.h +2 -2
index b23af19..cc5f9bf 100644
@@ -247,8 +247,8 @@ enum cmd_fwt_access_opts {
 	CMD_ACT_FWT_ACCESS_DEL,
 	CMD_ACT_FWT_ACCESS_LOOKUP,
 	CMD_ACT_FWT_ACCESS_LIST,
-	CMD_ACT_FWT_ACCESS_LIST_route,
-	CMD_ACT_FWT_ACCESS_LIST_neighbor,
+	CMD_ACT_FWT_ACCESS_LIST_ROUTE,
+	CMD_ACT_FWT_ACCESS_LIST_NEIGHBOR,
 	CMD_ACT_FWT_ACCESS_RESET,
 	CMD_ACT_FWT_ACCESS_CLEANUP,
 	CMD_ACT_FWT_ACCESS_TIME,
Signature · 1 line
1.5.3.4
#75 lore raw

[PATCH 70/48] libertas: convert DATA_RATE to a direct command

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 15:50:59 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   93 ++++++++++++++++++++++++-------
 drivers/net/wireless/libertas/cmd.h     |    3 +
 drivers/net/wireless/libertas/cmdresp.c |   23 --------
 drivers/net/wireless/libertas/hostcmd.h |    3 +-
 drivers/net/wireless/libertas/main.c    |    8 +--
 drivers/net/wireless/libertas/wext.c    |    9 +--
 6 files changed, 83 insertions(+), 56 deletions(-)
drivers/net/wireless/libertas/cmd.c +73 -20
index 9d621fe..eff7879 100644
@@ -706,30 +706,86 @@ static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv,
 	return 0;
 }
 
-static int lbs_cmd_802_11_data_rate(struct lbs_private *priv,
-				     struct cmd_ds_command *cmd,
-				     u16 cmd_action)
+/**
+ *  @brief Get the current data rate
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *
+ *  @return 	   	The data rate on success, error on failure
+ */
+int lbs_get_data_rate(struct lbs_private *priv)
 {
-	struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate;
+	struct cmd_ds_802_11_data_rate cmd;
+	int ret = -1;
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_data_rate) +
-			     S_DS_GEN);
-	cmd->command = cpu_to_le16(CMD_802_11_DATA_RATE);
-	memset(pdatarate, 0, sizeof(struct cmd_ds_802_11_data_rate));
-	pdatarate->action = cpu_to_le16(cmd_action);
-
-	if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) {
-		pdatarate->rates[0] = lbs_data_rate_to_fw_index(priv->cur_rate);
-		lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n",
-		       priv->cur_rate);
-	} else if (cmd_action == CMD_ACT_SET_TX_AUTO) {
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+	cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE);
+
+	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, cmd);
+	if (ret)
+		goto out;
+
+	lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
+
+	ret = (int) lbs_fw_index_to_data_rate(cmd.rates[0]);
+	lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", ret);
+
+out:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
+}
+
+/**
+ *  @brief Set the data rate
+ *
+ *  @param priv    	A pointer to struct lbs_private structure
+ *  @param rate  	The desired data rate, or 0 to clear a locked rate
+ *
+ *  @return 	   	0 on success, error on failure
+ */
+int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
+{
+	struct cmd_ds_802_11_data_rate cmd;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_CMD);
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+
+	if (rate > 0) {
+		cmd.action = cpu_to_le16(CMD_ACT_SET_TX_FIX_RATE);
+		cmd.rates[0] = lbs_data_rate_to_fw_index(rate);
+		if (cmd.rates[0] == 0) {
+			lbs_deb_cmd("DATA_RATE: invalid requested rate of"
+			            " 0x%02X\n", rate);
+			ret = 0;
+			goto out;
+		}
+		lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", cmd.rates[0]);
+	} else {
+		cmd.action = cpu_to_le16(CMD_ACT_SET_TX_AUTO);
 		lbs_deb_cmd("DATA_RATE: setting auto\n");
 	}
 
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
+	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, cmd);
+	if (ret)
+		goto out;
+
+	lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) &cmd, sizeof (cmd));
+
+	/* FIXME: get actual rates FW can do if this command actually returns
+	 * all data rates supported.
+	 */
+	priv->cur_rate = lbs_fw_index_to_data_rate(cmd.rates[0]);
+	lbs_deb_cmd("DATA_RATE: current rate is 0x%02x\n", priv->cur_rate);
+
+out:
+	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
+	return ret;
 }
 
 static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv,
@@ -1348,9 +1404,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		ret = lbs_cmd_802_11_radio_control(priv, cmdptr, cmd_action);
 		break;
 
-	case CMD_802_11_DATA_RATE:
-		ret = lbs_cmd_802_11_data_rate(priv, cmdptr, cmd_action);
-		break;
 	case CMD_802_11_RATE_ADAPT_RATESET:
 		ret = lbs_cmd_802_11_rate_adapt_rateset(priv,
 							 cmdptr, cmd_action);
drivers/net/wireless/libertas/cmd.h +3 -0
index 950acce..4bd6f56 100644
@@ -27,4 +27,7 @@ int lbs_update_hw_spec(struct lbs_private *priv);
 int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 		    struct cmd_ds_mesh_access *cmd);
 
+int lbs_get_data_rate(struct lbs_private *priv);
+int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
+
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/cmdresp.c +0 -23
index 6ff705b..797c943 100644
@@ -325,26 +325,6 @@ static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv,
 	return 0;
 }
 
-static int lbs_ret_802_11_data_rate(struct lbs_private *priv,
-				     struct cmd_ds_command *resp)
-{
-	struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate;
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) pdatarate,
-		sizeof(struct cmd_ds_802_11_data_rate));
-
-	/* FIXME: get actual rates FW can do if this command actually returns
-	 * all data rates supported.
-	 */
-	priv->cur_rate = lbs_fw_index_to_data_rate(pdatarate->rates[0]);
-	lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", priv->cur_rate);
-
-	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
-}
-
 static int lbs_ret_802_11_rf_channel(struct lbs_private *priv,
 				      struct cmd_ds_command *resp)
 {
@@ -565,9 +545,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 		ret = lbs_ret_802_11_enable_rsn(priv, resp);
 		break;
 
-	case CMD_RET(CMD_802_11_DATA_RATE):
-		ret = lbs_ret_802_11_data_rate(priv, resp);
-		break;
 	case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
 		ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
 		break;
drivers/net/wireless/libertas/hostcmd.h +2 -1
index d9b151a..d51010c 100644
@@ -461,6 +461,8 @@ struct PS_CMD_ConfirmSleep {
 };
 
 struct cmd_ds_802_11_data_rate {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le16 reserved;
 	u8 rates[MAX_RATES];
@@ -659,7 +661,6 @@ struct cmd_ds_command {
 		struct cmd_ds_802_11_rf_tx_power txp;
 		struct cmd_ds_802_11_rf_antenna rant;
 		struct cmd_ds_802_11_monitor_mode monitor;
-		struct cmd_ds_802_11_data_rate drate;
 		struct cmd_ds_802_11_rate_adapt_rateset rateset;
 		struct cmd_ds_mac_multicast_adr madr;
 		struct cmd_ds_802_11_ad_hoc_join adj;
drivers/net/wireless/libertas/main.c +2 -6
index 7f6b3cc..2fe7ad0 100644
@@ -854,12 +854,8 @@ static int lbs_setup_firmware(struct lbs_private *priv)
 
 	lbs_set_mac_packet_filter(priv);
 
-	/* Get the supported Data rates */
-	ret = lbs_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,
-				    CMD_ACT_GET_TX_RATE,
-				    CMD_OPTION_WAITFORRSP, 0, NULL);
-
-	if (ret) {
+	ret = lbs_get_data_rate(priv);
+	if (ret < 0) {
 		ret = -1;
 		goto done;
 	}
drivers/net/wireless/libertas/wext.c +3 -6
index 1e0b224..e44c0ce 100644
@@ -19,6 +19,7 @@
 #include "join.h"
 #include "wext.h"
 #include "assoc.h"
+#include "cmd.h"
 
 
 static inline void lbs_postpone_association_work(struct lbs_private *priv)
@@ -962,8 +963,7 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
 		  struct iw_param *vwrq, char *extra)
 {
 	struct lbs_private *priv = dev->priv;
-	u32 new_rate;
-	u16 action;
+	u8 new_rate = 0;
 	int ret = -EINVAL;
 	u8 rates[MAX_RATES + 1];
 
@@ -972,7 +972,6 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
 
 	/* Auto rate? */
 	if (vwrq->value == -1) {
-		action = CMD_ACT_SET_TX_AUTO;
 		priv->auto_rate = 1;
 		priv->cur_rate = 0;
 	} else {
@@ -989,12 +988,10 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
 		}
 
 		priv->cur_rate = new_rate;
-		action = CMD_ACT_SET_TX_FIX_RATE;
 		priv->auto_rate = 0;
 	}
 
-	ret = lbs_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,
-				    action, CMD_OPTION_WAITFORRSP, 0, NULL);
+	ret = lbs_set_data_rate(priv, new_rate);
 
 out:
 	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
Signature · 1 line
1.5.3.4
#76 lore raw

[PATCH 72/48] libertas: endianness fixes for get_channel/set_channel

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 17:35:51 -0500

---
 drivers/net/wireless/libertas/cmd.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/cmd.c +5 -4
index 32f9f88..0f07c2a 100644
@@ -831,8 +831,8 @@ int lbs_get_channel(struct lbs_private *priv)
 	if (ret)
 		goto out;
 
-	lbs_deb_cmd("current radio channel is %d\n", cmd.channel);
-	ret = (int) cmd.channel;
+	ret = le16_to_cpu(cmd.channel);
+	lbs_deb_cmd("current radio channel is %d\n", ret);
 
 out:
 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
@@ -863,8 +863,9 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel)
 	if (ret)
 		goto out;
 
-	priv->curbssparams.channel = cmd.channel;
-	lbs_deb_cmd("channel switch from %d to %d\n", old_channel, cmd.channel);
+	priv->curbssparams.channel = (uint8_t) le16_to_cpu(cmd.channel);
+	lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
+		priv->curbssparams.channel);
 
 out:
 	lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
Signature · 1 line
1.5.3.4
#77 lore raw

[PATCH 73/48] libertas: make some more functions static

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 17:44:10 -0500

sparse was getting on my tits.

---
 drivers/net/wireless/libertas/cmd.c    |   12 ++++++------
 drivers/net/wireless/libertas/if_usb.c |    2 +-
 drivers/net/wireless/libertas/main.c   |    8 ++++----
 3 files changed, 11 insertions(+), 11 deletions(-)
drivers/net/wireless/libertas/cmd.c +6 -6
index 0f07c2a..2228fec 100644
@@ -14,8 +14,8 @@
 #include "cmd.h"
 
 static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
-struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
-void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
+static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
+static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 		    struct cmd_ctrl_node *ptempnode,
 		    u16 wait_option, void *pdata_buf);
 
@@ -1716,7 +1716,7 @@ done:
  *  @param priv		A pointer to struct lbs_private structure
  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
  */
-struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
+static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
 {
 	struct cmd_ctrl_node *tempnode;
 	unsigned long flags;
@@ -1780,9 +1780,9 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode)
  *  @param pdata_buf	A pointer to informaion buffer
  *  @return 		0 or -1
  */
-void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
-		    struct cmd_ctrl_node *ptempnode,
-		    u16 wait_option, void *pdata_buf)
+static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
+				  struct cmd_ctrl_node *ptempnode,
+				  u16 wait_option, void *pdata_buf)
 {
 	lbs_deb_enter(LBS_DEB_HOST);
 
drivers/net/wireless/libertas/if_usb.c +1 -1
index a0866ef..7c57ff4 100644
@@ -113,7 +113,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 		lbs_deb_usb("Setting boot2 version failed\n");
 }
 
-void if_usb_fw_timeo(unsigned long priv)
+static void if_usb_fw_timeo(unsigned long priv)
 {
 	struct usb_card_rec *cardp = (void *)priv;
 
drivers/net/wireless/libertas/main.c +4 -4
index 2fe7ad0..c51d3af 100644
@@ -252,8 +252,8 @@ static ssize_t lbs_anycast_set(struct device *dev,
 	return strlen(buf);
 }
 
-int lbs_add_rtap(struct lbs_private *priv);
-void lbs_remove_rtap(struct lbs_private *priv);
+static int lbs_add_rtap(struct lbs_private *priv);
+static void lbs_remove_rtap(struct lbs_private *priv);
 
 /**
  * Get function for sysfs attribute rtap
@@ -1423,7 +1423,7 @@ static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev)
 }
 
 
-void lbs_remove_rtap(struct lbs_private *priv)
+static void lbs_remove_rtap(struct lbs_private *priv)
 {
 	if (priv->rtap_net_dev == NULL)
 		return;
@@ -1432,7 +1432,7 @@ void lbs_remove_rtap(struct lbs_private *priv)
 	priv->rtap_net_dev = NULL;
 }
 
-int lbs_add_rtap(struct lbs_private *priv)
+static int lbs_add_rtap(struct lbs_private *priv)
 {
 	int rc = 0;
 	struct net_device *rtap_dev;
Signature · 1 line
1.5.3.4
#78 lore raw

[PATCH 74/48] libertas: fix sparse endianness warnings in scan.c

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 17:54:36 -0500

---
 drivers/net/wireless/libertas/scan.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)
drivers/net/wireless/libertas/scan.c +5 -6
index 8b6ce61..92d84c7 100644
@@ -709,7 +709,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
 
 	if (*bytesleft >= sizeof(beaconsize)) {
 		/* Extract & convert beacon size from the command buffer */
-		beaconsize = le16_to_cpu(get_unaligned((u16 *)*pbeaconinfo));
+		beaconsize = le16_to_cpu(get_unaligned((__le16 *)*pbeaconinfo));
 		*bytesleft -= sizeof(beaconsize);
 		*pbeaconinfo += sizeof(beaconsize);
 	}
@@ -823,7 +823,7 @@ static int lbs_process_bss(struct bss_descriptor *bss,
 
 		case MFIE_TYPE_IBSS_SET:
 			pibss = (struct ieeetypes_ibssparamset *) pos;
-			bss->atimwindow = le32_to_cpu(pibss->atimwindow);
+			bss->atimwindow = le16_to_cpu(pibss->atimwindow);
 			memmove(&bss->ssparamset.ibssparamset, pibss,
 				sizeof(struct ieeetypes_ibssparamset));
 			lbs_deb_scan("got IBSS IE\n");
@@ -1562,12 +1562,11 @@ int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp)
 		goto done;
 	}
 
-	bytesleft = le16_to_cpu(get_unaligned((u16*)&pscan->bssdescriptsize));
+	bytesleft = le16_to_cpu(pscan->bssdescriptsize);
 	lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
 
-	scanrespsize = le16_to_cpu(get_unaligned((u16*)&resp->size));
-	lbs_deb_scan("SCAN_RESP: scan results %d\n",
-	       pscan->nr_sets);
+	scanrespsize = le16_to_cpu(resp->size);
+	lbs_deb_scan("SCAN_RESP: scan results %d\n", pscan->nr_sets);
 
 	pbssinfo = pscan->bssdesc_and_tlvbuffer;
 
Signature · 1 line
1.5.3.4
#79 lore raw

[PATCH 75/48] libertas: add lbs_mesh sysfs attribute for enabling mesh

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 18:56:42 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   17 +++++++
 drivers/net/wireless/libertas/cmd.h     |    2 +
 drivers/net/wireless/libertas/decl.h    |    2 -
 drivers/net/wireless/libertas/dev.h     |    2 +
 drivers/net/wireless/libertas/host.h    |    1 +
 drivers/net/wireless/libertas/hostcmd.h |   12 +++++
 drivers/net/wireless/libertas/if_usb.c  |    6 ---
 drivers/net/wireless/libertas/main.c    |   74 +++++++++++++++++++++++++++----
 8 files changed, 99 insertions(+), 17 deletions(-)
drivers/net/wireless/libertas/cmd.c +17 -0
index 2228fec..01d2349 100644
@@ -1093,6 +1093,23 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 }
 EXPORT_SYMBOL_GPL(lbs_mesh_access);
 
+int lbs_mesh_config(struct lbs_private *priv, int enable)
+{
+	struct cmd_ds_mesh_config cmd;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.action = cpu_to_le16(enable);
+	cmd.channel = cpu_to_le16(priv->curbssparams.channel);
+	cmd.type = cpu_to_le16(0x100 + 37);
+	
+	if (enable) {
+		cmd.length = cpu_to_le16(priv->mesh_ssid_len);
+		memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
+	}
+
+	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+}
+
 static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
 				struct cmd_ds_command *cmd,
 				u16 cmd_action)
drivers/net/wireless/libertas/cmd.h +2 -0
index 5b02d73..80714b5 100644
@@ -33,4 +33,6 @@ int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
 int lbs_get_channel(struct lbs_private *priv);
 int lbs_set_channel(struct lbs_private *priv, u8 channel);
 
+int lbs_mesh_config(struct lbs_private *priv, int enable);
+
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/decl.h +0 -2
index 33c8305..9b0ef16 100644
@@ -74,8 +74,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev);
 int lbs_remove_card(struct lbs_private *priv);
 int lbs_start_card(struct lbs_private *priv);
 int lbs_stop_card(struct lbs_private *priv);
-int lbs_add_mesh(struct lbs_private *priv, struct device *dev);
-void lbs_remove_mesh(struct lbs_private *priv);
 int lbs_reset_device(struct lbs_private *priv);
 void lbs_host_to_card_done(struct lbs_private *priv);
 
drivers/net/wireless/libertas/dev.h +2 -0
index 9921d0c..86b45a4 100644
@@ -201,6 +201,8 @@ struct lbs_private {
 
 	/** current ssid/bssid related parameters*/
 	struct current_bss_params curbssparams;
+	u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
+	u8 mesh_ssid_len;
 
 	/* IW_MODE_* */
 	u8 mode;
drivers/net/wireless/libertas/host.h +1 -0
index cc5f9bf..fcd2238 100644
@@ -113,6 +113,7 @@
 #define CMD_802_11_MONITOR_MODE       0x0098
 
 #define CMD_MESH_ACCESS               0x009b
+#define CMD_MESH_CONFIG				0x00a3
 
 #define CMD_SET_BOOT2_VER                 0x00a5
 
drivers/net/wireless/libertas/hostcmd.h +12 -0
index 7acb651..aab5d64 100644
@@ -626,6 +626,18 @@ struct cmd_ds_fwt_access {
 	u8 prec[ETH_ALEN];
 } __attribute__ ((packed));
 
+
+struct cmd_ds_mesh_config {
+	struct cmd_header hdr;
+
+        __le16 action;
+        __le16 channel;
+        __le16 type;
+        __le16 length;
+        u8 data[128];   /* last position reserved */
+} __attribute__ ((packed));
+
+
 struct cmd_ds_mesh_access {
 	struct cmd_header hdr;
 
drivers/net/wireless/libertas/if_usb.c +0 -6
index 7c57ff4..351c7ea 100644
@@ -232,9 +232,6 @@ static int if_usb_probe(struct usb_interface *intf,
 	cardp->priv = priv;
 	cardp->priv->fw_ready = 1;
 
-	if (lbs_add_mesh(priv, &udev->dev))
-		goto err_add_mesh;
-
 	cardp->eth_dev = priv->dev;
 
 	priv->hw_host_to_card = if_usb_host_to_card;
@@ -255,8 +252,6 @@ static int if_usb_probe(struct usb_interface *intf,
 	return 0;
 
 err_start_card:
-	lbs_remove_mesh(priv);
-err_add_mesh:
 	lbs_remove_card(priv);
 err_prog_firmware:
 	if_usb_reset_device(cardp);
@@ -286,7 +281,6 @@ static void if_usb_disconnect(struct usb_interface *intf)
 
 		priv->surpriseremoved = 1;
 		lbs_stop_card(priv);
-		lbs_remove_mesh(priv);
 		lbs_remove_card(priv);
 	}
 
drivers/net/wireless/libertas/main.c +65 -9

147 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#80 lore raw

[PATCH 67/48] libertas: convert CMD_MESH_ACCESS to a direct command

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 15:23:59 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   28 ++++++++-------------
 drivers/net/wireless/libertas/cmd.h     |    3 ++
 drivers/net/wireless/libertas/cmdresp.c |    5 ----
 drivers/net/wireless/libertas/hostcmd.h |    3 +-
 drivers/net/wireless/libertas/if_usb.c  |   11 ++------
 drivers/net/wireless/libertas/main.c    |   40 +++++++++++++++---------------
 6 files changed, 39 insertions(+), 51 deletions(-)
drivers/net/wireless/libertas/cmd.c +11 -17
index eeb09e0..9d621fe 100644
@@ -976,27 +976,25 @@ static int lbs_cmd_fwt_access(struct lbs_private *priv,
 	return 0;
 }
 
-static int lbs_cmd_mesh_access(struct lbs_private *priv,
-				struct cmd_ds_command *cmd,
-				u16 cmd_action, void *pdata_buf)
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+		    struct cmd_ds_mesh_access *cmd)
 {
-	struct cmd_ds_mesh_access *mesh_access = &cmd->params.mesh;
+	int ret;
+
 	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
 
-	cmd->command = cpu_to_le16(CMD_MESH_ACCESS);
-	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
-	cmd->result = 0;
+	cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
+	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
+	cmd->hdr.result = 0;
 
-	if (pdata_buf)
-		memcpy(mesh_access, pdata_buf, sizeof(*mesh_access));
-	else
-		memset(mesh_access, 0, sizeof(*mesh_access));
+	cmd->action = cpu_to_le16(cmd_action);
 
-	mesh_access->action = cpu_to_le16(cmd_action);
+	ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, (*cmd));
 
 	lbs_deb_leave(LBS_DEB_CMD);
-	return 0;
+	return ret;
 }
+EXPORT_SYMBOL_GPL(lbs_mesh_access);
 
 static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
 				struct cmd_ds_command *cmd,
@@ -1486,10 +1484,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf);
 		break;
 
-	case CMD_MESH_ACCESS:
-		ret = lbs_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf);
-		break;
-
 	case CMD_GET_TSF:
 		cmdptr->command = cpu_to_le16(CMD_GET_TSF);
 		cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_get_tsf) +
drivers/net/wireless/libertas/cmd.h +3 -0
index b8e5d21..716f25b 100644
@@ -24,4 +24,7 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
 
 int lbs_update_hw_spec(struct lbs_private *priv);
 
+int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
+		    struct cmd_ds_mesh_access *cmd);
+
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/cmdresp.c +0 -5
index b4cd7b7..6ff705b 100644
@@ -653,11 +653,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 			       sizeof(resp->params.fwt));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
-	case CMD_RET(CMD_MESH_ACCESS):
-		if (priv->cur_cmd->pdata_buf)
-			memcpy(priv->cur_cmd->pdata_buf, &resp->params.mesh,
-			       sizeof(resp->params.mesh));
-		break;
 	case CMD_RET(CMD_802_11_BEACON_CTRL):
 		ret = lbs_ret_802_11_bcn_ctrl(priv, resp);
 		break;
drivers/net/wireless/libertas/hostcmd.h +2 -1
index e5e2106..d9b151a 100644
@@ -623,6 +623,8 @@ struct cmd_ds_fwt_access {
 } __attribute__ ((packed));
 
 struct cmd_ds_mesh_access {
+	struct cmd_header hdr;
+
 	__le16 action;
 	__le32 data[32];	/* last position reserved */
 } __attribute__ ((packed));
@@ -687,7 +689,6 @@ struct cmd_ds_command {
 		struct cmd_tx_rate_query txrate;
 		struct cmd_ds_bt_access bt;
 		struct cmd_ds_fwt_access fwt;
-		struct cmd_ds_mesh_access mesh;
 		struct cmd_ds_get_tsf gettsf;
 		struct cmd_ds_802_11_subscribe_event subscribe_event;
 		struct cmd_ds_802_11_beacon_control bcn_ctrl;
drivers/net/wireless/libertas/if_usb.c +3 -8
index 5f2d944..a0866ef 100644
@@ -990,11 +990,9 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 		 */
 		struct cmd_ds_mesh_access mesh_access;
 		memset(&mesh_access, 0, sizeof(mesh_access));
+
 		mesh_access.data[0] = cpu_to_le32(1);
-		lbs_prepare_and_send_command(priv,
-				CMD_MESH_ACCESS,
-				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+		lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, &mesh_access);
 	}
 
 	netif_device_detach(cardp->eth_dev);
@@ -1031,10 +1029,7 @@ static int if_usb_resume(struct usb_interface *intf)
 		struct cmd_ds_mesh_access mesh_access;
 		memset(&mesh_access, 0, sizeof(mesh_access));
 		mesh_access.data[0] = cpu_to_le32(0);
-		lbs_prepare_and_send_command(priv,
-				CMD_MESH_ACCESS,
-				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+		lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, &mesh_access);
 	}
 
 	lbs_deb_leave(LBS_DEB_USB);
drivers/net/wireless/libertas/main.c +20 -20
index a081b91..7f6b3cc 100644
@@ -217,13 +217,15 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
 static ssize_t lbs_anycast_get(struct device *dev,
 		struct device_attribute *attr, char * buf)
 {
+	struct lbs_private *priv = to_net_dev(dev)->priv;
 	struct cmd_ds_mesh_access mesh_access;
+	int ret;
 
 	memset(&mesh_access, 0, sizeof(mesh_access));
-	lbs_prepare_and_send_command(to_net_dev(dev)->priv,
-			CMD_MESH_ACCESS,
-			CMD_ACT_MESH_GET_ANYCAST,
-			CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
+	if (ret)
+		return ret;
 
 	return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
 }
@@ -234,17 +236,19 @@ static ssize_t lbs_anycast_get(struct device *dev,
 static ssize_t lbs_anycast_set(struct device *dev,
 		struct device_attribute *attr, const char * buf, size_t count)
 {
+	struct lbs_private *priv = to_net_dev(dev)->priv;
 	struct cmd_ds_mesh_access mesh_access;
 	uint32_t datum;
+	int ret;
 
 	memset(&mesh_access, 0, sizeof(mesh_access));
 	sscanf(buf, "%x", &datum);
 	mesh_access.data[0] = cpu_to_le32(datum);
 
-	lbs_prepare_and_send_command((to_net_dev(dev))->priv,
-			CMD_MESH_ACCESS,
-			CMD_ACT_MESH_SET_ANYCAST,
-			CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
+	if (ret)
+		return ret;
+
 	return strlen(buf);
 }
 
@@ -323,14 +327,15 @@ static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
 static ssize_t lbs_autostart_enabled_get(struct device *dev,
 		struct device_attribute *attr, char * buf)
 {
+	struct lbs_private *priv = to_net_dev(dev)->priv;
 	struct cmd_ds_mesh_access mesh_access;
+	int ret;
 
 	memset(&mesh_access, 0, sizeof(mesh_access));
-	lbs_prepare_and_send_command(to_net_dev(dev)->priv,
-			CMD_MESH_ACCESS,
-			CMD_ACT_MESH_GET_AUTOSTART_ENABLED,
-			CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
 
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_AUTOSTART_ENABLED, &mesh_access);
+	if (ret)
+		return ret;
 	return sprintf(buf, "%d\n", le32_to_cpu(mesh_access.data[0]));
 }
 
@@ -346,10 +351,7 @@ static ssize_t lbs_autostart_enabled_set(struct device *dev,
 	sscanf(buf, "%d", &datum);
 	mesh_access.data[0] = cpu_to_le32(datum);
 
-	ret = lbs_prepare_and_send_command(priv,
-			CMD_MESH_ACCESS,
-			CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-			CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+	ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, &mesh_access);
 	if (ret == 0)
 		priv->mesh_autostart_enabled = datum ? 1 : 0;
 
@@ -866,10 +868,8 @@ static int lbs_setup_firmware(struct lbs_private *priv)
 	if (priv->mesh_dev) {
 		memset(&mesh_access, 0, sizeof(mesh_access));
 		mesh_access.data[0] = cpu_to_le32(0);
-		ret = lbs_prepare_and_send_command(priv,
-				CMD_MESH_ACCESS,
-				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
-				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);
+		ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED,
+				      &mesh_access);
 		if (ret) {
 			ret = -1;
 			goto done;
Signature · 1 line
1.5.3.4
#81 lore raw

[PATCH 71/48] libertas: convert RF_CHANNEL to a direct command

In reply to David Woodhouse

From: Dan Williams <[email protected]>
Date: Tue, 11 Dec 2007 16:54:15 -0500

---
 drivers/net/wireless/libertas/assoc.c   |   23 ++++++----
 drivers/net/wireless/libertas/cmd.c     |   71 +++++++++++++++++++++++--------
 drivers/net/wireless/libertas/cmd.h     |    3 +
 drivers/net/wireless/libertas/cmdresp.c |   25 -----------
 drivers/net/wireless/libertas/hostcmd.h |   10 +++--
 5 files changed, 75 insertions(+), 57 deletions(-)
drivers/net/wireless/libertas/assoc.c +13 -10
index 63bd692..bd9cfe1 100644
@@ -9,6 +9,7 @@
 #include "decl.h"
 #include "hostcmd.h"
 #include "host.h"
+#include "cmd.h"
 
 
 static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -165,11 +166,14 @@ done:
 static int update_channel(struct lbs_private *priv)
 {
 	int ret;
+
 	/* the channel in f/w could be out of sync, get the current channel */
 	lbs_deb_enter(LBS_DEB_ASSOC);
-	ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL,
-				    CMD_OPT_802_11_RF_CHANNEL_GET,
-				    CMD_OPTION_WAITFORRSP, 0, NULL);
+
+	ret = lbs_get_channel(priv);
+	if (ret > 0)
+		priv->curbssparams.channel = (u8) ret;
+
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
 	return ret;
 }
@@ -203,17 +207,16 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
 	       priv->curbssparams.channel, assoc_req->channel);
 
-	ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL,
-				CMD_OPT_802_11_RF_CHANNEL_SET,
-				CMD_OPTION_WAITFORRSP, 0, &assoc_req->channel);
-	if (ret < 0) {
+	ret = lbs_set_channel(priv, assoc_req->channel);
+	if (ret < 0)
 		lbs_deb_assoc("ASSOC: channel: error setting channel.");
-	}
 
+	/* FIXME: shouldn't need to grab the channel _again_ after setting
+	 * it since the firmware is supposed to return the new channel, but
+	 * whatever... */
 	ret = update_channel(priv);
-	if (ret < 0) {
+	if (ret < 0)
 		lbs_deb_assoc("ASSOC: channel: error getting channel.");
-	}
 
 	if (assoc_req->channel != priv->curbssparams.channel) {
 		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
drivers/net/wireless/libertas/cmd.c +53 -18

89 lines not on this page · raw message

drivers/net/wireless/libertas/cmd.h +3 -0
index 4bd6f56..5b02d73 100644
@@ -30,4 +30,7 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 int lbs_get_data_rate(struct lbs_private *priv);
 int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
 
+int lbs_get_channel(struct lbs_private *priv);
+int lbs_set_channel(struct lbs_private *priv, u8 channel);
+
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/cmdresp.c +0 -25
index 797c943..bf9941e 100644
@@ -325,28 +325,6 @@ static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv,
 	return 0;
 }
 
-static int lbs_ret_802_11_rf_channel(struct lbs_private *priv,
-				      struct cmd_ds_command *resp)
-{
-	struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
-	u16 action = le16_to_cpu(rfchannel->action);
-	u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
-
-	lbs_deb_enter(LBS_DEB_CMD);
-
-	if (action == CMD_OPT_802_11_RF_CHANNEL_GET
-	    && priv->curbssparams.channel != newchannel) {
-		lbs_deb_cmd("channel switch from %d to %d\n",
-		       priv->curbssparams.channel, newchannel);
-
-		/* Update the channel again */
-		priv->curbssparams.channel = newchannel;
-	}
-
-	lbs_deb_enter(LBS_DEB_CMD);
-	return 0;
-}
-
 static int lbs_ret_802_11_rssi(struct lbs_private *priv,
 				struct cmd_ds_command *resp)
 {
@@ -548,9 +526,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 	case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
 		ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp);
 		break;
-	case CMD_RET(CMD_802_11_RF_CHANNEL):
-		ret = lbs_ret_802_11_rf_channel(priv, resp);
-		break;
 
 	case CMD_RET(CMD_802_11_RSSI):
 		ret = lbs_ret_802_11_rssi(priv, resp);
drivers/net/wireless/libertas/hostcmd.h +6 -4
index d51010c..7acb651 100644
@@ -386,11 +386,13 @@ struct cmd_ds_802_11_inactivity_timeout {
 };
 
 struct cmd_ds_802_11_rf_channel {
+	struct cmd_header hdr;
+
 	__le16 action;
-	__le16 currentchannel;
-	__le16 rftype;
-	__le16 reserved;
-	u8 channellist[32];
+	__le16 channel;
+	__le16 rftype;      /* unused */
+	__le16 reserved;    /* unused */
+	u8 channellist[32]; /* unused */
 };
 
 struct cmd_ds_802_11_rssi {
Signature · 1 line
1.5.3.4
#82 lore raw

[PATCH 76/48] libertas: kill references to mesh autostart

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 18:57:49 -0500

---
 drivers/net/wireless/libertas/if_usb.c |   21 ------------
 drivers/net/wireless/libertas/main.c   |   54 --------------------------------
 2 files changed, 0 insertions(+), 75 deletions(-)
drivers/net/wireless/libertas/if_usb.c +0 -21
index 351c7ea..b19a6c9 100644
@@ -978,17 +978,6 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 	if (priv->psstate != PS_STATE_FULL_POWER)
 		return -1;
 
-	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
-		/* Mesh autostart must be activated while sleeping
-		 * On resume it will go back to the current state
-		 */
-		struct cmd_ds_mesh_access mesh_access;
-		memset(&mesh_access, 0, sizeof(mesh_access));
-
-		mesh_access.data[0] = cpu_to_le32(1);
-		lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, &mesh_access);
-	}
-
 	netif_device_detach(cardp->eth_dev);
 	netif_device_detach(priv->mesh_dev);
 
@@ -1016,16 +1005,6 @@ static int if_usb_resume(struct usb_interface *intf)
 	netif_device_attach(cardp->eth_dev);
 	netif_device_attach(priv->mesh_dev);
 
-	if (priv->mesh_dev && !priv->mesh_autostart_enabled) {
-		/* Mesh autostart was activated while sleeping
-		 * Disable it if appropriate
-		 */
-		struct cmd_ds_mesh_access mesh_access;
-		memset(&mesh_access, 0, sizeof(mesh_access));
-		mesh_access.data[0] = cpu_to_le32(0);
-		lbs_mesh_access(priv, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, &mesh_access);
-	}
-
 	lbs_deb_leave(LBS_DEB_USB);
 	return 0;
 }
drivers/net/wireless/libertas/main.c +0 -54

74 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#83 lore raw

[PATCH 77/48] libertas: kill rx_urb_recall and eth_dev members of struct usb_card_rec

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 18:36:35 -0500

---
 drivers/net/wireless/libertas/if_usb.c |   12 ++----------
 drivers/net/wireless/libertas/if_usb.h |    3 ---
 2 files changed, 2 insertions(+), 13 deletions(-)
drivers/net/wireless/libertas/if_usb.c +2 -10
index b19a6c9..02192e8 100644
@@ -175,8 +175,6 @@ static int if_usb_probe(struct usb_interface *intf,
 				       "Rx URB allocation failed\n");
 				goto dealloc;
 			}
-			cardp->rx_urb_recall = 0;
-
 			cardp->bulk_in_size =
 				le16_to_cpu(endpoint->wMaxPacketSize);
 			cardp->bulk_in_endpointAddr =
@@ -232,8 +230,6 @@ static int if_usb_probe(struct usb_interface *intf,
 	cardp->priv = priv;
 	cardp->priv->fw_ready = 1;
 
-	cardp->eth_dev = priv->dev;
-
 	priv->hw_host_to_card = if_usb_host_to_card;
 	priv->hw_get_int_status = if_usb_get_int_status;
 	priv->hw_read_event_cause = if_usb_read_event_cause;
@@ -978,15 +974,13 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 	if (priv->psstate != PS_STATE_FULL_POWER)
 		return -1;
 
-	netif_device_detach(cardp->eth_dev);
+	netif_device_detach(priv->dev);
 	netif_device_detach(priv->mesh_dev);
 
 	/* Unlink tx & rx urb */
 	usb_kill_urb(cardp->tx_urb);
 	usb_kill_urb(cardp->rx_urb);
 
-	cardp->rx_urb_recall = 1;
-
 	lbs_deb_leave(LBS_DEB_USB);
 	return 0;
 }
@@ -998,11 +992,9 @@ static int if_usb_resume(struct usb_interface *intf)
 
 	lbs_deb_enter(LBS_DEB_USB);
 
-	cardp->rx_urb_recall = 0;
-
 	if_usb_submit_rx_urb(cardp);
 
-	netif_device_attach(cardp->eth_dev);
+	netif_device_attach(priv->dev);
 	netif_device_attach(priv->mesh_dev);
 
 	lbs_deb_leave(LBS_DEB_USB);
drivers/net/wireless/libertas/if_usb.h +0 -3
index f028df1..668410f 100644
@@ -47,7 +47,6 @@ struct read_cb_info {
 
 /** USB card description structure*/
 struct usb_card_rec {
-	struct net_device *eth_dev;
 	struct usb_device *udev;
 	struct urb *rx_urb, *tx_urb;
 	struct lbs_private *priv;
@@ -75,8 +74,6 @@ struct usb_card_rec {
 	u32 usb_event_cause;
 	u8 usb_int_cause;
 
-	u8 rx_urb_recall;
-
 	s8 bootcmdresp;
 };
 
Signature · 1 line
1.5.3.4
#84 lore raw

[PATCH 78/48] libertas: whitespace cleanup in host.h

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 18:53:20 -0500

---
 drivers/net/wireless/libertas/host.h |  380 ++++++++++++++++------------------
 1 files changed, 178 insertions(+), 202 deletions(-)
drivers/net/wireless/libertas/host.h +178 -202
index fcd2238..64178cf 100644
@@ -6,21 +6,21 @@
 #define _LBS_HOST_H_
 
 /** PUBLIC DEFINITIONS */
-#define DEFAULT_AD_HOC_CHANNEL       6
-#define DEFAULT_AD_HOC_CHANNEL_A    36
+#define DEFAULT_AD_HOC_CHANNEL			6
+#define	DEFAULT_AD_HOC_CHANNEL_A		36
 
 /** IEEE 802.11 oids */
-#define OID_802_11_SSID                       0x00008002
-#define OID_802_11_INFRASTRUCTURE_MODE        0x00008008
-#define OID_802_11_FRAGMENTATION_THRESHOLD    0x00008009
-#define OID_802_11_RTS_THRESHOLD              0x0000800A
-#define OID_802_11_TX_ANTENNA_SELECTED        0x0000800D
-#define OID_802_11_SUPPORTED_RATES            0x0000800E
-#define OID_802_11_STATISTICS                 0x00008012
-#define OID_802_11_TX_RETRYCOUNT              0x0000801D
-#define OID_802_11D_ENABLE                    0x00008020
-
-#define CMD_OPTION_WAITFORRSP             0x0002
+#define OID_802_11_SSID				0x00008002
+#define OID_802_11_INFRASTRUCTURE_MODE		0x00008008
+#define OID_802_11_FRAGMENTATION_THRESHOLD	0x00008009
+#define OID_802_11_RTS_THRESHOLD		0x0000800A
+#define OID_802_11_TX_ANTENNA_SELECTED		0x0000800D
+#define OID_802_11_SUPPORTED_RATES		0x0000800E
+#define OID_802_11_STATISTICS			0x00008012
+#define OID_802_11_TX_RETRYCOUNT		0x0000801D
+#define OID_802_11D_ENABLE			0x00008020
+
+#define CMD_OPTION_WAITFORRSP			0x0002
 
 /** Host command IDs */
 
@@ -30,203 +30,179 @@
 #define CMD_RET(cmd)			(0x8000 | cmd)
 
 /* Return command convention exceptions: */
-#define CMD_RET_802_11_ASSOCIATE      0x8012
+#define CMD_RET_802_11_ASSOCIATE		0x8012
 
 /* Command codes */
-#define CMD_CODE_DNLD                 0x0002
-#define CMD_GET_HW_SPEC               0x0003
-#define CMD_EEPROM_UPDATE             0x0004
-#define CMD_802_11_RESET              0x0005
-#define CMD_802_11_SCAN               0x0006
-#define CMD_802_11_GET_LOG            0x000b
-#define CMD_MAC_MULTICAST_ADR         0x0010
-#define CMD_802_11_AUTHENTICATE       0x0011
-#define CMD_802_11_EEPROM_ACCESS      0x0059
-#define CMD_802_11_ASSOCIATE          0x0050
-#define CMD_802_11_SET_WEP            0x0013
-#define CMD_802_11_GET_STAT           0x0014
-#define CMD_802_3_GET_STAT            0x0015
-#define CMD_802_11_SNMP_MIB           0x0016
-#define CMD_MAC_REG_MAP               0x0017
-#define CMD_BBP_REG_MAP               0x0018
-#define CMD_MAC_REG_ACCESS            0x0019
-#define CMD_BBP_REG_ACCESS            0x001a
-#define CMD_RF_REG_ACCESS             0x001b
-#define CMD_802_11_RADIO_CONTROL      0x001c
-#define CMD_802_11_RF_CHANNEL         0x001d
-#define CMD_802_11_RF_TX_POWER        0x001e
-#define CMD_802_11_RSSI               0x001f
-#define CMD_802_11_RF_ANTENNA         0x0020
-
-#define CMD_802_11_PS_MODE	      0x0021
-
-#define CMD_802_11_DATA_RATE          0x0022
-#define CMD_RF_REG_MAP                0x0023
-#define CMD_802_11_DEAUTHENTICATE     0x0024
-#define CMD_802_11_REASSOCIATE        0x0025
-#define CMD_802_11_DISASSOCIATE       0x0026
-#define CMD_MAC_CONTROL               0x0028
-#define CMD_802_11_AD_HOC_START       0x002b
-#define CMD_802_11_AD_HOC_JOIN        0x002c
-
-#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS  0x002e
-#define CMD_802_11_ENABLE_RSN              0x002f
-#define CMD_802_11_PAIRWISE_TSC       0x0036
-#define CMD_802_11_GROUP_TSC          0x0037
-#define CMD_802_11_KEY_MATERIAL       0x005e
-
-#define CMD_802_11_SET_AFC            0x003c
-#define CMD_802_11_GET_AFC            0x003d
-
-#define CMD_802_11_AD_HOC_STOP        0x0040
-
-#define CMD_802_11_BEACON_STOP        0x0049
-
-#define CMD_802_11_MAC_ADDRESS        0x004D
-#define CMD_802_11_EEPROM_ACCESS      0x0059
-
-#define CMD_802_11_BAND_CONFIG        0x0058
-
-#define CMD_802_11D_DOMAIN_INFO       0x005b
-
-#define CMD_802_11_SLEEP_PARAMS          0x0066
-
-#define CMD_802_11_INACTIVITY_TIMEOUT    0x0067
-
-#define CMD_802_11_TPC_CFG               0x0072
-#define CMD_802_11_PWR_CFG               0x0073
-
-#define CMD_802_11_LED_GPIO_CTRL         0x004e
-
-#define CMD_802_11_SUBSCRIBE_EVENT       0x0075
-
-#define CMD_802_11_RATE_ADAPT_RATESET    0x0076
-
-#define CMD_802_11_TX_RATE_QUERY	0x007f
-
-#define CMD_GET_TSF                      0x0080
-
-#define CMD_BT_ACCESS                 0x0087
-
-#define CMD_FWT_ACCESS                0x0095
-
-#define CMD_802_11_MONITOR_MODE       0x0098
-
-#define CMD_MESH_ACCESS               0x009b
+#define CMD_CODE_DNLD				0x0002
+#define CMD_GET_HW_SPEC				0x0003
+#define	CMD_EEPROM_UPDATE			0x0004
+#define CMD_802_11_RESET			0x0005
+#define	CMD_802_11_SCAN				0x0006
+#define CMD_802_11_GET_LOG			0x000b
+#define CMD_MAC_MULTICAST_ADR			0x0010
+#define CMD_802_11_AUTHENTICATE			0x0011
+#define CMD_802_11_EEPROM_ACCESS		0x0059
+#define CMD_802_11_ASSOCIATE			0x0050
+#define CMD_802_11_SET_WEP			0x0013
+#define CMD_802_11_GET_STAT			0x0014
+#define CMD_802_3_GET_STAT			0x0015
+#define CMD_802_11_SNMP_MIB			0x0016
+#define CMD_MAC_REG_MAP				0x0017
+#define CMD_BBP_REG_MAP				0x0018
+#define CMD_MAC_REG_ACCESS			0x0019
+#define CMD_BBP_REG_ACCESS			0x001a
+#define CMD_RF_REG_ACCESS			0x001b
+#define CMD_802_11_RADIO_CONTROL		0x001c
+#define CMD_802_11_RF_CHANNEL			0x001d
+#define CMD_802_11_RF_TX_POWER			0x001e
+#define CMD_802_11_RSSI				0x001f
+#define CMD_802_11_RF_ANTENNA			0x0020
+#define CMD_802_11_PS_MODE			0x0021
+#define CMD_802_11_DATA_RATE			0x0022
+#define CMD_RF_REG_MAP				0x0023
+#define CMD_802_11_DEAUTHENTICATE		0x0024
+#define CMD_802_11_REASSOCIATE			0x0025
+#define CMD_802_11_DISASSOCIATE			0x0026
+#define CMD_MAC_CONTROL				0x0028
+#define CMD_802_11_AD_HOC_START			0x002b
+#define CMD_802_11_AD_HOC_JOIN			0x002c
+#define CMD_802_11_QUERY_TKIP_REPLY_CNTRS	0x002e
+#define CMD_802_11_ENABLE_RSN			0x002f
+#define CMD_802_11_PAIRWISE_TSC			0x0036
+#define CMD_802_11_GROUP_TSC			0x0037
+#define CMD_802_11_SET_AFC			0x003c
+#define CMD_802_11_GET_AFC			0x003d
+#define CMD_802_11_AD_HOC_STOP			0x0040
+#define CMD_802_11_BEACON_STOP			0x0049
+#define CMD_802_11_MAC_ADDRESS			0x004d
+#define CMD_802_11_LED_GPIO_CTRL		0x004e
+#define CMD_802_11_EEPROM_ACCESS		0x0059
+#define CMD_802_11_BAND_CONFIG			0x0058
+#define CMD_802_11D_DOMAIN_INFO			0x005b
+#define CMD_802_11_KEY_MATERIAL			0x005e
+#define CMD_802_11_SLEEP_PARAMS			0x0066
+#define CMD_802_11_INACTIVITY_TIMEOUT		0x0067
+#define CMD_802_11_TPC_CFG			0x0072
+#define CMD_802_11_PWR_CFG			0x0073
+#define CMD_802_11_SUBSCRIBE_EVENT		0x0075
+#define CMD_802_11_RATE_ADAPT_RATESET		0x0076
+#define CMD_802_11_TX_RATE_QUERY		0x007f
+#define	CMD_GET_TSF				0x0080
+#define CMD_BT_ACCESS				0x0087
+#define CMD_FWT_ACCESS				0x0095
+#define CMD_802_11_MONITOR_MODE			0x0098
+#define CMD_MESH_ACCESS				0x009b
 #define CMD_MESH_CONFIG				0x00a3
-
-#define CMD_SET_BOOT2_VER                 0x00a5
-
-#define CMD_802_11_BEACON_CTRL        0x00b0
+#define	CMD_SET_BOOT2_VER			0x00a5
+#define CMD_802_11_BEACON_CTRL			0x00b0
 
 /* For the IEEE Power Save */
-#define CMD_SUBCMD_ENTER_PS               0x0030
-#define CMD_SUBCMD_EXIT_PS                0x0031
-#define CMD_SUBCMD_SLEEP_CONFIRMED        0x0034
-#define CMD_SUBCMD_FULL_POWERDOWN         0x0035
-#define CMD_SUBCMD_FULL_POWERUP           0x0036
-
-#define CMD_ENABLE_RSN                    0x0001
-#define CMD_DISABLE_RSN                   0x0000
+#define CMD_SUBCMD_ENTER_PS		0x0030
+#define CMD_SUBCMD_EXIT_PS		0x0031
+#define CMD_SUBCMD_SLEEP_CONFIRMED	0x0034
+#define CMD_SUBCMD_FULL_POWERDOWN	0x0035
+#define CMD_SUBCMD_FULL_POWERUP		0x0036
 
-#define CMD_ACT_SET                       0x0001
-#define CMD_ACT_GET                       0x0000
+#define CMD_ENABLE_RSN			0x0001
+#define CMD_DISABLE_RSN			0x0000
 
-#define CMD_ACT_GET_AES                   (CMD_ACT_GET + 2)
-#define CMD_ACT_SET_AES                   (CMD_ACT_SET + 2)
-#define CMD_ACT_REMOVE_AES                (CMD_ACT_SET + 3)
+#define CMD_ACT_GET			0x0000
+#define CMD_ACT_SET			0x0001
+#define CMD_ACT_GET_AES			0x0002
+#define CMD_ACT_SET_AES			0x0003
+#define CMD_ACT_REMOVE_AES		0x0004
 
 /* Define action or option for CMD_802_11_SET_WEP */
-#define CMD_ACT_ADD                         0x0002
-#define CMD_ACT_REMOVE                      0x0004
-#define CMD_ACT_USE_DEFAULT                 0x0008
+#define CMD_ACT_ADD			0x0002
+#define CMD_ACT_REMOVE			0x0004
+#define CMD_ACT_USE_DEFAULT		0x0008
 
-#define CMD_TYPE_WEP_40_BIT                 0x01
-#define CMD_TYPE_WEP_104_BIT                0x02
+#define CMD_TYPE_WEP_40_BIT		0x01
+#define CMD_TYPE_WEP_104_BIT		0x02
 
-#define CMD_NUM_OF_WEP_KEYS                 4
+#define CMD_NUM_OF_WEP_KEYS		4
 
-#define CMD_WEP_KEY_INDEX_MASK              0x3fff
+#define CMD_WEP_KEY_INDEX_MASK		0x3fff
 
 /* Define action or option for CMD_802_11_RESET */
-#define CMD_ACT_HALT                        0x0003
+#define CMD_ACT_HALT			0x0003
 
 /* Define action or option for CMD_802_11_SCAN */
-#define CMD_BSS_TYPE_BSS                    0x0001
-#define CMD_BSS_TYPE_IBSS                   0x0002
-#define CMD_BSS_TYPE_ANY                    0x0003
+#define CMD_BSS_TYPE_BSS		0x0001
+#define CMD_BSS_TYPE_IBSS		0x0002
+#define CMD_BSS_TYPE_ANY		0x0003
 
 /* Define action or option for CMD_802_11_SCAN */
-#define CMD_SCAN_TYPE_ACTIVE                0x0000
-#define CMD_SCAN_TYPE_PASSIVE               0x0001
+#define CMD_SCAN_TYPE_ACTIVE		0x0000
+#define CMD_SCAN_TYPE_PASSIVE		0x0001
 
 #define CMD_SCAN_RADIO_TYPE_BG		0
 
-#define CMD_SCAN_PROBE_DELAY_TIME           0
+#define	CMD_SCAN_PROBE_DELAY_TIME	0
 
 /* Define action or option for CMD_MAC_CONTROL */
-#define CMD_ACT_MAC_RX_ON                   0x0001
-#define CMD_ACT_MAC_TX_ON                   0x0002
-#define CMD_ACT_MAC_LOOPBACK_ON             0x0004
-#define CMD_ACT_MAC_WEP_ENABLE              0x0008
-#define CMD_ACT_MAC_INT_ENABLE              0x0010
-#define CMD_ACT_MAC_MULTICAST_ENABLE        0x0020
-#define CMD_ACT_MAC_BROADCAST_ENABLE        0x0040
-#define CMD_ACT_MAC_PROMISCUOUS_ENABLE      0x0080
-#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE    0x0100
-#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE  0x0400
+#define CMD_ACT_MAC_RX_ON			0x0001
+#define CMD_ACT_MAC_TX_ON			0x0002
+#define CMD_ACT_MAC_LOOPBACK_ON			0x0004
+#define CMD_ACT_MAC_WEP_ENABLE			0x0008
+#define CMD_ACT_MAC_INT_ENABLE			0x0010
+#define CMD_ACT_MAC_MULTICAST_ENABLE		0x0020
+#define CMD_ACT_MAC_BROADCAST_ENABLE		0x0040
+#define CMD_ACT_MAC_PROMISCUOUS_ENABLE		0x0080
+#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE	0x0100
+#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE	0x0400
 
 /* Define action or option for CMD_802_11_RADIO_CONTROL */
-#define CMD_TYPE_AUTO_PREAMBLE              0x0001
-#define CMD_TYPE_SHORT_PREAMBLE             0x0002
-#define CMD_TYPE_LONG_PREAMBLE              0x0003
+#define CMD_TYPE_AUTO_PREAMBLE		0x0001
+#define CMD_TYPE_SHORT_PREAMBLE		0x0002
+#define CMD_TYPE_LONG_PREAMBLE		0x0003
 
 /* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
-#define CMD_SUBSCRIBE_RSSI_LOW              0x0001
-#define CMD_SUBSCRIBE_SNR_LOW               0x0002
-#define CMD_SUBSCRIBE_FAILCOUNT             0x0004
-#define CMD_SUBSCRIBE_BCNMISS               0x0008
-#define CMD_SUBSCRIBE_RSSI_HIGH             0x0010
-#define CMD_SUBSCRIBE_SNR_HIGH              0x0020
+#define CMD_SUBSCRIBE_RSSI_LOW		0x0001
+#define CMD_SUBSCRIBE_SNR_LOW		0x0002
+#define CMD_SUBSCRIBE_FAILCOUNT		0x0004
+#define CMD_SUBSCRIBE_BCNMISS		0x0008
+#define CMD_SUBSCRIBE_RSSI_HIGH		0x0010
+#define CMD_SUBSCRIBE_SNR_HIGH		0x0020
 
-#define TURN_ON_RF                              0x01
-#define RADIO_ON                                0x01
-#define RADIO_OFF                               0x00
+#define TURN_ON_RF			0x01
+#define RADIO_ON			0x01
+#define RADIO_OFF			0x00
 
-#define SET_AUTO_PREAMBLE                       0x05
-#define SET_SHORT_PREAMBLE                      0x03
-#define SET_LONG_PREAMBLE                       0x01
+#define SET_AUTO_PREAMBLE		0x05
+#define SET_SHORT_PREAMBLE		0x03
+#define SET_LONG_PREAMBLE		0x01
 
 /* Define action or option for CMD_802_11_RF_CHANNEL */
-#define CMD_OPT_802_11_RF_CHANNEL_GET       0x00
-#define CMD_OPT_802_11_RF_CHANNEL_SET       0x01
+#define CMD_OPT_802_11_RF_CHANNEL_GET	0x00
+#define CMD_OPT_802_11_RF_CHANNEL_SET	0x01
 
 /* Define action or option for CMD_802_11_RF_TX_POWER */
-#define CMD_ACT_TX_POWER_OPT_GET            0x0000
-#define CMD_ACT_TX_POWER_OPT_SET_HIGH       0x8007
-#define CMD_ACT_TX_POWER_OPT_SET_MID        0x8004
-#define CMD_ACT_TX_POWER_OPT_SET_LOW        0x8000
+#define CMD_ACT_TX_POWER_OPT_GET	0x0000
+#define CMD_ACT_TX_POWER_OPT_SET_HIGH	0x8007
+#define CMD_ACT_TX_POWER_OPT_SET_MID	0x8004
+#define CMD_ACT_TX_POWER_OPT_SET_LOW	0x8000
 
-#define CMD_ACT_TX_POWER_INDEX_HIGH         0x0007
-#define CMD_ACT_TX_POWER_INDEX_MID          0x0004
-#define CMD_ACT_TX_POWER_INDEX_LOW          0x0000
+#define CMD_ACT_TX_POWER_INDEX_HIGH	0x0007
+#define CMD_ACT_TX_POWER_INDEX_MID	0x0004
+#define CMD_ACT_TX_POWER_INDEX_LOW	0x0000
 
 /* Define action or option for CMD_802_11_DATA_RATE */
-#define CMD_ACT_SET_TX_AUTO                 0x0000
-#define CMD_ACT_SET_TX_FIX_RATE             0x0001
-#define CMD_ACT_GET_TX_RATE                 0x0002
+#define CMD_ACT_SET_TX_AUTO		0x0000
+#define CMD_ACT_SET_TX_FIX_RATE		0x0001
+#define CMD_ACT_GET_TX_RATE		0x0002
 
-#define CMD_ACT_SET_RX                      0x0001
-#define CMD_ACT_SET_TX                      0x0002
-#define CMD_ACT_SET_BOTH                    0x0003
-#define CMD_ACT_GET_RX                      0x0004
-#define CMD_ACT_GET_TX                      0x0008
-#define CMD_ACT_GET_BOTH                    0x000c
+#define CMD_ACT_SET_RX			0x0001
+#define	CMD_ACT_SET_TX			0x0002
+#define CMD_ACT_SET_BOTH		0x0003
+#define	CMD_ACT_GET_RX			0x0004
+#define CMD_ACT_GET_TX			0x0008
+#define	CMD_ACT_GET_BOTH		0x000c
 
 /* Define action or option for CMD_802_11_PS_MODE */
-#define CMD_TYPE_CAM                        0x0000
-#define CMD_TYPE_MAX_PSP                    0x0001
-#define CMD_TYPE_FAST_PSP                   0x0002
+#define CMD_TYPE_CAM			0x0000
+#define	CMD_TYPE_MAX_PSP		0x0001
+#define CMD_TYPE_FAST_PSP		0x0002
 
 /* Define action or option for CMD_BT_ACCESS */
 enum cmd_bt_access_opts {
@@ -275,36 +251,36 @@ enum cmd_mesh_access_opts {
 };
 
 /** Card Event definition */
-#define MACREG_INT_CODE_TX_PPA_FREE             0
-#define MACREG_INT_CODE_TX_DMA_DONE             1
-#define MACREG_INT_CODE_LINK_LOST_W_SCAN        2
-#define MACREG_INT_CODE_LINK_LOST_NO_SCAN       3
-#define MACREG_INT_CODE_LINK_SENSED             4
-#define MACREG_INT_CODE_CMD_FINISHED            5
-#define MACREG_INT_CODE_MIB_CHANGED             6
-#define MACREG_INT_CODE_INIT_DONE               7
-#define MACREG_INT_CODE_DEAUTHENTICATED         8
-#define MACREG_INT_CODE_DISASSOCIATED           9
-#define MACREG_INT_CODE_PS_AWAKE                10
-#define MACREG_INT_CODE_PS_SLEEP                11
-#define MACREG_INT_CODE_MIC_ERR_MULTICAST       13
-#define MACREG_INT_CODE_MIC_ERR_UNICAST         14
-#define MACREG_INT_CODE_WM_AWAKE                15
-#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE        16
-#define MACREG_INT_CODE_ADHOC_BCN_LOST          17
-#define MACREG_INT_CODE_HOST_AWAKE              18
-#define MACREG_INT_CODE_STOP_TX                 19
-#define MACREG_INT_CODE_START_TX                20
-#define MACREG_INT_CODE_CHANNEL_SWITCH          21
-#define MACREG_INT_CODE_MEASUREMENT_RDY         22
-#define MACREG_INT_CODE_WMM_CHANGE              23
-#define MACREG_INT_CODE_BG_SCAN_REPORT          24
-#define MACREG_INT_CODE_RSSI_LOW                25
-#define MACREG_INT_CODE_SNR_LOW                 26
-#define MACREG_INT_CODE_MAX_FAIL                27
-#define MACREG_INT_CODE_RSSI_HIGH               28
-#define MACREG_INT_CODE_SNR_HIGH                29
-#define MACREG_INT_CODE_MESH_AUTO_STARTED       35
-#define MACREG_INT_CODE_FIRMWARE_READY          48
+#define MACREG_INT_CODE_TX_PPA_FREE		0
+#define MACREG_INT_CODE_TX_DMA_DONE		1
+#define MACREG_INT_CODE_LINK_LOST_W_SCAN	2
+#define MACREG_INT_CODE_LINK_LOST_NO_SCAN	3
+#define MACREG_INT_CODE_LINK_SENSED		4
+#define MACREG_INT_CODE_CMD_FINISHED		5
+#define MACREG_INT_CODE_MIB_CHANGED		6
+#define MACREG_INT_CODE_INIT_DONE		7
+#define MACREG_INT_CODE_DEAUTHENTICATED		8
+#define MACREG_INT_CODE_DISASSOCIATED		9
+#define MACREG_INT_CODE_PS_AWAKE		10
+#define MACREG_INT_CODE_PS_SLEEP		11
+#define MACREG_INT_CODE_MIC_ERR_MULTICAST	13
+#define MACREG_INT_CODE_MIC_ERR_UNICAST		14
+#define MACREG_INT_CODE_WM_AWAKE		15
+#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE	16
+#define MACREG_INT_CODE_ADHOC_BCN_LOST		17
+#define MACREG_INT_CODE_HOST_AWAKE		18
+#define MACREG_INT_CODE_STOP_TX			19
+#define MACREG_INT_CODE_START_TX		20
+#define MACREG_INT_CODE_CHANNEL_SWITCH		21
+#define MACREG_INT_CODE_MEASUREMENT_RDY		22
+#define MACREG_INT_CODE_WMM_CHANGE		23
+#define MACREG_INT_CODE_BG_SCAN_REPORT		24
+#define MACREG_INT_CODE_RSSI_LOW		25
+#define MACREG_INT_CODE_SNR_LOW			26
+#define MACREG_INT_CODE_MAX_FAIL		27
+#define MACREG_INT_CODE_RSSI_HIGH		28
+#define MACREG_INT_CODE_SNR_HIGH		29
+#define MACREG_INT_CODE_MESH_AUTO_STARTED	35
+#define MACREG_INT_CODE_FIRMWARE_READY		48
 
 #endif
Signature · 1 line
1.5.3.4
#85 lore raw

[PATCH 79/48] libertas: allow get/set SSID on mshX device

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 19:30:57 -0500

---
 drivers/net/wireless/libertas/wext.c |   52 ++++++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/wext.c +50 -2
index e44c0ce..0a06072 100644
@@ -1917,6 +1917,54 @@ out:
 	return ret;
 }
 
+static int lbs_mesh_get_essid(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_point *dwrq, char *extra)
+{
+	struct lbs_private *priv = dev->priv;
+
+	lbs_deb_enter(LBS_DEB_WEXT);
+
+	memcpy(extra, priv->mesh_ssid, priv->mesh_ssid_len);
+
+	dwrq->length = priv->mesh_ssid_len;
+
+	dwrq->flags = 1;	/* active */
+
+	lbs_deb_leave(LBS_DEB_WEXT);
+	return 0;
+}
+
+static int lbs_mesh_set_essid(struct net_device *dev,
+			      struct iw_request_info *info,
+			      struct iw_point *dwrq, char *extra)
+{
+	struct lbs_private *priv = dev->priv;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_WEXT);
+
+	/* Check the size of the string */
+	if (dwrq->length > IW_ESSID_MAX_SIZE) {
+		ret = -E2BIG;
+		goto out;
+	}
+
+	if (!dwrq->flags || !dwrq->length) {
+		ret = -EINVAL;
+		goto out;
+	} else {
+		/* Specific SSID requested */
+		memcpy(priv->mesh_ssid, extra, dwrq->length);
+		priv->mesh_ssid_len = dwrq->length;
+	}
+
+	lbs_mesh_config(priv, 1);
+ out:
+	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+	return ret;
+}
+
 /**
  *  @brief Connect to the AP or Ad-hoc Network with specific bssid
  *
@@ -2071,8 +2119,8 @@ static const iw_handler mesh_wlan_handler[] = {
 	(iw_handler) NULL,	/* SIOCGIWAPLIST - deprecated */
 	(iw_handler) lbs_set_scan,	/* SIOCSIWSCAN */
 	(iw_handler) lbs_get_scan,	/* SIOCGIWSCAN */
-	(iw_handler) NULL,		/* SIOCSIWESSID */
-	(iw_handler) NULL,		/* SIOCGIWESSID */
+	(iw_handler) lbs_mesh_set_essid,/* SIOCSIWESSID */
+	(iw_handler) lbs_mesh_get_essid,/* SIOCGIWESSID */
 	(iw_handler) NULL,		/* SIOCSIWNICKN */
 	(iw_handler) mesh_get_nick,	/* SIOCGIWNICKN */
 	(iw_handler) NULL,	/* -- hole -- */
Signature · 1 line
1.5.3.4
#86 lore raw

[PATCH 80/48] libertas: allow setting channel on mshX device

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 19:56:28 -0500

---
 drivers/net/wireless/libertas/wext.c |   53 +++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/wext.c +52 -1
index 0a06072..262d4cc 100644
@@ -959,6 +959,57 @@ out:
 	return ret;
 }
 
+static int lbs_mesh_set_freq(struct net_device *dev,
+			     struct iw_request_info *info,
+			     struct iw_freq *fwrq, char *extra)
+{
+	struct lbs_private *priv = dev->priv;
+	struct chan_freq_power *cfp;
+	int ret = -EINVAL;
+
+	lbs_deb_enter(LBS_DEB_WEXT);
+
+	/* If setting by frequency, convert to a channel */
+	if (fwrq->e == 1) {
+		long f = fwrq->m / 100000;
+
+		cfp = find_cfp_by_band_and_freq(priv, 0, f);
+		if (!cfp) {
+			lbs_deb_wext("invalid freq %ld\n", f);
+			goto out;
+		}
+
+		fwrq->e = 0;
+		fwrq->m = (int) cfp->channel;
+	}
+
+	/* Setting by channel number */
+	if (fwrq->m > 1000 || fwrq->e > 0) {
+		goto out;
+	}
+
+	cfp = lbs_find_cfp_by_band_and_channel(priv, 0, fwrq->m);
+	if (!cfp) {
+		goto out;
+	}
+
+	if (fwrq->m != priv->curbssparams.channel) {
+		lbs_deb_wext("mesh channel change forces eth disconnect\n");
+		if (priv->mode == IW_MODE_INFRA)
+			lbs_send_deauthentication(priv);
+		else if (priv->mode == IW_MODE_ADHOC)
+			lbs_stop_adhoc_network(priv);
+	}
+	priv->curbssparams.channel = fwrq->m;
+	lbs_mesh_config(priv, 0);
+	lbs_mesh_config(priv, 1);
+	ret = 0;
+
+out:
+	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
+	return ret;
+}
+
 static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
 		  struct iw_param *vwrq, char *extra)
 {
@@ -2097,7 +2148,7 @@ static const iw_handler mesh_wlan_handler[] = {
 	(iw_handler) lbs_get_name,	/* SIOCGIWNAME */
 	(iw_handler) NULL,	/* SIOCSIWNWID */
 	(iw_handler) NULL,	/* SIOCGIWNWID */
-	(iw_handler) lbs_set_freq,	/* SIOCSIWFREQ */
+	(iw_handler) lbs_mesh_set_freq,	/* SIOCSIWFREQ */
 	(iw_handler) lbs_get_freq,	/* SIOCGIWFREQ */
 	(iw_handler) NULL,		/* SIOCSIWMODE */
 	(iw_handler) mesh_wlan_get_mode,	/* SIOCGIWMODE */
Signature · 1 line
1.5.3.4
#87 lore raw

[PATCH 81/48] libertas: add missing newline on debug message

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 19:57:05 -0500

---
 drivers/net/wireless/libertas/assoc.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/assoc.c +1 -1
index bd9cfe1..a4b9756 100644
@@ -219,7 +219,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 		lbs_deb_assoc("ASSOC: channel: error getting channel.");
 
 	if (assoc_req->channel != priv->curbssparams.channel) {
-		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d",
+		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
 		              assoc_req->channel);
 		goto done;
 	}
Signature · 1 line
1.5.3.4
#88 lore raw

[PATCH 82/48] libertas: disable mesh temporarily while setting eth channel/assoc

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 20:03:01 -0500

Otherwise the device won't let us change channels.

---
 drivers/net/wireless/libertas/assoc.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/assoc.c +12 -2
index a4b9756..7b672fe 100644
@@ -204,6 +204,12 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	if (assoc_req->channel == priv->curbssparams.channel)
 		goto done;
 
+	if (priv->mesh_dev) {
+		/* Disconnect mesh while associating -- otherwise it
+		   won't let us change channels */
+		lbs_mesh_config(priv, 0);
+	}
+
 	lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
 	       priv->curbssparams.channel, assoc_req->channel);
 
@@ -221,7 +227,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	if (assoc_req->channel != priv->curbssparams.channel) {
 		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
 		              assoc_req->channel);
-		goto done;
+		goto restore_mesh;
 	}
 
 	if (   assoc_req->secinfo.wep_enabled
@@ -236,7 +242,11 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	/* Must restart/rejoin adhoc networks after channel change */
 	set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
 
-done:
+ restore_mesh:
+	if (priv->mesh_dev)
+		lbs_mesh_config(priv, 1);
+
+ done:
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
 	return ret;
 }
Signature · 1 line
1.5.3.4
#89 lore raw

[PATCH 83/48] libertas: add debugging output to lbs_mesh_config()

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 22:52:03 -0500

---
 drivers/net/wireless/libertas/cmd.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmd.c +3 -1
index 01d2349..1cb42dc 100644
@@ -1106,7 +1106,9 @@ int lbs_mesh_config(struct lbs_private *priv, int enable)
 		cmd.length = cpu_to_le16(priv->mesh_ssid_len);
 		memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
 	}
-
+	lbs_deb_cmd("mesh config channel %d SSID %s\n",
+		    priv->curbssparams.channel,
+		    escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
 	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
 }
 
Signature · 1 line
1.5.3.4
#90 lore raw

[PATCH 84/48] libertas: be more careful about command responses matching cur_cmd

In reply to David Woodhouse

Date: Tue, 11 Dec 2007 23:42:49 -0500

Especially in the light of OLPC trac #5461, in which the firmware starts sending us seemingly random command responses which bear little relation to the command we sent it.

---
 drivers/net/wireless/libertas/cmd.c     |    4 +-
 drivers/net/wireless/libertas/cmdresp.c |   36 +++++++++++++++++++------------
 drivers/net/wireless/libertas/if_usb.c  |    1 +
 drivers/net/wireless/libertas/main.c    |    2 +-
 4 files changed, 26 insertions(+), 17 deletions(-)
drivers/net/wireless/libertas/cmd.c +2 -2
index 1cb42dc..5ddb46a 100644
@@ -1216,8 +1216,8 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 	cmdsize = le16_to_cpu(cmd->size);
 	command = le16_to_cpu(cmd->command);
 
-	lbs_deb_host("DNLD_CMD: command 0x%04x, size %d, jiffies %lu\n",
-		    command, cmdsize, jiffies);
+	lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n",
+		     command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies);
 	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
 
 	cmdnode->cmdwaitqwoken = 0;
drivers/net/wireless/libertas/cmdresp.c +22 -14
index bf9941e..53f73c4 100644
@@ -611,7 +611,7 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 
 	default:
 		lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n",
-			    resp->command);
+			     le16_to_cpu(resp->command));
 		break;
 	}
 	lbs_deb_leave(LBS_DEB_HOST);
@@ -620,17 +620,14 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 
 int lbs_process_rx_command(struct lbs_private *priv)
 {
-	u16 respcmd;
+	uint16_t respcmd, curcmd;
 	struct cmd_header *resp;
 	int ret = 0;
-	ulong flags;
-	u16 result;
+	unsigned long flags;
+	uint16_t result;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	/* Now we got response from FW, cancel the command timer */
-	del_timer(&priv->command_timer);
-
 	mutex_lock(&priv->lock);
 	spin_lock_irqsave(&priv->driver_lock, flags);
 
@@ -640,24 +637,35 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		goto done;
 	}
+
+	curcmd = le16_to_cpu(priv->cur_cmd->cmdbuf->command);
+
 	resp = priv->cur_cmd->cmdbuf;
 
 	respcmd = le16_to_cpu(resp->command);
 	result = le16_to_cpu(resp->result);
 
-	lbs_deb_host("CMD_RESP: response 0x%04x, size %d, jiffies %lu\n",
-		respcmd, priv->upld_len, jiffies);
+	lbs_deb_host("CMD_RESP: response 0x%04x, seq %d, size %d, jiffies %lu\n",
+		     respcmd, le16_to_cpu(resp->seqnum), priv->upld_len, jiffies);
 	lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", (void *) resp, priv->upld_len);
 
-	if (!(respcmd & 0x8000)) {
-		lbs_deb_host("invalid response!\n");
-		priv->cur_cmd_retcode = -1;
-		__lbs_cleanup_and_insert_cmd(priv, priv->cur_cmd);
-		priv->cur_cmd = NULL;
+	if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
+		lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
+			    le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		ret = -1;
 		goto done;
 	}
+	if (respcmd != CMD_RET(curcmd) &&
+	    respcmd != CMD_802_11_ASSOCIATE && curcmd != CMD_RET_802_11_ASSOCIATE) {
+		lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
+		spin_unlock_irqrestore(&priv->driver_lock, flags);
+		ret = -1;
+		goto done;
+	}
+
+	/* Now we got response from FW, cancel the command timer */
+	del_timer(&priv->command_timer);
 
 	/* Store the response code to cur_cmd_retcode. */
 	priv->cur_cmd_retcode = result;
drivers/net/wireless/libertas/if_usb.c +1 -0
index 02192e8..6b8ac62 100644
@@ -643,6 +643,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 	/* take care of cur_cmd = NULL case by reading the
 	 * data to clear the interrupt */
 	if (!priv->cur_cmd) {
+		lbs_deb_hex(LBS_DEB_HOST, "Unsolicited CMD_RESP", (void *) recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
 		cmdbuf = priv->upld_buf;
 		priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
 	} else
drivers/net/wireless/libertas/main.c +1 -1
index bb685ac..cdf5934 100644
@@ -893,7 +893,7 @@ static void command_timer_fn(unsigned long data)
 		return;
 	}
 
-	lbs_deb_fw("command_timer_fn fired, cmd %x\n", node->cmdbuf->command);
+	lbs_pr_info("command %x timed out\n", le16_to_cpu(node->cmdbuf->command));
 
 	if (!priv->fw_ready)
 		return;
Signature · 1 line
1.5.3.4
#91 lore raw

[PATCH 85/48] libertas: add missing newlines in debugging statements

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 00:14:21 -0500

---
 drivers/net/wireless/libertas/assoc.c  |   10 +++++-----
 drivers/net/wireless/libertas/cmd.c    |    8 ++++----
 drivers/net/wireless/libertas/if_usb.c |    2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)
drivers/net/wireless/libertas/assoc.c +5 -5
index 7b672fe..21a5696 100644
@@ -198,7 +198,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 
 	ret = update_channel(priv);
 	if (ret < 0) {
-		lbs_deb_assoc("ASSOC: channel: error getting channel.");
+		lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
 	}
 
 	if (assoc_req->channel == priv->curbssparams.channel)
@@ -215,14 +215,14 @@ static int assoc_helper_channel(struct lbs_private *priv,
 
 	ret = lbs_set_channel(priv, assoc_req->channel);
 	if (ret < 0)
-		lbs_deb_assoc("ASSOC: channel: error setting channel.");
+		lbs_deb_assoc("ASSOC: channel: error setting channel.\n");
 
 	/* FIXME: shouldn't need to grab the channel _again_ after setting
 	 * it since the firmware is supposed to return the new channel, but
 	 * whatever... */
 	ret = update_channel(priv);
 	if (ret < 0)
-		lbs_deb_assoc("ASSOC: channel: error getting channel.");
+		lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
 
 	if (assoc_req->channel != priv->curbssparams.channel) {
 		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
@@ -240,7 +240,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	}
 
 	/* Must restart/rejoin adhoc networks after channel change */
-	set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
+ 	set_bit(ASSOC_FLAG_SSID, &assoc_req->flags);
 
  restore_mesh:
 	if (priv->mesh_dev)
@@ -334,7 +334,7 @@ static int assoc_helper_secinfo(struct lbs_private *priv,
 				    CMD_OPTION_WAITFORRSP,
 				    0, &rsn);
 	if (ret) {
-		lbs_deb_assoc("Failed to get RSN status: %d", ret);
+		lbs_deb_assoc("Failed to get RSN status: %d\n", ret);
 		goto out;
 	}
 
drivers/net/wireless/libertas/cmd.c +4 -4
index 5ddb46a..8d8f9d9 100644
@@ -222,7 +222,7 @@ static int lbs_cmd_802_11_set_wep(struct lbs_private *priv,
 		int i;
 
 		if (!assoc_req) {
-			lbs_deb_cmd("Invalid association request!");
+			lbs_deb_cmd("Invalid association request!\n");
 			ret = -1;
 			goto done;
 		}
@@ -2088,17 +2088,17 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode)
 
 	if (priv->dnld_sent) {
 		allowed = 0;
-		lbs_deb_host("dnld_sent was set");
+		lbs_deb_host("dnld_sent was set\n");
 	}
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	if (priv->cur_cmd) {
 		allowed = 0;
-		lbs_deb_host("cur_cmd was set");
+		lbs_deb_host("cur_cmd was set\n");
 	}
 	if (priv->intcounter > 0) {
 		allowed = 0;
-		lbs_deb_host("intcounter %d", priv->intcounter);
+		lbs_deb_host("intcounter %d\n", priv->intcounter);
 	}
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
drivers/net/wireless/libertas/if_usb.c +1 -1
index 6b8ac62..3f8b83c 100644
@@ -220,7 +220,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	/* Upload firmware */
 	cardp->rinfo.cardp = cardp;
 	if (if_usb_prog_firmware(cardp)) {
-		lbs_deb_usbd(&udev->dev, "FW upload failed");
+		lbs_deb_usbd(&udev->dev, "FW upload failed\n");
 		goto err_prog_firmware;
 	}
 
Signature · 1 line
1.5.3.4
#92 lore raw

[PATCH 86/48] libertas: slight cleanup of netif queue stop/wake

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 00:41:51 -0500

In particular, we shouldn't be waking the queues in lbs_host_to_card_done() any more.

---
 drivers/net/wireless/libertas/cmdresp.c |   14 ++++++++------
 drivers/net/wireless/libertas/join.c    |    7 ++++---
 drivers/net/wireless/libertas/main.c    |   12 +-----------
 drivers/net/wireless/libertas/scan.c    |   12 +++++++-----
 4 files changed, 20 insertions(+), 25 deletions(-)
drivers/net/wireless/libertas/cmdresp.c +8 -6
index 53f73c4..a809f8f 100644
@@ -43,14 +43,15 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
 	msleep_interruptible(1000);
 	wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
 
-	/* Free Tx and Rx packets */
-	kfree_skb(priv->currenttxskb);
-	priv->currenttxskb = NULL;
-
 	/* report disconnect to upper layer */
 	netif_stop_queue(priv->dev);
 	netif_carrier_off(priv->dev);
 
+	/* Free Tx and Rx packets */
+	kfree_skb(priv->currenttxskb);
+	priv->currenttxskb = NULL;
+	priv->tx_pending_len = 0;
+
 	/* reset SNR/NF/RSSI values */
 	memset(priv->SNR, 0x00, sizeof(priv->SNR));
 	memset(priv->NF, 0x00, sizeof(priv->NF));
@@ -883,9 +884,10 @@ int lbs_process_event(struct lbs_private *priv)
 		}
 		lbs_pr_info("EVENT: MESH_AUTO_STARTED\n");
 		priv->mesh_connect_status = LBS_CONNECTED;
-		if (priv->mesh_open == 1) {
-			netif_wake_queue(priv->mesh_dev);
+		if (priv->mesh_open) {
 			netif_carrier_on(priv->mesh_dev);
+			if (!priv->tx_pending_len)
+				netif_wake_queue(priv->mesh_dev);
 		}
 		priv->mode = IW_MODE_ADHOC;
 		schedule_work(&priv->sync_channel);
drivers/net/wireless/libertas/join.c +4 -3
index 14425d9..2d45080 100644
@@ -781,8 +781,8 @@ int lbs_ret_80211_associate(struct lbs_private *priv,
 	priv->numSNRNF = 0;
 
 	netif_carrier_on(priv->dev);
-	netif_wake_queue(priv->dev);
-
+	if (!priv->tx_pending_len)
+		netif_wake_queue(priv->dev);
 
 	memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
@@ -865,7 +865,8 @@ int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
 	priv->curbssparams.ssid_len = bss->ssid_len;
 
 	netif_carrier_on(priv->dev);
-	netif_wake_queue(priv->dev);
+	if (!priv->tx_pending_len)
+		netif_wake_queue(priv->dev);
 
 	memset(&wrqu, 0, sizeof(wrqu));
 	memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
drivers/net/wireless/libertas/main.c +1 -11
index cdf5934..f9bdd12 100644
@@ -489,19 +489,9 @@ void lbs_host_to_card_done(struct lbs_private *priv)
 	priv->dnld_sent = DNLD_RES_RECEIVED;
 
 	/* Wake main thread if commands are pending */
-	if (!priv->cur_cmd)
+	if (!priv->cur_cmd || priv->tx_pending_len > 0)
 		wake_up_interruptible(&priv->waitq);
 
-	/* Don't wake netif queues if we're in monitor mode and
-	   a TX packet is already pending, or if there are commands
-	   queued to be sent. */
-	if (!priv->currenttxskb && list_empty(&priv->cmdpendingq)) {
-		if (priv->dev && priv->connect_status == LBS_CONNECTED)
-			netif_wake_queue(priv->dev);
-
-		if (priv->mesh_dev && priv->mesh_connect_status == LBS_CONNECTED)
-			netif_wake_queue(priv->mesh_dev);
-	}
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
drivers/net/wireless/libertas/scan.c +7 -5
index 92d84c7..9a61188 100644
@@ -590,13 +590,13 @@ int lbs_scan_networks(struct lbs_private *priv,
 	netif_stop_queue(priv->dev);
 	netif_carrier_off(priv->dev);
 	if (priv->mesh_dev) {
-			netif_stop_queue(priv->mesh_dev);
-			netif_carrier_off(priv->mesh_dev);
+		netif_stop_queue(priv->mesh_dev);
+		netif_carrier_off(priv->mesh_dev);
 	}
 
 	/* Prepare to continue an interrupted scan */
 	lbs_deb_scan("chan_count %d, last_scanned_channel %d\n",
-		chan_count, priv->last_scanned_channel);
+		     chan_count, priv->last_scanned_channel);
 	curr_chans = chan_list;
 	/* advance channel list by already-scanned-channels */
 	if (priv->last_scanned_channel > 0) {
@@ -659,11 +659,13 @@ out2:
 out:
 	if (priv->connect_status == LBS_CONNECTED) {
 		netif_carrier_on(priv->dev);
-		netif_wake_queue(priv->dev);
+		if (!priv->tx_pending_len)
+			netif_wake_queue(priv->dev);
 	}
 	if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) {
 		netif_carrier_on(priv->mesh_dev);
-		netif_wake_queue(priv->mesh_dev);
+		if (!priv->tx_pending_len)
+			netif_wake_queue(priv->mesh_dev);
 	}
 	kfree(chan_list);
 
Signature · 1 line
1.5.3.4
#93 lore raw

[PATCH 87/48] libertas: add lbs_host_sleep_cfg() command function

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 15:19:29 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   19 +++++++++++++++++++
 drivers/net/wireless/libertas/cmd.h     |    3 +++
 drivers/net/wireless/libertas/defs.h    |    7 +++++++
 drivers/net/wireless/libertas/host.h    |    2 ++
 drivers/net/wireless/libertas/hostcmd.h |    7 +++++++
 5 files changed, 38 insertions(+), 0 deletions(-)
drivers/net/wireless/libertas/cmd.c +19 -0
index 8d8f9d9..2d7b646 100644
@@ -111,6 +111,25 @@ out:
 	return ret;
 }
 
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
+		       uint8_t gpio, uint8_t gap)
+{
+	struct cmd_ds_host_sleep cmd_config;
+	int ret;
+
+	cmd_config.criteria = cpu_to_le32(criteria);
+	cmd_config.gpio = gpio;
+	cmd_config.gap = gap;
+
+	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, cmd_config);
+	if (ret) {
+		lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
+		return ret;
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
+
 static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv,
 				   struct cmd_ds_command *cmd,
 				   u16 cmd_action)
drivers/net/wireless/libertas/cmd.h +3 -0
index 80714b5..8d72c7e 100644
@@ -35,4 +35,7 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel);
 
 int lbs_mesh_config(struct lbs_private *priv, int enable);
 
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
+		       uint8_t gpio, uint8_t gap);
+
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/defs.h +7 -0
index 9b98ae7..3053cc2 100644
@@ -141,6 +141,13 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define	LBS_UPLD_SIZE			2312
 #define DEV_NAME_LEN			32
 
+/* Wake criteria for HOST_SLEEP_CFG command */
+#define EHS_WAKE_ON_BROADCAST_DATA	0x0001
+#define EHS_WAKE_ON_UNICAST_DATA	0x0002
+#define EHS_WAKE_ON_MAC_EVENT		0x0004
+#define EHS_WAKE_ON_MULTICAST_DATA	0x0008
+#define EHS_REMOVE_WAKEUP		0xFFFFFFFF
+
 /** Misc constants */
 /* This section defines 802.11 specific contants */
 
drivers/net/wireless/libertas/host.h +2 -0
index 64178cf..fe00081 100644
@@ -73,6 +73,8 @@
 #define CMD_802_11_SET_AFC			0x003c
 #define CMD_802_11_GET_AFC			0x003d
 #define CMD_802_11_AD_HOC_STOP			0x0040
+#define CMD_802_11_HOST_SLEEP_CFG		0x0043
+#define CMD_802_11_HOST_SLEEP_ACTIVATE		0x0045
 #define CMD_802_11_BEACON_STOP			0x0049
 #define CMD_802_11_MAC_ADDRESS			0x004d
 #define CMD_802_11_LED_GPIO_CTRL		0x004e
drivers/net/wireless/libertas/hostcmd.h +7 -0
index aab5d64..aa4cea0 100644
@@ -540,6 +540,13 @@ struct MrvlIEtype_keyParamSet {
 	u8 key[32];
 };
 
+struct cmd_ds_host_sleep {
+	struct cmd_header hdr;
+	__le32 criteria;
+	uint8_t gpio;
+	uint8_t gap;
+} __attribute__ ((packed));
+
 struct cmd_ds_802_11_key_material {
 	__le16 action;
 	struct MrvlIEtype_keyParamSet keyParamSet[2];
Signature · 1 line
1.5.3.4
#94 lore raw

[PATCH 88/48] libertas: switch lbs_cmd() to take a _pointer_ to the command structure

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 16:00:42 -0500

This way, it looks more like a normal function.

---
 drivers/net/wireless/libertas/cmd.c    |   17 +++++++++--------
 drivers/net/wireless/libertas/cmd.h    |   10 ++++------
 drivers/net/wireless/libertas/if_usb.c |    2 +-
 3 files changed, 14 insertions(+), 15 deletions(-)
drivers/net/wireless/libertas/cmd.c +9 -8
index 2d7b646..f87cecb 100644
@@ -56,7 +56,7 @@ int lbs_update_hw_spec(struct lbs_private *priv)
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
-	ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, cmd);
+	ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
 	if (ret)
 		goto out;
 
@@ -121,7 +121,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 	cmd_config.gpio = gpio;
 	cmd_config.gap = gap;
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, cmd_config);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
 	if (ret) {
 		lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
 		return ret;
@@ -743,7 +743,7 @@ int lbs_get_data_rate(struct lbs_private *priv)
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	cmd.action = cpu_to_le16(CMD_ACT_GET_TX_RATE);
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, cmd);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
 	if (ret)
 		goto out;
 
@@ -790,7 +790,7 @@ int lbs_set_data_rate(struct lbs_private *priv, u8 rate)
 		lbs_deb_cmd("DATA_RATE: setting auto\n");
 	}
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, cmd);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_DATA_RATE, &cmd);
 	if (ret)
 		goto out;
 
@@ -846,7 +846,7 @@ int lbs_get_channel(struct lbs_private *priv)
 	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 	cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, cmd);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
 	if (ret)
 		goto out;
 
@@ -878,7 +878,7 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel)
 	cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
 	cmd.channel = cpu_to_le16(channel);
 
-	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, cmd);
+	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
 	if (ret)
 		goto out;
 
@@ -1105,7 +1105,7 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 
 	cmd->action = cpu_to_le16(cmd_action);
 
-	ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, (*cmd));
+	ret = lbs_cmd_with_response(priv, CMD_MESH_ACCESS, cmd);
 
 	lbs_deb_leave(LBS_DEB_CMD);
 	return ret;
@@ -1128,7 +1128,7 @@ int lbs_mesh_config(struct lbs_private *priv, int enable)
 	lbs_deb_cmd("mesh config channel %d SSID %s\n",
 		    priv->curbssparams.channel,
 		    escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
-	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
 }
 
 static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
@@ -2160,6 +2160,7 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
 	lbs_deb_leave(LBS_DEB_CMD);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
 
 /**
  *  @brief Simple way to call firmware functions
drivers/net/wireless/libertas/cmd.h +4 -6
index 8d72c7e..e800295 100644
@@ -6,13 +6,11 @@
 #include "hostcmd.h"
 #include "dev.h"
 
-#define lbs_cmd(priv, cmdnr, cmd, callback, callback_arg) \
-	__lbs_cmd(priv, cmdnr, &(cmd).hdr, sizeof(cmd),	  \
-			callback, callback_arg)
+#define lbs_cmd(priv, cmdnr, cmd, cb, cb_arg)	\
+	__lbs_cmd(priv, cmdnr, &(cmd)->hdr, sizeof(*(cmd)), cb, cb_arg)
 
-#define lbs_cmd_with_response(priv, cmdnr, cmd) \
-	__lbs_cmd(priv, cmdnr, &(cmd).hdr, sizeof(cmd), \
-		  lbs_cmd_copyback, (unsigned long) &cmd)
+#define lbs_cmd_with_response(priv, cmdnr, cmd)	\
+	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
  
 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	      struct cmd_header *in_cmd, int in_cmd_size, 
drivers/net/wireless/libertas/if_usb.c +1 -1
index 3f8b83c..74fec9d 100644
@@ -109,7 +109,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 	b2_cmd.action = 0;
 	b2_cmd.version = priv->boot2_version;
 
-	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, b2_cmd, NULL, 0))
+	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, NULL, 0))
 		lbs_deb_usb("Setting boot2 version failed\n");
 }
 
Signature · 1 line
1.5.3.4
#95 lore raw

[PATCH 89/48] libertas: make worker thread not freezable

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 16:04:12 -0500

We want it to send the HOST_SLEEP_ACTIVATE command on the way down...

---
 drivers/net/wireless/libertas/main.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/main.c +0 -4
index f9bdd12..dd432ea 100644
@@ -6,7 +6,6 @@
 
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
-#include <linux/freezer.h>
 #include <linux/etherdevice.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
@@ -653,8 +652,6 @@ static int lbs_thread(void *data)
 
 	init_waitqueue_entry(&wait, current);
 
-	set_freezable();
-
 	for (;;) {
 		int shouldsleep;
 
@@ -698,7 +695,6 @@ static int lbs_thread(void *data)
 
 		set_current_state(TASK_RUNNING);
 		remove_wait_queue(&priv->waitq, &wait);
-		try_to_freeze();
 
 		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
 			       priv->intcounter, priv->currenttxskb, priv->dnld_sent);
Signature · 1 line
1.5.3.4
#96 lore raw

[PATCH 90/48] libertas: implement suspend and resume core methods

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 17:38:56 -0500

We (ab)use priv->fw_ready to stop the worker thread from sending more commands or data after the response to the HOST_SLEEP_ACTIVATE command comes in. And we set it from the callback function _directly_ to ensure that the worker thread sees it immediately; if we did it in lbs_suspend() after waking up, that might be too late.

---
 drivers/net/wireless/libertas/cmd.h  |    2 +
 drivers/net/wireless/libertas/main.c |   47 ++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 0 deletions(-)
drivers/net/wireless/libertas/cmd.h +2 -0
index e800295..e44a0db 100644
@@ -35,5 +35,7 @@ int lbs_mesh_config(struct lbs_private *priv, int enable);
 
 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
 		       uint8_t gpio, uint8_t gap);
+int lbs_suspend(struct lbs_private *priv);
+int lbs_resume(struct lbs_private *priv);
 
 #endif /* _LBS_CMD_H */
drivers/net/wireless/libertas/main.c +47 -0

53 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#97 lore raw

[PATCH 93/48] libertas: make lbs_update_channel() function non-static

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 22:50:21 -0500

We'll want to use this for meshfrobbing

---
 drivers/net/wireless/libertas/assoc.c |    8 ++++----
 drivers/net/wireless/libertas/decl.h  |    1 +
 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/assoc.c +4 -4
index 21a5696..ff976eb 100644
@@ -163,7 +163,7 @@ done:
 }
 
 
-static int update_channel(struct lbs_private *priv)
+int lbs_update_channel(struct lbs_private *priv)
 {
 	int ret;
 
@@ -184,7 +184,7 @@ void lbs_sync_channel(struct work_struct *work)
 		sync_channel);
 
 	lbs_deb_enter(LBS_DEB_ASSOC);
-	if (update_channel(priv) != 0)
+	if (lbs_update_channel(priv))
 		lbs_pr_info("Channel synchronization failed.");
 	lbs_deb_leave(LBS_DEB_ASSOC);
 }
@@ -196,7 +196,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 
 	lbs_deb_enter(LBS_DEB_ASSOC);
 
-	ret = update_channel(priv);
+	ret = lbs_update_channel(priv);
 	if (ret < 0) {
 		lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
 	}
@@ -220,7 +220,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	/* FIXME: shouldn't need to grab the channel _again_ after setting
 	 * it since the firmware is supposed to return the new channel, but
 	 * whatever... */
-	ret = update_channel(priv);
+	ret = lbs_update_channel(priv);
 	if (ret < 0)
 		lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
 
drivers/net/wireless/libertas/decl.h +1 -0
index 9b0ef16..45f081b 100644
@@ -77,4 +77,5 @@ int lbs_stop_card(struct lbs_private *priv);
 int lbs_reset_device(struct lbs_private *priv);
 void lbs_host_to_card_done(struct lbs_private *priv);
 
+int lbs_update_channel(struct lbs_private *priv);
 #endif
Signature · 1 line
1.5.3.4
#98 lore raw

[PATCH 91/48] libertas: implement suspend/resume for USB devices

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 17:40:56 -0500

---
 drivers/net/wireless/libertas/if_usb.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)
drivers/net/wireless/libertas/if_usb.c +11 -5
index 74fec9d..15715a6 100644
@@ -242,6 +242,10 @@ static int if_usb_probe(struct usb_interface *intf,
 
 	if_usb_set_boot2_ver(priv);
 
+	/* Set suspend/resume configuration:
+	   wake via GPIO2 after a 20ms delay */
+	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA, 2, 20);
+
 	usb_get_dev(udev);
 	usb_set_intfdata(intf, cardp);
 
@@ -969,21 +973,24 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct usb_card_rec *cardp = usb_get_intfdata(intf);
 	struct lbs_private *priv = cardp->priv;
+	int ret;
 
 	lbs_deb_enter(LBS_DEB_USB);
 
 	if (priv->psstate != PS_STATE_FULL_POWER)
 		return -1;
 
-	netif_device_detach(priv->dev);
-	netif_device_detach(priv->mesh_dev);
+	ret = lbs_suspend(priv);
+	if (ret)
+		goto out;
 
 	/* Unlink tx & rx urb */
 	usb_kill_urb(cardp->tx_urb);
 	usb_kill_urb(cardp->rx_urb);
 
+ out:
 	lbs_deb_leave(LBS_DEB_USB);
-	return 0;
+	return ret;
 }
 
 static int if_usb_resume(struct usb_interface *intf)
@@ -995,8 +1002,7 @@ static int if_usb_resume(struct usb_interface *intf)
 
 	if_usb_submit_rx_urb(cardp);
 
-	netif_device_attach(priv->dev);
-	netif_device_attach(priv->mesh_dev);
+	lbs_resume(priv);
 
 	lbs_deb_leave(LBS_DEB_USB);
 	return 0;
Signature · 1 line
1.5.3.4
#99 lore raw

[PATCH 92/48] libertas: add ethtool support for wake-on-lan configuration

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 20:06:06 -0500

Also, check that suspend is refused if HOST_SLEEP_CFG hasn't been done.

---
 drivers/net/wireless/libertas/cmd.c     |   14 +++++----
 drivers/net/wireless/libertas/cmd.h     |    3 +-
 drivers/net/wireless/libertas/dev.h     |    5 +++
 drivers/net/wireless/libertas/ethtool.c |   47 +++++++++++++++++++++++++++++++
 drivers/net/wireless/libertas/if_usb.c  |    6 ++--
 drivers/net/wireless/libertas/main.c    |    8 +++++
 6 files changed, 72 insertions(+), 11 deletions(-)
drivers/net/wireless/libertas/cmd.c +8 -6
index f87cecb..ddf1527 100644
@@ -111,21 +111,23 @@ out:
 	return ret;
 }
 
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
-		       uint8_t gpio, uint8_t gap)
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
 {
 	struct cmd_ds_host_sleep cmd_config;
 	int ret;
 
 	cmd_config.criteria = cpu_to_le32(criteria);
-	cmd_config.gpio = gpio;
-	cmd_config.gap = gap;
+	cmd_config.gpio = priv->wol_gpio;
+	cmd_config.gap = priv->wol_gap;
 
 	ret = lbs_cmd_with_response(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config);
-	if (ret) {
+	if (!ret) {
+		lbs_deb_cmd("Set WOL criteria to %x\n", criteria);
+		priv->wol_criteria = criteria;
+	} else {
 		lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
-		return ret;
 	}
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
drivers/net/wireless/libertas/cmd.h +1 -2
index e44a0db..55f2436 100644
@@ -33,8 +33,7 @@ int lbs_set_channel(struct lbs_private *priv, u8 channel);
 
 int lbs_mesh_config(struct lbs_private *priv, int enable);
 
-int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
-		       uint8_t gpio, uint8_t gap);
+int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
 int lbs_suspend(struct lbs_private *priv);
 int lbs_resume(struct lbs_private *priv);
 
drivers/net/wireless/libertas/dev.h +5 -0
index 86b45a4..60a6a51 100644
@@ -153,6 +153,11 @@ struct lbs_private {
 	int (*hw_get_int_status) (struct lbs_private *priv, u8 *);
 	int (*hw_read_event_cause) (struct lbs_private *);
 
+	/* Wake On LAN */
+	uint32_t wol_criteria;
+	uint8_t wol_gpio;
+	uint8_t wol_gap;
+
 	/* was struct lbs_adapter from here... */
 
 	/** Wlan adapter data structure*/
drivers/net/wireless/libertas/ethtool.c +47 -0

64 lines not on this page · raw message

drivers/net/wireless/libertas/if_usb.c +3 -3
index 15715a6..8191416 100644
@@ -242,9 +242,9 @@ static int if_usb_probe(struct usb_interface *intf,
 
 	if_usb_set_boot2_ver(priv);
 
-	/* Set suspend/resume configuration:
-	   wake via GPIO2 after a 20ms delay */
-	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA, 2, 20);
+	priv->wol_gpio = 2; /* Wake via GPIO2... */
+	priv->wol_gap = 20; /* ... after 20ms    */
+	lbs_host_sleep_cfg(priv, EHS_WAKE_ON_UNICAST_DATA);
 
 	usb_get_dev(udev);
 	usb_set_intfdata(intf, cardp);
drivers/net/wireless/libertas/main.c +8 -0
index 1ea119e..5e2f329 100644
@@ -839,6 +839,11 @@ int lbs_suspend(struct lbs_private *priv)
 	struct cmd_header cmd;
 	int ret;
 
+	if (priv->wol_criteria == 0xffffffff) {
+		lbs_pr_info("Suspend attempt without configuring wake params!\n");
+		return -EINVAL;
+	}
+
 	memset(&cmd, 0, sizeof(cmd));
 	
 	ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
@@ -1088,6 +1093,9 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 	sprintf(priv->mesh_ssid, "mesh");
 	priv->mesh_ssid_len = 4;
 
+	priv->wol_criteria = 0xffffffff;
+	priv->wol_gpio = 0xff;
+
 	goto done;
 
 err_init_adapter:
Signature · 1 line
1.5.3.4
#100 lore raw

[PATCH 94/48] libertas: cope with both old and new mesh TLV values

In reply to David Woodhouse

Date: Wed, 12 Dec 2007 23:29:13 -0500

---
 drivers/net/wireless/libertas/cmd.c  |    6 +++---
 drivers/net/wireless/libertas/dev.h  |    2 ++
 drivers/net/wireless/libertas/main.c |   32 +++++++++++++++++++++++++++++---
 3 files changed, 34 insertions(+), 6 deletions(-)
drivers/net/wireless/libertas/cmd.c +3 -3
index ddf1527..c4299ae 100644
@@ -1121,14 +1121,14 @@ int lbs_mesh_config(struct lbs_private *priv, int enable)
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.action = cpu_to_le16(enable);
 	cmd.channel = cpu_to_le16(priv->curbssparams.channel);
-	cmd.type = cpu_to_le16(0x100 + 37);
+	cmd.type = cpu_to_le16(priv->mesh_tlv);
 	
 	if (enable) {
 		cmd.length = cpu_to_le16(priv->mesh_ssid_len);
 		memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
 	}
-	lbs_deb_cmd("mesh config channel %d SSID %s\n",
-		    priv->curbssparams.channel,
+	lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
+		    enable, priv->mesh_tlv, priv->curbssparams.channel,
 		    escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
 	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
 }
drivers/net/wireless/libertas/dev.h +2 -0
index 60a6a51..e6f553d 100644
@@ -206,6 +206,8 @@ struct lbs_private {
 
 	/** current ssid/bssid related parameters*/
 	struct current_bss_params curbssparams;
+
+	uint16_t mesh_tlv;
 	u8 mesh_ssid[IW_ESSID_MAX_SIZE + 1];
 	u8 mesh_ssid_len;
 
drivers/net/wireless/libertas/main.c +29 -3
index 5e2f329..2409df8 100644
@@ -1171,8 +1171,33 @@ int lbs_start_card(struct lbs_private *priv)
 	}
 	if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
 		lbs_pr_err("cannot register lbs_rtap attribute\n");
-	if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-		lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+	/* Enable mesh, if supported, and work out which TLV it uses.
+	   0x100 + 291 is an unofficial value used in 5.110.20.pXX
+	   0x100 + 37 is the official value used in 5.110.21.pXX
+	   but we check them in that order because 20.pXX doesn't 
+	   give an error -- it just silently fails. */
+
+	/* 5.110.20.pXX firmware will fail the command if the channel
+	   doesn't match the existing channel. But only if the TLV
+	   is correct. If the channel is wrong, _BOTH_ versions will
+	   give an error to 0x100+291, and allow 0x100+37 to succeed.
+	   It's just that 5.110.20.pXX will not have done anything
+	   useful */
+
+	lbs_update_channel(priv);
+	priv->mesh_tlv = 0x100 + 291;
+	if (lbs_mesh_config(priv, 1)) {
+		priv->mesh_tlv = 0x100 + 37;
+		if (lbs_mesh_config(priv, 1))
+			priv->mesh_tlv = 0;
+	}
+	if (priv->mesh_tlv) {
+		lbs_add_mesh(priv);
+
+		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+			lbs_pr_err("cannot register lbs_mesh attribute\n");
+	}
 
 	lbs_debugfs_init_one(priv, dev);
 
@@ -1201,7 +1226,8 @@ int lbs_stop_card(struct lbs_private *priv)
 
 	lbs_debugfs_remove_one(priv);
 	device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
-	device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
+	if (priv->mesh_tlv)
+		device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
 
 	/* Flush pending command nodes */
 	spin_lock_irqsave(&priv->driver_lock, flags);
Signature · 1 line
1.5.3.4
#101 lore raw

[PATCH 95/48] libertas: pass channel argument directly to lbs_mesh_config()

In reply to David Woodhouse

Date: Thu, 13 Dec 2007 00:32:36 -0500

There is weirdness here; the firmware seems to refuse to change channels at will.

---
 drivers/net/wireless/libertas/assoc.c |   11 ++++++-----
 drivers/net/wireless/libertas/cmd.c   |    6 +++---
 drivers/net/wireless/libertas/cmd.h   |    2 +-
 drivers/net/wireless/libertas/main.c  |    6 +++---
 drivers/net/wireless/libertas/wext.c  |    7 +++----
 5 files changed, 16 insertions(+), 16 deletions(-)
drivers/net/wireless/libertas/assoc.c +6 -5
index ff976eb..cd8e043 100644
@@ -205,13 +205,14 @@ static int assoc_helper_channel(struct lbs_private *priv,
 		goto done;
 
 	if (priv->mesh_dev) {
-		/* Disconnect mesh while associating -- otherwise it
-		   won't let us change channels */
-		lbs_mesh_config(priv, 0);
+		/* Change mesh channel first; 21.p21 firmware won't let
+		   you change channel otherwise (even though it'll return
+		   an error to this */
+		lbs_mesh_config(priv, 0, assoc_req->channel);
 	}
 
 	lbs_deb_assoc("ASSOC: channel: %d -> %d\n",
-	       priv->curbssparams.channel, assoc_req->channel);
+		      priv->curbssparams.channel, assoc_req->channel);
 
 	ret = lbs_set_channel(priv, assoc_req->channel);
 	if (ret < 0)
@@ -244,7 +245,7 @@ static int assoc_helper_channel(struct lbs_private *priv,
 
  restore_mesh:
 	if (priv->mesh_dev)
-		lbs_mesh_config(priv, 1);
+		lbs_mesh_config(priv, 1, priv->curbssparams.channel);
 
  done:
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
drivers/net/wireless/libertas/cmd.c +3 -3
index c4299ae..171acc2 100644
@@ -1114,13 +1114,13 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 }
 EXPORT_SYMBOL_GPL(lbs_mesh_access);
 
-int lbs_mesh_config(struct lbs_private *priv, int enable)
+int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
 {
 	struct cmd_ds_mesh_config cmd;
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.action = cpu_to_le16(enable);
-	cmd.channel = cpu_to_le16(priv->curbssparams.channel);
+	cmd.channel = cpu_to_le16(chan);
 	cmd.type = cpu_to_le16(priv->mesh_tlv);
 	
 	if (enable) {
@@ -1128,7 +1128,7 @@ int lbs_mesh_config(struct lbs_private *priv, int enable)
 		memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
 	}
 	lbs_deb_cmd("mesh config enable %d TLV %x channel %d SSID %s\n",
-		    enable, priv->mesh_tlv, priv->curbssparams.channel,
+		    enable, priv->mesh_tlv, chan,
 		    escape_essid(priv->mesh_ssid, priv->mesh_ssid_len));
 	return lbs_cmd_with_response(priv, CMD_MESH_CONFIG, &cmd);
 }
drivers/net/wireless/libertas/cmd.h +1 -1
index 55f2436..a4aaa6b 100644
@@ -31,7 +31,7 @@ int lbs_set_data_rate(struct lbs_private *priv, u8 rate);
 int lbs_get_channel(struct lbs_private *priv);
 int lbs_set_channel(struct lbs_private *priv, u8 channel);
 
-int lbs_mesh_config(struct lbs_private *priv, int enable);
+int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan);
 
 int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria);
 int lbs_suspend(struct lbs_private *priv);
drivers/net/wireless/libertas/main.c +3 -3
index 2409df8..9232b97 100644
@@ -344,7 +344,7 @@ static ssize_t lbs_mesh_set(struct device *dev,
 	if (enable == !!priv->mesh_dev)
 		return count;
 
-	ret = lbs_mesh_config(priv, enable);
+	ret = lbs_mesh_config(priv, enable, priv->curbssparams.channel);
 	if (ret)
 		return ret;
 		
@@ -1187,9 +1187,9 @@ int lbs_start_card(struct lbs_private *priv)
 
 	lbs_update_channel(priv);
 	priv->mesh_tlv = 0x100 + 291;
-	if (lbs_mesh_config(priv, 1)) {
+	if (lbs_mesh_config(priv, 1, priv->curbssparams.channel)) {
 		priv->mesh_tlv = 0x100 + 37;
-		if (lbs_mesh_config(priv, 1))
+		if (lbs_mesh_config(priv, 1, priv->curbssparams.channel))
 			priv->mesh_tlv = 0;
 	}
 	if (priv->mesh_tlv) {
drivers/net/wireless/libertas/wext.c +3 -4
index 262d4cc..b1e2472 100644
@@ -1000,9 +1000,8 @@ static int lbs_mesh_set_freq(struct net_device *dev,
 		else if (priv->mode == IW_MODE_ADHOC)
 			lbs_stop_adhoc_network(priv);
 	}
-	priv->curbssparams.channel = fwrq->m;
-	lbs_mesh_config(priv, 0);
-	lbs_mesh_config(priv, 1);
+	lbs_mesh_config(priv, 1, fwrq->m);
+	lbs_update_channel(priv);
 	ret = 0;
 
 out:
@@ -2010,7 +2009,7 @@ static int lbs_mesh_set_essid(struct net_device *dev,
 		priv->mesh_ssid_len = dwrq->length;
 	}
 
-	lbs_mesh_config(priv, 1);
+	lbs_mesh_config(priv, 1, priv->curbssparams.channel);
  out:
 	lbs_deb_leave_args(LBS_DEB_WEXT, "ret %d", ret);
 	return ret;
Signature · 1 line
1.5.3.4
#102 lore raw

[PATCH 96/48] libertas: use spin_is_locked() instead of spin_trylock() in lbs_interrupt()

In reply to David Woodhouse

Date: Thu, 13 Dec 2007 01:53:57 -0500

We get scary warnings on UP if we use spin_trylock() and find, as we hoped, that the lock in question is already locked.

---
 drivers/net/wireless/libertas/main.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/net/wireless/libertas/main.c +1 -2
index 9232b97..5d2bf53 100644
@@ -1414,8 +1414,7 @@ void lbs_interrupt(struct lbs_private *priv)
 
 	lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->intcounter);
 
-	if (spin_trylock(&priv->driver_lock)) {
-		spin_unlock(&priv->driver_lock);
+	if (!spin_is_locked(&priv->driver_lock)) {
 		printk(KERN_CRIT "%s called without driver_lock held\n", __func__);
 		WARN_ON(1);
 	}
Signature · 1 line
1.5.3.4
#103 lore raw

[PATCH 97/48] libertas: don't exit worker thread until kthread_stop() is called

In reply to David Woodhouse

Date: Thu, 13 Dec 2007 21:48:00 -0500

The kthread code can't cope with a thread exiting of its own accord and then someone calling kthread_stop() for it. When the thread detects that it needs to die, make it wait for kthread_stop() to be called.

---
 drivers/net/wireless/libertas/main.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/libertas/main.c +9 -4
index 5d2bf53..b51513f 100644
@@ -662,8 +662,10 @@ static int lbs_thread(void *data)
 		set_current_state(TASK_INTERRUPTIBLE);
 		spin_lock_irq(&priv->driver_lock);
 
-		if (priv->surpriseremoved)
+		if (kthread_should_stop())
 			shouldsleep = 0;	/* Bye */
+		else if (priv->surpriseremoved)
+			shouldsleep = 1;	/* We need to wait until we're _told_ to die */
 		else if (priv->psstate == PS_STATE_SLEEP)
 			shouldsleep = 1;	/* Sleep mode. Nothing we can do till it wakes */
 		else if (priv->intcounter)
@@ -699,12 +701,15 @@ static int lbs_thread(void *data)
 		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p dnld_sent=%d\n",
 			       priv->intcounter, priv->currenttxskb, priv->dnld_sent);
 
-		if (kthread_should_stop() || priv->surpriseremoved) {
-			lbs_deb_thread("main-thread: break from main thread: surpriseremoved=0x%x\n",
-				       priv->surpriseremoved);
+		if (kthread_should_stop()) {
+			lbs_deb_thread("main-thread: break from main thread\n");
 			break;
 		}
 
+		if (priv->surpriseremoved) {
+			lbs_deb_thread("adapter removed; waiting to die...\n");
+			continue;
+		}
 
 		spin_lock_irq(&priv->driver_lock);
 
Signature · 1 line
1.5.3.4
#104 lore raw

[PATCH 98/48] libertas: stop attempting to reset devices on unload

In reply to David Woodhouse

Date: Thu, 13 Dec 2007 21:53:16 -0500

It wasn't working anyway -- by the time we get into if_usb_disconnect() the USB core has already stopped us talking to the thing; even if it's just on unload and the device still exists.

---
 drivers/net/wireless/libertas/if_usb.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)
drivers/net/wireless/libertas/if_usb.c +0 -5
index 8191416..25925bd 100644
@@ -278,16 +278,11 @@ static void if_usb_disconnect(struct usb_interface *intf)
 	cardp->surprise_removed = 1;
 
 	if (priv) {
-
 		priv->surpriseremoved = 1;
 		lbs_stop_card(priv);
 		lbs_remove_card(priv);
 	}
 
-	/* this is (apparently?) necessary for future usage of the device */
-	lbs_prepare_and_send_command(priv, CMD_802_11_RESET, CMD_ACT_HALT,
-			0, 0, NULL);
-
 	/* Unlink and free urb */
 	if_usb_free(cardp);
 
Signature · 1 line
1.5.3.4
#105 lore raw

[PATCH 100/48] libertas: kill whitespace at end of lines

In reply to David Woodhouse

Date: Fri, 14 Dec 2007 22:53:41 -0500

---
 drivers/net/wireless/libertas/cmd.c     |    2 +-
 drivers/net/wireless/libertas/cmd.h     |    4 ++--
 drivers/net/wireless/libertas/debugfs.c |    2 +-
 drivers/net/wireless/libertas/if_sdio.c |    2 +-
 drivers/net/wireless/libertas/if_usb.c  |    4 ++--
 drivers/net/wireless/libertas/main.c    |   14 +++++++-------
 drivers/net/wireless/libertas/tx.c      |    4 ++--
 7 files changed, 16 insertions(+), 16 deletions(-)
drivers/net/wireless/libertas/cmd.c +1 -1
index 171acc2..ffef721 100644
@@ -1122,7 +1122,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
 	cmd.action = cpu_to_le16(enable);
 	cmd.channel = cpu_to_le16(chan);
 	cmd.type = cpu_to_le16(priv->mesh_tlv);
-	
+
 	if (enable) {
 		cmd.length = cpu_to_le16(priv->mesh_ssid_len);
 		memcpy(cmd.data, priv->mesh_ssid, priv->mesh_ssid_len);
drivers/net/wireless/libertas/cmd.h +2 -2
index a4aaa6b..999fabe 100644
@@ -11,9 +11,9 @@
 
 #define lbs_cmd_with_response(priv, cmdnr, cmd)	\
 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
- 
+
 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
-	      struct cmd_header *in_cmd, int in_cmd_size, 
+	      struct cmd_header *in_cmd, int in_cmd_size,
 	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
 	      unsigned long callback_arg);
 
drivers/net/wireless/libertas/debugfs.c +1 -1
index f4858bd..226b183 100644
@@ -295,7 +295,7 @@ static ssize_t lbs_setuserscan(struct file *file,
 
 	if (!buf)
 		return -ENOMEM;
-		
+
 	buf_size = min(count, len - 1);
 	if (copy_from_user(buf, userbuf, buf_size)) {
 		res = -EFAULT;
drivers/net/wireless/libertas/if_sdio.c +1 -1
index 85675c5..b24584d 100644
@@ -19,7 +19,7 @@
  * current block size.
  *
  * As SDIO is still new to the kernel, it is unfortunately common with
- * bugs in the host controllers related to that. One such bug is that 
+ * bugs in the host controllers related to that. One such bug is that
  * controllers cannot do transfers that aren't a multiple of 4 bytes.
  * If you don't have time to fix the host controller driver, you can
  * work around the problem by modifying if_sdio_host_to_card() and
drivers/net/wireless/libertas/if_usb.c +2 -2
index 9cb9e03..396ce67 100644
@@ -152,7 +152,7 @@ static int if_usb_probe(struct usb_interface *intf,
 
 	setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
 	init_waitqueue_head(&cardp->fw_wq);
-								     
+
 	cardp->udev = udev;
 	iface_desc = intf->cur_altsetting;
 
@@ -871,7 +871,7 @@ restart:
 
 	/* ... and wait for the process to complete */
 	wait_event_interruptible(cardp->fw_wq, cardp->surprise_removed || cardp->fwdnldover);
-	
+
 	del_timer_sync(&cardp->fw_timeout);
 	usb_kill_urb(cardp->rx_urb);
 
drivers/net/wireless/libertas/main.c +7 -7
index b51513f..0dc7de6 100644
@@ -255,7 +255,7 @@ static int lbs_add_rtap(struct lbs_private *priv);
 static void lbs_remove_rtap(struct lbs_private *priv);
 static int lbs_add_mesh(struct lbs_private *priv);
 static void lbs_remove_mesh(struct lbs_private *priv);
-  
+
 
 /**
  * Get function for sysfs attribute rtap
@@ -347,7 +347,7 @@ static ssize_t lbs_mesh_set(struct device *dev,
 	ret = lbs_mesh_config(priv, enable, priv->curbssparams.channel);
 	if (ret)
 		return ret;
-		
+
 	if (enable)
 		lbs_add_mesh(priv);
 	else
@@ -401,7 +401,7 @@ static int lbs_dev_open(struct net_device *dev)
 		netif_carrier_on(dev);
 	} else {
 		priv->infra_open = 1;
-		
+
 		if (priv->connect_status == LBS_CONNECTED)
 			netif_carrier_on(dev);
 		else
@@ -433,7 +433,7 @@ static int lbs_mesh_stop(struct net_device *dev)
 
 	netif_stop_queue(dev);
 	netif_carrier_off(dev);
-	
+
 	spin_unlock_irq(&priv->driver_lock);
 	return 0;
 }
@@ -453,7 +453,7 @@ static int lbs_eth_stop(struct net_device *dev)
 	priv->infra_open = 0;
 
 	netif_stop_queue(dev);
-	
+
 	spin_unlock_irq(&priv->driver_lock);
 	return 0;
 }
@@ -850,7 +850,7 @@ int lbs_suspend(struct lbs_private *priv)
 	}
 
 	memset(&cmd, 0, sizeof(cmd));
-	
+
 	ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_ACTIVATE, &cmd,
 			sizeof(cmd), lbs_suspend_callback, 0);
 	if (ret)
@@ -1180,7 +1180,7 @@ int lbs_start_card(struct lbs_private *priv)
 	/* Enable mesh, if supported, and work out which TLV it uses.
 	   0x100 + 291 is an unofficial value used in 5.110.20.pXX
 	   0x100 + 37 is the official value used in 5.110.21.pXX
-	   but we check them in that order because 20.pXX doesn't 
+	   but we check them in that order because 20.pXX doesn't
 	   give an error -- it just silently fails. */
 
 	/* 5.110.20.pXX firmware will fail the command if the channel
drivers/net/wireless/libertas/tx.c +2 -2
index 8a1a396..00d95f7 100644
@@ -93,8 +93,8 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		netif_stop_queue(priv->mesh_dev);
 
 	if (priv->tx_pending_len) {
-		/* This can happen if packets come in on the mesh and eth 
-		   device simultaneously -- there's no mutual exclusion on 
+		/* This can happen if packets come in on the mesh and eth
+		   device simultaneously -- there's no mutual exclusion on
 		   hard_start_xmit() calls between devices. */
 		lbs_deb_tx("Packet on %s while busy\n", dev->name);
 		ret = NETDEV_TX_BUSY;
Signature · 1 line
1.5.3.4
#106 lore raw

[PATCH 99/48] libertas: clean up if_usb driver

In reply to David Woodhouse

Date: Fri, 14 Dec 2007 00:47:05 -0500

It was just getting on my tits, really.

---
 drivers/net/wireless/libertas/if_usb.c |  428 ++++++++++++++------------------
 drivers/net/wireless/libertas/if_usb.h |   95 ++++----
 2 files changed, 225 insertions(+), 298 deletions(-)
drivers/net/wireless/libertas/if_usb.c +181 -247
index 25925bd..9cb9e03 100644
@@ -16,6 +16,9 @@
 #include "cmd.h"
 #include "if_usb.h"
 
+#define INSANEDEBUG	0
+#define lbs_deb_usb2(...) do { if (INSANEDEBUG) lbs_deb_usbd(__VA_ARGS__); } while (0)
+
 #define MESSAGE_HEADER_LEN	4
 
 static char *lbs_fw_name = "usb8388.bin";
@@ -32,17 +35,16 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
 
 static void if_usb_receive(struct urb *urb);
 static void if_usb_receive_fwload(struct urb *urb);
-static int if_usb_prog_firmware(struct usb_card_rec *cardp);
-static int if_usb_host_to_card(struct lbs_private *priv,
-	u8 type,
-	u8 *payload,
-	u16 nb);
-static int if_usb_get_int_status(struct lbs_private *priv, u8 *);
+static int if_usb_prog_firmware(struct if_usb_card *cardp);
+static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
+			       uint8_t *payload, uint16_t nb);
+static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *);
 static int if_usb_read_event_cause(struct lbs_private *);
-static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb);
-static void if_usb_free(struct usb_card_rec *cardp);
-static int if_usb_submit_rx_urb(struct usb_card_rec *cardp);
-static int if_usb_reset_device(struct usb_card_rec *cardp);
+static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
+			uint16_t nb);
+static void if_usb_free(struct if_usb_card *cardp);
+static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
+static int if_usb_reset_device(struct if_usb_card *cardp);
 
 /**
  *  @brief  call back function to handle the status of the URB
@@ -51,18 +53,16 @@ static int if_usb_reset_device(struct usb_card_rec *cardp);
  */
 static void if_usb_write_bulk_callback(struct urb *urb)
 {
-	struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context;
+	struct if_usb_card *cardp = (struct if_usb_card *) urb->context;
 
 	/* handle the transmission complete validations */
 
 	if (urb->status == 0) {
 		struct lbs_private *priv = cardp->priv;
 
-		/*
-		lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
-		lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
-		       urb->actual_length);
-		*/
+		lbs_deb_usb2(&urb->dev->dev, "URB status is successful\n");
+		lbs_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
+			     urb->actual_length);
 
 		/* Used for both firmware TX and regular TX.  priv isn't
 		 * valid at firmware load time.
@@ -79,10 +79,10 @@ static void if_usb_write_bulk_callback(struct urb *urb)
 
 /**
  *  @brief  free tx/rx urb, skb and rx buffer
- *  @param cardp	pointer usb_card_rec
+ *  @param cardp	pointer if_usb_card
  *  @return 	   	N/A
  */
-static void if_usb_free(struct usb_card_rec *cardp)
+static void if_usb_free(struct if_usb_card *cardp)
 {
 	lbs_deb_enter(LBS_DEB_USB);
 
@@ -96,8 +96,8 @@ static void if_usb_free(struct usb_card_rec *cardp)
 	usb_free_urb(cardp->rx_urb);
 	cardp->rx_urb = NULL;
 
-	kfree(cardp->bulk_out_buffer);
-	cardp->bulk_out_buffer = NULL;
+	kfree(cardp->ep_out_buf);
+	cardp->ep_out_buf = NULL;
 
 	lbs_deb_leave(LBS_DEB_USB);
 }
@@ -115,7 +115,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 
 static void if_usb_fw_timeo(unsigned long priv)
 {
-	struct usb_card_rec *cardp = (void *)priv;
+	struct if_usb_card *cardp = (void *)priv;
 
 	if (cardp->fwdnldover) {
 		lbs_deb_usb("Download complete, no event. Assuming success\n");
@@ -125,6 +125,7 @@ static void if_usb_fw_timeo(unsigned long priv)
 	}
 	wake_up(&cardp->fw_wq);
 }
+
 /**
  *  @brief sets the configuration values
  *  @param ifnum	interface number
@@ -138,12 +139,12 @@ static int if_usb_probe(struct usb_interface *intf,
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	struct lbs_private *priv;
-	struct usb_card_rec *cardp;
+	struct if_usb_card *cardp;
 	int i;
 
 	udev = interface_to_usbdev(intf);
 
-	cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
+	cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
 	if (!cardp) {
 		lbs_pr_err("Out of memory allocating private data.\n");
 		goto error;
@@ -156,7 +157,7 @@ static int if_usb_probe(struct usb_interface *intf,
 	iface_desc = intf->cur_altsetting;
 
 	lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
-	       " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
+		     " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
 		     le16_to_cpu(udev->descriptor.bcdUSB),
 		     udev->descriptor.bDeviceClass,
 		     udev->descriptor.bDeviceSubClass,
@@ -164,61 +165,40 @@ static int if_usb_probe(struct usb_interface *intf,
 
 	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
 		endpoint = &iface_desc->endpoint[i].desc;
-		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
-		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-			USB_ENDPOINT_XFER_BULK)) {
-			/* we found a bulk in endpoint */
-			lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n",
-				     le16_to_cpu(endpoint->wMaxPacketSize));
-			if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
-				lbs_deb_usbd(&udev->dev,
-				       "Rx URB allocation failed\n");
-				goto dealloc;
-			}
-			cardp->bulk_in_size =
-				le16_to_cpu(endpoint->wMaxPacketSize);
-			cardp->bulk_in_endpointAddr =
-			    (endpoint->
-			     bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
-			lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n",
-			       endpoint->bEndpointAddress);
-		}
+		if (usb_endpoint_is_bulk_in(endpoint)) {
+			cardp->ep_in_size = le16_to_cpu(endpoint->wMaxPacketSize);
+			cardp->ep_in = usb_endpoint_num(endpoint);
 
-		if (((endpoint->
-		      bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
-		     USB_DIR_OUT)
-		    && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-			USB_ENDPOINT_XFER_BULK)) {
-			/* We found bulk out endpoint */
-			if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
-				lbs_deb_usbd(&udev->dev,
-				       "Tx URB allocation failed\n");
-				goto dealloc;
-			}
+			lbs_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in);
+			lbs_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size);
 
-			cardp->bulk_out_size =
-				le16_to_cpu(endpoint->wMaxPacketSize);
-			lbs_deb_usbd(&udev->dev,
-				     "Bulk out size is %d\n",
-				     le16_to_cpu(endpoint->wMaxPacketSize));
-			cardp->bulk_out_endpointAddr =
-			    endpoint->bEndpointAddress;
-			lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n",
-				    endpoint->bEndpointAddress);
-			cardp->bulk_out_buffer =
-			    kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
-				    GFP_KERNEL);
-
-			if (!cardp->bulk_out_buffer) {
-				lbs_deb_usbd(&udev->dev,
-				       "Could not allocate buffer\n");
-				goto dealloc;
-			}
+		} else if (usb_endpoint_is_bulk_out(endpoint)) {
+			cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize);
+			cardp->ep_out = usb_endpoint_num(endpoint);
+
+			lbs_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out);
+			lbs_deb_usbd(&udev->dev, "Bulk out size is %d\n", cardp->ep_out_size);
 		}
 	}
+	if (!cardp->ep_out_size || !cardp->ep_in_size) {
+		lbs_deb_usbd(&udev->dev, "Endpoints not found\n");
+		goto dealloc;
+	}
+	if (!(cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
+		lbs_deb_usbd(&udev->dev, "Rx URB allocation failed\n");
+		goto dealloc;
+	}
+	if (!(cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL))) {
+		lbs_deb_usbd(&udev->dev, "Tx URB allocation failed\n");
+		goto dealloc;
+	}
+	cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE, GFP_KERNEL);
+	if (!cardp->ep_out_buf) {
+		lbs_deb_usbd(&udev->dev, "Could not allocate buffer\n");
+		goto dealloc;
+	}
 
 	/* Upload firmware */
-	cardp->rinfo.cardp = cardp;
 	if (if_usb_prog_firmware(cardp)) {
 		lbs_deb_usbd(&udev->dev, "FW upload failed\n");
 		goto err_prog_firmware;
@@ -269,12 +249,11 @@ error:
  */
 static void if_usb_disconnect(struct usb_interface *intf)
 {
-	struct usb_card_rec *cardp = usb_get_intfdata(intf);
+	struct if_usb_card *cardp = usb_get_intfdata(intf);
 	struct lbs_private *priv = (struct lbs_private *) cardp->priv;
 
 	lbs_deb_enter(LBS_DEB_MAIN);
 
-	/* Update Surprise removed to TRUE */
 	cardp->surprise_removed = 1;
 
 	if (priv) {
@@ -297,98 +276,75 @@ static void if_usb_disconnect(struct usb_interface *intf)
  *  @param priv		pointer to struct lbs_private
  *  @return 	   	0
  */
-static int if_usb_send_fw_pkt(struct usb_card_rec *cardp)
+static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
 {
-	struct FWData *fwdata;
-	struct fwheader *fwheader;
-	u8 *firmware = cardp->fw->data;
-
-	fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
-
-	if (!fwdata)
-		return -1;
-
-	fwheader = &fwdata->fwheader;
+	struct fwdata *fwdata = cardp->ep_out_buf;
+	uint8_t *firmware = cardp->fw->data;
 
+	/* If we got a CRC failure on the last block, back
+	   up and retry it */
 	if (!cardp->CRC_OK) {
 		cardp->totalbytes = cardp->fwlastblksent;
-		cardp->fwseqnum = cardp->lastseqnum - 1;
+		cardp->fwseqnum--;
 	}
 
-	/*
-	lbs_deb_usbd(&cardp->udev->dev, "totalbytes = %d\n",
-		    cardp->totalbytes);
-	*/
+	lbs_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
+		     cardp->totalbytes);
 
-	memcpy(fwheader, &firmware[cardp->totalbytes],
+	/* struct fwdata (which we sent to the card) has an
+	   extra __le32 field in between the header and the data,
+	   which is not in the struct fwheader in the actual
+	   firmware binary. Insert the seqnum in the middle... */
+	memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
 	       sizeof(struct fwheader));
 
 	cardp->fwlastblksent = cardp->totalbytes;
 	cardp->totalbytes += sizeof(struct fwheader);
 
-	/* lbs_deb_usbd(&cardp->udev->dev,"Copy Data\n"); */
 	memcpy(fwdata->data, &firmware[cardp->totalbytes],
-	       le32_to_cpu(fwdata->fwheader.datalength));
+	       le32_to_cpu(fwdata->hdr.datalength));
 
-	/*
-	lbs_deb_usbd(&cardp->udev->dev,
-		    "Data length = %d\n", le32_to_cpu(fwdata->fwheader.datalength));
-	*/
+	lbs_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
+		     le32_to_cpu(fwdata->hdr.datalength));
 
-	cardp->fwseqnum = cardp->fwseqnum + 1;
+	fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
+	cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);
 
-	fwdata->seqnum = cpu_to_le32(cardp->fwseqnum);
-	cardp->lastseqnum = cardp->fwseqnum;
-	cardp->totalbytes += le32_to_cpu(fwdata->fwheader.datalength);
+	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
+		     le32_to_cpu(fwdata->hdr.datalength));
+
+	if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
+		lbs_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
+		lbs_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n",
+			     cardp->fwseqnum, cardp->totalbytes);
+	} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
+		lbs_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n");
+		lbs_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");
 
-	if (fwheader->dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
-		/*
-		lbs_deb_usbd(&cardp->udev->dev, "There are data to follow\n");
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "seqnum = %d totalbytes = %d\n", cardp->fwseqnum,
-			    cardp->totalbytes);
-		*/
-		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
-		usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
-
-	} else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
-		/*
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "Host has finished FW downloading\n");
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "Donwloading FW JUMP BLOCK\n");
-		*/
-		memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
-		usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
 		cardp->fwfinalblk = 1;
 	}
 
-	/*
-	lbs_deb_usbd(&cardp->udev->dev,
-		    "The firmware download is done size is %d\n",
-		    cardp->totalbytes);
-	*/
-
-	kfree(fwdata);
+	lbs_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
+		     cardp->totalbytes);
 
 	return 0;
 }
 
-static int if_usb_reset_device(struct usb_card_rec *cardp)
+static int if_usb_reset_device(struct if_usb_card *cardp)
 {
-	struct cmd_ds_command *cmd = (void *)&cardp->bulk_out_buffer[4];
+	struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
 	int ret;
 
 	lbs_deb_enter(LBS_DEB_USB);
 
-	*(__le32 *)cardp->bulk_out_buffer = cpu_to_le32(CMD_TYPE_REQUEST);
+	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
 
 	cmd->command = cpu_to_le16(CMD_802_11_RESET);
 	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset) + S_DS_GEN);
 	cmd->result = cpu_to_le16(0);
 	cmd->seqnum = cpu_to_le16(0x5a5a);
 	cmd->params.reset.action = cpu_to_le16(CMD_ACT_HALT);
-	usb_tx_block(cardp, cardp->bulk_out_buffer, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
+	usb_tx_block(cardp, cardp->ep_out_buf, 4 + S_DS_GEN + sizeof(struct cmd_ds_802_11_reset));
 
 	msleep(100);
 	ret = usb_reset_device(cardp->udev);
@@ -406,7 +362,7 @@ static int if_usb_reset_device(struct usb_card_rec *cardp)
  *  @param nb		data length
  *  @return 	   	0 or -1
  */
-static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
+static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
 {
 	int ret = -1;
 
@@ -418,17 +374,16 @@ static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
 
 	usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
 			  usb_sndbulkpipe(cardp->udev,
-					  cardp->bulk_out_endpointAddr),
+					  cardp->ep_out),
 			  payload, nb, if_usb_write_bulk_callback, cardp);
 
 	cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
 
 	if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) {
-		/*  transfer failed */
 		lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret);
 		ret = -1;
 	} else {
-		/* lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb success\n"); */
+		lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");
 		ret = 0;
 	}
 
@@ -436,11 +391,10 @@ tx_ret:
 	return ret;
 }
 
-static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
+static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
 				  void (*callbackfn)(struct urb *urb))
 {
 	struct sk_buff *skb;
-	struct read_cb_info *rinfo = &cardp->rinfo;
 	int ret = -1;
 
 	if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
@@ -448,27 +402,25 @@ static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
 		goto rx_ret;
 	}
 
-	rinfo->skb = skb;
+	cardp->rx_skb = skb;
 
 	/* Fill the receive configuration URB and initialise the Rx call back */
 	usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
-			  usb_rcvbulkpipe(cardp->udev,
-					  cardp->bulk_in_endpointAddr),
+			  usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
 			  (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
 			  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
-			  rinfo);
+			  cardp);
 
 	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;
 
-	/* lbs_deb_usbd(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); */
+	lbs_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb);
 	if ((ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC))) {
-		/* handle failure conditions */
 		lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret);
 		kfree_skb(skb);
-		rinfo->skb = NULL;
+		cardp->rx_skb = NULL;
 		ret = -1;
 	} else {
-		/* lbs_deb_usbd(&cardp->udev->dev, "Submit Rx URB success\n"); */
+		lbs_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
 		ret = 0;
 	}
 
@@ -476,27 +428,26 @@ rx_ret:
 	return ret;
 }
 
-static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
+static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
 {
 	return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
 }
 
-static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
+static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
 {
 	return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
 }
 
 static void if_usb_receive_fwload(struct urb *urb)
 {
-	struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
-	struct sk_buff *skb = rinfo->skb;
-	struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
+	struct if_usb_card *cardp = urb->context;
+	struct sk_buff *skb = cardp->rx_skb;
 	struct fwsyncheader *syncfwheader;
-	struct bootcmdrespStr bootcmdresp;
+	struct bootcmdresp bootcmdresp;
 
 	if (urb->status) {
 		lbs_deb_usbd(&cardp->udev->dev,
-			    "URB status is failed during fw load\n");
+			     "URB status is failed during fw load\n");
 		kfree_skb(skb);
 		return;
 	}
@@ -509,8 +460,8 @@ static void if_usb_receive_fwload(struct urb *urb)
 			lbs_pr_info("Firmware ready event received\n");
 			wake_up(&cardp->fw_wq);
 		} else {
-			lbs_deb_usb("Waiting for confirmation; got %x %x\n", le32_to_cpu(tmp[0]),
-				    le32_to_cpu(tmp[1]));
+			lbs_deb_usb("Waiting for confirmation; got %x %x\n",
+				    le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
 			if_usb_submit_rx_urb_fwload(cardp);
 		}
 		kfree_skb(skb);
@@ -519,37 +470,36 @@ static void if_usb_receive_fwload(struct urb *urb)
 	if (cardp->bootcmdresp <= 0) {
 		memcpy (&bootcmdresp, skb->data + IPFIELD_ALIGN_OFFSET,
 			sizeof(bootcmdresp));
+
 		if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
 			kfree_skb(skb);
 			if_usb_submit_rx_urb_fwload(cardp);
 			cardp->bootcmdresp = 1;
 			lbs_deb_usbd(&cardp->udev->dev,
-				    "Received valid boot command response\n");
+				     "Received valid boot command response\n");
 			return;
 		}
-		if (bootcmdresp.u32magicnumber != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
-			if (bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_REQUEST) ||
-			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_DATA) ||
-			    bootcmdresp.u32magicnumber == cpu_to_le32(CMD_TYPE_INDICATION)) {
+		if (bootcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
+			if (bootcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
+			    bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
+			    bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
 				if (!cardp->bootcmdresp)
 					lbs_pr_info("Firmware already seems alive; resetting\n");
 				cardp->bootcmdresp = -1;
 			} else {
 				lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
-					    le32_to_cpu(bootcmdresp.u32magicnumber));
+					    le32_to_cpu(bootcmdresp.magic));
 			}
-		} else if (bootcmdresp.u8cmd_tag != BOOT_CMD_FW_BY_USB) {
-			lbs_pr_info(
-				"boot cmd response cmd_tag error (%d)\n",
-				bootcmdresp.u8cmd_tag);
-		} else if (bootcmdresp.u8result != BOOT_CMD_RESP_OK) {
-			lbs_pr_info(
-				"boot cmd response result error (%d)\n",
-				bootcmdresp.u8result);
+		} else if (bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
+			lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
+				    bootcmdresp.cmd);
+		} else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
+			lbs_pr_info("boot cmd response result error (%d)\n",
+				    bootcmdresp.result);
 		} else {
 			cardp->bootcmdresp = 1;
 			lbs_deb_usbd(&cardp->udev->dev,
-				    "Received valid boot command response\n");
+				     "Received valid boot command response\n");
 		}
 		kfree_skb(skb);
 		if_usb_submit_rx_urb_fwload(cardp);
@@ -564,20 +514,15 @@ static void if_usb_receive_fwload(struct urb *urb)
 	}
 
 	memcpy(syncfwheader, skb->data + IPFIELD_ALIGN_OFFSET,
-			sizeof(struct fwsyncheader));
+	       sizeof(struct fwsyncheader));
 
 	if (!syncfwheader->cmd) {
-		/*
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "FW received Blk with correct CRC\n");
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "FW received Blk seqnum = %d\n",
-		       syncfwheader->seqnum);
-		*/
+		lbs_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n");
+		lbs_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n",
+			     le32_to_cpu(syncfwheader->seqnum));
 		cardp->CRC_OK = 1;
 	} else {
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "FW received Blk with CRC error\n");
+		lbs_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n");
 		cardp->CRC_OK = 0;
 	}
 
@@ -604,13 +549,12 @@ static void if_usb_receive_fwload(struct urb *urb)
 #define MRVDRV_MIN_PKT_LEN	30
 
 static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
-				       struct usb_card_rec *cardp,
+				       struct if_usb_card *cardp,
 				       struct lbs_private *priv)
 {
-	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE +
-	    MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) {
-		lbs_deb_usbd(&cardp->udev->dev,
-			    "Packet length is Invalid\n");
+	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
+	    || recvlength < MRVDRV_MIN_PKT_LEN) {
+		lbs_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
 		kfree_skb(skb);
 		return;
 	}
@@ -618,19 +562,21 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
 	skb_reserve(skb, IPFIELD_ALIGN_OFFSET);
 	skb_put(skb, recvlength);
 	skb_pull(skb, MESSAGE_HEADER_LEN);
+
 	lbs_process_rxed_packet(priv, skb);
 	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
 }
 
-static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
+static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 				      struct sk_buff *skb,
-				      struct usb_card_rec *cardp,
+				      struct if_usb_card *cardp,
 				      struct lbs_private *priv)
 {
-	u8 *cmdbuf;
+	uint8_t *cmdbuf;
+
 	if (recvlength > LBS_CMD_BUFFER_SIZE) {
 		lbs_deb_usbd(&cardp->udev->dev,
-			    "The receive buffer is too large\n");
+			     "The receive buffer is too large\n");
 		kfree_skb(skb);
 		return;
 	}
@@ -642,16 +588,16 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 	/* take care of cur_cmd = NULL case by reading the
 	 * data to clear the interrupt */
 	if (!priv->cur_cmd) {
-		lbs_deb_hex(LBS_DEB_HOST, "Unsolicited CMD_RESP", (void *) recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
+		lbs_deb_hex(LBS_DEB_HOST, "Unsolicited CMD_RESP",
+			    (void *) recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
 		cmdbuf = priv->upld_buf;
 		priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
 	} else
-		cmdbuf = (u8 *) priv->cur_cmd->cmdbuf;
+		cmdbuf = (uint8_t *) priv->cur_cmd->cmdbuf;
 
 	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
 	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
-	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN,
-	       priv->upld_len);
+	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
 
 	kfree_skb(skb);
 	lbs_interrupt(priv);
@@ -659,8 +605,6 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
 
 	lbs_deb_usbd(&cardp->udev->dev,
 		    "Wake up main thread to handle cmd response\n");
-
-	return;
 }
 
 /**
@@ -672,30 +616,26 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
  */
 static void if_usb_receive(struct urb *urb)
 {
-	struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
-	struct sk_buff *skb = rinfo->skb;
-	struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
+	struct if_usb_card *cardp = urb->context;
+	struct sk_buff *skb = cardp->rx_skb;
 	struct lbs_private *priv = cardp->priv;
-
 	int recvlength = urb->actual_length;
-	u8 *recvbuff = NULL;
-	u32 recvtype = 0;
+	uint8_t *recvbuff = NULL;
+	uint32_t recvtype = 0;
+	__le32 *pkt = (__le32 *)(skb->data + IPFIELD_ALIGN_OFFSET);
 
 	lbs_deb_enter(LBS_DEB_USB);
 
 	if (recvlength) {
-		__le32 tmp;
-
 		if (urb->status) {
-			lbs_deb_usbd(&cardp->udev->dev,
-				    "URB status is failed\n");
+			lbs_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
+				     urb->status);
 			kfree_skb(skb);
 			goto setup_for_next;
 		}
 
 		recvbuff = skb->data + IPFIELD_ALIGN_OFFSET;
-		memcpy(&tmp, recvbuff, sizeof(u32));
-		recvtype = le32_to_cpu(tmp);
+		recvtype = le32_to_cpu(pkt[0]);
 		lbs_deb_usbd(&cardp->udev->dev,
 			    "Recv length = 0x%x, Recv type = 0x%X\n",
 			    recvlength, recvtype);
@@ -716,9 +656,13 @@ static void if_usb_receive(struct urb *urb)
 	case CMD_TYPE_INDICATION:
 		/* Event cause handling */
 		spin_lock(&priv->driver_lock);
-		cardp->usb_event_cause = le32_to_cpu(*(__le32 *) (recvbuff + MESSAGE_HEADER_LEN));
+
+		cardp->usb_event_cause = le32_to_cpu(pkt[1]);
+
 		lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n",
-			    cardp->usb_event_cause);
+			     cardp->usb_event_cause);
+
+		/* Icky undocumented magic special case */
 		if (cardp->usb_event_cause & 0xffff0000) {
 			lbs_send_tx_feedback(priv);
 			spin_unlock(&priv->driver_lock);
@@ -732,7 +676,7 @@ static void if_usb_receive(struct urb *urb)
 		goto rx_exit;
 	default:
 		lbs_deb_usbd(&cardp->udev->dev, "Unknown command type 0x%X\n",
-		             recvtype);
+			     recvtype);
 		kfree_skb(skb);
 		break;
 	}
@@ -751,55 +695,48 @@ rx_exit:
  *  @param len		number of bytes
  *  @return 	   	0 or -1
  */
-static int if_usb_host_to_card(struct lbs_private *priv,
-	u8 type,
-	u8 *payload,
-	u16 nb)
+static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
+			       uint8_t *payload, uint16_t nb)
 {
-	struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
+	struct if_usb_card *cardp = priv->card;
 
 	lbs_deb_usbd(&cardp->udev->dev,"*** type = %u\n", type);
 	lbs_deb_usbd(&cardp->udev->dev,"size after = %d\n", nb);
 
 	if (type == MVMS_CMD) {
-		__le32 tmp = cpu_to_le32(CMD_TYPE_REQUEST);
+		*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
 		priv->dnld_sent = DNLD_CMD_SENT;
-		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
-		       MESSAGE_HEADER_LEN);
-
 	} else {
-		__le32 tmp = cpu_to_le32(CMD_TYPE_DATA);
+		*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
 		priv->dnld_sent = DNLD_DATA_SENT;
-		memcpy(cardp->bulk_out_buffer, (u8 *) & tmp,
-		       MESSAGE_HEADER_LEN);
 	}
 
-	memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
+	memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);
 
-	return usb_tx_block(cardp, cardp->bulk_out_buffer,
-	                    nb + MESSAGE_HEADER_LEN);
+	return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN);
 }
 
 /* called with priv->driver_lock held */
-static int if_usb_get_int_status(struct lbs_private *priv, u8 *ireg)
+static int if_usb_get_int_status(struct lbs_private *priv, uint8_t *ireg)
 {
-	struct usb_card_rec *cardp = priv->card;
+	struct if_usb_card *cardp = priv->card;
 
 	*ireg = cardp->usb_int_cause;
 	cardp->usb_int_cause = 0;
 
-	lbs_deb_usbd(&cardp->udev->dev,"Int cause is 0x%X\n", *ireg);
+	lbs_deb_usbd(&cardp->udev->dev, "Int cause is 0x%X\n", *ireg);
 
 	return 0;
 }
 
 static int if_usb_read_event_cause(struct lbs_private *priv)
 {
-	struct usb_card_rec *cardp = priv->card;
+	struct if_usb_card *cardp = priv->card;
 
 	priv->eventcause = cardp->usb_event_cause;
 	/* Re-submit rx urb here to avoid event lost issue */
 	if_usb_submit_rx_urb(cardp);
+
 	return 0;
 }
 
@@ -809,20 +746,17 @@ static int if_usb_read_event_cause(struct lbs_private *priv)
  *                  2:Boot from FW in EEPROM
  *  @return 	   	0
  */
-static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
+static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
 {
-	struct bootcmdstr sbootcmd;
-	int i;
+	struct bootcmd *bootcmd = cardp->ep_out_buf;
 
 	/* Prepare command */
-	sbootcmd.u32magicnumber = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
-	sbootcmd.u8cmd_tag = ivalue;
-	for (i=0; i<11; i++)
-		sbootcmd.au8dumy[i]=0x00;
-	memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
+	bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
+	bootcmd->cmd = ivalue;
+	memset(bootcmd->pad, 0, sizeof(bootcmd->pad));
 
 	/* Issue command */
-	usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
+	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd));
 
 	return 0;
 }
@@ -835,10 +769,10 @@ static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
  *         len               image length
  *  @return     0 or -1
  */
-static int check_fwfile_format(u8 *data, u32 totlen)
+static int check_fwfile_format(uint8_t *data, uint32_t totlen)
 {
-	u32 bincmd, exit;
-	u32 blksize, offset, len;
+	uint32_t bincmd, exit;
+	uint32_t blksize, offset, len;
 	int ret;
 
 	ret = 1;
@@ -876,7 +810,7 @@ static int check_fwfile_format(u8 *data, u32 totlen)
 }
 
 
-static int if_usb_prog_firmware(struct usb_card_rec *cardp)
+static int if_usb_prog_firmware(struct if_usb_card *cardp)
 {
 	int i = 0;
 	static int reset_count = 10;
@@ -953,11 +887,11 @@ restart:
 		goto release_fw;
 	}
 
-release_fw:
+ release_fw:
 	release_firmware(cardp->fw);
 	cardp->fw = NULL;
 
-done:
+ done:
 	lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
 	return ret;
 }
@@ -966,7 +900,7 @@ done:
 #ifdef CONFIG_PM
 static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 {
-	struct usb_card_rec *cardp = usb_get_intfdata(intf);
+	struct if_usb_card *cardp = usb_get_intfdata(intf);
 	struct lbs_private *priv = cardp->priv;
 	int ret;
 
@@ -990,7 +924,7 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
 
 static int if_usb_resume(struct usb_interface *intf)
 {
-	struct usb_card_rec *cardp = usb_get_intfdata(intf);
+	struct if_usb_card *cardp = usb_get_intfdata(intf);
 	struct lbs_private *priv = cardp->priv;
 
 	lbs_deb_enter(LBS_DEB_USB);
@@ -1041,5 +975,5 @@ module_init(if_usb_init_module);
 module_exit(if_usb_exit_module);
 
 MODULE_DESCRIPTION("8388 USB WLAN Driver");
-MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_AUTHOR("Marvell International Ltd. and Red Hat, Inc.");
 MODULE_LICENSE("GPL");
drivers/net/wireless/libertas/if_usb.h +44 -51

133 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#107 lore raw

[PATCH 101/48] libertas: kill unused wait_option field in struct cmd_ctrl_node

In reply to David Woodhouse

Date: Fri, 14 Dec 2007 23:08:13 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   12 ++++--------
 drivers/net/wireless/libertas/hostcmd.h |    2 --
 2 files changed, 4 insertions(+), 10 deletions(-)
drivers/net/wireless/libertas/cmd.c +4 -8
index ffef721..5ceb331 100644
@@ -17,7 +17,7 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
 static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
 static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 		    struct cmd_ctrl_node *ptempnode,
-		    u16 wait_option, void *pdata_buf);
+		    void *pdata_buf);
 
 
 /**
@@ -1392,7 +1392,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 		goto done;
 	}
 
-	lbs_set_cmd_ctrl_node(priv, cmdnode, wait_option, pdata_buf);
+	lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
 
 	cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
 
@@ -1554,7 +1554,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 	case CMD_802_11_INACTIVITY_TIMEOUT:
 		ret = lbs_cmd_802_11_inactivity_timeout(priv, cmdptr,
 							 cmd_action, pdata_buf);
-		lbs_set_cmd_ctrl_node(priv, cmdnode, 0, pdata_buf);
+		lbs_set_cmd_ctrl_node(priv, cmdnode, pdata_buf);
 		break;
 
 	case CMD_802_11_TPC_CFG:
@@ -1800,7 +1800,6 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode)
 		return;
 	cmdnode->cmdwaitqwoken = 1;
 	wake_up_interruptible(&cmdnode->cmdwait_q);
-	cmdnode->wait_option = 0;
 	cmdnode->pdata_buf = NULL;
 	cmdnode->callback = NULL;
 	cmdnode->callback_arg = 0;
@@ -1816,20 +1815,18 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode)
  *
  *  @param priv		A pointer to struct lbs_private structure
  *  @param ptempnode	A pointer to cmd_ctrl_node structure
- *  @param wait_option	wait option: wait response or not
  *  @param pdata_buf	A pointer to informaion buffer
  *  @return 		0 or -1
  */
 static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 				  struct cmd_ctrl_node *ptempnode,
-				  u16 wait_option, void *pdata_buf)
+				  void *pdata_buf)
 {
 	lbs_deb_enter(LBS_DEB_HOST);
 
 	if (!ptempnode)
 		return;
 
-	ptempnode->wait_option = wait_option;
 	ptempnode->pdata_buf = pdata_buf;
 	ptempnode->callback = NULL;
 	ptempnode->callback_arg = 0;
@@ -2213,7 +2210,6 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 		goto done;
 	}
 
-	cmdnode->wait_option = CMD_OPTION_WAITFORRSP;
 	cmdnode->callback = callback;
 	cmdnode->callback_arg = callback_arg;
 
drivers/net/wireless/libertas/hostcmd.h +0 -2
index aa4cea0..1b31250 100644
@@ -74,8 +74,6 @@ struct cmd_header {
 
 struct cmd_ctrl_node {
 	struct list_head list;
-	/* wait for finish or not */
-	u16 wait_option;
 	/* command response */
 	void *pdata_buf;
 	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
Signature · 1 line
1.5.3.4
#108 lore raw

[PATCH 102/48] libertas: rename and clean up DownloadcommandToStation

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 00:09:25 -0500

Call it lbs_submit_command(), remove a bunch of things which can be (or, in the case of zeroing ->cmdwaitqwoken, already are) done elsewhere.

---
 drivers/net/wireless/libertas/cmd.c |   36 ++++++++--------------------------
 1 files changed, 9 insertions(+), 27 deletions(-)
drivers/net/wireless/libertas/cmd.c +9 -27
index 5ceb331..4dc6bbe 100644
@@ -1170,6 +1170,10 @@ void lbs_queue_cmd(struct lbs_private *priv,
 		lbs_deb_host("QUEUE_CMD: cmdnode or cmdbuf is NULL\n");
 		goto done;
 	}
+	if (!cmdnode->cmdbuf->size) {
+		lbs_deb_host("DNLD_CMD: cmd size is zero\n");
+		goto done;
+	}
 
 	/* Exit_PS command needs to be queued in the header always. */
 	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
@@ -1197,15 +1201,8 @@ done:
 	lbs_deb_leave(LBS_DEB_HOST);
 }
 
-/*
- * TODO: Fix the issue when DownloadcommandToStation is being called the
- * second time when the command times out. All the cmdptr->xxx are in little
- * endian and therefore all the comparissions will fail.
- * For now - we are not performing the endian conversion the second time - but
- * for PS and DEEP_SLEEP we need to worry
- */
-static int DownloadcommandToStation(struct lbs_private *priv,
-				    struct cmd_ctrl_node *cmdnode)
+static int lbs_submit_command(struct lbs_private *priv,
+			      struct cmd_ctrl_node *cmdnode)
 {
 	unsigned long flags;
 	struct cmd_header *cmd;
@@ -1215,21 +1212,9 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	if (!priv || !cmdnode) {
-		lbs_deb_host("DNLD_CMD: priv or cmdmode is NULL\n");
-		goto done;
-	}
-
 	cmd = cmdnode->cmdbuf;
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
-	if (!cmd || !cmd->size) {
-		lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n");
-		__lbs_cleanup_and_insert_cmd(priv, cmdnode);
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		goto done;
-	}
-
 	priv->cur_cmd = cmdnode;
 	priv->cur_cmd_retcode = 0;
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1241,12 +1226,9 @@ static int DownloadcommandToStation(struct lbs_private *priv,
 		     command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies);
 	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
 
-	cmdnode->cmdwaitqwoken = 0;
-
 	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
-
-	if (ret != 0) {
-		lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n");
+	if (ret) {
+		lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
 		spin_lock_irqsave(&priv->driver_lock, flags);
 		priv->cur_cmd_retcode = ret;
 		__lbs_cleanup_and_insert_cmd(priv, priv->cur_cmd);
@@ -1952,7 +1934,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
 		list_del(&cmdnode->list);
 		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
 			    le16_to_cpu(cmd->command));
-		DownloadcommandToStation(priv, cmdnode);
+		lbs_submit_command(priv, cmdnode);
 	} else {
 		/*
 		 * check if in power save mode, if yes, put the device back
Signature · 1 line
1.5.3.4
#109 lore raw

[PATCH 103/48] libertas: don't use __lbs_cmd() with empty callback in if_usb.c

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 01:22:09 -0500

We're about to change semantics, leaving callers of lbs_prepare_and_send_command() with the old broken priv->cur_cmd_retcode crap. The existence of the callback command will be the trigger for the new semantics when handling the response.

---
 drivers/net/wireless/libertas/if_usb.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/if_usb.c +1 -1
index 396ce67..cf88251 100644
@@ -109,7 +109,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 	b2_cmd.action = 0;
 	b2_cmd.version = priv->boot2_version;
 
-	if (lbs_cmd(priv, CMD_SET_BOOT2_VER, &b2_cmd, NULL, 0))
+	if (lbs_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
 		lbs_deb_usb("Setting boot2 version failed\n");
 }
 
Signature · 1 line
1.5.3.4
#110 lore raw

[PATCH 104/48] libertas: remove some pointless checks for cmdnode buffer being present

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 00:41:51 -0500

We allocate them all at the same time, at startup. If they go missing, we have more serious things to worry about, and the resulting oops will be a perfectly acceptable result.

---
 drivers/net/wireless/libertas/cmd.c |   16 ++++------------
 1 files changed, 4 insertions(+), 12 deletions(-)
drivers/net/wireless/libertas/cmd.c +4 -12
index 4dc6bbe..4ffb84a 100644
@@ -1166,8 +1166,8 @@ void lbs_queue_cmd(struct lbs_private *priv,
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	if (!cmdnode || !cmdnode->cmdbuf) {
-		lbs_deb_host("QUEUE_CMD: cmdnode or cmdbuf is NULL\n");
+	if (!cmdnode) {
+		lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
 		goto done;
 	}
 	if (!cmdnode->cmdbuf->size) {
@@ -1195,7 +1195,7 @@ void lbs_queue_cmd(struct lbs_private *priv,
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 	lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
-	       le16_to_cpu(cmdnode->cmdbuf->command));
+		     le16_to_cpu(cmdnode->cmdbuf->command));
 
 done:
 	lbs_deb_leave(LBS_DEB_HOST);
@@ -1380,13 +1380,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 
 	lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
 
-	if (!cmdptr) {
-		lbs_deb_host("PREP_CMD: cmdptr is NULL\n");
-		lbs_cleanup_and_insert_cmd(priv, cmdnode);
-		ret = -1;
-		goto done;
-	}
-
 	/* Set sequence number, command and INT option */
 	priv->seqnum++;
 	cmdptr->seqnum = cpu_to_le16(priv->seqnum);
@@ -1786,8 +1779,7 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode)
 	cmdnode->callback = NULL;
 	cmdnode->callback_arg = 0;
 
-	if (cmdnode->cmdbuf != NULL)
-		memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
+	memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
Signature · 1 line
1.5.3.4
#111 lore raw

[PATCH 105/48] libertas: introduce and use lbs_complete_command() for command completion

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 01:52:54 -0500

---
 drivers/net/wireless/libertas/cmd.c     |   25 ++++++++++++++++++-------
 drivers/net/wireless/libertas/cmdresp.c |   10 +++-------
 drivers/net/wireless/libertas/decl.h    |    5 ++---
 3 files changed, 23 insertions(+), 17 deletions(-)
drivers/net/wireless/libertas/cmd.c +18 -7
index 4ffb84a..9c73902 100644
@@ -1230,9 +1230,7 @@ static int lbs_submit_command(struct lbs_private *priv,
 	if (ret) {
 		lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		priv->cur_cmd_retcode = ret;
-		__lbs_cleanup_and_insert_cmd(priv, priv->cur_cmd);
-		priv->cur_cmd = NULL;
+		lbs_complete_command(priv, priv->cur_cmd, ret);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		goto done;
 	}
@@ -1275,8 +1273,8 @@ static int lbs_cmd_mac_control(struct lbs_private *priv,
  *  This function inserts command node to cmdfreeq
  *  after cleans it. Requires priv->driver_lock held.
  */
-void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
-	struct cmd_ctrl_node *ptempcmd)
+static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
+					 struct cmd_ctrl_node *ptempcmd)
 {
 
 	if (!ptempcmd)
@@ -1296,6 +1294,15 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 }
 
+void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+			  int result)
+{
+	if (cmd == priv->cur_cmd)
+		priv->cur_cmd_retcode = result;
+	__lbs_cleanup_and_insert_cmd(priv, cmd);
+	priv->cur_cmd = NULL;
+}
+
 int lbs_set_radio_control(struct lbs_private *priv)
 {
 	int ret = 0;
@@ -1901,7 +1908,9 @@ int lbs_execute_next_command(struct lbs_private *priv)
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
 					list_del(&cmdnode->list);
-					lbs_cleanup_and_insert_cmd(priv, cmdnode);
+					spin_lock_irqsave(&priv->driver_lock, flags);
+					lbs_complete_command(priv, cmdnode, 0);
+					spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 					ret = 0;
 					goto done;
@@ -1912,7 +1921,9 @@ int lbs_execute_next_command(struct lbs_private *priv)
 					lbs_deb_host(
 					       "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
 					list_del(&cmdnode->list);
-					lbs_cleanup_and_insert_cmd(priv, cmdnode);
+					spin_lock_irqsave(&priv->driver_lock, flags);
+					lbs_complete_command(priv, cmdnode, 0);
+					spin_unlock_irqrestore(&priv->driver_lock, flags);
 					priv->needtowakeup = 1;
 
 					ret = 0;
drivers/net/wireless/libertas/cmdresp.c +3 -7
index a809f8f..89f8316 100644
@@ -717,8 +717,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 			lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
 		}
 
-		__lbs_cleanup_and_insert_cmd(priv, priv->cur_cmd);
-		priv->cur_cmd = NULL;
+		lbs_complete_command(priv, priv->cur_cmd, result);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 		ret = 0;
@@ -739,9 +738,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 			break;
 
 		}
-
-		__lbs_cleanup_and_insert_cmd(priv, priv->cur_cmd);
-		priv->cur_cmd = NULL;
+		lbs_complete_command(priv, priv->cur_cmd, result);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 		ret = -1;
@@ -760,8 +757,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 
 	if (priv->cur_cmd) {
 		/* Clean up and Put current command back to cmdfreeq */
-		__lbs_cleanup_and_insert_cmd(priv, priv->cur_cmd);
-		priv->cur_cmd = NULL;
+		lbs_complete_command(priv, priv->cur_cmd, result);
 	}
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
drivers/net/wireless/libertas/decl.h +2 -3
index 45f081b..5dd5c9e 100644
@@ -45,9 +45,8 @@ void lbs_get_fwversion(struct lbs_private *priv,
 
 /** The proc fs interface */
 int lbs_process_rx_command(struct lbs_private *priv);
-void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
-	struct cmd_ctrl_node *ptempcmd);
-
+void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
+			  int result);
 int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev);
 int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band);
 
Signature · 1 line
1.5.3.4
#112 lore raw

[PATCH 106/48] libertas: don't re-initialise cmdnode when taking it off the free queue

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 01:57:12 -0500

We initialise it when we add it to the queue. No need to do it again.

---
 drivers/net/wireless/libertas/cmd.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
drivers/net/wireless/libertas/cmd.c +0 -3
index 9c73902..fd321dd 100644
@@ -1761,9 +1761,6 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
 
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
-	if (tempnode)
-		cleanup_cmdnode(tempnode);
-
 	lbs_deb_leave(LBS_DEB_HOST);
 	return tempnode;
 }
Signature · 1 line
1.5.3.4
#113 lore raw

[PATCH 108/48] libertas: let __lbs_cmd() free its own cmdnode

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 02:06:16 -0500

---
 drivers/net/wireless/libertas/cmd.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmd.c +3 -1
index 4c0bd9f..e7f07c3 100644
@@ -1310,7 +1310,8 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 	cmd->cmdwaitqwoken = 1;
 	wake_up_interruptible(&cmd->cmdwait_q);
 
-	__lbs_cleanup_and_insert_cmd(priv, cmd);
+	if (!cmd->callback)
+		__lbs_cleanup_and_insert_cmd(priv, cmd);
 	priv->cur_cmd = NULL;
 }
 
@@ -2219,6 +2220,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 		priv->cur_cmd_retcode = 0;
 		ret = -1;
 	}
+	__lbs_cleanup_and_insert_cmd(priv, cmdnode);
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
 done:
Signature · 1 line
1.5.3.4
#114 lore raw

[PATCH 107/48] libertas: kill cleanup_cmdnode()

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 02:02:56 -0500

Move the wakeup into lbs_complete_command(), and leave the other bits in __lbs_cleanup_and_insert_cmd() which was the only caller now anyway.

There are two remaining direct callers of lbs_cleanup_and_insert_cmd(), and they are both fine without the wakeup.

---
 drivers/net/wireless/libertas/cmd.c |   39 +++++++++++++++-------------------
 1 files changed, 17 insertions(+), 22 deletions(-)
drivers/net/wireless/libertas/cmd.c +17 -22
index fd321dd..4c0bd9f 100644
@@ -13,7 +13,6 @@
 #include "wext.h"
 #include "cmd.h"
 
-static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode);
 static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
 static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 		    struct cmd_ctrl_node *ptempnode,
@@ -1274,14 +1273,22 @@ static int lbs_cmd_mac_control(struct lbs_private *priv,
  *  after cleans it. Requires priv->driver_lock held.
  */
 static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
-					 struct cmd_ctrl_node *ptempcmd)
+					 struct cmd_ctrl_node *cmdnode)
 {
+	lbs_deb_enter(LBS_DEB_HOST);
 
-	if (!ptempcmd)
-		return;
+	if (!cmdnode)
+		goto out;
 
-	cleanup_cmdnode(ptempcmd);
-	list_add_tail(&ptempcmd->list, &priv->cmdfreeq);
+	cmdnode->pdata_buf = NULL;
+	cmdnode->callback = NULL;
+	cmdnode->callback_arg = 0;
+
+	memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
+
+	list_add_tail(&cmdnode->list, &priv->cmdfreeq);
+ out:
+	lbs_deb_leave(LBS_DEB_HOST);
 }
 
 static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
@@ -1299,6 +1306,10 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 {
 	if (cmd == priv->cur_cmd)
 		priv->cur_cmd_retcode = result;
+
+	cmd->cmdwaitqwoken = 1;
+	wake_up_interruptible(&cmd->cmdwait_q);
+
 	__lbs_cleanup_and_insert_cmd(priv, cmd);
 	priv->cur_cmd = NULL;
 }
@@ -1771,22 +1782,6 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
  *  @param ptempnode	A pointer to cmdCtrlNode structure
  *  @return 		n/a
  */
-static void cleanup_cmdnode(struct cmd_ctrl_node *cmdnode)
-{
-	lbs_deb_enter(LBS_DEB_HOST);
-
-	if (!cmdnode)
-		return;
-	cmdnode->cmdwaitqwoken = 1;
-	wake_up_interruptible(&cmdnode->cmdwait_q);
-	cmdnode->pdata_buf = NULL;
-	cmdnode->callback = NULL;
-	cmdnode->callback_arg = 0;
-
-	memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
-
-	lbs_deb_leave(LBS_DEB_HOST);
-}
 
 /**
  *  @brief This function initializes the command node.
Signature · 1 line
1.5.3.4
#115 lore raw

[PATCH 109/48] libertas: kill pdata_buf member of struct cmd_ctrl_node

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 02:38:17 -0500

We can use the callback_arg for it; that's the way we're heading anyway...

---
 drivers/net/wireless/libertas/cmd.c     |    4 +---
 drivers/net/wireless/libertas/cmdresp.c |   26 +++++++++++++-------------
 drivers/net/wireless/libertas/hostcmd.h |    1 -
 3 files changed, 14 insertions(+), 17 deletions(-)
drivers/net/wireless/libertas/cmd.c +1 -3
index e7f07c3..f2e027b 100644
@@ -1280,7 +1280,6 @@ static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
 	if (!cmdnode)
 		goto out;
 
-	cmdnode->pdata_buf = NULL;
 	cmdnode->callback = NULL;
 	cmdnode->callback_arg = 0;
 
@@ -1801,9 +1800,8 @@ static void lbs_set_cmd_ctrl_node(struct lbs_private *priv,
 	if (!ptempnode)
 		return;
 
-	ptempnode->pdata_buf = pdata_buf;
 	ptempnode->callback = NULL;
-	ptempnode->callback_arg = 0;
+	ptempnode->callback_arg = (unsigned long)pdata_buf;
 
 	lbs_deb_leave(LBS_DEB_HOST);
 }
drivers/net/wireless/libertas/cmdresp.c +13 -13
index 89f8316..4c22e78 100644
@@ -399,13 +399,13 @@ static int lbs_ret_802_11_enable_rsn(struct lbs_private *priv,
                                           struct cmd_ds_command *resp)
 {
 	struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn;
-	u32 * pdata_buf = priv->cur_cmd->pdata_buf;
+	uint32_t * pdata_buf = (uint32_t *)priv->cur_cmd->callback_arg;
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
 	if (enable_rsn->action == cpu_to_le16(CMD_ACT_GET)) {
 		if (pdata_buf)
-			*pdata_buf = (u32) le16_to_cpu(enable_rsn->enable);
+			*pdata_buf = (uint32_t) le16_to_cpu(enable_rsn->enable);
 	}
 
 	lbs_deb_leave(LBS_DEB_CMD);
@@ -435,7 +435,7 @@ static int lbs_ret_802_11_subscribe_event(struct lbs_private *priv,
 	struct cmd_ds_802_11_subscribe_event *cmd_event =
 		&resp->params.subscribe_event;
 	struct cmd_ds_802_11_subscribe_event *dst_event =
-		priv->cur_cmd->pdata_buf;
+		(void *)priv->cur_cmd->callback_arg;
 
 	lbs_deb_enter(LBS_DEB_CMD);
 
@@ -505,7 +505,7 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 	case CMD_RET(CMD_802_11_SET_AFC):
 	case CMD_RET(CMD_802_11_GET_AFC):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove(priv->cur_cmd->pdata_buf, &resp->params.afc,
+		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc,
 			sizeof(struct cmd_ds_802_11_afc));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
@@ -557,20 +557,20 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 		break;
 	case CMD_RET(CMD_802_11_INACTIVITY_TIMEOUT):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		*((u16 *) priv->cur_cmd->pdata_buf) =
+		*((uint16_t *) priv->cur_cmd->callback_arg) =
 		    le16_to_cpu(resp->params.inactivity_timeout.timeout);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
 
 	case CMD_RET(CMD_802_11_TPC_CFG):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove(priv->cur_cmd->pdata_buf, &resp->params.tpccfg,
+		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
 			sizeof(struct cmd_ds_802_11_tpc_cfg));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
 	case CMD_RET(CMD_802_11_LED_GPIO_CTRL):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove(priv->cur_cmd->pdata_buf, &resp->params.ledgpio,
+		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.ledgpio,
 			sizeof(struct cmd_ds_802_11_led_ctrl));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
@@ -580,7 +580,7 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 
 	case CMD_RET(CMD_802_11_PWR_CFG):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		memmove(priv->cur_cmd->pdata_buf, &resp->params.pwrcfg,
+		memmove((void *)priv->cur_cmd->callback_arg, &resp->params.pwrcfg,
 			sizeof(struct cmd_ds_802_11_pwr_cfg));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 
@@ -588,21 +588,21 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 
 	case CMD_RET(CMD_GET_TSF):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		memcpy(priv->cur_cmd->pdata_buf,
+		memcpy((void *)priv->cur_cmd->callback_arg,
 		       &resp->params.gettsf.tsfvalue, sizeof(u64));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
 	case CMD_RET(CMD_BT_ACCESS):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		if (priv->cur_cmd->pdata_buf)
-			memcpy(priv->cur_cmd->pdata_buf,
+		if (priv->cur_cmd->callback_arg)
+			memcpy((void *)priv->cur_cmd->callback_arg,
 			       &resp->params.bt.addr1, 2 * ETH_ALEN);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
 	case CMD_RET(CMD_FWT_ACCESS):
 		spin_lock_irqsave(&priv->driver_lock, flags);
-		if (priv->cur_cmd->pdata_buf)
-			memcpy(priv->cur_cmd->pdata_buf, &resp->params.fwt,
+		if (priv->cur_cmd->callback_arg)
+			memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt,
 			       sizeof(resp->params.fwt));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		break;
drivers/net/wireless/libertas/hostcmd.h +0 -1
index 1b31250..719da73 100644
@@ -75,7 +75,6 @@ struct cmd_header {
 struct cmd_ctrl_node {
 	struct list_head list;
 	/* command response */
-	void *pdata_buf;
 	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
 	unsigned long callback_arg;
 	/* command data */
Signature · 1 line
1.5.3.4
#116 lore raw

[PATCH 110/48] libertas: store command result in cmdnode instead of priv->cur_cmd_retcode

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 04:22:52 -0500

... at least for users of __lbs_cmd().

---
 drivers/net/wireless/libertas/cmd.c     |   12 ++++++------
 drivers/net/wireless/libertas/hostcmd.h |    1 +
 drivers/net/wireless/libertas/main.c    |    1 +
 3 files changed, 8 insertions(+), 6 deletions(-)
drivers/net/wireless/libertas/cmd.c +6 -6
index f2e027b..c8f1bd5 100644
@@ -1173,6 +1173,7 @@ void lbs_queue_cmd(struct lbs_private *priv,
 		lbs_deb_host("DNLD_CMD: cmd size is zero\n");
 		goto done;
 	}
+	cmdnode->result = 0;
 
 	/* Exit_PS command needs to be queued in the header always. */
 	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
@@ -1306,6 +1307,7 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
 	if (cmd == priv->cur_cmd)
 		priv->cur_cmd_retcode = result;
 
+	cmd->result = result;
 	cmd->cmdwaitqwoken = 1;
 	wake_up_interruptible(&cmd->cmdwait_q);
 
@@ -2212,12 +2214,10 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
-	if (priv->cur_cmd_retcode) {
-		lbs_deb_host("PREP_CMD: command failed with return code %d\n",
-		       priv->cur_cmd_retcode);
-		priv->cur_cmd_retcode = 0;
-		ret = -1;
-	}
+	ret = cmdnode->result;
+	if (ret)
+		lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
+			    command, ret);
 	__lbs_cleanup_and_insert_cmd(priv, cmdnode);
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
drivers/net/wireless/libertas/hostcmd.h +1 -0
index 719da73..ea4d484 100644
@@ -74,6 +74,7 @@ struct cmd_header {
 
 struct cmd_ctrl_node {
 	struct list_head list;
+	int result;
 	/* command response */
 	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *);
 	unsigned long callback_arg;
drivers/net/wireless/libertas/main.c +1 -0
index 0dc7de6..839ffe8 100644
@@ -1237,6 +1237,7 @@ int lbs_stop_card(struct lbs_private *priv)
 	/* Flush pending command nodes */
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	list_for_each_entry(cmdnode, &priv->cmdpendingq, list) {
+		cmdnode->result = -ENOENT;
 		cmdnode->cmdwaitqwoken = 1;
 		wake_up_interruptible(&cmdnode->cmdwait_q);
 	}
Signature · 1 line
1.5.3.4
#117 lore raw

[PATCH 111/48] libertas: add __lbs_cmd_async() for asynchronous command submission

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 03:09:33 -0500

---
 drivers/net/wireless/libertas/cmd.c |   60 +++++++++++++++++-----------------
 drivers/net/wireless/libertas/cmd.h |    6 +++
 2 files changed, 36 insertions(+), 30 deletions(-)
drivers/net/wireless/libertas/cmd.c +30 -30
index c8f1bd5..3079b3f 100644
@@ -2139,42 +2139,18 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
 }
 EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
 
-/**
- *  @brief Simple way to call firmware functions
- *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param psmode  	one of the many CMD_802_11_xxxx
- *  @param cmd          pointer to the parameters structure for above command
- *                      (this should not include the command, size, sequence
- *                      and result fields from struct cmd_ds_gen)
- *  @param cmd_size     size structure pointed to by cmd
- *  @param rsp          pointer to an area where the result should be placed
- *  @param rsp_size     pointer to the size of the rsp area. If the firmware
- *                      returns fewer bytes, then this *rsp_size will be
- *                      changed to the actual size.
- *  @return 	   	-1 in case of a higher level error, otherwise
- *                      the result code from the firmware
- */
-int __lbs_cmd(struct lbs_private *priv, uint16_t command,
-	      struct cmd_header *in_cmd, int in_cmd_size,
-	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
-	      unsigned long callback_arg)
+struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
+				      struct cmd_header *in_cmd, int in_cmd_size,
+				      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+				      unsigned long callback_arg)
 {
 	struct cmd_ctrl_node *cmdnode;
-	unsigned long flags;
-	int ret = 0;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
-	if (!priv) {
-		lbs_deb_host("PREP_CMD: priv is NULL\n");
-		ret = -1;
-		goto done;
-	}
-
 	if (priv->surpriseremoved) {
 		lbs_deb_host("PREP_CMD: card removed\n");
-		ret = -1;
+		cmdnode = ERR_PTR(-ENOENT);
 		goto done;
 	}
 
@@ -2184,7 +2160,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 
 		/* Wake up main thread to execute next command */
 		wake_up_interruptible(&priv->waitq);
-		ret = -1;
+		cmdnode = ERR_PTR(-ENOBUFS);
 		goto done;
 	}
 
@@ -2210,6 +2186,29 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	lbs_queue_cmd(priv, cmdnode, 1);
 	wake_up_interruptible(&priv->waitq);
 
+ done:
+	lbs_deb_leave_args(LBS_DEB_HOST, "ret %p", cmdnode);
+	return cmdnode;
+}
+
+int __lbs_cmd(struct lbs_private *priv, uint16_t command,
+	      struct cmd_header *in_cmd, int in_cmd_size,
+	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+	      unsigned long callback_arg)
+{
+	struct cmd_ctrl_node *cmdnode;
+	unsigned long flags;
+	int ret = 0;
+
+	lbs_deb_enter(LBS_DEB_HOST);
+
+	cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
+				  callback, callback_arg);
+	if (IS_ERR(cmdnode)) {
+		ret = PTR_ERR(cmdnode);
+		goto done;
+	}
+
 	might_sleep();
 	wait_event_interruptible(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
 
@@ -2218,6 +2217,7 @@ int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	if (ret)
 		lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
 			    command, ret);
+
 	__lbs_cleanup_and_insert_cmd(priv, cmdnode);
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
drivers/net/wireless/libertas/cmd.h +6 -0
index 999fabe..2f4c1ec 100644
@@ -12,6 +12,12 @@
 #define lbs_cmd_with_response(priv, cmdnr, cmd)	\
 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
 
+/* __lbs_cmd() will free the cmdnode and return success/failure.
+   __lbs_cmd_async() requires that the callback free the cmdnode */
+struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command,
+				      struct cmd_header *in_cmd, int in_cmd_size,
+				      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
+				      unsigned long callback_arg);
 int __lbs_cmd(struct lbs_private *priv, uint16_t command,
 	      struct cmd_header *in_cmd, int in_cmd_size,
 	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
Signature · 1 line
1.5.3.4
#118 lore raw

[PATCH 112/48] libertas: ensure response buffer size is always set for lbs_cmd_with_response

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 03:46:44 -0500

---
 drivers/net/wireless/libertas/cmd.c    |    4 +++-
 drivers/net/wireless/libertas/cmd.h    |    4 ++++
 drivers/net/wireless/libertas/if_usb.c |    1 +
 3 files changed, 8 insertions(+), 1 deletions(-)
drivers/net/wireless/libertas/cmd.c +3 -1
index 3079b3f..c3d7f60 100644
@@ -115,6 +115,7 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria)
 	struct cmd_ds_host_sleep cmd_config;
 	int ret;
 
+	cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
 	cmd_config.criteria = cpu_to_le32(criteria);
 	cmd_config.gpio = priv->wol_gpio;
 	cmd_config.gap = priv->wol_gap;
@@ -1101,7 +1102,7 @@ int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
 	lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
 
 	cmd->hdr.command = cpu_to_le16(CMD_MESH_ACCESS);
-	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_access) + S_DS_GEN);
+	cmd->hdr.size = cpu_to_le16(sizeof(*cmd));
 	cmd->hdr.result = 0;
 
 	cmd->action = cpu_to_le16(cmd_action);
@@ -1121,6 +1122,7 @@ int lbs_mesh_config(struct lbs_private *priv, uint16_t enable, uint16_t chan)
 	cmd.action = cpu_to_le16(enable);
 	cmd.channel = cpu_to_le16(chan);
 	cmd.type = cpu_to_le16(priv->mesh_tlv);
+	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 
 	if (enable) {
 		cmd.length = cpu_to_le16(priv->mesh_ssid_len);
drivers/net/wireless/libertas/cmd.h +4 -0
index 2f4c1ec..e334f0e 100644
@@ -9,6 +9,10 @@
 #define lbs_cmd(priv, cmdnr, cmd, cb, cb_arg)	\
 	__lbs_cmd(priv, cmdnr, &(cmd)->hdr, sizeof(*(cmd)), cb, cb_arg)
 
+
+/* lbs_cmd_with_response() infers the size of the command to be _sent_
+   and requires that the caller sets cmd->size to the (LE) size of
+   the _response_ buffer. */
 #define lbs_cmd_with_response(priv, cmdnr, cmd)	\
 	lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
 
drivers/net/wireless/libertas/if_usb.c +1 -0
index cf88251..8bc23b3 100644
@@ -106,6 +106,7 @@ static void if_usb_set_boot2_ver(struct lbs_private *priv)
 {
 	struct cmd_ds_set_boot2_ver b2_cmd;
 
+	b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
 	b2_cmd.action = 0;
 	b2_cmd.version = priv->boot2_version;
 
Signature · 1 line
1.5.3.4
#119 lore raw

[PATCH 113/48] libertas: handle command timeout in main thread instead of directly in timer

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 19:33:43 -0500

And handle the case where it times out more than once, too, instead of locking up for ever.

---
 drivers/net/wireless/libertas/cmdresp.c |    6 +++
 drivers/net/wireless/libertas/dev.h     |    2 +
 drivers/net/wireless/libertas/main.c    |   52 ++++++++++++++++++-------------
 3 files changed, 38 insertions(+), 22 deletions(-)
drivers/net/wireless/libertas/cmdresp.c +6 -0
index 4c22e78..ef63c37 100644
@@ -667,6 +667,12 @@ int lbs_process_rx_command(struct lbs_private *priv)
 
 	/* Now we got response from FW, cancel the command timer */
 	del_timer(&priv->command_timer);
+	priv->cmd_timed_out = 0;
+	if (priv->nr_retries) {
+		lbs_pr_info("Received result %x to command %x after %d retries\n",
+			    result, curcmd, priv->nr_retries);
+		priv->nr_retries = 0;
+	}
 
 	/* Store the response code to cur_cmd_retcode. */
 	priv->cur_cmd_retcode = result;
drivers/net/wireless/libertas/dev.h +2 -0
index e6f553d..465080f 100644
@@ -201,6 +201,8 @@ struct lbs_private {
 
 	/** Timers */
 	struct timer_list command_timer;
+	int nr_retries;
+	int cmd_timed_out;
 
 	u8 hisregcpy;
 
drivers/net/wireless/libertas/main.c +30 -22

77 lines not on this page · raw message

Signature · 1 line
1.5.3.4
#120 lore raw

[PATCH 114/48] libertas: kill 'addtail' argument to lbs_queue_cmd() and make it static

In reply to David Woodhouse

Date: Sat, 15 Dec 2007 20:04:54 -0500

---
 drivers/net/wireless/libertas/cmd.c  |   14 +++++---------
 drivers/net/wireless/libertas/decl.h |    4 ----
 2 files changed, 5 insertions(+), 13 deletions(-)
drivers/net/wireless/libertas/cmd.c +5 -9
index c3d7f60..7682b9d 100644
@@ -1155,15 +1155,11 @@ static int lbs_cmd_bcn_ctrl(struct lbs_private * priv,
 	return 0;
 }
 
-/*
- * Note: NEVER use lbs_queue_cmd() with addtail==0 other than for
- * the command timer, because it does not account for queued commands.
- */
-void lbs_queue_cmd(struct lbs_private *priv,
-	struct cmd_ctrl_node *cmdnode,
-	u8 addtail)
+static void lbs_queue_cmd(struct lbs_private *priv,
+			  struct cmd_ctrl_node *cmdnode)
 {
 	unsigned long flags;
+	int addtail = 1;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
@@ -1635,7 +1631,7 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 
 	cmdnode->cmdwaitqwoken = 0;
 
-	lbs_queue_cmd(priv, cmdnode, 1);
+	lbs_queue_cmd(priv, cmdnode);
 	wake_up_interruptible(&priv->waitq);
 
 	if (wait_option & CMD_OPTION_WAITFORRSP) {
@@ -2185,7 +2181,7 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv, uint16_t command
 	 * because the caller of lbs_cmd() sets up all of *cmd for us. */
 
 	cmdnode->cmdwaitqwoken = 0;
-	lbs_queue_cmd(priv, cmdnode, 1);
+	lbs_queue_cmd(priv, cmdnode);
 	wake_up_interruptible(&priv->waitq);
 
  done:
drivers/net/wireless/libertas/decl.h +0 -4
index 5dd5c9e..aaacd9b 100644
@@ -28,10 +28,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
 	u16 cmd_action,
 	u16 wait_option, u32 cmd_oid, void *pdata_buf);
 
-void lbs_queue_cmd(struct lbs_private *priv,
-	struct cmd_ctrl_node *cmdnode,
-	u8 addtail);
-
 int lbs_allocate_cmd_buffer(struct lbs_private *priv);
 int lbs_execute_next_command(struct lbs_private *priv);
 int lbs_process_event(struct lbs_private *priv);
Signature · 1 line
1.5.3.4
#121 lore raw

[PATCH 115/48] libertas: fix return from lbs_update_channel()

In reply to David Woodhouse

Date: Sun, 16 Dec 2007 17:21:00 -0500

If we return the channel number in a 'ret' variable where anything non-zero is later interpreted as an error, that isn't nice. It breaks WPA, for a start. OLPC trac #5485

---
 drivers/net/wireless/libertas/assoc.c |   16 ++++++++++------
 1 files changed, 10 insertions(+), 6 deletions(-)
drivers/net/wireless/libertas/assoc.c +10 -6
index cd8e043..882e51c 100644
@@ -167,13 +167,14 @@ int lbs_update_channel(struct lbs_private *priv)
 {
 	int ret;
 
-	/* the channel in f/w could be out of sync, get the current channel */
+	/* the channel in f/w could be out of sync; get the current channel */
 	lbs_deb_enter(LBS_DEB_ASSOC);
 
 	ret = lbs_get_channel(priv);
-	if (ret > 0)
-		priv->curbssparams.channel = (u8) ret;
-
+	if (ret > 0) {
+		priv->curbssparams.channel = ret;
+		ret = 0;
+	}
 	lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
 	return ret;
 }
@@ -197,8 +198,9 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	lbs_deb_enter(LBS_DEB_ASSOC);
 
 	ret = lbs_update_channel(priv);
-	if (ret < 0) {
+	if (ret) {
 		lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
+		goto done;
 	}
 
 	if (assoc_req->channel == priv->curbssparams.channel)
@@ -222,8 +224,10 @@ static int assoc_helper_channel(struct lbs_private *priv,
 	 * it since the firmware is supposed to return the new channel, but
 	 * whatever... */
 	ret = lbs_update_channel(priv);
-	if (ret < 0)
+	if (ret) {
 		lbs_deb_assoc("ASSOC: channel: error getting channel.\n");
+		goto done;
+	}
 
 	if (assoc_req->channel != priv->curbssparams.channel) {
 		lbs_deb_assoc("ASSOC: channel: failed to update channel to %d\n",
Signature · 1 line
1.5.3.4
#122 lore raw

[PATCH 123/48] libertas: use priv->upld_buf for command responses

In reply to David Woodhouse

Date: Mon, 17 Dec 2007 15:22:43 -0500

If we don't scribble over the command we sent, then we can retry it when the firmware responds with 0x0004 (which means -EAGAIN).

---
 drivers/net/wireless/libertas/cmdresp.c |    2 +-
 drivers/net/wireless/libertas/if_cs.c   |   10 +---------
 drivers/net/wireless/libertas/if_sdio.c |    8 +-------
 drivers/net/wireless/libertas/if_usb.c  |   14 +-------------
 4 files changed, 4 insertions(+), 30 deletions(-)
drivers/net/wireless/libertas/cmdresp.c +1 -1
index d305e98..4d38461 100644
@@ -639,7 +639,7 @@ int lbs_process_rx_command(struct lbs_private *priv)
 		goto done;
 	}
 
-	resp = priv->cur_cmd->cmdbuf;
+	resp = (void *)priv->upld_buf;
 
 	curcmd = le16_to_cpu(resp->command);
 
drivers/net/wireless/libertas/if_cs.c +1 -9
index 5814363..4b5ab9a 100644
@@ -647,7 +647,6 @@ static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg)
 	struct if_cs_card *card = (struct if_cs_card *)priv->card;
 	int ret = 0;
 	u16 int_cause;
-	u8 *cmdbuf;
 	*ireg = 0;
 
 	lbs_deb_enter(LBS_DEB_CS);
@@ -679,14 +678,7 @@ sbi_get_int_status_exit:
 	/* Card has a command result for us */
 	if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
 		spin_lock(&priv->driver_lock);
-		if (!priv->cur_cmd) {
-			cmdbuf = priv->upld_buf;
-			priv->hisregcpy &= ~IF_CS_C_S_RX_UPLD_RDY;
-		} else {
-			cmdbuf = (u8 *) priv->cur_cmd->cmdbuf;
-		}
-
-		ret = if_cs_receive_cmdres(priv, cmdbuf, &priv->upld_len);
+		ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len);
 		spin_unlock(&priv->driver_lock);
 		if (ret < 0)
 			lbs_pr_err("could not receive cmd from card\n");
drivers/net/wireless/libertas/if_sdio.c +1 -7
index b24584d..5a828c7 100644
@@ -136,12 +136,6 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 
 	spin_lock_irqsave(&card->priv->driver_lock, flags);
 
-	if (!card->priv->cur_cmd) {
-		lbs_deb_sdio("discarding spurious response\n");
-		ret = 0;
-		goto out;
-	}
-
 	if (size > LBS_CMD_BUFFER_SIZE) {
 		lbs_deb_sdio("response packet too large (%d bytes)\n",
 			(int)size);
@@ -149,7 +143,7 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card,
 		goto out;
 	}
 
-	memcpy(card->priv->cur_cmd->cmdbuf, buffer, size);
+	memcpy(card->priv->upld_buf, buffer, size);
 	card->priv->upld_len = size;
 
 	card->int_cause |= MRVDRV_CMD_UPLD_RDY;
drivers/net/wireless/libertas/if_usb.c +1 -13
index 3931fe6..7db8e6c 100644
@@ -589,8 +589,6 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 				      struct if_usb_card *cardp,
 				      struct lbs_private *priv)
 {
-	uint8_t *cmdbuf;
-
 	if (recvlength > LBS_CMD_BUFFER_SIZE) {
 		lbs_deb_usbd(&cardp->udev->dev,
 			     "The receive buffer is too large\n");
@@ -602,19 +600,9 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
 		BUG();
 
 	spin_lock(&priv->driver_lock);
-	/* take care of cur_cmd = NULL case by reading the
-	 * data to clear the interrupt */
-	if (!priv->cur_cmd) {
-		lbs_deb_hex(LBS_DEB_HOST, "Unsolicited CMD_RESP",
-			    (void *) recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
-		cmdbuf = priv->upld_buf;
-		priv->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;
-	} else
-		cmdbuf = (uint8_t *) priv->cur_cmd->cmdbuf;
-
 	cardp->usb_int_cause |= MRVDRV_CMD_UPLD_RDY;
 	priv->upld_len = (recvlength - MESSAGE_HEADER_LEN);
-	memcpy(cmdbuf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
+	memcpy(priv->upld_buf, recvbuff + MESSAGE_HEADER_LEN, priv->upld_len);
 
 	kfree_skb(skb);
 	lbs_interrupt(priv);
Signature · 1 line
1.5.3.4
#123 lore raw

[PATCH 125/48] libertas: make lbs_submit_command always 'succeed' and set command timer

In reply to David Woodhouse

Date: Mon, 17 Dec 2007 16:03:58 -0500

Even if it fails, we want to wait a while and try again, with an ultimate timeout if it the condition persists. So again, just use the standard command timeout behaviour.

---
 drivers/net/wireless/libertas/cmd.c |   42 ++++++++++++++++------------------
 1 files changed, 20 insertions(+), 22 deletions(-)
drivers/net/wireless/libertas/cmd.c +20 -22
index 10c60ba..0ae9851 100644
@@ -1199,14 +1199,15 @@ done:
 	lbs_deb_leave(LBS_DEB_HOST);
 }
 
-static int lbs_submit_command(struct lbs_private *priv,
-			      struct cmd_ctrl_node *cmdnode)
+static void lbs_submit_command(struct lbs_private *priv,
+			       struct cmd_ctrl_node *cmdnode)
 {
 	unsigned long flags;
 	struct cmd_header *cmd;
-	int ret = -1;
-	u16 cmdsize;
-	u16 command;
+	uint16_t cmdsize;
+	uint16_t command;
+	int timeo = 5 * HZ;
+	int ret;
 
 	lbs_deb_enter(LBS_DEB_HOST);
 
@@ -1220,33 +1221,30 @@ static int lbs_submit_command(struct lbs_private *priv,
 	cmdsize = le16_to_cpu(cmd->size);
 	command = le16_to_cpu(cmd->command);
 
+	/* These commands take longer */
+	if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
+	    command == CMD_802_11_AUTHENTICATE)
+		timeo = 10 * HZ;
+
 	lbs_deb_host("DNLD_CMD: command 0x%04x, seq %d, size %d, jiffies %lu\n",
 		     command, le16_to_cpu(cmd->seqnum), cmdsize, jiffies);
 	lbs_deb_hex(LBS_DEB_HOST, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
 
 	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
+
 	if (ret) {
 		lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
-		spin_lock_irqsave(&priv->driver_lock, flags);
-		lbs_complete_command(priv, priv->cur_cmd, ret);
-		spin_unlock_irqrestore(&priv->driver_lock, flags);
-		goto done;
-	}
-
-	lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n", command, jiffies);
+		/* Let the timer kick in and retry, and potentially reset
+		   the whole thing if the condition persists */
+		timeo = HZ;
+	} else
+		lbs_deb_cmd("DNLD_CMD: sent command 0x%04x, jiffies %lu\n",
+			    command, jiffies);
 
 	/* Setup the timer after transmit command */
-	if (command == CMD_802_11_SCAN || command == CMD_802_11_AUTHENTICATE
-	    || command == CMD_802_11_ASSOCIATE)
-		mod_timer(&priv->command_timer, jiffies + (10*HZ));
-	else
-		mod_timer(&priv->command_timer, jiffies + (5*HZ));
-
-	ret = 0;
+	mod_timer(&priv->command_timer, jiffies + timeo);
 
-done:
-	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
-	return ret;
+	lbs_deb_leave(LBS_DEB_HOST);
 }
 
 static int lbs_cmd_mac_control(struct lbs_private *priv,
Signature · 1 line
1.5.3.4