All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/10] brcmfmac: transmit flow control and e-scan support
@ 2012-09-10 13:16 Arend van Spriel
  2012-09-10 13:16 ` [PATCH 01/10] brcmfmac: Stop all net if queues on tx flow halt Arend van Spriel
                   ` (11 more replies)
  0 siblings, 12 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Arend van Spriel

This series contains transmit flow control handling when the brcmfmac driver
has no resources to transfer packets over the host interface. This improves
throughput number for TCP. The other feature in this series is event based
scanning in which firmware sends an event per BSS.

The other changes in this series are small fixes.

This series is for the v3.7 kernel and applies to the wireless-next tree.

Hante Meuleman (10):
  brcmfmac: Stop all net if queues on tx flow halt.
  brcmfmac: Add extra data support to firmware event queueing.
  brcmfmac: Fix extra data support handling.
  brcmfmac: Add tx flow control on net if queue for USB.
  brcmfmac: Clean up scan related code.
  brcmfmac: fix big endian bug in i-scan.
  brcmfmac: Fix big endian host configuration data.
  brcmfmac: refill buffers on rx protocol error.
  brcmfmac: avoid using local usb data.
  brcmfmac: add e-scan support.

 drivers/net/wireless/brcm80211/Kconfig             |    8 +
 drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |   24 +
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    2 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |   34 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   16 +-
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |    8 +-
 drivers/net/wireless/brcm80211/brcmfmac/usb.c      |  184 +++----
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |  564 +++++++++++++++++++-
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |   25 +
 9 files changed, 717 insertions(+), 148 deletions(-)

-- 
1.7.9.5



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 01/10] brcmfmac: Stop all net if queues on tx flow halt.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 13:16 ` [PATCH 02/10] brcmfmac: Add extra data support to firmware event queueing Arend van Spriel
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

When tx flow is to be blocked due to host interface throttle then
all net if queues should be stopped.

Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    2 +-
 .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   16 ++++++++++------
 drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |    8 ++++----
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 537f499..9b8ee19 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -103,7 +103,7 @@ extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
 extern void brcmf_detach(struct device *dev);
 
 /* Indication from bus module to change flow-control state */
-extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on);
+extern void brcmf_txflowblock(struct device *dev, bool state);
 
 /* Notify tx completion */
 extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 7f9ba82..b08f347 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -350,19 +350,23 @@ done:
 	return 0;
 }
 
-void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state)
+void brcmf_txflowblock(struct device *dev, bool state)
 {
 	struct net_device *ndev;
 	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
 	struct brcmf_pub *drvr = bus_if->drvr;
+	int i;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
-	ndev = drvr->iflist[ifidx]->ndev;
-	if (state == ON)
-		netif_stop_queue(ndev);
-	else
-		netif_wake_queue(ndev);
+	for (i = 0; i < BRCMF_MAX_IFS; i++)
+		if (drvr->iflist[i]) {
+			ndev = drvr->iflist[i]->ndev;
+			if (state)
+				netif_stop_queue(ndev);
+			else
+				netif_wake_queue(ndev);
+		}
 }
 
 static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 2dd6b48..4580ff3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2235,8 +2235,8 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
 	if (bus->sdiodev->bus_if->drvr_up &&
 	    (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
 	    bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
-		bus->txoff = OFF;
-		brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF);
+		bus->txoff = false;
+		brcmf_txflowblock(bus->sdiodev->dev, false);
 	}
 
 	return cnt;
@@ -2672,8 +2672,8 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
 	spin_unlock_bh(&bus->txqlock);
 
 	if (pktq_len(&bus->txq) >= TXHI) {
-		bus->txoff = ON;
-		brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
+		bus->txoff = true;
+		brcmf_txflowblock(bus->sdiodev->dev, true);
 	}
 
 #ifdef DEBUG
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 02/10] brcmfmac: Add extra data support to firmware event queueing.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
  2012-09-10 13:16 ` [PATCH 01/10] brcmfmac: Stop all net if queues on tx flow halt Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 13:16 ` [PATCH 03/10] brcmfmac: Fix extra data support handling Arend van Spriel
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

Firmware events can contain extra data. This patch adds support to
copy this data when it exists.

Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |    2 ++
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |   16 +++++++++++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 37f5708..9e2fb5b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -140,6 +140,8 @@ struct brcmf_event_msg {
 	__be32 datalen;
 	u8 addr[ETH_ALEN];
 	char ifname[IFNAMSIZ];
+	u8 ifidx;
+	u8 bsscfgidx;
 } __packed;
 
 struct brcm_ethhdr {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index a6b382b..6383052 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3321,18 +3321,28 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
 
 static s32
 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
-		const struct brcmf_event_msg *msg)
+		const struct brcmf_event_msg *msg, void *data)
 {
 	struct brcmf_cfg80211_event_q *e;
 	s32 err = 0;
 	ulong flags;
+	u32 data_len;
+	u32 total_len;
 
-	e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
+	total_len = sizeof(struct brcmf_cfg80211_event_q);
+	if (data)
+		data_len += be32_to_cpu(msg->datalen);
+	else
+		data_len = 0;
+	total_len += data_len;
+	e = kzalloc(total_len, GFP_ATOMIC);
 	if (!e)
 		return -ENOMEM;
 
 	e->etype = event;
 	memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
+	if (data)
+		memcpy(&e->edata, data, data_len);
 
 	spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
 	list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
@@ -3501,7 +3511,7 @@ brcmf_cfg80211_event(struct net_device *ndev,
 	u32 event_type = be32_to_cpu(e->event_type);
 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
 
-	if (!brcmf_enq_event(cfg_priv, event_type, e))
+	if (!brcmf_enq_event(cfg_priv, event_type, e, data))
 		schedule_work(&cfg_priv->event_work);
 }
 
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 03/10] brcmfmac: Fix extra data support handling.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
  2012-09-10 13:16 ` [PATCH 01/10] brcmfmac: Stop all net if queues on tx flow halt Arend van Spriel
  2012-09-10 13:16 ` [PATCH 02/10] brcmfmac: Add extra data support to firmware event queueing Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 16:37   ` Florian Fainelli
  2012-09-10 13:16 ` [PATCH 04/10] brcmfmac: Add tx flow control on net if queue for USB Arend van Spriel
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

This patch fixes bug in length calculation.

Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 6383052..4553fa0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3331,7 +3331,7 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
 
 	total_len = sizeof(struct brcmf_cfg80211_event_q);
 	if (data)
-		data_len += be32_to_cpu(msg->datalen);
+		data_len = be32_to_cpu(msg->datalen);
 	else
 		data_len = 0;
 	total_len += data_len;
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 04/10] brcmfmac: Add tx flow control on net if queue for USB.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (2 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 03/10] brcmfmac: Fix extra data support handling Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 13:16 ` [PATCH 05/10] brcmfmac: Clean up scan related code Arend van Spriel
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

Enable tx flow control for USB host interface.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/usb.c |   61 +++++++++++++++----------
 1 file changed, 36 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 7fe68aa..8aab2a2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -119,9 +119,8 @@ struct brcmf_usbdev_info {
 	int rx_low_watermark;
 	int tx_low_watermark;
 	int tx_high_watermark;
-	bool txoff;
-	bool rxoff;
-	bool txoverride;
+	int tx_freecount;
+	bool tx_flowblock;
 
 	struct brcmf_usbreq *tx_reqs;
 	struct brcmf_usbreq *rx_reqs;
@@ -179,14 +178,6 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
 	return brcmf_usb_get_buspub(dev)->devinfo;
 }
 
-#if 0
-static void
-brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
-{
-	dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff);
-}
-#endif
-
 static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
 	 uint *condition, bool *pending)
 {
@@ -420,7 +411,7 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
 }
 
 static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
-					  struct list_head *q)
+					  struct list_head *q, int *counter)
 {
 	unsigned long flags;
 	struct brcmf_usbreq  *req;
@@ -431,17 +422,22 @@ static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
 	}
 	req = list_entry(q->next, struct brcmf_usbreq, list);
 	list_del_init(q->next);
+	if (counter)
+		(*counter)--;
 	spin_unlock_irqrestore(&devinfo->qlock, flags);
 	return req;
 
 }
 
 static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
-			  struct list_head *q, struct brcmf_usbreq *req)
+			  struct list_head *q, struct brcmf_usbreq *req,
+			  int *counter)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&devinfo->qlock, flags);
 	list_add_tail(&req->list, q);
+	if (counter)
+		(*counter)++;
 	spin_unlock_irqrestore(&devinfo->qlock, flags);
 }
 
@@ -523,8 +519,12 @@ static void brcmf_usb_tx_complete(struct urb *urb)
 
 	brcmu_pkt_buf_free_skb(req->skb);
 	req->skb = NULL;
-	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
-
+	brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
+	if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
+		devinfo->tx_flowblock) {
+		brcmf_txflowblock(devinfo->dev, false);
+		devinfo->tx_flowblock = false;
+	}
 }
 
 static void brcmf_usb_rx_complete(struct urb *urb)
@@ -543,7 +543,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
 	} else {
 		devinfo->bus_pub.bus->dstats.rx_errors++;
 		brcmu_pkt_buf_free_skb(skb);
-		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
 		return;
 	}
 
@@ -552,7 +552,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
 		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
 			brcmf_dbg(ERROR, "rx protocol error\n");
 			brcmu_pkt_buf_free_skb(skb);
-			brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+			brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
 			devinfo->bus_pub.bus->dstats.rx_errors++;
 		} else {
 			brcmf_rx_packet(devinfo->dev, ifidx, skb);
@@ -560,7 +560,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
 		}
 	} else {
 		brcmu_pkt_buf_free_skb(skb);
-		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
 	}
 	return;
 
@@ -577,7 +577,7 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
 
 	skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
 	if (!skb) {
-		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
 		return;
 	}
 	req->skb = skb;
@@ -586,14 +586,14 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
 			  skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
 			  req);
 	req->devinfo = devinfo;
-	brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
+	brcmf_usb_enq(devinfo, &devinfo->rx_postq, req, NULL);
 
 	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
 	if (ret) {
 		brcmf_usb_del_fromq(devinfo, req);
 		brcmu_pkt_buf_free_skb(req->skb);
 		req->skb = NULL;
-		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
+		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
 	}
 	return;
 }
@@ -606,7 +606,7 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
 		brcmf_dbg(ERROR, "bus is not up\n");
 		return;
 	}
-	while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL)
+	while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL)
 		brcmf_usb_rx_refill(devinfo, req);
 }
 
@@ -684,7 +684,8 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
 		return -EIO;
 	}
 
-	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
+	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
+					&devinfo->tx_freecount);
 	if (!req) {
 		brcmu_pkt_buf_free_skb(skb);
 		brcmf_dbg(ERROR, "no req to send\n");
@@ -696,14 +697,21 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
 	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
 			  skb->data, skb->len, brcmf_usb_tx_complete, req);
 	req->urb->transfer_flags |= URB_ZERO_PACKET;
-	brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
+	brcmf_usb_enq(devinfo, &devinfo->tx_postq, req, NULL);
 	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
 	if (ret) {
 		brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n");
 		brcmf_usb_del_fromq(devinfo, req);
 		brcmu_pkt_buf_free_skb(req->skb);
 		req->skb = NULL;
-		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
+		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
+						&devinfo->tx_freecount);
+	} else {
+		if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
+			!devinfo->tx_flowblock) {
+			brcmf_txflowblock(dev, true);
+			devinfo->tx_flowblock = true;
+		}
 	}
 
 	return ret;
@@ -1316,6 +1324,8 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
 	INIT_LIST_HEAD(&devinfo->tx_freeq);
 	INIT_LIST_HEAD(&devinfo->tx_postq);
 
+	devinfo->tx_flowblock = false;
+
 	devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
 	if (!devinfo->rx_reqs)
 		goto error;
@@ -1323,6 +1333,7 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
 	devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
 	if (!devinfo->tx_reqs)
 		goto error;
+	devinfo->tx_freecount = ntxq;
 
 	devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!devinfo->intr_urb) {
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 05/10] brcmfmac: Clean up scan related code.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (3 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 04/10] brcmfmac: Add tx flow control on net if queue for USB Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 13:16 ` [PATCH 06/10] brcmfmac: fix big endian bug in i-scan Arend van Spriel
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

Clean up scan related code in preparation of a new scan mechanism (e-scan)
which will follow in a separate patch.

Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |   22 ++++++++------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 4553fa0..4a27ca0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -490,8 +490,8 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
 	}
 }
 
-static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
-			  struct brcmf_ssid *ssid)
+static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
+			     struct brcmf_ssid *ssid)
 {
 	memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
 	params_le->bss_type = DOT11_BSSTYPE_ANY;
@@ -545,7 +545,7 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
 		return -ENOMEM;
 	BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
 
-	wl_iscan_prep(&params->params_le, ssid);
+	brcmf_iscan_prep(&params->params_le, ssid);
 
 	params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
 	params->action = cpu_to_le16(action);
@@ -598,9 +598,9 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
 }
 
 static s32
-__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
-		   struct cfg80211_scan_request *request,
-		   struct cfg80211_ssid *this_ssid)
+brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
+		     struct cfg80211_scan_request *request,
+		     struct cfg80211_ssid *this_ssid)
 {
 	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
 	struct cfg80211_ssid *ssids;
@@ -703,7 +703,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
 	if (!check_sys_up(wiphy))
 		return -EIO;
 
-	err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
+	err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
 	if (err)
 		WL_ERR("scan error (%d)\n", err);
 
@@ -2547,10 +2547,8 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
 	clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
 
 	/* Turn off watchdog timer */
-	if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
-		WL_INFO("Enable MPC\n");
+	if (test_bit(WL_STATUS_READY, &cfg_priv->status))
 		brcmf_set_mpc(ndev, 1);
-	}
 
 	WL_TRACE("Exit\n");
 
@@ -3194,10 +3192,8 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
 	cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
 
 	err = brcmf_inform_bss(cfg_priv);
-	if (err) {
+	if (err)
 		scan_abort = true;
-		goto scan_done_out;
-	}
 
 scan_done_out:
 	if (cfg_priv->scan_request) {
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 06/10] brcmfmac: fix big endian bug in i-scan.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (4 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 05/10] brcmfmac: Clean up scan related code Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 16:37   ` Florian Fainelli
  2012-09-10 13:16 ` [PATCH 07/10] brcmfmac: Fix big endian host configuration data Arend van Spriel
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

ssid len is 32 bit and needs endian conversion for big endian systems.

Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 4a27ca0..6623f48 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -501,8 +501,10 @@ static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
 	params_le->active_time = cpu_to_le32(-1);
 	params_le->passive_time = cpu_to_le32(-1);
 	params_le->home_time = cpu_to_le32(-1);
-	if (ssid && ssid->SSID_len)
-		memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
+	if (ssid && ssid->SSID_len) {
+		params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
+		memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
+	}
 }
 
 static s32
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 07/10] brcmfmac: Fix big endian host configuration data.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (5 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 06/10] brcmfmac: fix big endian bug in i-scan Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 16:38   ` Florian Fainelli
  2012-09-10 13:16 ` [PATCH 08/10] brcmfmac: refill buffers on rx protocol error Arend van Spriel
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

Fixes big endian host configuration parameters.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |   26 ++++++++++++--------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 2621dd3..6f70953 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -764,8 +764,11 @@ static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
 {
 	char iovbuf[32];
 	int retcode;
+	__le32 arp_mode_le;
 
-	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
+	arp_mode_le = cpu_to_le32(arp_mode);
+	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf,
+			sizeof(iovbuf));
 	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
 				   iovbuf, sizeof(iovbuf));
 	retcode = retcode >= 0 ? 0 : retcode;
@@ -781,8 +784,11 @@ static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
 {
 	char iovbuf[32];
 	int retcode;
+	__le32 arp_enable_le;
 
-	brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
+	arp_enable_le = cpu_to_le32(arp_enable);
+
+	brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4,
 			iovbuf, sizeof(iovbuf));
 	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
 				   iovbuf, sizeof(iovbuf));
@@ -800,10 +806,10 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
 	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];	/*  Room for
 				 "event_msgs" + '\0' + bitvec  */
 	char buf[128], *ptr;
-	u32 roaming = 1;
-	uint bcn_timeout = 3;
-	int scan_assoc_time = 40;
-	int scan_unassoc_time = 40;
+	__le32 roaming_le = cpu_to_le32(1);
+	__le32 bcn_timeout_le = cpu_to_le32(3);
+	__le32 scan_assoc_time_le = cpu_to_le32(40);
+	__le32 scan_unassoc_time_le = cpu_to_le32(40);
 	int i;
 	struct brcmf_bus_dcmd *cmdlst;
 	struct list_head *cur, *q;
@@ -829,14 +835,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
 
 	/* Setup timeout if Beacons are lost and roam is off to report
 		 link down */
-	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
+	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf,
 		    sizeof(iovbuf));
 	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
 				  sizeof(iovbuf));
 
 	/* Enable/Disable build-in roaming to allowed ext supplicant to take
 		 of romaing */
-	brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
+	brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4,
 		      iovbuf, sizeof(iovbuf));
 	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
 				  sizeof(iovbuf));
@@ -848,9 +854,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
 				  sizeof(iovbuf));
 
 	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
-			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
+		 (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le));
 	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
-			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
+		 (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le));
 
 	/* Set and enable ARP offload feature */
 	brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 08/10] brcmfmac: refill buffers on rx protocol error.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (6 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 07/10] brcmfmac: Fix big endian host configuration data Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 13:16 ` [PATCH 09/10] brcmfmac: avoid using local usb data Arend van Spriel
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

This patch fixes a bug where rx buffer does not get refilled if the
packet received has an rx protocol error.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/usb.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 8aab2a2..6e3ff6f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -552,12 +552,10 @@ static void brcmf_usb_rx_complete(struct urb *urb)
 		if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
 			brcmf_dbg(ERROR, "rx protocol error\n");
 			brcmu_pkt_buf_free_skb(skb);
-			brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
 			devinfo->bus_pub.bus->dstats.rx_errors++;
-		} else {
+		} else
 			brcmf_rx_packet(devinfo->dev, ifidx, skb);
-			brcmf_usb_rx_refill(devinfo, req);
-		}
+		brcmf_usb_rx_refill(devinfo, req);
 	} else {
 		brcmu_pkt_buf_free_skb(skb);
 		brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 09/10] brcmfmac: avoid using local usb data.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (7 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 08/10] brcmfmac: refill buffers on rx protocol error Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 13:16 ` [PATCH 10/10] brcmfmac: add e-scan support Arend van Spriel
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

This patch removes usage of some of the local data in the usb
host interface driver. This is a step in the preperation to
support multiple USB devices.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/usb.c |  119 ++++++++-----------------
 1 file changed, 39 insertions(+), 80 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 6e3ff6f..c6d5aeb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -80,20 +80,6 @@ enum usbdev_suspend_state {
 	USBOS_SUSPEND_STATE_SUSPENDED	/* Device suspended */
 };
 
-struct brcmf_usb_probe_info {
-	void *usbdev_info;
-	struct usb_device *usb; /* USB device pointer from OS */
-	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
-	int intr_size; /* Size of interrupt message */
-	int interval;  /* Interrupt polling interval */
-	int vid;
-	int pid;
-	enum usb_device_speed device_speed;
-	enum usbdev_suspend_state suspend_state;
-	struct usb_interface *intf;
-};
-static struct brcmf_usb_probe_info usbdev_probe_info;
-
 struct brcmf_usb_image {
 	void *data;
 	u32 len;
@@ -134,7 +120,6 @@ struct brcmf_usbdev_info {
 
 	struct usb_device *usbdev;
 	struct device *dev;
-	enum usb_device_speed  device_speed;
 
 	int ctl_in_pipe, ctl_out_pipe;
 	struct urb *ctl_urb; /* URB for control endpoint */
@@ -154,9 +139,6 @@ struct brcmf_usbdev_info {
 	int intr_size;          /* Size of interrupt message */
 	int interval;           /* Interrupt polling interval */
 	struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
-
-	struct brcmf_usb_probe_info probe_info;
-
 };
 
 static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
@@ -1166,11 +1148,8 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
 }
 
 
-static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
+static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
 {
-	struct brcmf_usbdev_info *devinfo =
-		(struct brcmf_usbdev_info *)bus_pub;
-
 	brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
 
 	/* store the image globally */
@@ -1187,7 +1166,6 @@ static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
 
 	kfree(devinfo->tx_reqs);
 	kfree(devinfo->rx_reqs);
-	kfree(devinfo);
 }
 
 #define TRX_MAGIC       0x30524448      /* "HDR0" */
@@ -1280,14 +1258,9 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
 
 
 static
-struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
+struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
+				      int nrxq, int ntxq)
 {
-	struct brcmf_usbdev_info *devinfo;
-
-	devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
-	if (devinfo == NULL)
-		return NULL;
-
 	devinfo->bus_pub.nrxq = nrxq;
 	devinfo->rx_low_watermark = nrxq / 2;
 	devinfo->bus_pub.devinfo = devinfo;
@@ -1296,18 +1269,6 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
 	/* flow control when too many tx urbs posted */
 	devinfo->tx_low_watermark = ntxq / 4;
 	devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
-	devinfo->dev = dev;
-	devinfo->usbdev = usbdev_probe_info.usb;
-	devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
-	devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
-	devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
-	devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
-
-	devinfo->interval = usbdev_probe_info.interval;
-	devinfo->intr_size = usbdev_probe_info.intr_size;
-
-	memcpy(&devinfo->probe_info, &usbdev_probe_info,
-		sizeof(struct brcmf_usb_probe_info));
 	devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
 
 	/* Initialize other structure content */
@@ -1366,19 +1327,19 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
 
 error:
 	brcmf_dbg(ERROR, "failed!\n");
-	brcmf_usb_detach(&devinfo->bus_pub);
+	brcmf_usb_detach(devinfo);
 	return NULL;
 }
 
-static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
-				u32 bustype, u32 hdrlen)
+static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
+			      const char *desc,	u32 bustype, u32 hdrlen)
 {
 	struct brcmf_bus *bus = NULL;
 	struct brcmf_usbdev *bus_pub = NULL;
 	int ret;
+	struct device *dev = devinfo->dev;
 
-
-	bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
+	bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
 	if (!bus_pub) {
 		ret = -ENODEV;
 		goto fail;
@@ -1417,23 +1378,21 @@ static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
 	return 0;
 fail:
 	/* Release resources in reverse order */
-	if (bus_pub)
-		brcmf_usb_detach(bus_pub);
 	kfree(bus);
+	brcmf_usb_detach(devinfo);
 	return ret;
 }
 
 static void
-brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
+brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
 {
-	if (!bus_pub)
+	if (!devinfo)
 		return;
-	brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);
-
-	brcmf_detach(bus_pub->devinfo->dev);
-	kfree(bus_pub->bus);
-	brcmf_usb_detach(bus_pub);
+	brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo);
 
+	brcmf_detach(devinfo->dev);
+	kfree(devinfo->bus_pub.bus);
+	brcmf_usb_detach(devinfo);
 }
 
 static int
@@ -1445,18 +1404,18 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	struct usb_device *usb = interface_to_usbdev(intf);
 	int num_of_eps;
 	u8 endpoint_num;
+	struct brcmf_usbdev_info *devinfo;
 
 	brcmf_dbg(TRACE, "enter\n");
 
-	usbdev_probe_info.usb = usb;
-	usbdev_probe_info.intf = intf;
+	devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
+	if (devinfo == NULL)
+		return -ENOMEM;
 
-	if (id != NULL) {
-		usbdev_probe_info.vid = id->idVendor;
-		usbdev_probe_info.pid = id->idProduct;
-	}
+	devinfo->usbdev = usb;
+	devinfo->dev = &usb->dev;
 
-	usb_set_intfdata(intf, &usbdev_probe_info);
+	usb_set_intfdata(intf, devinfo);
 
 	/* Check that the device supports only one configuration */
 	if (usb->descriptor.bNumConfigurations != 1) {
@@ -1505,11 +1464,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	}
 
 	endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
-	usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num);
+	devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
 
-	usbdev_probe_info.rx_pipe = 0;
-	usbdev_probe_info.rx_pipe2 = 0;
-	usbdev_probe_info.tx_pipe = 0;
+	devinfo->rx_pipe = 0;
+	devinfo->rx_pipe2 = 0;
+	devinfo->tx_pipe = 0;
 	num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
 
 	/* Check data endpoints and get pipes */
@@ -1526,35 +1485,33 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 			       USB_ENDPOINT_NUMBER_MASK;
 		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
 			== USB_DIR_IN) {
-			if (!usbdev_probe_info.rx_pipe) {
-				usbdev_probe_info.rx_pipe =
+			if (!devinfo->rx_pipe) {
+				devinfo->rx_pipe =
 					usb_rcvbulkpipe(usb, endpoint_num);
 			} else {
-				usbdev_probe_info.rx_pipe2 =
+				devinfo->rx_pipe2 =
 					usb_rcvbulkpipe(usb, endpoint_num);
 			}
 		} else {
-			usbdev_probe_info.tx_pipe =
-					usb_sndbulkpipe(usb, endpoint_num);
+			devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num);
 		}
 	}
 
 	/* Allocate interrupt URB and data buffer */
 	/* RNDIS says 8-byte intr, our old drivers used 4-byte */
 	if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
-		usbdev_probe_info.intr_size = 8;
+		devinfo->intr_size = 8;
 	else
-		usbdev_probe_info.intr_size = 4;
+		devinfo->intr_size = 4;
 
-	usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
+	devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
 
-	usbdev_probe_info.device_speed = usb->speed;
 	if (usb->speed == USB_SPEED_HIGH)
 		brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
 	else
 		brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
 
-	ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0);
+	ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0);
 	if (ret)
 		goto fail;
 
@@ -1563,6 +1520,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
 fail:
 	brcmf_dbg(ERROR, "failed with errno %d\n", ret);
+	kfree(devinfo);
 	usb_set_intfdata(intf, NULL);
 	return ret;
 
@@ -1571,11 +1529,12 @@ fail:
 static void
 brcmf_usb_disconnect(struct usb_interface *intf)
 {
-	struct usb_device *usb = interface_to_usbdev(intf);
+	struct brcmf_usbdev_info *devinfo;
 
 	brcmf_dbg(TRACE, "enter\n");
-	brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev));
-	usb_set_intfdata(intf, NULL);
+	devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
+	brcmf_usb_disconnect_cb(devinfo);
+	kfree(devinfo);
 }
 
 /*
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 10/10] brcmfmac: add e-scan support.
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (8 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 09/10] brcmfmac: avoid using local usb data Arend van Spriel
@ 2012-09-10 13:16 ` Arend van Spriel
  2012-09-10 20:59 ` [PATCH 00/10] brcmfmac: transmit flow control and " Arend van Spriel
  2012-09-11 18:49 ` Arend van Spriel
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 13:16 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Hante Meuleman, Arend van Spriel

From: Hante Meuleman <meuleman@broadcom.com>

This patch adds e-scan support (currently i-scan is in use). E-scan
is a more powerful and memory efficient method for scanning. E-scan
will be the default scan method and eventually, i-scan support will
be removed. The scan methods do not make any difference to the end-user.

Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
 drivers/net/wireless/brcm80211/Kconfig             |    8 +
 drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |   22 +
 .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |    8 +-
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |  522 +++++++++++++++++++-
 .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |   25 +
 5 files changed, 583 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index b480088..c9d811e 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -55,6 +55,14 @@ config BRCMFMAC_USB
 	  IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
 	  use the driver for an USB wireless card.
 
+config BRCMISCAN
+	bool "Broadcom I-Scan (OBSOLETE)"
+	depends on BRCMFMAC
+	---help---
+	  This option enables the I-Scan method. By default fullmac uses the
+	  new E-Scan method which uses less memory in firmware and gives no
+	  limitation on the number of scan results.
+
 config BRCMDBG
 	bool "Broadcom driver debug functions"
 	depends on BRCMSMAC || BRCMFMAC
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 9e2fb5b..4766d9f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -130,6 +130,10 @@
 #define BRCMF_EVENT_MSG_FLUSHTXQ	0x02
 #define BRCMF_EVENT_MSG_GROUP		0x04
 
+#define BRCMF_ESCAN_REQ_VERSION 1
+
+#define WLC_BSS_RSSI_ON_CHANNEL		0x0002
+
 struct brcmf_event_msg {
 	__be16 version;
 	__be16 flags;
@@ -456,6 +460,24 @@ struct brcmf_scan_results_le {
 	__le32 count;
 };
 
+struct brcmf_escan_params_le {
+	__le32 version;
+	__le16 action;
+	__le16 sync_id;
+	struct brcmf_scan_params_le params_le;
+};
+
+struct brcmf_escan_result_le {
+	__le32 buflen;
+	__le32 version;
+	__le16 sync_id;
+	__le16 bss_count;
+	struct brcmf_bss_info_le bss_info_le;
+};
+
+#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
+	sizeof(struct brcmf_bss_info_le))
+
 /* used for association with a specific BSSID and chanspec list */
 struct brcmf_assoc_params_le {
 	/* 00:00:00:00:00:00: broadcast scan */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 6f70953..8121dba 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -205,7 +205,8 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
 		BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
 		BRCMF_E_IF, "IF"}, {
 		BRCMF_E_RSSI, "RSSI"}, {
-		BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
+		BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
+		BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"}
 	};
 	uint event_type, flags, auth_type, datalen;
 	static u32 seqnum_prev;
@@ -350,6 +351,11 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
 		brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
 		break;
 
+	case BRCMF_E_ESCAN_RESULT:
+		brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
+		datalen = 0;
+		break;
+
 	case BRCMF_E_PFN_NET_FOUND:
 	case BRCMF_E_PFN_NET_LOST:
 	case BRCMF_E_PFN_SCAN_COMPLETE:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 6623f48..32ee052 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -693,11 +693,342 @@ scan_out:
 	return err;
 }
 
+static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
+			     struct cfg80211_scan_request *request)
+{
+	u32 n_ssids;
+	u32 n_channels;
+	s32 i;
+	s32 offset;
+	__le16 chanspec;
+	u16 channel;
+	struct ieee80211_channel *req_channel;
+	char *ptr;
+	struct brcmf_ssid ssid;
+
+	memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
+	params_le->bss_type = DOT11_BSSTYPE_ANY;
+	params_le->scan_type = 0;
+	params_le->channel_num = 0;
+	params_le->nprobes = cpu_to_le32(-1);
+	params_le->active_time = cpu_to_le32(-1);
+	params_le->passive_time = cpu_to_le32(-1);
+	params_le->home_time = cpu_to_le32(-1);
+	memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
+
+	/* if request is null exit so it will be all channel broadcast scan */
+	if (!request)
+		return;
+
+	n_ssids = request->n_ssids;
+	n_channels = request->n_channels;
+	/* Copy channel array if applicable */
+	WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
+	if (n_channels > 0) {
+		for (i = 0; i < n_channels; i++) {
+			chanspec = 0;
+			req_channel = request->channels[i];
+			channel = ieee80211_frequency_to_channel(
+					req_channel->center_freq);
+			if (req_channel->band == IEEE80211_BAND_2GHZ)
+				chanspec |= WL_CHANSPEC_BAND_2G;
+			else
+				chanspec |= WL_CHANSPEC_BAND_5G;
+
+			if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
+				chanspec |= WL_CHANSPEC_BW_20;
+				chanspec |= WL_CHANSPEC_CTL_SB_NONE;
+			} else {
+				chanspec |= WL_CHANSPEC_BW_40;
+				if (req_channel->flags &
+						IEEE80211_CHAN_NO_HT40PLUS)
+					chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
+				else
+					chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
+			}
+
+			params_le->channel_list[i] =
+				(channel & WL_CHANSPEC_CHAN_MASK) |
+				chanspec;
+			WL_SCAN("Chan : %d, Channel spec: %x\n",
+				channel, params_le->channel_list[i]);
+			params_le->channel_list[i] =
+				cpu_to_le16(params_le->channel_list[i]);
+		}
+	} else {
+		WL_SCAN("Scanning all channels\n");
+	}
+	/* Copy ssid array if applicable */
+	WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
+	if (n_ssids > 0) {
+		offset = offsetof(struct brcmf_scan_params_le, channel_list) +
+				n_channels * sizeof(u16);
+		offset = roundup(offset, sizeof(u32));
+		ptr = (char *)params_le + offset;
+		for (i = 0; i < n_ssids; i++) {
+			memset(&ssid, 0, sizeof(ssid));
+			ssid.SSID_len = cpu_to_le32(request->ssids[i].ssid_len);
+			memcpy(ssid.SSID, request->ssids[i].ssid,
+					request->ssids[i].ssid_len);
+			if (!ssid.SSID_len)
+				WL_SCAN("%d: Broadcast scan\n", i);
+			else
+				WL_SCAN("%d: scan for  %s size =%d\n", i,
+				ssid.SSID, ssid.SSID_len);
+			memcpy(ptr, &ssid, sizeof(ssid));
+			ptr += sizeof(ssid);
+		}
+	} else {
+		WL_SCAN("Broadcast scan %p\n", request->ssids);
+		if ((request->ssids) && request->ssids->ssid_len) {
+			WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
+				request->ssids->ssid_len);
+			params_le->ssid_le.SSID_len =
+				cpu_to_le32(request->ssids->ssid_len);
+			memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
+				request->ssids->ssid_len);
+		}
+	}
+	/* Adding mask to channel numbers */
+	params_le->channel_num =
+		cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
+			(n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
+}
+
+static s32
+brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
+			    struct net_device *ndev,
+			    bool aborted, bool fw_abort)
+{
+	struct brcmf_scan_params_le params_le;
+	struct cfg80211_scan_request *scan_request;
+	s32 err = 0;
+
+	WL_SCAN("Enter\n");
+
+	/* clear scan request, because the FW abort can cause a second call */
+	/* to this functon and might cause a double cfg80211_scan_done      */
+	scan_request = cfg_priv->scan_request;
+	cfg_priv->scan_request = NULL;
+
+	if (timer_pending(&cfg_priv->escan_timeout))
+		del_timer_sync(&cfg_priv->escan_timeout);
+
+	if (fw_abort) {
+		/* Do a scan abort to stop the driver's scan engine */
+		WL_SCAN("ABORT scan in firmware\n");
+		memset(&params_le, 0, sizeof(params_le));
+		memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
+		params_le.bss_type = DOT11_BSSTYPE_ANY;
+		params_le.scan_type = 0;
+		params_le.channel_num = cpu_to_le32(1);
+		params_le.nprobes = cpu_to_le32(1);
+		params_le.active_time = cpu_to_le32(-1);
+		params_le.passive_time = cpu_to_le32(-1);
+		params_le.home_time = cpu_to_le32(-1);
+		/* Scan is aborted by setting channel_list[0] to -1 */
+		params_le.channel_list[0] = cpu_to_le16(-1);
+		/* E-Scan (or anyother type) can be aborted by SCAN */
+		err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &params_le,
+			sizeof(params_le));
+		if (err)
+			WL_ERR("Scan abort  failed\n");
+	}
+	if (scan_request) {
+		WL_SCAN("ESCAN Completed scan: %s\n",
+				aborted ? "Aborted" : "Done");
+		cfg80211_scan_done(scan_request, aborted);
+		brcmf_set_mpc(ndev, 1);
+	}
+	if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
+		WL_ERR("Scan complete while device not scanning\n");
+		return -EPERM;
+	}
+
+	return err;
+}
+
+static s32
+brcmf_run_escan(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev,
+		struct cfg80211_scan_request *request, u16 action)
+{
+	s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
+			  offsetof(struct brcmf_escan_params_le, params_le);
+	struct brcmf_escan_params_le *params;
+	s32 err = 0;
+
+	WL_SCAN("E-SCAN START\n");
+
+	if (request != NULL) {
+		/* Allocate space for populating ssids in struct */
+		params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
+
+		/* Allocate space for populating ssids in struct */
+		params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
+	}
+
+	params = kzalloc(params_size, GFP_KERNEL);
+	if (!params) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
+	brcmf_escan_prep(&params->params_le, request);
+	params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
+	params->action = cpu_to_le16(action);
+	params->sync_id = cpu_to_le16(0x1234);
+
+	err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
+			cfg_priv->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
+	if (err) {
+		if (err == -EBUSY)
+			WL_INFO("system busy : escan canceled\n");
+		else
+			WL_ERR("error (%d)\n", err);
+	}
+
+	kfree(params);
+exit:
+	return err;
+}
+
+static s32
+brcmf_do_escan(struct brcmf_cfg80211_priv *cfg_priv, struct wiphy *wiphy,
+	       struct net_device *ndev, struct cfg80211_scan_request *request)
+{
+	s32 err;
+	__le32 passive_scan;
+	struct brcmf_scan_results *results;
+
+	WL_SCAN("Enter\n");
+	cfg_priv->escan_info.ndev = ndev;
+	cfg_priv->escan_info.wiphy = wiphy;
+	cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
+	passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
+	err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
+			&passive_scan, sizeof(passive_scan));
+	if (err) {
+		WL_ERR("error (%d)\n", err);
+		return err;
+	}
+	brcmf_set_mpc(ndev, 0);
+	results = (struct brcmf_scan_results *)cfg_priv->escan_info.escan_buf;
+	results->version = 0;
+	results->count = 0;
+	results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
+
+	err = brcmf_run_escan(cfg_priv, ndev, request, WL_ESCAN_ACTION_START);
+	if (err)
+		brcmf_set_mpc(ndev, 1);
+	return err;
+}
+
+static s32
+brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
+		     struct cfg80211_scan_request *request,
+		     struct cfg80211_ssid *this_ssid)
+{
+	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
+	struct cfg80211_ssid *ssids;
+	struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
+	__le32 passive_scan;
+	bool escan_req;
+	bool spec_scan;
+	s32 err;
+	u32 SSID_len;
+
+	WL_SCAN("START ESCAN\n");
+
+	if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
+		WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
+		return -EAGAIN;
+	}
+	if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
+		WL_ERR("Scanning being aborted : status (%lu)\n",
+		       cfg_priv->status);
+		return -EAGAIN;
+	}
+	if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
+		WL_ERR("Connecting : status (%lu)\n",
+		       cfg_priv->status);
+		return -EAGAIN;
+	}
+
+	/* Arm scan timeout timer */
+	mod_timer(&cfg_priv->escan_timeout, jiffies +
+			WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
+
+	escan_req = false;
+	if (request) {
+		/* scan bss */
+		ssids = request->ssids;
+		escan_req = true;
+	} else {
+		/* scan in ibss */
+		/* we don't do escan in ibss */
+		ssids = this_ssid;
+	}
+
+	cfg_priv->scan_request = request;
+	set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
+	if (escan_req) {
+		err = brcmf_do_escan(cfg_priv, wiphy, ndev, request);
+		if (!err)
+			return err;
+		else
+			goto scan_out;
+	} else {
+		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
+		       ssids->ssid, ssids->ssid_len);
+		memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
+		SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
+		sr->ssid_le.SSID_len = cpu_to_le32(0);
+		spec_scan = false;
+		if (SSID_len) {
+			memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
+			sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
+			spec_scan = true;
+		} else
+			WL_SCAN("Broadcast scan\n");
+
+		passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
+		err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
+				&passive_scan, sizeof(passive_scan));
+		if (err) {
+			WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
+			goto scan_out;
+		}
+		brcmf_set_mpc(ndev, 0);
+		err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
+				      sizeof(sr->ssid_le));
+		if (err) {
+			if (err == -EBUSY)
+				WL_INFO("BUSY: scan for \"%s\" canceled\n",
+					sr->ssid_le.SSID);
+			else
+				WL_ERR("WLC_SCAN error (%d)\n", err);
+
+			brcmf_set_mpc(ndev, 1);
+			goto scan_out;
+		}
+	}
+
+	return 0;
+
+scan_out:
+	clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
+	if (timer_pending(&cfg_priv->escan_timeout))
+		del_timer_sync(&cfg_priv->escan_timeout);
+	cfg_priv->scan_request = NULL;
+	return err;
+}
+
 static s32
 brcmf_cfg80211_scan(struct wiphy *wiphy,
 		 struct cfg80211_scan_request *request)
 {
 	struct net_device *ndev = request->wdev->netdev;
+	struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
 	s32 err = 0;
 
 	WL_TRACE("Enter\n");
@@ -705,7 +1036,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
 	if (!check_sys_up(wiphy))
 		return -EIO;
 
-	err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
+	if (cfg_priv->iscan_on)
+		err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
+	else if (cfg_priv->escan_on)
+		err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
+
 	if (err)
 		WL_ERR("scan error (%d)\n", err);
 
@@ -2474,6 +2809,175 @@ static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
 	return err;
 }
 
+static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
+{
+	struct brcmf_cfg80211_priv *cfg_priv =
+			container_of(work, struct brcmf_cfg80211_priv,
+				     escan_timeout_work);
+
+	brcmf_notify_escan_complete(cfg_priv,
+		cfg_priv->escan_info.ndev, true, true);
+}
+
+static void brcmf_escan_timeout(unsigned long data)
+{
+	struct brcmf_cfg80211_priv *cfg_priv =
+			(struct brcmf_cfg80211_priv *)data;
+
+	if (cfg_priv->scan_request) {
+		WL_ERR("timer expired\n");
+		if (cfg_priv->escan_on)
+			schedule_work(&cfg_priv->escan_timeout_work);
+	}
+}
+
+static s32
+brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
+			      struct brcmf_bss_info_le *bss_info_le)
+{
+	if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
+		(CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
+		CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
+		bss_info_le->SSID_len == bss->SSID_len &&
+		!memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
+		if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
+			(bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
+			/* preserve max RSSI if the measurements are
+			* both on-channel or both off-channel
+			*/
+			if (bss_info_le->RSSI > bss->RSSI)
+				bss->RSSI = bss_info_le->RSSI;
+		} else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
+			(bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
+			/* preserve the on-channel rssi measurement
+			* if the new measurement is off channel
+			*/
+			bss->RSSI = bss_info_le->RSSI;
+			bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
+		}
+		return 1;
+	}
+	return 0;
+}
+
+static s32
+brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
+			     struct net_device *ndev,
+			     const struct brcmf_event_msg *e, void *data)
+{
+	s32 status;
+	s32 err = 0;
+	struct brcmf_escan_result_le *escan_result_le;
+	struct brcmf_bss_info_le *bss_info_le;
+	struct brcmf_bss_info_le *bss = NULL;
+	u32 bi_length;
+	struct brcmf_scan_results *list;
+	u32 i;
+
+	status = be32_to_cpu(e->status);
+
+	if (!ndev || !cfg_priv->escan_on ||
+			!test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
+		WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
+			ndev, cfg_priv->escan_on,
+			!test_bit(WL_STATUS_SCANNING, &cfg_priv->status));
+		return -EPERM;
+	}
+
+	if (status == BRCMF_E_STATUS_PARTIAL) {
+		WL_SCAN("ESCAN Partial result\n");
+		escan_result_le = (struct brcmf_escan_result_le *) data;
+		if (!escan_result_le) {
+			WL_ERR("Invalid escan result (NULL pointer)\n");
+			goto exit;
+		}
+		if (!cfg_priv->scan_request) {
+			WL_SCAN("result without cfg80211 request\n");
+			goto exit;
+		}
+
+		if (le16_to_cpu(escan_result_le->bss_count) != 1) {
+			WL_ERR("Invalid bss_count %d: ignoring\n",
+				escan_result_le->bss_count);
+			goto exit;
+		}
+		bss_info_le = &escan_result_le->bss_info_le;
+
+		bi_length = le32_to_cpu(bss_info_le->length);
+		if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
+					WL_ESCAN_RESULTS_FIXED_SIZE)) {
+			WL_ERR("Invalid bss_info length %d: ignoring\n",
+				bi_length);
+			goto exit;
+		}
+
+		if (!(cfg_to_wiphy(cfg_priv)->interface_modes &
+					BIT(NL80211_IFTYPE_ADHOC))) {
+			if (le16_to_cpu(bss_info_le->capability) &
+						WLAN_CAPABILITY_IBSS) {
+				WL_ERR("Ignoring IBSS result\n");
+				goto exit;
+			}
+		}
+
+		list = (struct brcmf_scan_results *)
+				cfg_priv->escan_info.escan_buf;
+		if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
+			WL_ERR("Buffer is too small: ignoring\n");
+			goto exit;
+		}
+
+		for (i = 0; i < list->count; i++) {
+			bss = bss ? (struct brcmf_bss_info_le *)
+				((unsigned char *)bss +
+				le32_to_cpu(bss->length)) : list->bss_info_le;
+			if (brcmf_compare_update_same_bss(bss, bss_info_le))
+				goto exit;
+		}
+		memcpy(&(cfg_priv->escan_info.escan_buf[list->buflen]),
+			bss_info_le, bi_length);
+		list->version = le32_to_cpu(bss_info_le->version);
+		list->buflen += bi_length;
+		list->count++;
+	} else {
+		cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+		if (cfg_priv->scan_request) {
+			cfg_priv->bss_list = (struct brcmf_scan_results *)
+				cfg_priv->escan_info.escan_buf;
+			brcmf_inform_bss(cfg_priv);
+			if (status == BRCMF_E_STATUS_SUCCESS) {
+				WL_SCAN("ESCAN Completed\n");
+				brcmf_notify_escan_complete(cfg_priv, ndev,
+					false, false);
+			} else {
+				WL_ERR("ESCAN Aborted, Event 0x%x\n", status);
+				brcmf_notify_escan_complete(cfg_priv, ndev,
+					true, false);
+			}
+			brcmf_set_mpc(ndev, 1);
+		} else
+			WL_ERR("Unexpected scan result 0x%x\n", status);
+	}
+exit:
+	return err;
+}
+
+static void brcmf_init_escan(struct brcmf_cfg80211_priv *cfg_priv)
+{
+
+	if (cfg_priv->escan_on) {
+		cfg_priv->el.handler[BRCMF_E_ESCAN_RESULT] =
+			brcmf_cfg80211_escan_handler;
+		cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+		/* Init scan_timeout timer */
+		init_timer(&cfg_priv->escan_timeout);
+		cfg_priv->escan_timeout.data = (unsigned long) cfg_priv;
+		cfg_priv->escan_timeout.function = brcmf_escan_timeout;
+		INIT_WORK(&cfg_priv->escan_timeout_work,
+			brcmf_cfg80211_escan_timeout_worker);
+	}
+}
+
 static __always_inline void brcmf_delay(u32 ms)
 {
 	if (ms < 1000 / HZ) {
@@ -3242,6 +3746,8 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
 	cfg_priv->profile = NULL;
 	kfree(cfg_priv->scan_req_int);
 	cfg_priv->scan_req_int = NULL;
+	kfree(cfg_priv->escan_ioctl_buf);
+	cfg_priv->escan_ioctl_buf = NULL;
 	kfree(cfg_priv->dcmd_buf);
 	cfg_priv->dcmd_buf = NULL;
 	kfree(cfg_priv->extra_buf);
@@ -3270,6 +3776,9 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
 					 GFP_KERNEL);
 	if (!cfg_priv->scan_req_int)
 		goto init_priv_mem_out;
+	cfg_priv->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
+	if (!cfg_priv->escan_ioctl_buf)
+		goto init_priv_mem_out;
 	cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
 	if (!cfg_priv->dcmd_buf)
 		goto init_priv_mem_out;
@@ -3406,8 +3915,17 @@ static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
 
 	cfg_priv->scan_request = NULL;
 	cfg_priv->pwr_save = true;
+#ifdef CONFIG_BRCMISCAN
 	cfg_priv->iscan_on = true;	/* iscan on & off switch.
 				 we enable iscan per default */
+	cfg_priv->escan_on = false;	/* escan on & off switch.
+				 we disable escan per default */
+#else
+	cfg_priv->iscan_on = false;	/* iscan on & off switch.
+				 we disable iscan per default */
+	cfg_priv->escan_on = true;	/* escan on & off switch.
+				 we enable escan per default */
+#endif
 	cfg_priv->roam_on = true;	/* roam on & off switch.
 				 we enable roam per default */
 
@@ -3425,6 +3943,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
 	err = brcmf_init_iscan(cfg_priv);
 	if (err)
 		return err;
+	brcmf_init_escan(cfg_priv);
 	brcmf_init_conf(cfg_priv->conf);
 	brcmf_init_prof(cfg_priv->profile);
 	brcmf_link_down(cfg_priv);
@@ -3583,6 +4102,7 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
 	setbit(eventmask, BRCMF_E_TXFAIL);
 	setbit(eventmask, BRCMF_E_JOIN_START);
 	setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
+	setbit(eventmask, BRCMF_E_ESCAN_RESULT);
 
 	brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
 			iovbuf, sizeof(iovbuf));
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index b5d9b36..3b21297 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -123,6 +123,13 @@ do {								\
 #define WL_SCAN_UNASSOC_TIME		40
 #define WL_SCAN_PASSIVE_TIME		120
 
+#define WL_ESCAN_BUF_SIZE		(1024 * 64)
+#define WL_ESCAN_TIMER_INTERVAL_MS	8000 /* E-Scan timeout */
+
+#define WL_ESCAN_ACTION_START		1
+#define WL_ESCAN_ACTION_CONTINUE	2
+#define WL_ESCAN_ACTION_ABORT		3
+
 /* dongle status */
 enum wl_status {
 	WL_STATUS_READY,
@@ -275,6 +282,19 @@ struct brcmf_cfg80211_pmk_list {
 	struct pmkid foo[MAXPMKID - 1];
 };
 
+/* dongle escan state */
+enum wl_escan_state {
+	WL_ESCAN_STATE_IDLE,
+	WL_ESCAN_STATE_SCANNING
+};
+
+struct escan_info {
+	u32 escan_state;
+	u8 escan_buf[WL_ESCAN_BUF_SIZE];
+	struct wiphy *wiphy;
+	struct net_device *ndev;
+};
+
 /* dongle private data of cfg80211 interface */
 struct brcmf_cfg80211_priv {
 	struct wireless_dev *wdev;	/* representing wl cfg80211 device */
@@ -315,6 +335,11 @@ struct brcmf_cfg80211_priv {
 	u8 *dcmd_buf;		/* dcmd buffer */
 	u8 *extra_buf;		/* maily to grab assoc information */
 	struct dentry *debugfsdir;
+	bool escan_on;		/* escan on/off switch */
+	struct escan_info escan_info;   /* escan information */
+	struct timer_list escan_timeout;   /* Timer for catch scan timeout */
+	struct work_struct escan_timeout_work;	/* scan timeout worker */
+	u8 *escan_ioctl_buf;
 	u8 ci[0] __aligned(NETDEV_ALIGN);
 };
 
-- 
1.7.9.5



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 03/10] brcmfmac: Fix extra data support handling.
  2012-09-10 13:16 ` [PATCH 03/10] brcmfmac: Fix extra data support handling Arend van Spriel
@ 2012-09-10 16:37   ` Florian Fainelli
  0 siblings, 0 replies; 16+ messages in thread
From: Florian Fainelli @ 2012-09-10 16:37 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: John W. Linville, Linux Wireless List, Hante Meuleman

Hello,

On Monday 10 September 2012 15:16:51 Arend van Spriel wrote:
> From: Hante Meuleman <meuleman@broadcom.com>
> 
> This patch fixes bug in length calculation.
> 
> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
> Reviewed-by: Arend Van Spriel <arend@broadcom.com>
> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
> Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>
> ---
>  .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 
b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
> index 6383052..4553fa0 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
> @@ -3331,7 +3331,7 @@ brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, 
u32 event,
>  
>  	total_len = sizeof(struct brcmf_cfg80211_event_q);
>  	if (data)
> -		data_len += be32_to_cpu(msg->datalen);
> +		data_len = be32_to_cpu(msg->datalen);

This should be folded in patch 2/10 since this is where the bug gets 
introduced.
--
Florian

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 06/10] brcmfmac: fix big endian bug in i-scan.
  2012-09-10 13:16 ` [PATCH 06/10] brcmfmac: fix big endian bug in i-scan Arend van Spriel
@ 2012-09-10 16:37   ` Florian Fainelli
  0 siblings, 0 replies; 16+ messages in thread
From: Florian Fainelli @ 2012-09-10 16:37 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: John W. Linville, Linux Wireless List, Hante Meuleman

Hello,

On Monday 10 September 2012 15:16:54 Arend van Spriel wrote:
> From: Hante Meuleman <meuleman@broadcom.com>
> 
> ssid len is 32 bit and needs endian conversion for big endian systems.
> 
> Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>

This looks like a candidate for stable.

> ---
>  .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |    6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c 
b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
> index 4a27ca0..6623f48 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
> @@ -501,8 +501,10 @@ static void brcmf_iscan_prep(struct 
brcmf_scan_params_le *params_le,
>  	params_le->active_time = cpu_to_le32(-1);
>  	params_le->passive_time = cpu_to_le32(-1);
>  	params_le->home_time = cpu_to_le32(-1);
> -	if (ssid && ssid->SSID_len)
> -		memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
> +	if (ssid && ssid->SSID_len) {
> +		params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
> +		memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
> +	}
>  }
>  
>  static s32
> -- 
> 1.7.9.5
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 07/10] brcmfmac: Fix big endian host configuration data.
  2012-09-10 13:16 ` [PATCH 07/10] brcmfmac: Fix big endian host configuration data Arend van Spriel
@ 2012-09-10 16:38   ` Florian Fainelli
  0 siblings, 0 replies; 16+ messages in thread
From: Florian Fainelli @ 2012-09-10 16:38 UTC (permalink / raw)
  To: Arend van Spriel; +Cc: John W. Linville, Linux Wireless List, Hante Meuleman

On Monday 10 September 2012 15:16:55 Arend van Spriel wrote:
> From: Hante Meuleman <meuleman@broadcom.com>
> 
> Fixes big endian host configuration parameters.
> 
> Reviewed-by: Arend Van Spriel <arend@broadcom.com>
> Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
> Signed-off-by: Arend van Spriel <arend@broadcom.com>

This one too looks like a stable candidate.

> ---
>  .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |   26 
++++++++++++--------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c 
b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
> index 2621dd3..6f70953 100644
> --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
> +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
> @@ -764,8 +764,11 @@ static void brcmf_c_arp_offload_set(struct brcmf_pub 
*drvr, int arp_mode)
>  {
>  	char iovbuf[32];
>  	int retcode;
> +	__le32 arp_mode_le;
>  
> -	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
> +	arp_mode_le = cpu_to_le32(arp_mode);
> +	brcmf_c_mkiovar("arp_ol", (char *)&arp_mode_le, 4, iovbuf,
> +			sizeof(iovbuf));
>  	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
>  				   iovbuf, sizeof(iovbuf));
>  	retcode = retcode >= 0 ? 0 : retcode;
> @@ -781,8 +784,11 @@ static void brcmf_c_arp_offload_enable(struct brcmf_pub 
*drvr, int arp_enable)
>  {
>  	char iovbuf[32];
>  	int retcode;
> +	__le32 arp_enable_le;
>  
> -	brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
> +	arp_enable_le = cpu_to_le32(arp_enable);
> +
> +	brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4,
>  			iovbuf, sizeof(iovbuf));
>  	retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
>  				   iovbuf, sizeof(iovbuf));
> @@ -800,10 +806,10 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
>  	char iovbuf[BRCMF_EVENTING_MASK_LEN + 12];	/*  Room for
>  				 "event_msgs" + '\0' + bitvec  */
>  	char buf[128], *ptr;
> -	u32 roaming = 1;
> -	uint bcn_timeout = 3;
> -	int scan_assoc_time = 40;
> -	int scan_unassoc_time = 40;
> +	__le32 roaming_le = cpu_to_le32(1);
> +	__le32 bcn_timeout_le = cpu_to_le32(3);
> +	__le32 scan_assoc_time_le = cpu_to_le32(40);
> +	__le32 scan_unassoc_time_le = cpu_to_le32(40);
>  	int i;
>  	struct brcmf_bus_dcmd *cmdlst;
>  	struct list_head *cur, *q;
> @@ -829,14 +835,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
>  
>  	/* Setup timeout if Beacons are lost and roam is off to report
>  		 link down */
> -	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
> +	brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf,
>  		    sizeof(iovbuf));
>  	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
>  				  sizeof(iovbuf));
>  
>  	/* Enable/Disable build-in roaming to allowed ext supplicant to take
>  		 of romaing */
> -	brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
> +	brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4,
>  		      iovbuf, sizeof(iovbuf));
>  	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
>  				  sizeof(iovbuf));
> @@ -848,9 +854,9 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
>  				  sizeof(iovbuf));
>  
>  	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
> -			 (char *)&scan_assoc_time, sizeof(scan_assoc_time));
> +		 (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le));
>  	brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
> -			 (char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
> +		 (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le));
>  
>  	/* Set and enable ARP offload feature */
>  	brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
> -- 
> 1.7.9.5
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 00/10] brcmfmac: transmit flow control and e-scan support
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (9 preceding siblings ...)
  2012-09-10 13:16 ` [PATCH 10/10] brcmfmac: add e-scan support Arend van Spriel
@ 2012-09-10 20:59 ` Arend van Spriel
  2012-09-11 18:49 ` Arend van Spriel
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-10 20:59 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Florian Fainelli

On 09/10/2012 03:16 PM, Arend van Spriel wrote:
> This series contains transmit flow control handling when the brcmfmac driver
> has no resources to transfer packets over the host interface. This improves
> throughput number for TCP. The other feature in this series is event based
> scanning in which firmware sends an event per BSS.
>
> The other changes in this series are small fixes.
>
> This series is for the v3.7 kernel and applies to the wireless-next tree.
>
> Hante Meuleman (10):
>    brcmfmac: Stop all net if queues on tx flow halt.
>    brcmfmac: Add extra data support to firmware event queueing.
>    brcmfmac: Fix extra data support handling.
>    brcmfmac: Add tx flow control on net if queue for USB.
>    brcmfmac: Clean up scan related code.

>    brcmfmac: fix big endian bug in i-scan.
>    brcmfmac: Fix big endian host configuration data.

Hi John,

Florian indicated that these are stable candidates. Do you agree? If so,
I will take them out of this series and resend the patches.

Gr. AvS

>    brcmfmac: refill buffers on rx protocol error.
>    brcmfmac: avoid using local usb data.
>    brcmfmac: add e-scan support.
>
>   drivers/net/wireless/brcm80211/Kconfig             |    8 +
>   drivers/net/wireless/brcm80211/brcmfmac/dhd.h      |   24 +
>   drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h  |    2 +-
>   .../net/wireless/brcm80211/brcmfmac/dhd_common.c   |   34 +-
>   .../net/wireless/brcm80211/brcmfmac/dhd_linux.c    |   16 +-
>   drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c |    8 +-
>   drivers/net/wireless/brcm80211/brcmfmac/usb.c      |  184 +++----
>   .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c  |  564 +++++++++++++++++++-
>   .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h  |   25 +
>   9 files changed, 717 insertions(+), 148 deletions(-)
>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 00/10] brcmfmac: transmit flow control and e-scan support
  2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
                   ` (10 preceding siblings ...)
  2012-09-10 20:59 ` [PATCH 00/10] brcmfmac: transmit flow control and " Arend van Spriel
@ 2012-09-11 18:49 ` Arend van Spriel
  11 siblings, 0 replies; 16+ messages in thread
From: Arend van Spriel @ 2012-09-11 18:49 UTC (permalink / raw)
  To: John W. Linville; +Cc: Linux Wireless List, Florian Fainelli

On 09/10/2012 03:16 PM, Arend van Spriel wrote:
> This series contains transmit flow control handling when the brcmfmac driver
> has no resources to transfer packets over the host interface. This improves
> throughput number for TCP. The other feature in this series is event based
> scanning in which firmware sends an event per BSS.
>
> The other changes in this series are small fixes.
>
> This series is for the v3.7 kernel and applies to the wireless-next tree.

Hi John,

Please drop this series. I will resent it to address the comments made 
by Florian.

Gr. AvS


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2012-09-11 18:49 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-10 13:16 [PATCH 00/10] brcmfmac: transmit flow control and e-scan support Arend van Spriel
2012-09-10 13:16 ` [PATCH 01/10] brcmfmac: Stop all net if queues on tx flow halt Arend van Spriel
2012-09-10 13:16 ` [PATCH 02/10] brcmfmac: Add extra data support to firmware event queueing Arend van Spriel
2012-09-10 13:16 ` [PATCH 03/10] brcmfmac: Fix extra data support handling Arend van Spriel
2012-09-10 16:37   ` Florian Fainelli
2012-09-10 13:16 ` [PATCH 04/10] brcmfmac: Add tx flow control on net if queue for USB Arend van Spriel
2012-09-10 13:16 ` [PATCH 05/10] brcmfmac: Clean up scan related code Arend van Spriel
2012-09-10 13:16 ` [PATCH 06/10] brcmfmac: fix big endian bug in i-scan Arend van Spriel
2012-09-10 16:37   ` Florian Fainelli
2012-09-10 13:16 ` [PATCH 07/10] brcmfmac: Fix big endian host configuration data Arend van Spriel
2012-09-10 16:38   ` Florian Fainelli
2012-09-10 13:16 ` [PATCH 08/10] brcmfmac: refill buffers on rx protocol error Arend van Spriel
2012-09-10 13:16 ` [PATCH 09/10] brcmfmac: avoid using local usb data Arend van Spriel
2012-09-10 13:16 ` [PATCH 10/10] brcmfmac: add e-scan support Arend van Spriel
2012-09-10 20:59 ` [PATCH 00/10] brcmfmac: transmit flow control and " Arend van Spriel
2012-09-11 18:49 ` Arend van Spriel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.