Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 10/21] rt2x00: rt2800pci: use rt2800mmio prefix for initialization functions
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

The functions are used for devices with memory
mapped I/O and contain no PCI specific code at
all. Use rt2800mmio prefix instead of rt2800pci
in the function names to reflect that.

The patch contains no functional changes.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index d0e4ec5..7770471 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -245,7 +245,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 /*
  * Initialization functions.
  */
-static bool rt2800pci_get_entry_state(struct queue_entry *entry)
+static bool rt2800mmio_get_entry_state(struct queue_entry *entry)
 {
 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
 	u32 word;
@@ -261,7 +261,7 @@ static bool rt2800pci_get_entry_state(struct queue_entry *entry)
 	}
 }
 
-static void rt2800pci_clear_entry(struct queue_entry *entry)
+static void rt2800mmio_clear_entry(struct queue_entry *entry)
 {
 	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
 	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
@@ -290,7 +290,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry)
 	}
 }
 
-static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
+static int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev)
 {
 	struct queue_entry_priv_mmio *entry_priv;
 
@@ -358,7 +358,7 @@ static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev)
 /*
  * Device state switch handlers.
  */
-static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev)
+static int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
 
@@ -411,7 +411,7 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 	/* Wait for DMA, ignore error until we initialize queues. */
 	rt2800_wait_wpdma_ready(rt2x00dev);
 
-	if (unlikely(rt2800pci_init_queues(rt2x00dev)))
+	if (unlikely(rt2800mmio_init_queues(rt2x00dev)))
 		return -EIO;
 
 	retval = rt2800_enable_radio(rt2x00dev);
@@ -553,7 +553,7 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
 	.read_eeprom		= rt2800pci_read_eeprom,
 	.hwcrypt_disabled	= rt2800pci_hwcrypt_disabled,
 	.drv_write_firmware	= rt2800pci_write_firmware,
-	.drv_init_registers	= rt2800pci_init_registers,
+	.drv_init_registers	= rt2800mmio_init_registers,
 	.drv_get_txwi		= rt2800mmio_get_txwi,
 };
 
@@ -570,8 +570,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
 	.load_firmware		= rt2800_load_firmware,
 	.initialize		= rt2x00mmio_initialize,
 	.uninitialize		= rt2x00mmio_uninitialize,
-	.get_entry_state	= rt2800pci_get_entry_state,
-	.clear_entry		= rt2800pci_clear_entry,
+	.get_entry_state	= rt2800mmio_get_entry_state,
+	.clear_entry		= rt2800mmio_clear_entry,
 	.set_device_state	= rt2800pci_set_device_state,
 	.rfkill_poll		= rt2800_rfkill_poll,
 	.link_stats		= rt2800_link_stats,
-- 
1.7.10

^ permalink raw reply related

* [PATCH 09/21] rt2x00: rt2800pci: move queue functions to the rt2800mmio module
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

Move the functions into a separate module, in order
to make those usable from other modules. Also move
the queue register offset macros from rt2800pci.h
into rt2800mmio.h.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800mmio.c |  137 ++++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800mmio.h |   15 ++++
 drivers/net/wireless/rt2x00/rt2800pci.c  |  133 -----------------------------
 drivers/net/wireless/rt2x00/rt2800pci.h  |    9 --
 4 files changed, 152 insertions(+), 142 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.c b/drivers/net/wireless/rt2x00/rt2800mmio.c
index bfae4f0..c42bea5 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
@@ -552,6 +552,143 @@ void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev,
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_toggle_irq);
 
+/*
+ * Queue handlers.
+ */
+void rt2800mmio_start_queue(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	switch (queue->qid) {
+	case QID_RX:
+		rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+		rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+		break;
+	case QID_BEACON:
+		rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+		rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+		rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);
+		rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);
+		break;
+	default:
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_start_queue);
+
+void rt2800mmio_kick_queue(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	struct queue_entry *entry;
+
+	switch (queue->qid) {
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		entry = rt2x00queue_get_entry(queue, Q_INDEX);
+		rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
+					  entry->entry_idx);
+		break;
+	case QID_MGMT:
+		entry = rt2x00queue_get_entry(queue, Q_INDEX);
+		rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5),
+					  entry->entry_idx);
+		break;
+	default:
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue);
+
+void rt2800mmio_stop_queue(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	u32 reg;
+
+	switch (queue->qid) {
+	case QID_RX:
+		rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
+		rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+		break;
+	case QID_BEACON:
+		rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+		rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+		rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
+		rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);
+
+		/*
+		 * Wait for current invocation to finish. The tasklet
+		 * won't be scheduled anymore afterwards since we disabled
+		 * the TBTT and PRE TBTT timer.
+		 */
+		tasklet_kill(&rt2x00dev->tbtt_tasklet);
+		tasklet_kill(&rt2x00dev->pretbtt_tasklet);
+
+		break;
+	default:
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_stop_queue);
+
+void rt2800mmio_queue_init(struct data_queue *queue)
+{
+	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
+	unsigned short txwi_size, rxwi_size;
+
+	rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size);
+
+	switch (queue->qid) {
+	case QID_RX:
+		queue->limit = 128;
+		queue->data_size = AGGREGATION_SIZE;
+		queue->desc_size = RXD_DESC_SIZE;
+		queue->winfo_size = rxwi_size;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	case QID_AC_VO:
+	case QID_AC_VI:
+	case QID_AC_BE:
+	case QID_AC_BK:
+		queue->limit = 64;
+		queue->data_size = AGGREGATION_SIZE;
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->winfo_size = txwi_size;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	case QID_BEACON:
+		queue->limit = 8;
+		queue->data_size = 0; /* No DMA required for beacons */
+		queue->desc_size = TXD_DESC_SIZE;
+		queue->winfo_size = txwi_size;
+		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
+		break;
+
+	case QID_ATIM:
+		/* fallthrough */
+	default:
+		BUG();
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_queue_init);
+
 MODULE_AUTHOR(DRV_PROJECT);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("rt2800 MMIO library");
diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.h b/drivers/net/wireless/rt2x00/rt2800mmio.h
index 30e66ab..676df2e 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
@@ -32,6 +32,15 @@
 #define RT2800MMIO_H
 
 /*
+ * Queue register offset macros
+ */
+#define TX_QUEUE_REG_OFFSET	0x10
+#define TX_BASE_PTR(__x)	(TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_MAX_CNT(__x)		(TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_CTX_IDX(__x)		(TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
+#define TX_DTX_IDX(__x)		(TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
+
+/*
  * DMA descriptor defines.
  */
 #define TXD_DESC_SIZE			(4 * sizeof(__le32))
@@ -138,4 +147,10 @@ irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance);
 void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev,
 			   enum dev_state state);
 
+/* Queue handlers */
+void rt2800mmio_start_queue(struct data_queue *queue);
+void rt2800mmio_kick_queue(struct data_queue *queue);
+void rt2800mmio_stop_queue(struct data_queue *queue);
+void rt2800mmio_queue_init(struct data_queue *queue);
+
 #endif /* RT2800MMIO_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 118f2d5..d0e4ec5 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -202,96 +202,6 @@ static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
 #endif /* CONFIG_PCI */
 
 /*
- * Queue handlers.
- */
-static void rt2800mmio_start_queue(struct data_queue *queue)
-{
-	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-	u32 reg;
-
-	switch (queue->qid) {
-	case QID_RX:
-		rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
-		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
-		rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-		break;
-	case QID_BEACON:
-		rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
-		rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
-		rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, &reg);
-		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);
-		rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);
-		break;
-	default:
-		break;
-	}
-}
-
-static void rt2800mmio_kick_queue(struct data_queue *queue)
-{
-	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-	struct queue_entry *entry;
-
-	switch (queue->qid) {
-	case QID_AC_VO:
-	case QID_AC_VI:
-	case QID_AC_BE:
-	case QID_AC_BK:
-		entry = rt2x00queue_get_entry(queue, Q_INDEX);
-		rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
-					  entry->entry_idx);
-		break;
-	case QID_MGMT:
-		entry = rt2x00queue_get_entry(queue, Q_INDEX);
-		rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5),
-					  entry->entry_idx);
-		break;
-	default:
-		break;
-	}
-}
-
-static void rt2800mmio_stop_queue(struct data_queue *queue)
-{
-	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-	u32 reg;
-
-	switch (queue->qid) {
-	case QID_RX:
-		rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
-		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
-		rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-		break;
-	case QID_BEACON:
-		rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
-		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
-		rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg);
-
-		rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, &reg);
-		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
-		rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg);
-
-		/*
-		 * Wait for current invocation to finish. The tasklet
-		 * won't be scheduled anymore afterwards since we disabled
-		 * the TBTT and PRE TBTT timer.
-		 */
-		tasklet_kill(&rt2x00dev->tbtt_tasklet);
-		tasklet_kill(&rt2x00dev->pretbtt_tasklet);
-
-		break;
-	default:
-		break;
-	}
-}
-
-/*
  * Firmware functions
  */
 static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -689,49 +599,6 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
 	.sta_remove		= rt2800_sta_remove,
 };
 
-static void rt2800mmio_queue_init(struct data_queue *queue)
-{
-	struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
-	unsigned short txwi_size, rxwi_size;
-
-	rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size);
-
-	switch (queue->qid) {
-	case QID_RX:
-		queue->limit = 128;
-		queue->data_size = AGGREGATION_SIZE;
-		queue->desc_size = RXD_DESC_SIZE;
-		queue->winfo_size = rxwi_size;
-		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
-		break;
-
-	case QID_AC_VO:
-	case QID_AC_VI:
-	case QID_AC_BE:
-	case QID_AC_BK:
-		queue->limit = 64;
-		queue->data_size = AGGREGATION_SIZE;
-		queue->desc_size = TXD_DESC_SIZE;
-		queue->winfo_size = txwi_size;
-		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
-		break;
-
-	case QID_BEACON:
-		queue->limit = 8;
-		queue->data_size = 0; /* No DMA required for beacons */
-		queue->desc_size = TXD_DESC_SIZE;
-		queue->winfo_size = txwi_size;
-		queue->priv_size = sizeof(struct queue_entry_priv_mmio);
-		break;
-
-	case QID_ATIM:
-		/* fallthrough */
-	default:
-		BUG();
-		break;
-	}
-}
-
 static const struct rt2x00_ops rt2800pci_ops = {
 	.name			= KBUILD_MODNAME,
 	.drv_data_size		= sizeof(struct rt2800_drv_data),
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h
index 0e55159..a81c9ee 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.h
+++ b/drivers/net/wireless/rt2x00/rt2800pci.h
@@ -35,15 +35,6 @@
 #define RT2800PCI_H
 
 /*
- * Queue register offset macros
- */
-#define TX_QUEUE_REG_OFFSET		0x10
-#define TX_BASE_PTR(__x)		(TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET))
-#define TX_MAX_CNT(__x)			(TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET))
-#define TX_CTX_IDX(__x)			(TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
-#define TX_DTX_IDX(__x)			(TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET))
-
-/*
  * 8051 firmware image.
  */
 #define FIRMWARE_RT2860			"rt2860.bin"
-- 
1.7.10

^ permalink raw reply related

* [PATCH 11/21] rt2x00: rt2800pci: move initialization functions to the rt2800mmio module
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

Move the functions into a separate module, in order
to make those usable from other modules.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800mmio.c |  163 ++++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800mmio.h |    6 ++
 drivers/net/wireless/rt2x00/rt2800pci.c  |  159 -----------------------------
 3 files changed, 169 insertions(+), 159 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.c b/drivers/net/wireless/rt2x00/rt2800mmio.c
index c42bea5..7e8c224 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
@@ -689,6 +689,169 @@ void rt2800mmio_queue_init(struct data_queue *queue)
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_queue_init);
 
+/*
+ * Initialization functions.
+ */
+bool rt2800mmio_get_entry_state(struct queue_entry *entry)
+{
+	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
+	u32 word;
+
+	if (entry->queue->qid == QID_RX) {
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+
+		return (!rt2x00_get_field32(word, RXD_W1_DMA_DONE));
+	} else {
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+
+		return (!rt2x00_get_field32(word, TXD_W1_DMA_DONE));
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_get_entry_state);
+
+void rt2800mmio_clear_entry(struct queue_entry *entry)
+{
+	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
+	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+	u32 word;
+
+	if (entry->queue->qid == QID_RX) {
+		rt2x00_desc_read(entry_priv->desc, 0, &word);
+		rt2x00_set_field32(&word, RXD_W0_SDP0, skbdesc->skb_dma);
+		rt2x00_desc_write(entry_priv->desc, 0, word);
+
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+		rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);
+		rt2x00_desc_write(entry_priv->desc, 1, word);
+
+		/*
+		 * Set RX IDX in register to inform hardware that we have
+		 * handled this entry and it is available for reuse again.
+		 */
+		rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX,
+					  entry->entry_idx);
+	} else {
+		rt2x00_desc_read(entry_priv->desc, 1, &word);
+		rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
+		rt2x00_desc_write(entry_priv->desc, 1, word);
+	}
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_clear_entry);
+
+int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev)
+{
+	struct queue_entry_priv_mmio *entry_priv;
+
+	/*
+	 * Initialize registers.
+	 */
+	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
+	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0,
+				  entry_priv->desc_dma);
+	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0,
+				  rt2x00dev->tx[0].limit);
+	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0);
+
+	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
+	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1,
+				  entry_priv->desc_dma);
+	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1,
+				  rt2x00dev->tx[1].limit);
+	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0);
+
+	entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
+	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2,
+				  entry_priv->desc_dma);
+	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2,
+				  rt2x00dev->tx[2].limit);
+	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0);
+
+	entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
+	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3,
+				  entry_priv->desc_dma);
+	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3,
+				  rt2x00dev->tx[3].limit);
+	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0);
+
+	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0);
+
+	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0);
+
+	entry_priv = rt2x00dev->rx->entries[0].priv_data;
+	rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR,
+				  entry_priv->desc_dma);
+	rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT,
+				  rt2x00dev->rx[0].limit);
+	rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX,
+				  rt2x00dev->rx[0].limit - 1);
+	rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0);
+
+	rt2800_disable_wpdma(rt2x00dev);
+
+	rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_init_queues);
+
+int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+	u32 reg;
+
+	/*
+	 * Reset DMA indexes
+	 */
+	rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
+	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
+	rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+
+	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+
+	if (rt2x00_is_pcie(rt2x00dev) &&
+	    (rt2x00_rt(rt2x00dev, RT3090) ||
+	     rt2x00_rt(rt2x00dev, RT3390) ||
+	     rt2x00_rt(rt2x00dev, RT3572) ||
+	     rt2x00_rt(rt2x00dev, RT3593) ||
+	     rt2x00_rt(rt2x00dev, RT5390) ||
+	     rt2x00_rt(rt2x00dev, RT5392) ||
+	     rt2x00_rt(rt2x00dev, RT5592))) {
+		rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, &reg);
+		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
+		rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
+		rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg);
+	}
+
+	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+	reg = 0;
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+	rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+	rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_init_registers);
+
 MODULE_AUTHOR(DRV_PROJECT);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("rt2800 MMIO library");
diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.h b/drivers/net/wireless/rt2x00/rt2800mmio.h
index 676df2e..392895a 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
@@ -153,4 +153,10 @@ void rt2800mmio_kick_queue(struct data_queue *queue);
 void rt2800mmio_stop_queue(struct data_queue *queue);
 void rt2800mmio_queue_init(struct data_queue *queue);
 
+/* Initialization functions */
+bool rt2800mmio_get_entry_state(struct queue_entry *entry);
+void rt2800mmio_clear_entry(struct queue_entry *entry);
+int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev);
+int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev);
+
 #endif /* RT2800MMIO_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 7770471..5ae90df6 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -243,167 +243,8 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 }
 
 /*
- * Initialization functions.
- */
-static bool rt2800mmio_get_entry_state(struct queue_entry *entry)
-{
-	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
-	u32 word;
-
-	if (entry->queue->qid == QID_RX) {
-		rt2x00_desc_read(entry_priv->desc, 1, &word);
-
-		return (!rt2x00_get_field32(word, RXD_W1_DMA_DONE));
-	} else {
-		rt2x00_desc_read(entry_priv->desc, 1, &word);
-
-		return (!rt2x00_get_field32(word, TXD_W1_DMA_DONE));
-	}
-}
-
-static void rt2800mmio_clear_entry(struct queue_entry *entry)
-{
-	struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
-	struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
-	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
-	u32 word;
-
-	if (entry->queue->qid == QID_RX) {
-		rt2x00_desc_read(entry_priv->desc, 0, &word);
-		rt2x00_set_field32(&word, RXD_W0_SDP0, skbdesc->skb_dma);
-		rt2x00_desc_write(entry_priv->desc, 0, word);
-
-		rt2x00_desc_read(entry_priv->desc, 1, &word);
-		rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0);
-		rt2x00_desc_write(entry_priv->desc, 1, word);
-
-		/*
-		 * Set RX IDX in register to inform hardware that we have
-		 * handled this entry and it is available for reuse again.
-		 */
-		rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX,
-					  entry->entry_idx);
-	} else {
-		rt2x00_desc_read(entry_priv->desc, 1, &word);
-		rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1);
-		rt2x00_desc_write(entry_priv->desc, 1, word);
-	}
-}
-
-static int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev)
-{
-	struct queue_entry_priv_mmio *entry_priv;
-
-	/*
-	 * Initialize registers.
-	 */
-	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
-	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0,
-				  entry_priv->desc_dma);
-	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0,
-				  rt2x00dev->tx[0].limit);
-	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0);
-
-	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
-	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1,
-				  entry_priv->desc_dma);
-	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1,
-				  rt2x00dev->tx[1].limit);
-	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0);
-
-	entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
-	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2,
-				  entry_priv->desc_dma);
-	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2,
-				  rt2x00dev->tx[2].limit);
-	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0);
-
-	entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
-	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3,
-				  entry_priv->desc_dma);
-	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3,
-				  rt2x00dev->tx[3].limit);
-	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0);
-
-	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0);
-
-	rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0);
-
-	entry_priv = rt2x00dev->rx->entries[0].priv_data;
-	rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR,
-				  entry_priv->desc_dma);
-	rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT,
-				  rt2x00dev->rx[0].limit);
-	rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX,
-				  rt2x00dev->rx[0].limit - 1);
-	rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0);
-
-	rt2800_disable_wpdma(rt2x00dev);
-
-	rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0);
-
-	return 0;
-}
-
-/*
  * Device state switch handlers.
  */
-static int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev)
-{
-	u32 reg;
-
-	/*
-	 * Reset DMA indexes
-	 */
-	rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX3, 1);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
-	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
-	rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
-
-	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
-	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
-
-	if (rt2x00_is_pcie(rt2x00dev) &&
-	    (rt2x00_rt(rt2x00dev, RT3090) ||
-	     rt2x00_rt(rt2x00dev, RT3390) ||
-	     rt2x00_rt(rt2x00dev, RT3572) ||
-	     rt2x00_rt(rt2x00dev, RT3593) ||
-	     rt2x00_rt(rt2x00dev, RT5390) ||
-	     rt2x00_rt(rt2x00dev, RT5392) ||
-	     rt2x00_rt(rt2x00dev, RT5592))) {
-		rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, &reg);
-		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
-		rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
-		rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg);
-	}
-
-	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
-
-	reg = 0;
-	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
-	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
-	rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
-
-	rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
-
-	return 0;
-}
-
 static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	int retval;
-- 
1.7.10

^ permalink raw reply related

* [PATCH 12/21] rt2x00: rt2800pci: use separate ops for the SoC driver
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

This makes it possible to use different callback
functions for PCI and SoC devices which will allow
to move the SoC driver into a separate module.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |  104 ++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 5ae90df6..344a73d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -356,6 +356,7 @@ static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
 	return retval;
 }
 
+#ifdef CONFIG_PCI
 static const struct ieee80211_ops rt2800pci_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.start			= rt2x00mac_start,
@@ -459,7 +460,6 @@ static const struct rt2x00_ops rt2800pci_ops = {
 /*
  * RT2800pci module information.
  */
-#ifdef CONFIG_PCI
 static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
 	{ PCI_DEVICE(0x1814, 0x0601) },
 	{ PCI_DEVICE(0x1814, 0x0681) },
@@ -517,9 +517,109 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 MODULE_LICENSE("GPL");
 
 #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+static const struct ieee80211_ops rt2800soc_mac80211_ops = {
+	.tx			= rt2x00mac_tx,
+	.start			= rt2x00mac_start,
+	.stop			= rt2x00mac_stop,
+	.add_interface		= rt2x00mac_add_interface,
+	.remove_interface	= rt2x00mac_remove_interface,
+	.config			= rt2x00mac_config,
+	.configure_filter	= rt2x00mac_configure_filter,
+	.set_key		= rt2x00mac_set_key,
+	.sw_scan_start		= rt2x00mac_sw_scan_start,
+	.sw_scan_complete	= rt2x00mac_sw_scan_complete,
+	.get_stats		= rt2x00mac_get_stats,
+	.get_tkip_seq		= rt2800_get_tkip_seq,
+	.set_rts_threshold	= rt2800_set_rts_threshold,
+	.sta_add		= rt2x00mac_sta_add,
+	.sta_remove		= rt2x00mac_sta_remove,
+	.bss_info_changed	= rt2x00mac_bss_info_changed,
+	.conf_tx		= rt2800_conf_tx,
+	.get_tsf		= rt2800_get_tsf,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
+	.ampdu_action		= rt2800_ampdu_action,
+	.flush			= rt2x00mac_flush,
+	.get_survey		= rt2800_get_survey,
+	.get_ringparam		= rt2x00mac_get_ringparam,
+	.tx_frames_pending	= rt2x00mac_tx_frames_pending,
+};
+
+static const struct rt2800_ops rt2800soc_rt2800_ops = {
+	.register_read		= rt2x00mmio_register_read,
+	.register_read_lock	= rt2x00mmio_register_read, /* same for SoCs */
+	.register_write		= rt2x00mmio_register_write,
+	.register_write_lock	= rt2x00mmio_register_write, /* same for SoCs */
+	.register_multiread	= rt2x00mmio_register_multiread,
+	.register_multiwrite	= rt2x00mmio_register_multiwrite,
+	.regbusy_read		= rt2x00mmio_regbusy_read,
+	.read_eeprom		= rt2800pci_read_eeprom,
+	.hwcrypt_disabled	= rt2800pci_hwcrypt_disabled,
+	.drv_write_firmware	= rt2800pci_write_firmware,
+	.drv_init_registers	= rt2800mmio_init_registers,
+	.drv_get_txwi		= rt2800mmio_get_txwi,
+};
+
+static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
+	.irq_handler		= rt2800mmio_interrupt,
+	.txstatus_tasklet	= rt2800mmio_txstatus_tasklet,
+	.pretbtt_tasklet	= rt2800mmio_pretbtt_tasklet,
+	.tbtt_tasklet		= rt2800mmio_tbtt_tasklet,
+	.rxdone_tasklet		= rt2800mmio_rxdone_tasklet,
+	.autowake_tasklet	= rt2800mmio_autowake_tasklet,
+	.probe_hw		= rt2800_probe_hw,
+	.get_firmware_name	= rt2800pci_get_firmware_name,
+	.check_firmware		= rt2800_check_firmware,
+	.load_firmware		= rt2800_load_firmware,
+	.initialize		= rt2x00mmio_initialize,
+	.uninitialize		= rt2x00mmio_uninitialize,
+	.get_entry_state	= rt2800mmio_get_entry_state,
+	.clear_entry		= rt2800mmio_clear_entry,
+	.set_device_state	= rt2800pci_set_device_state,
+	.rfkill_poll		= rt2800_rfkill_poll,
+	.link_stats		= rt2800_link_stats,
+	.reset_tuner		= rt2800_reset_tuner,
+	.link_tuner		= rt2800_link_tuner,
+	.gain_calibration	= rt2800_gain_calibration,
+	.vco_calibration	= rt2800_vco_calibration,
+	.start_queue		= rt2800mmio_start_queue,
+	.kick_queue		= rt2800mmio_kick_queue,
+	.stop_queue		= rt2800mmio_stop_queue,
+	.flush_queue		= rt2x00mmio_flush_queue,
+	.write_tx_desc		= rt2800mmio_write_tx_desc,
+	.write_tx_data		= rt2800_write_tx_data,
+	.write_beacon		= rt2800_write_beacon,
+	.clear_beacon		= rt2800_clear_beacon,
+	.fill_rxdone		= rt2800mmio_fill_rxdone,
+	.config_shared_key	= rt2800_config_shared_key,
+	.config_pairwise_key	= rt2800_config_pairwise_key,
+	.config_filter		= rt2800_config_filter,
+	.config_intf		= rt2800_config_intf,
+	.config_erp		= rt2800_config_erp,
+	.config_ant		= rt2800_config_ant,
+	.config			= rt2800_config,
+	.sta_add		= rt2800_sta_add,
+	.sta_remove		= rt2800_sta_remove,
+};
+
+static const struct rt2x00_ops rt2800soc_ops = {
+	.name			= KBUILD_MODNAME,
+	.drv_data_size		= sizeof(struct rt2800_drv_data),
+	.max_ap_intf		= 8,
+	.eeprom_size		= EEPROM_SIZE,
+	.rf_size		= RF_SIZE,
+	.tx_queues		= NUM_TX_QUEUES,
+	.queue_init		= rt2800mmio_queue_init,
+	.lib			= &rt2800soc_rt2x00_ops,
+	.drv			= &rt2800soc_rt2800_ops,
+	.hw			= &rt2800soc_mac80211_ops,
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+	.debugfs		= &rt2800_rt2x00debug,
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+};
+
 static int rt2800soc_probe(struct platform_device *pdev)
 {
-	return rt2x00soc_probe(pdev, &rt2800pci_ops);
+	return rt2x00soc_probe(pdev, &rt2800soc_ops);
 }
 
 static struct platform_driver rt2800soc_driver = {
-- 
1.7.10

^ permalink raw reply related

* [PATCH 14/21] rt2x00: rt2800pci: use separate firmware callbacks for SoC devices
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

Use empty firmware callbacks for SoC devices because those
don't require firmware.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   38 +++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index afd422f..efc35b4 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -164,7 +164,6 @@ static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
 {
 	return rt2800_read_eeprom_efuse(rt2x00dev);
 }
-#endif /* CONFIG_PCI */
 
 /*
  * Firmware functions
@@ -206,6 +205,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 
 	return 0;
 }
+#endif /* CONFIG_PCI */
 
 /*
  * Device state switch handlers.
@@ -493,6 +493,34 @@ static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
 	return 0;
 }
 
+/* Firmware functions */
+static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+{
+	WARN_ON_ONCE(1);
+	return NULL;
+}
+
+static int rt2800soc_load_firmware(struct rt2x00_dev *rt2x00dev,
+				   const u8 *data, const size_t len)
+{
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
+static int rt2800soc_check_firmware(struct rt2x00_dev *rt2x00dev,
+				    const u8 *data, const size_t len)
+{
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
+static int rt2800soc_write_firmware(struct rt2x00_dev *rt2x00dev,
+				    const u8 *data, const size_t len)
+{
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
 static const struct ieee80211_ops rt2800soc_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.start			= rt2x00mac_start,
@@ -530,7 +558,7 @@ static const struct rt2800_ops rt2800soc_rt2800_ops = {
 	.regbusy_read		= rt2x00mmio_regbusy_read,
 	.read_eeprom		= rt2800soc_read_eeprom,
 	.hwcrypt_disabled	= rt2800pci_hwcrypt_disabled,
-	.drv_write_firmware	= rt2800pci_write_firmware,
+	.drv_write_firmware	= rt2800soc_write_firmware,
 	.drv_init_registers	= rt2800mmio_init_registers,
 	.drv_get_txwi		= rt2800mmio_get_txwi,
 };
@@ -543,9 +571,9 @@ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
 	.rxdone_tasklet		= rt2800mmio_rxdone_tasklet,
 	.autowake_tasklet	= rt2800mmio_autowake_tasklet,
 	.probe_hw		= rt2800_probe_hw,
-	.get_firmware_name	= rt2800pci_get_firmware_name,
-	.check_firmware		= rt2800_check_firmware,
-	.load_firmware		= rt2800_load_firmware,
+	.get_firmware_name	= rt2800soc_get_firmware_name,
+	.check_firmware		= rt2800soc_check_firmware,
+	.load_firmware		= rt2800soc_load_firmware,
 	.initialize		= rt2x00mmio_initialize,
 	.uninitialize		= rt2x00mmio_uninitialize,
 	.get_entry_state	= rt2800mmio_get_entry_state,
-- 
1.7.10

^ permalink raw reply related

* [PATCH 13/21] rt2x00: rt2800pci: use separate read_eeprom callback for SoC devices
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

Rename the 'rt2800pci_read_eeprom_soc function' to
'rt2800soc_read_eeprom' and use that directly in the
SoC specific 'rt2800_ops' structure. Also move the
'rt2800pci_eeprom_read' function into an 'ifdef PCI'
section and remove the 'rt2800pci_read_eeprom_soc'
call from that.

Additionally, remove the dummy inline eeprom functions.
Those are not used anymore.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   56 +++++++++----------------------
 1 file changed, 16 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 344a73d..afd422f 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -91,26 +91,6 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 }
 
-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
-static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
-{
-	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
-
-	if (!base_addr)
-		return -ENOMEM;
-
-	memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
-
-	iounmap(base_addr);
-	return 0;
-}
-#else
-static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev)
-{
-	return -ENOMEM;
-}
-#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
-
 #ifdef CONFIG_PCI
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
 {
@@ -184,21 +164,6 @@ static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
 {
 	return rt2800_read_eeprom_efuse(rt2x00dev);
 }
-#else
-static inline int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
-{
-	return -EOPNOTSUPP;
-}
-
-static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev)
-{
-	return 0;
-}
-
-static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
-{
-	return -EOPNOTSUPP;
-}
 #endif /* CONFIG_PCI */
 
 /*
@@ -339,6 +304,7 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 	return retval;
 }
 
+#ifdef CONFIG_PCI
 /*
  * Device probe functions.
  */
@@ -346,9 +312,7 @@ static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
 {
 	int retval;
 
-	if (rt2x00_is_soc(rt2x00dev))
-		retval = rt2800pci_read_eeprom_soc(rt2x00dev);
-	else if (rt2800pci_efuse_detect(rt2x00dev))
+	if (rt2800pci_efuse_detect(rt2x00dev))
 		retval = rt2800pci_read_eeprom_efuse(rt2x00dev);
 	else
 		retval = rt2800pci_read_eeprom_pci(rt2x00dev);
@@ -356,7 +320,6 @@ static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
 	return retval;
 }
 
-#ifdef CONFIG_PCI
 static const struct ieee80211_ops rt2800pci_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.start			= rt2x00mac_start,
@@ -517,6 +480,19 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 MODULE_LICENSE("GPL");
 
 #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
+
+	if (!base_addr)
+		return -ENOMEM;
+
+	memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+
+	iounmap(base_addr);
+	return 0;
+}
+
 static const struct ieee80211_ops rt2800soc_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.start			= rt2x00mac_start,
@@ -552,7 +528,7 @@ static const struct rt2800_ops rt2800soc_rt2800_ops = {
 	.register_multiread	= rt2x00mmio_register_multiread,
 	.register_multiwrite	= rt2x00mmio_register_multiwrite,
 	.regbusy_read		= rt2x00mmio_regbusy_read,
-	.read_eeprom		= rt2800pci_read_eeprom,
+	.read_eeprom		= rt2800soc_read_eeprom,
 	.hwcrypt_disabled	= rt2800pci_hwcrypt_disabled,
 	.drv_write_firmware	= rt2800pci_write_firmware,
 	.drv_init_registers	= rt2800mmio_init_registers,
-- 
1.7.10

^ permalink raw reply related

* [PATCH 16/21] rt2x00: rt2800pci: rename rt2800pci_disable_radio function
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

The function contain code for SoC devices only.
Rename the function to 'rt2800soc_disable_radio'
and move it to the SoC specific section. Use
the renamed function in the SoC specific code
only and remove the 'if rt2x00_is_soc(rt2x00dev)'
condition from the function body.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index e424b7a..4cfd8f7 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -237,15 +237,6 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 	return retval;
 }
 
-static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
-{
-	if (rt2x00_is_soc(rt2x00dev)) {
-		rt2800_disable_radio(rt2x00dev);
-		rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
-		rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
-	}
-}
-
 #ifdef CONFIG_PCI
 static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
 			       enum dev_state state)
@@ -280,7 +271,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 		 * After the radio has been disabled, the device should
 		 * be put to sleep for powersaving.
 		 */
-		rt2800pci_disable_radio(rt2x00dev);
 		rt2800pci_set_state(rt2x00dev, STATE_SLEEP);
 		break;
 	case STATE_RADIO_IRQ_ON:
@@ -480,6 +470,13 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 MODULE_LICENSE("GPL");
 
 #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_disable_radio(rt2x00dev);
+	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
+}
+
 static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
 				      enum dev_state state)
 {
@@ -491,7 +488,7 @@ static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
 		break;
 
 	case STATE_RADIO_OFF:
-		rt2800pci_disable_radio(rt2x00dev);
+		rt2800soc_disable_radio(rt2x00dev);
 		break;
 
 	case STATE_RADIO_IRQ_ON:
-- 
1.7.10

^ permalink raw reply related

* [PATCH 15/21] rt2x00: rt2800pci: use separate set_state callback for SoC devices
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

The 'rt2800pci_set_state' function uses MCU commands
to set the device state, however these have no effect
on SoC devices. Use a different set_state callback
which does not use the MCU fcuntions.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   43 +++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index efc35b4..e424b7a 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -246,6 +246,7 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
 	}
 }
 
+#ifdef CONFIG_PCI
 static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
 			       enum dev_state state)
 {
@@ -304,7 +305,6 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev,
 	return retval;
 }
 
-#ifdef CONFIG_PCI
 /*
  * Device probe functions.
  */
@@ -480,6 +480,45 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 MODULE_LICENSE("GPL");
 
 #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
+				      enum dev_state state)
+{
+	int retval = 0;
+
+	switch (state) {
+	case STATE_RADIO_ON:
+		retval = rt2800pci_enable_radio(rt2x00dev);
+		break;
+
+	case STATE_RADIO_OFF:
+		rt2800pci_disable_radio(rt2x00dev);
+		break;
+
+	case STATE_RADIO_IRQ_ON:
+	case STATE_RADIO_IRQ_OFF:
+		rt2800mmio_toggle_irq(rt2x00dev, state);
+		break;
+
+	case STATE_DEEP_SLEEP:
+	case STATE_SLEEP:
+	case STATE_STANDBY:
+	case STATE_AWAKE:
+		/* These states are not supported, but don't report an error */
+		retval = 0;
+		break;
+
+	default:
+		retval = -ENOTSUPP;
+		break;
+	}
+
+	if (unlikely(retval))
+		rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n",
+			   state, retval);
+
+	return retval;
+}
+
 static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
 {
 	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
@@ -578,7 +617,7 @@ static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
 	.uninitialize		= rt2x00mmio_uninitialize,
 	.get_entry_state	= rt2800mmio_get_entry_state,
 	.clear_entry		= rt2800mmio_clear_entry,
-	.set_device_state	= rt2800pci_set_device_state,
+	.set_device_state	= rt2800soc_set_device_state,
 	.rfkill_poll		= rt2800_rfkill_poll,
 	.link_stats		= rt2800_link_stats,
 	.reset_tuner		= rt2800_reset_tuner,
-- 
1.7.10

^ permalink raw reply related

* [PATCH 17/21] rt2x00: rt2800pci: split rt2800pci_enable_radio function
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

The function is called for PCI and SoC devices
however the MCU related part of the function
has no effect on SoC devices. Move the common
part of the function into a separate helper and
use that for the SoC devices.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 4cfd8f7..88dd242 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -61,6 +61,7 @@ static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
 	return modparam_nohwcrypt;
 }
 
+#ifdef CONFIG_PCI
 static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 {
 	unsigned int i;
@@ -91,7 +92,6 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 }
 
-#ifdef CONFIG_PCI
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
 {
 	struct rt2x00_dev *rt2x00dev = eeprom->data;
@@ -210,17 +210,23 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 /*
  * Device state switch handlers.
  */
-static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
+static int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
-	int retval;
-
 	/* Wait for DMA, ignore error until we initialize queues. */
 	rt2800_wait_wpdma_ready(rt2x00dev);
 
 	if (unlikely(rt2800mmio_init_queues(rt2x00dev)))
 		return -EIO;
 
-	retval = rt2800_enable_radio(rt2x00dev);
+	return rt2800_enable_radio(rt2x00dev);
+}
+
+#ifdef CONFIG_PCI
+static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+	int retval;
+
+	retval = rt2800mmio_enable_radio(rt2x00dev);
 	if (retval)
 		return retval;
 
@@ -237,7 +243,6 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 	return retval;
 }
 
-#ifdef CONFIG_PCI
 static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
 			       enum dev_state state)
 {
@@ -484,7 +489,7 @@ static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
 
 	switch (state) {
 	case STATE_RADIO_ON:
-		retval = rt2800pci_enable_radio(rt2x00dev);
+		retval = rt2800mmio_enable_radio(rt2x00dev);
 		break;
 
 	case STATE_RADIO_OFF:
-- 
1.7.10

^ permalink raw reply related

* [PATCH 18/21] rt2x00: rt2800pci: move rt2800mmio_enable_radio function to another module
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

Move the function into the rt2800mmio module, in order
to make it usable from other modules.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800mmio.c |   15 +++++++++++++++
 drivers/net/wireless/rt2x00/rt2800mmio.h |    3 +++
 drivers/net/wireless/rt2x00/rt2800pci.c  |   13 -------------
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.c b/drivers/net/wireless/rt2x00/rt2800mmio.c
index 7e8c224..ae15228 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.c
@@ -852,6 +852,21 @@ int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_init_registers);
 
+/*
+ * Device state switch handlers.
+ */
+int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+	/* Wait for DMA, ignore error until we initialize queues. */
+	rt2800_wait_wpdma_ready(rt2x00dev);
+
+	if (unlikely(rt2800mmio_init_queues(rt2x00dev)))
+		return -EIO;
+
+	return rt2800_enable_radio(rt2x00dev);
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
+
 MODULE_AUTHOR(DRV_PROJECT);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("rt2800 MMIO library");
diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.h b/drivers/net/wireless/rt2x00/rt2800mmio.h
index 392895a..6a10de3 100644
--- a/drivers/net/wireless/rt2x00/rt2800mmio.h
+++ b/drivers/net/wireless/rt2x00/rt2800mmio.h
@@ -159,4 +159,7 @@ void rt2800mmio_clear_entry(struct queue_entry *entry);
 int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev);
 int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev);
 
+/* Device state switch handlers. */
+int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev);
+
 #endif /* RT2800MMIO_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 88dd242..77ddd1a 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -205,23 +205,10 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 
 	return 0;
 }
-#endif /* CONFIG_PCI */
 
 /*
  * Device state switch handlers.
  */
-static int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev)
-{
-	/* Wait for DMA, ignore error until we initialize queues. */
-	rt2800_wait_wpdma_ready(rt2x00dev);
-
-	if (unlikely(rt2800mmio_init_queues(rt2x00dev)))
-		return -EIO;
-
-	return rt2800_enable_radio(rt2x00dev);
-}
-
-#ifdef CONFIG_PCI
 static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	int retval;
-- 
1.7.10

^ permalink raw reply related

* [PATCH 19/21] rt2x00: rt2800pci: use separate hwcrypt_disabled callback for SoC devices
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

The 'rt2800pci_hwcrypt_disabled' function is the
only PCI specific callback which is used by the
SoC driver. Create a clone of that to get rid of
the dependency.

Even though the two functions are using the same
variable, but the SoC specific code will be moved
into a separate module which will have its own
'modparam_nohwcrypt' variable.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 77ddd1a..488d1c4 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -56,12 +56,12 @@ static bool modparam_nohwcrypt = false;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
+#ifdef CONFIG_PCI
 static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
 {
 	return modparam_nohwcrypt;
 }
 
-#ifdef CONFIG_PCI
 static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 {
 	unsigned int i;
@@ -462,6 +462,11 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
 MODULE_LICENSE("GPL");
 
 #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
+static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
+{
+	return modparam_nohwcrypt;
+}
+
 static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
 {
 	rt2800_disable_radio(rt2x00dev);
@@ -585,7 +590,7 @@ static const struct rt2800_ops rt2800soc_rt2800_ops = {
 	.register_multiwrite	= rt2x00mmio_register_multiwrite,
 	.regbusy_read		= rt2x00mmio_regbusy_read,
 	.read_eeprom		= rt2800soc_read_eeprom,
-	.hwcrypt_disabled	= rt2800pci_hwcrypt_disabled,
+	.hwcrypt_disabled	= rt2800soc_hwcrypt_disabled,
 	.drv_write_firmware	= rt2800soc_write_firmware,
 	.drv_init_registers	= rt2800mmio_init_registers,
 	.drv_get_txwi		= rt2800mmio_get_txwi,
-- 
1.7.10

^ permalink raw reply related

* [PATCH 20/21] rt2x00: rt2800pci: move SoC specific code into a separate module
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

The PCI and SoC specific drivers are using separate
code now so it is not reasonable to use the same
module for both drivers anymore.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/Kconfig     |   21 ++-
 drivers/net/wireless/rt2x00/Makefile    |    1 +
 drivers/net/wireless/rt2x00/rt2800pci.c |  244 +---------------------------
 drivers/net/wireless/rt2x00/rt2800soc.c |  263 +++++++++++++++++++++++++++++++
 4 files changed, 284 insertions(+), 245 deletions(-)
 create mode 100644 drivers/net/wireless/rt2x00/rt2800soc.c

diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index e863249..006b8bc 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -58,12 +58,11 @@ config RT61PCI
 
 config RT2800PCI
 	tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
-	depends on PCI || SOC_RT288X || SOC_RT305X
+	depends on PCI
 	select RT2800_LIB
 	select RT2800_LIB_MMIO
 	select RT2X00_LIB_MMIO
-	select RT2X00_LIB_PCI if PCI
-	select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
+	select RT2X00_LIB_PCI
 	select RT2X00_LIB_FIRMWARE
 	select RT2X00_LIB_CRYPTO
 	select CRC_CCITT
@@ -200,6 +199,22 @@ config RT2800USB_UNKNOWN
 
 endif
 
+config RT2800SOC
+	tristate "Ralink WiSoC support"
+	depends on SOC_RT288X || SOC_RT305X
+	select RT2X00_LIB_SOC
+	select RT2X00_LIB_MMIO
+	select RT2X00_LIB_CRYPTO
+	select RT2X00_LIB_FIRMWARE
+	select RT2800_LIB
+	select RT2800_LIB_MMIO
+	---help---
+	  This adds support for Ralink WiSoC devices.
+	  Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352.
+
+	  When compiled as a module, this driver will be called rt2800soc.
+
+
 config RT2800_LIB
 	tristate
 
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index d11e356..24a6601 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_RT2800PCI)			+= rt2800pci.o
 obj-$(CONFIG_RT2500USB)			+= rt2500usb.o
 obj-$(CONFIG_RT73USB)			+= rt73usb.o
 obj-$(CONFIG_RT2800USB)			+= rt2800usb.o
+obj-$(CONFIG_RT2800SOC)			+= rt2800soc.o
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 488d1c4..260d2fd 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -37,13 +37,11 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/platform_device.h>
 #include <linux/eeprom_93cx6.h>
 
 #include "rt2x00.h"
 #include "rt2x00mmio.h"
 #include "rt2x00pci.h"
-#include "rt2x00soc.h"
 #include "rt2800lib.h"
 #include "rt2800mmio.h"
 #include "rt2800.h"
@@ -56,7 +54,6 @@ static bool modparam_nohwcrypt = false;
 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
-#ifdef CONFIG_PCI
 static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
 {
 	return modparam_nohwcrypt;
@@ -449,230 +446,15 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
 #endif
 	{ 0, }
 };
-#endif /* CONFIG_PCI */
 
 MODULE_AUTHOR(DRV_PROJECT);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver.");
 MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards");
-#ifdef CONFIG_PCI
 MODULE_FIRMWARE(FIRMWARE_RT2860);
 MODULE_DEVICE_TABLE(pci, rt2800pci_device_table);
-#endif /* CONFIG_PCI */
 MODULE_LICENSE("GPL");
 
-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
-static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
-{
-	return modparam_nohwcrypt;
-}
-
-static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
-{
-	rt2800_disable_radio(rt2x00dev);
-	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
-	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
-}
-
-static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
-				      enum dev_state state)
-{
-	int retval = 0;
-
-	switch (state) {
-	case STATE_RADIO_ON:
-		retval = rt2800mmio_enable_radio(rt2x00dev);
-		break;
-
-	case STATE_RADIO_OFF:
-		rt2800soc_disable_radio(rt2x00dev);
-		break;
-
-	case STATE_RADIO_IRQ_ON:
-	case STATE_RADIO_IRQ_OFF:
-		rt2800mmio_toggle_irq(rt2x00dev, state);
-		break;
-
-	case STATE_DEEP_SLEEP:
-	case STATE_SLEEP:
-	case STATE_STANDBY:
-	case STATE_AWAKE:
-		/* These states are not supported, but don't report an error */
-		retval = 0;
-		break;
-
-	default:
-		retval = -ENOTSUPP;
-		break;
-	}
-
-	if (unlikely(retval))
-		rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n",
-			   state, retval);
-
-	return retval;
-}
-
-static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
-{
-	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
-
-	if (!base_addr)
-		return -ENOMEM;
-
-	memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
-
-	iounmap(base_addr);
-	return 0;
-}
-
-/* Firmware functions */
-static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
-{
-	WARN_ON_ONCE(1);
-	return NULL;
-}
-
-static int rt2800soc_load_firmware(struct rt2x00_dev *rt2x00dev,
-				   const u8 *data, const size_t len)
-{
-	WARN_ON_ONCE(1);
-	return 0;
-}
-
-static int rt2800soc_check_firmware(struct rt2x00_dev *rt2x00dev,
-				    const u8 *data, const size_t len)
-{
-	WARN_ON_ONCE(1);
-	return 0;
-}
-
-static int rt2800soc_write_firmware(struct rt2x00_dev *rt2x00dev,
-				    const u8 *data, const size_t len)
-{
-	WARN_ON_ONCE(1);
-	return 0;
-}
-
-static const struct ieee80211_ops rt2800soc_mac80211_ops = {
-	.tx			= rt2x00mac_tx,
-	.start			= rt2x00mac_start,
-	.stop			= rt2x00mac_stop,
-	.add_interface		= rt2x00mac_add_interface,
-	.remove_interface	= rt2x00mac_remove_interface,
-	.config			= rt2x00mac_config,
-	.configure_filter	= rt2x00mac_configure_filter,
-	.set_key		= rt2x00mac_set_key,
-	.sw_scan_start		= rt2x00mac_sw_scan_start,
-	.sw_scan_complete	= rt2x00mac_sw_scan_complete,
-	.get_stats		= rt2x00mac_get_stats,
-	.get_tkip_seq		= rt2800_get_tkip_seq,
-	.set_rts_threshold	= rt2800_set_rts_threshold,
-	.sta_add		= rt2x00mac_sta_add,
-	.sta_remove		= rt2x00mac_sta_remove,
-	.bss_info_changed	= rt2x00mac_bss_info_changed,
-	.conf_tx		= rt2800_conf_tx,
-	.get_tsf		= rt2800_get_tsf,
-	.rfkill_poll		= rt2x00mac_rfkill_poll,
-	.ampdu_action		= rt2800_ampdu_action,
-	.flush			= rt2x00mac_flush,
-	.get_survey		= rt2800_get_survey,
-	.get_ringparam		= rt2x00mac_get_ringparam,
-	.tx_frames_pending	= rt2x00mac_tx_frames_pending,
-};
-
-static const struct rt2800_ops rt2800soc_rt2800_ops = {
-	.register_read		= rt2x00mmio_register_read,
-	.register_read_lock	= rt2x00mmio_register_read, /* same for SoCs */
-	.register_write		= rt2x00mmio_register_write,
-	.register_write_lock	= rt2x00mmio_register_write, /* same for SoCs */
-	.register_multiread	= rt2x00mmio_register_multiread,
-	.register_multiwrite	= rt2x00mmio_register_multiwrite,
-	.regbusy_read		= rt2x00mmio_regbusy_read,
-	.read_eeprom		= rt2800soc_read_eeprom,
-	.hwcrypt_disabled	= rt2800soc_hwcrypt_disabled,
-	.drv_write_firmware	= rt2800soc_write_firmware,
-	.drv_init_registers	= rt2800mmio_init_registers,
-	.drv_get_txwi		= rt2800mmio_get_txwi,
-};
-
-static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
-	.irq_handler		= rt2800mmio_interrupt,
-	.txstatus_tasklet	= rt2800mmio_txstatus_tasklet,
-	.pretbtt_tasklet	= rt2800mmio_pretbtt_tasklet,
-	.tbtt_tasklet		= rt2800mmio_tbtt_tasklet,
-	.rxdone_tasklet		= rt2800mmio_rxdone_tasklet,
-	.autowake_tasklet	= rt2800mmio_autowake_tasklet,
-	.probe_hw		= rt2800_probe_hw,
-	.get_firmware_name	= rt2800soc_get_firmware_name,
-	.check_firmware		= rt2800soc_check_firmware,
-	.load_firmware		= rt2800soc_load_firmware,
-	.initialize		= rt2x00mmio_initialize,
-	.uninitialize		= rt2x00mmio_uninitialize,
-	.get_entry_state	= rt2800mmio_get_entry_state,
-	.clear_entry		= rt2800mmio_clear_entry,
-	.set_device_state	= rt2800soc_set_device_state,
-	.rfkill_poll		= rt2800_rfkill_poll,
-	.link_stats		= rt2800_link_stats,
-	.reset_tuner		= rt2800_reset_tuner,
-	.link_tuner		= rt2800_link_tuner,
-	.gain_calibration	= rt2800_gain_calibration,
-	.vco_calibration	= rt2800_vco_calibration,
-	.start_queue		= rt2800mmio_start_queue,
-	.kick_queue		= rt2800mmio_kick_queue,
-	.stop_queue		= rt2800mmio_stop_queue,
-	.flush_queue		= rt2x00mmio_flush_queue,
-	.write_tx_desc		= rt2800mmio_write_tx_desc,
-	.write_tx_data		= rt2800_write_tx_data,
-	.write_beacon		= rt2800_write_beacon,
-	.clear_beacon		= rt2800_clear_beacon,
-	.fill_rxdone		= rt2800mmio_fill_rxdone,
-	.config_shared_key	= rt2800_config_shared_key,
-	.config_pairwise_key	= rt2800_config_pairwise_key,
-	.config_filter		= rt2800_config_filter,
-	.config_intf		= rt2800_config_intf,
-	.config_erp		= rt2800_config_erp,
-	.config_ant		= rt2800_config_ant,
-	.config			= rt2800_config,
-	.sta_add		= rt2800_sta_add,
-	.sta_remove		= rt2800_sta_remove,
-};
-
-static const struct rt2x00_ops rt2800soc_ops = {
-	.name			= KBUILD_MODNAME,
-	.drv_data_size		= sizeof(struct rt2800_drv_data),
-	.max_ap_intf		= 8,
-	.eeprom_size		= EEPROM_SIZE,
-	.rf_size		= RF_SIZE,
-	.tx_queues		= NUM_TX_QUEUES,
-	.queue_init		= rt2800mmio_queue_init,
-	.lib			= &rt2800soc_rt2x00_ops,
-	.drv			= &rt2800soc_rt2800_ops,
-	.hw			= &rt2800soc_mac80211_ops,
-#ifdef CONFIG_RT2X00_LIB_DEBUGFS
-	.debugfs		= &rt2800_rt2x00debug,
-#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
-};
-
-static int rt2800soc_probe(struct platform_device *pdev)
-{
-	return rt2x00soc_probe(pdev, &rt2800soc_ops);
-}
-
-static struct platform_driver rt2800soc_driver = {
-	.driver		= {
-		.name		= "rt2800_wmac",
-		.owner		= THIS_MODULE,
-		.mod_name	= KBUILD_MODNAME,
-	},
-	.probe		= rt2800soc_probe,
-	.remove		= rt2x00soc_remove,
-	.suspend	= rt2x00soc_suspend,
-	.resume		= rt2x00soc_resume,
-};
-#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */
-
-#ifdef CONFIG_PCI
 static int rt2800pci_probe(struct pci_dev *pci_dev,
 			   const struct pci_device_id *id)
 {
@@ -687,38 +469,16 @@ static struct pci_driver rt2800pci_driver = {
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
 };
-#endif /* CONFIG_PCI */
+
 
 static int __init rt2800pci_init(void)
 {
-	int ret = 0;
-
-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
-	ret = platform_driver_register(&rt2800soc_driver);
-	if (ret)
-		return ret;
-#endif
-#ifdef CONFIG_PCI
-	ret = pci_register_driver(&rt2800pci_driver);
-	if (ret) {
-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
-		platform_driver_unregister(&rt2800soc_driver);
-#endif
-		return ret;
-	}
-#endif
-
-	return ret;
+	return pci_register_driver(&rt2800pci_driver);
 }
 
 static void __exit rt2800pci_exit(void)
 {
-#ifdef CONFIG_PCI
 	pci_unregister_driver(&rt2800pci_driver);
-#endif
-#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
-	platform_driver_unregister(&rt2800soc_driver);
-#endif
 }
 
 module_init(rt2800pci_init);
diff --git a/drivers/net/wireless/rt2x00/rt2800soc.c b/drivers/net/wireless/rt2x00/rt2800soc.c
new file mode 100644
index 0000000..1359227
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2800soc.c
@@ -0,0 +1,263 @@
+/*	Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com>
+ *	Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com>
+ *	Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org>
+ *	Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com>
+ *	Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de>
+ *	Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com>
+ *	Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com>
+ *	Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com>
+ *	<http://rt2x00.serialmonkey.com>
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	This program is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *	GNU General Public License for more details.
+ *
+ *	You should have received a copy of the GNU General Public License
+ *	along with this program; if not, write to the
+ *	Free Software Foundation, Inc.,
+ *	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*	Module: rt2800soc
+ *	Abstract: rt2800 WiSoC specific routines.
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "rt2x00.h"
+#include "rt2x00mmio.h"
+#include "rt2x00soc.h"
+#include "rt2800.h"
+#include "rt2800lib.h"
+#include "rt2800mmio.h"
+
+/* Allow hardware encryption to be disabled. */
+static bool modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
+{
+	return modparam_nohwcrypt;
+}
+
+static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_disable_radio(rt2x00dev);
+	rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+	rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0);
+}
+
+static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev,
+				      enum dev_state state)
+{
+	int retval = 0;
+
+	switch (state) {
+	case STATE_RADIO_ON:
+		retval = rt2800mmio_enable_radio(rt2x00dev);
+		break;
+
+	case STATE_RADIO_OFF:
+		rt2800soc_disable_radio(rt2x00dev);
+		break;
+
+	case STATE_RADIO_IRQ_ON:
+	case STATE_RADIO_IRQ_OFF:
+		rt2800mmio_toggle_irq(rt2x00dev, state);
+		break;
+
+	case STATE_DEEP_SLEEP:
+	case STATE_SLEEP:
+	case STATE_STANDBY:
+	case STATE_AWAKE:
+		/* These states are not supported, but don't report an error */
+		retval = 0;
+		break;
+
+	default:
+		retval = -ENOTSUPP;
+		break;
+	}
+
+	if (unlikely(retval))
+		rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n",
+			   state, retval);
+
+	return retval;
+}
+
+static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+	void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE);
+
+	if (!base_addr)
+		return -ENOMEM;
+
+	memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE);
+
+	iounmap(base_addr);
+	return 0;
+}
+
+/* Firmware functions */
+static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+{
+	WARN_ON_ONCE(1);
+	return NULL;
+}
+
+static int rt2800soc_load_firmware(struct rt2x00_dev *rt2x00dev,
+				   const u8 *data, const size_t len)
+{
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
+static int rt2800soc_check_firmware(struct rt2x00_dev *rt2x00dev,
+				    const u8 *data, const size_t len)
+{
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
+static int rt2800soc_write_firmware(struct rt2x00_dev *rt2x00dev,
+				    const u8 *data, const size_t len)
+{
+	WARN_ON_ONCE(1);
+	return 0;
+}
+
+static const struct ieee80211_ops rt2800soc_mac80211_ops = {
+	.tx			= rt2x00mac_tx,
+	.start			= rt2x00mac_start,
+	.stop			= rt2x00mac_stop,
+	.add_interface		= rt2x00mac_add_interface,
+	.remove_interface	= rt2x00mac_remove_interface,
+	.config			= rt2x00mac_config,
+	.configure_filter	= rt2x00mac_configure_filter,
+	.set_key		= rt2x00mac_set_key,
+	.sw_scan_start		= rt2x00mac_sw_scan_start,
+	.sw_scan_complete	= rt2x00mac_sw_scan_complete,
+	.get_stats		= rt2x00mac_get_stats,
+	.get_tkip_seq		= rt2800_get_tkip_seq,
+	.set_rts_threshold	= rt2800_set_rts_threshold,
+	.sta_add		= rt2x00mac_sta_add,
+	.sta_remove		= rt2x00mac_sta_remove,
+	.bss_info_changed	= rt2x00mac_bss_info_changed,
+	.conf_tx		= rt2800_conf_tx,
+	.get_tsf		= rt2800_get_tsf,
+	.rfkill_poll		= rt2x00mac_rfkill_poll,
+	.ampdu_action		= rt2800_ampdu_action,
+	.flush			= rt2x00mac_flush,
+	.get_survey		= rt2800_get_survey,
+	.get_ringparam		= rt2x00mac_get_ringparam,
+	.tx_frames_pending	= rt2x00mac_tx_frames_pending,
+};
+
+static const struct rt2800_ops rt2800soc_rt2800_ops = {
+	.register_read		= rt2x00mmio_register_read,
+	.register_read_lock	= rt2x00mmio_register_read, /* same for SoCs */
+	.register_write		= rt2x00mmio_register_write,
+	.register_write_lock	= rt2x00mmio_register_write, /* same for SoCs */
+	.register_multiread	= rt2x00mmio_register_multiread,
+	.register_multiwrite	= rt2x00mmio_register_multiwrite,
+	.regbusy_read		= rt2x00mmio_regbusy_read,
+	.read_eeprom		= rt2800soc_read_eeprom,
+	.hwcrypt_disabled	= rt2800soc_hwcrypt_disabled,
+	.drv_write_firmware	= rt2800soc_write_firmware,
+	.drv_init_registers	= rt2800mmio_init_registers,
+	.drv_get_txwi		= rt2800mmio_get_txwi,
+};
+
+static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
+	.irq_handler		= rt2800mmio_interrupt,
+	.txstatus_tasklet	= rt2800mmio_txstatus_tasklet,
+	.pretbtt_tasklet	= rt2800mmio_pretbtt_tasklet,
+	.tbtt_tasklet		= rt2800mmio_tbtt_tasklet,
+	.rxdone_tasklet		= rt2800mmio_rxdone_tasklet,
+	.autowake_tasklet	= rt2800mmio_autowake_tasklet,
+	.probe_hw		= rt2800_probe_hw,
+	.get_firmware_name	= rt2800soc_get_firmware_name,
+	.check_firmware		= rt2800soc_check_firmware,
+	.load_firmware		= rt2800soc_load_firmware,
+	.initialize		= rt2x00mmio_initialize,
+	.uninitialize		= rt2x00mmio_uninitialize,
+	.get_entry_state	= rt2800mmio_get_entry_state,
+	.clear_entry		= rt2800mmio_clear_entry,
+	.set_device_state	= rt2800soc_set_device_state,
+	.rfkill_poll		= rt2800_rfkill_poll,
+	.link_stats		= rt2800_link_stats,
+	.reset_tuner		= rt2800_reset_tuner,
+	.link_tuner		= rt2800_link_tuner,
+	.gain_calibration	= rt2800_gain_calibration,
+	.vco_calibration	= rt2800_vco_calibration,
+	.start_queue		= rt2800mmio_start_queue,
+	.kick_queue		= rt2800mmio_kick_queue,
+	.stop_queue		= rt2800mmio_stop_queue,
+	.flush_queue		= rt2x00mmio_flush_queue,
+	.write_tx_desc		= rt2800mmio_write_tx_desc,
+	.write_tx_data		= rt2800_write_tx_data,
+	.write_beacon		= rt2800_write_beacon,
+	.clear_beacon		= rt2800_clear_beacon,
+	.fill_rxdone		= rt2800mmio_fill_rxdone,
+	.config_shared_key	= rt2800_config_shared_key,
+	.config_pairwise_key	= rt2800_config_pairwise_key,
+	.config_filter		= rt2800_config_filter,
+	.config_intf		= rt2800_config_intf,
+	.config_erp		= rt2800_config_erp,
+	.config_ant		= rt2800_config_ant,
+	.config			= rt2800_config,
+	.sta_add		= rt2800_sta_add,
+	.sta_remove		= rt2800_sta_remove,
+};
+
+static const struct rt2x00_ops rt2800soc_ops = {
+	.name			= KBUILD_MODNAME,
+	.drv_data_size		= sizeof(struct rt2800_drv_data),
+	.max_ap_intf		= 8,
+	.eeprom_size		= EEPROM_SIZE,
+	.rf_size		= RF_SIZE,
+	.tx_queues		= NUM_TX_QUEUES,
+	.queue_init		= rt2800mmio_queue_init,
+	.lib			= &rt2800soc_rt2x00_ops,
+	.drv			= &rt2800soc_rt2800_ops,
+	.hw			= &rt2800soc_mac80211_ops,
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+	.debugfs		= &rt2800_rt2x00debug,
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+};
+
+static int rt2800soc_probe(struct platform_device *pdev)
+{
+	return rt2x00soc_probe(pdev, &rt2800soc_ops);
+}
+
+static struct platform_driver rt2800soc_driver = {
+	.driver		= {
+		.name		= "rt2800_wmac",
+		.owner		= THIS_MODULE,
+		.mod_name	= KBUILD_MODNAME,
+	},
+	.probe		= rt2800soc_probe,
+	.remove		= rt2x00soc_remove,
+	.suspend	= rt2x00soc_suspend,
+	.resume		= rt2x00soc_resume,
+};
+
+module_platform_driver(rt2800soc_driver);
+
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Ralink WiSoC Wireless LAN driver.");
+MODULE_LICENSE("GPL");
-- 
1.7.10

^ permalink raw reply related

* [PATCH 21/21] rt2x00: rt2800pci: use module_pci_driver macro
From: Gabor Juhos @ 2013-10-17  7:42 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1381995755-16471-1-git-send-email-juhosg@openwrt.org>

Use the module_pci_driver() macro to make the code simpler
by eliminating module_init and module_exit calls.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 drivers/net/wireless/rt2x00/rt2800pci.c |   14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 260d2fd..b504455 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -470,16 +470,4 @@ static struct pci_driver rt2800pci_driver = {
 	.resume		= rt2x00pci_resume,
 };
 
-
-static int __init rt2800pci_init(void)
-{
-	return pci_register_driver(&rt2800pci_driver);
-}
-
-static void __exit rt2800pci_exit(void)
-{
-	pci_unregister_driver(&rt2800pci_driver);
-}
-
-module_init(rt2800pci_init);
-module_exit(rt2800pci_exit);
+module_pci_driver(rt2800pci_driver);
-- 
1.7.10

^ permalink raw reply related

* [PATCH 3.12] mac80211: disable WMM with invalid parameters
From: Johannes Berg @ 2013-10-17  7:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: Antonio Quartulli, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Some APs (notably a Sitecom WL-153 v1 with firmware 1.45) are sending
invalid WMM parameters setting AIFSN, ECWmin and ECWmax to zero. The
spec mandates that the value of AIFSN is at least 2, and some cards
(e.g. Intel with the iwldvm driver) can't transmit when the invalid
QoS parameters are actually uploaded to the firmware.

Since there's little chance of being able to guess the values that
the AP actually meant, disable WMM if such an invalid case is found.
Since ECWmin/ECWmax are allowed to be zero, only verify AIFSN >= 2
and ECWmin <= ECWmax.

Reported-by: Antonio Quartulli <antonio@meshcoding.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mlme.c        | 86 +++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 611abfc..0764095 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -335,6 +335,7 @@ enum ieee80211_sta_flags {
 	IEEE80211_STA_DISABLE_VHT	= BIT(11),
 	IEEE80211_STA_DISABLE_80P80MHZ	= BIT(12),
 	IEEE80211_STA_DISABLE_160MHZ	= BIT(13),
+	IEEE80211_STA_DISABLE_WMM	= BIT(14),
 };
 
 struct ieee80211_mgd_auth_data {
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 86e4ad5..9c47060 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2717,7 +2717,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
 	 */
 	ifmgd->wmm_last_param_set = -1;
 
-	if (elems.wmm_param)
+	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && elems.wmm_param)
 		ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
 					 elems.wmm_param_len);
 	else
@@ -3152,7 +3152,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 	ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
 					 &elems, true);
 
-	if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
+	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
+	    ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
 				     elems.wmm_param_len))
 		changed |= BSS_CHANGED_QOS;
 
@@ -4135,6 +4136,44 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 	return err;
 }
 
+static bool ieee80211_usable_wmm_params(struct ieee80211_sub_if_data *sdata,
+					const u8 *wmm_param, int len)
+{
+	const u8 *pos;
+	size_t left;
+
+	if (len < 8)
+		return false;
+
+	if (wmm_param[5] != 1 /* version */)
+		return false;
+
+	pos = wmm_param + 8;
+	left = len - 8;
+
+	for (; left >= 4; left -= 4, pos += 4) {
+		u8 aifsn = pos[0] & 0x0f;
+		u8 ecwmin = pos[1] & 0x0f;
+		u8 ecwmax = (pos[1] & 0xf0) >> 4;
+		int aci = (pos[0] >> 5) & 0x03;
+
+		if (aifsn < 2) {
+			sdata_info(sdata,
+				   "AP has invalid WMM params (AIFSN=%d for ACI %d), disabling WMM\n",
+				   aifsn, aci);
+			return false;
+		}
+		if (ecwmin > ecwmax) {
+			sdata_info(sdata,
+				   "AP has invalid WMM params (ECWmin/max=%d/%d for ACI %d), disabling WMM\n",
+				   ecwmin, ecwmax, aci);
+			return false;
+		}
+	}
+
+	return true;
+}
+
 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 			struct cfg80211_assoc_request *req)
 {
@@ -4192,9 +4231,36 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	}
 
 	/* prepare assoc data */
-	
+
 	ifmgd->beacon_crc_valid = false;
 
+	assoc_data->wmm = bss->wmm_used &&
+			  (local->hw.queues >= IEEE80211_NUM_ACS);
+	if (assoc_data->wmm) {
+		/* try to check validity of WMM params IE */
+		const struct cfg80211_bss_ies *ies;
+		const u8 *wp, *start;
+		int len;
+
+		rcu_read_lock();
+		ies = rcu_dereference(req->bss->ies);
+		start = ies->data;
+		len = ies->len;
+
+		do {
+			wp = cfg80211_find_vendor_ie(0x0050F2, 2, start, len);
+			start = wp;
+			len -= wp[1];
+		} while (wp && wp[1] > 6 && wp[6] != 1);
+
+		if (!wp || !ieee80211_usable_wmm_params(sdata, wp + 2,
+							wp[1] - 2)) {
+			assoc_data->wmm = false;
+			ifmgd->flags |= IEEE80211_STA_DISABLE_WMM;
+		}
+		rcu_read_unlock();
+	}
+
 	/*
 	 * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
 	 * We still associate in non-HT mode (11a/b/g) if any one of these
@@ -4224,18 +4290,22 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 	/* Also disable HT if we don't support it or the AP doesn't use WMM */
 	sband = local->hw.wiphy->bands[req->bss->channel->band];
 	if (!sband->ht_cap.ht_supported ||
-	    local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
+	    local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
+	    ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
 		ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
-		if (!bss->wmm_used)
+		if (!bss->wmm_used &&
+		    !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
 			netdev_info(sdata->dev,
 				    "disabling HT as WMM/QoS is not supported by the AP\n");
 	}
 
 	/* disable VHT if we don't support it or the AP doesn't use WMM */
 	if (!sband->vht_cap.vht_supported ||
-	    local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) {
+	    local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used ||
+	    ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
 		ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
-		if (!bss->wmm_used)
+		if (!bss->wmm_used &&
+		    !(ifmgd->flags & IEEE80211_STA_DISABLE_WMM))
 			netdev_info(sdata->dev,
 				    "disabling VHT as WMM/QoS is not supported by the AP\n");
 	}
@@ -4264,8 +4334,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 		sdata->smps_mode = ifmgd->req_smps;
 
 	assoc_data->capability = req->bss->capability;
-	assoc_data->wmm = bss->wmm_used &&
-			  (local->hw.queues >= IEEE80211_NUM_ACS);
 	assoc_data->supp_rates = bss->supp_rates;
 	assoc_data->supp_rates_len = bss->supp_rates_len;
 
-- 
1.8.4.rc3


^ permalink raw reply related

* Re: [PATCH 3.12 3/3] mac80211: sanity check WMM/QoS parameters
From: Johannes Berg @ 2013-10-17  7:46 UTC (permalink / raw)
  To: linux-wireless
In-Reply-To: <1381843030-12260-3-git-send-email-johannes@sipsolutions.net>

On Tue, 2013-10-15 at 15:17 +0200, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> Check for invalid WMM parameters (AIFSN < 2 or CWmax < CWmin)
> and try to set them to usable values in this case.
> 
> Notably the Sitecom WL-153 v1 with firmware 1.45 is sending
> AIFSN, ECWmin and ECWmax as all zero.

We reviewed this and decided that it would be more robust to connect as
a non-WMM station, since we can't know what other parameters are wrong.
I've just posted a replacement patch to that effect.

johannes


^ permalink raw reply

* [PATCH] ath10k: add error handling to ath10k_pci_wait()
From: Kalle Valo @ 2013-10-17  8:36 UTC (permalink / raw)
  To: ath10k; +Cc: linux-wireless

ath10k_pci_wait() didn't notify any errors to callers, it
just printed a warning so add proper error handling.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c |   28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 1e9cfcc9..92759cd 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -525,15 +525,19 @@ static bool ath10k_pci_target_is_awake(struct ath10k *ar)
 	return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON);
 }
 
-static void ath10k_pci_wait(struct ath10k *ar)
+static int ath10k_pci_wait(struct ath10k *ar)
 {
 	int n = 100;
 
 	while (n-- && !ath10k_pci_target_is_awake(ar))
 		msleep(10);
 
-	if (n < 0)
+	if (n < 0) {
 		ath10k_warn("Unable to wakeup target\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
 }
 
 int ath10k_do_pci_wake(struct ath10k *ar)
@@ -2227,7 +2231,13 @@ static int ath10k_pci_start_intr_legacy(struct ath10k *ar)
 		  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
 		  PCIE_SOC_WAKE_ADDRESS);
 
-	ath10k_pci_wait(ar);
+	ret = ath10k_pci_wait(ar);
+	if (ret) {
+		ath10k_warn("Failed to enable legacy interrupt, target did not wake up: %d\n",
+			    ret);
+		free_irq(ar_pci->pdev->irq, ar);
+		return ret;
+	}
 
 	/*
 	 * A potential race occurs here: The CORE_BASE write
@@ -2290,6 +2300,10 @@ static int ath10k_pci_start_intr(struct ath10k *ar)
 	}
 
 	ret = ath10k_pci_start_intr_legacy(ar);
+	if (ret) {
+		ath10k_warn("Failed to start legacy interrupts: %d\n", ret);
+		return ret;
+	}
 
 exit:
 	ar_pci->num_msi_intrs = num;
@@ -2315,13 +2329,19 @@ static int ath10k_pci_reset_target(struct ath10k *ar)
 {
 	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
 	int wait_limit = 300; /* 3 sec */
+	int ret;
 
 	/* Wait for Target to finish initialization before we proceed. */
 	iowrite32(PCIE_SOC_WAKE_V_MASK,
 		  ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS +
 		  PCIE_SOC_WAKE_ADDRESS);
 
-	ath10k_pci_wait(ar);
+	ret = ath10k_pci_wait(ar);
+	if (ret) {
+		ath10k_warn("Failed to reset target, target did not wake up: %d\n",
+			    ret);
+		return ret;
+	}
 
 	while (wait_limit-- &&
 	       !(ioread32(ar_pci->mem + FW_INDICATOR_ADDRESS) &


^ permalink raw reply related

* Pull request: ath 20131017
From: Kalle Valo @ 2013-10-17  9:06 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, ath10k, ath6kl-devel

Hi John,

here's a pull request for ath6kl and ath10k. Notable changes:

Bartosz added support to ath10k for our 10.x AP firmware branch, which
gives us AP specific features and fixes. We still support the main
firmware branch as well just like before, ath10k detects runtime what
firmware is used. Unfortunately the firmware interface in 10.x branch is
somewhat different so there was quite a lot of changes in ath10k for
this.

Michal and Sujith did some performance improvements in ath10k. Vladimir
fixed a compiler warning and Fengguang removed an extra semicolon.

Please let me know if there are any problems.

Kalle

The following changes since commit 6e712d427cb0542afdd5220edb6e4f4f8a5b952d:

  ath10k: replenish HTT RX buffers in a tasklet (2013-09-26 17:22:54 +0300)

are available in the git repository at:

  git://github.com/kvalo/ath.git for-linville

for you to fetch changes up to 56b84287d14aa74823a9c290d0c5839d38365110:

  ath10k: add might_sleep() to ath10k_wmi_cmd_send() (2013-10-16 15:44:47 +0300)

----------------------------------------------------------------
Bartosz Markowski (18):
      ath10k: introduce dynamic WMI structures
      ath10k: add wmi_10x_<cmd/event> definitions
      ath10k: warn if give WMI command is not supported
      ath10k: implement WMI events handling frame for both firmwares
      ath10k: split ath10k_wmi_service_ready_event_rx
      ath10k: drop the fw versioning sanity check
      ath10k: implement host memory chunks
      ath10k: bring back the WMI path for mgmt frames
      ath10k: split wmi_cmd_init path
      ath10k: add TARGET values for 10.x firmware
      ath10k: introduce dynamic vdev parameters
      ath10k: introduce dynamic pdev parameters
      ath10k: handle FW API differences for scan structures
      ath10k: enable 10.x firmware branch support
      ath10k: extend the max_scan time
      ath10k: do not warn about unsupported vdev param
      ath10k: rename WMI_CMD_UNDEFINED
      ath10k: return better errno for unsupported pdev params

Fengguang Wu (1):
      ath10k: remove unneded semicolon from ath10k_core_fetch_firmware_api_n()

Kalle Valo (6):
      ath10k: rename board_data in struct ath10k
      ath10k: store separate pointers for firmware data
      ath10k: implement firmware IE container support
      ath10k: fix ath10k_debug_start() locking
      ath10k: fix ath10k_bss_assoc() to not sleep in atomic context
      ath10k: add might_sleep() to ath10k_wmi_cmd_send()

Marek Puzyniak (1):
      ath10k: make monitor vdev down before stoping it

Michal Kazior (12):
      ath10k: split tid calculation from tx function
      ath10k: split vdev_id calculation from tx function
      ath10k: remove ce_sendlist_send
      ath10k: remove num_sends_allowed
      ath10k: fix printf format string
      ath10k: fix possible memory leak in new FW loading
      ath10k: fix RX performance when using AP 10.X FW
      ath10k: use workqueue to set WEP TX key
      ath10k: fix add_interface failure handling
      ath10k: track vif list internally
      ath10k: fix scheduling while atomic config bug
      ath10k: remove unnecessary checks

Sujith Manoharan (1):
      ath10k: Fix bug in max. VHT A-MPDU size

Vladimir Murzin (1):
      ath6kl: fix compilation warning in ath6kl_htc_pipe_conn_service

 drivers/net/wireless/ath/ath10k/ce.c     |   35 +-
 drivers/net/wireless/ath/ath10k/ce.h     |   16 +-
 drivers/net/wireless/ath/ath10k/core.c   |  285 ++++++--
 drivers/net/wireless/ath/ath10k/core.h   |   47 +-
 drivers/net/wireless/ath/ath10k/debug.c  |   15 +-
 drivers/net/wireless/ath/ath10k/debug.h  |    5 +
 drivers/net/wireless/ath/ath10k/htt_tx.c |    4 +-
 drivers/net/wireless/ath/ath10k/hw.h     |   56 +-
 drivers/net/wireless/ath/ath10k/mac.c    |  512 ++++++++------
 drivers/net/wireless/ath/ath10k/mac.h    |    2 +
 drivers/net/wireless/ath/ath10k/pci.c    |   25 +-
 drivers/net/wireless/ath/ath10k/pci.h    |    3 -
 drivers/net/wireless/ath/ath10k/wmi.c    | 1087 ++++++++++++++++++++++++++++--
 drivers/net/wireless/ath/ath10k/wmi.h    |  968 +++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath6kl/htc.h    |    2 +-
 15 files changed, 2674 insertions(+), 388 deletions(-)

^ permalink raw reply

* Re: Power saving features for iwl4965
From: Stanislaw Gruszka @ 2013-10-17  9:06 UTC (permalink / raw)
  To: Pedro Francisco; +Cc: Tino Keitel, ML linux-wireless
In-Reply-To: <CAJZjf_x3xwMijn5Jjc0qAaFdzq-4sH-gtm+hv5jKVpFCSBu0=Q@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2086 bytes --]

On Sun, Aug 04, 2013 at 03:53:14PM +0100, Pedro Francisco wrote:
> On Sun, Aug 4, 2013 at 3:24 PM, Pedro Francisco
> <pedrogfrancisco@gmail.com> wrote:
> > On Wed, Jul 31, 2013 at 1:08 PM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> >> On Wed, Jul 17, 2013 at 12:48:30PM +0100, Pedro Francisco wrote:
> >>> On Tue, Jul 16, 2013 at 11:27 AM, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> >>> >> I seem only to be able to trigger it with disable_hw_scan=0, I need
> >>> >> further testing with disable_hw_scan=1 (I use disable_hw_scan=0
> >>> >> because it prevents me from getting disconnected from eduroam Cisco
> >>> >> APs -- haven't tested disable_hw_scan=0 since the VOIP-friendly SW
> >>> >> scanning patch, however).
> >>> >>
> >>> >> Do you want the log anyway? (modprobe iwl3945 debug=0x47ffffff
> >>> >> disable_hw_scan=0 and runtime PCI powersave also enabled -- I don't
> >>> >> know if it matters).
> >>> >
> >>> > As this is not causing troubles with default disable_hw_scan option,
> >>> > I'll post that patch.
> >>>
> >>> My mistake, I can trigger error conditions _independently_ of
> >>> disable_hw_scan option being enabled or disabled, as long as powersave
> >>> is enabled.
> >>>
> >>> I'll send you a private email with the logs.
> >>
> >> I think I found bug which couse this firmware crash. We have only 5
> >> queues so updating write_ptr for txq[5] can cause random value write
> >> to HBUS_TARG_WRPTR register. I also added spin_lock to do not abuse
> >> writes we do in tx skb.
> >>
> >> Please test attached patch (with powersave on :-)
> >
> > Still not working :( I tested for two nights, first one was fine,
> > second was not (the only difference was I had kernel parameter
> > `slub_debug` on the second night, but my guess it shouldn't affect
> > anything?).
> >
> > Snippet of log follows, full logs I'll send privately (beware,
> > unzipped it's 423MB).

Sorry for late answer. I have two more patches, which perhaps make
powersave stop crashing on 3945. Please test them (note that I only
compile tested, be carefull :-)

Thanks
Stanislaw


[-- Attachment #2: 0001-iwlegacy-poke-device-when-waiting-for-hcmd.patch --]
[-- Type: text/plain, Size: 2005 bytes --]

>From c9da2966ce58ed1446367a0b14b0953ebc3fbfbe Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Thu, 17 Oct 2013 10:48:44 +0200
Subject: [PATCH 1/2] iwlegacy poke device when waiting for hcmd

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/iwlegacy/common.c |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index b03e22e..7ada864 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -254,8 +254,6 @@ il_get_cmd_string(u8 cmd)
 }
 EXPORT_SYMBOL(il_get_cmd_string);
 
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
-
 static void
 il_generic_cmd_callback(struct il_priv *il, struct il_device_cmd *cmd,
 			struct il_rx_pkt *pkt)
@@ -305,11 +303,15 @@ il_send_cmd_async(struct il_priv *il, struct il_host_cmd *cmd)
 	return 0;
 }
 
+#define HOST_COMPLETE_TIMEOUT (HZ / 2)
+#define COMMAND_POKE_TIMEOUT  (HZ / 10)
+
 int
 il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd)
 {
-	int cmd_idx;
-	int ret;
+	unsigned long flags;
+	int cmd_idx, ret;
+	int timeout = HOST_COMPLETE_TIMEOUT;
 
 	lockdep_assert_held(&il->mutex);
 
@@ -333,9 +335,20 @@ il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd)
 		goto out;
 	}
 
-	ret = wait_event_timeout(il->wait_command_queue,
-				 !test_bit(S_HCMD_ACTIVE, &il->status),
-				 HOST_COMPLETE_TIMEOUT);
+	while (timeout) {
+		ret = wait_event_timeout(il->wait_command_queue,
+					 !test_bit(S_HCMD_ACTIVE, &il->status),
+					 COMMAND_POKE_TIMEOUT);
+		if (ret)
+			break;
+
+		/* Poke the device, it may have lost the command. */
+		spin_lock_irqsave(&il->reg_lock, flags);
+		_il_grab_nic_access(il);
+		_il_release_nic_access(il);
+		spin_unlock_irqrestore(&il->reg_lock, flags);
+	}
+
 	if (!ret) {
 		if (test_bit(S_HCMD_ACTIVE, &il->status)) {
 			IL_ERR("Error sending %s: time out after %dms.\n",
-- 
1.7.1


[-- Attachment #3: 0002-iwlegacy-merge-and-fix-reclaim-for-3945.patch --]
[-- Type: text/plain, Size: 3829 bytes --]

>From 05b86620fcec5f18293b0df2a4dddbe34ae24125 Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Thu, 17 Oct 2013 11:03:21 +0200
Subject: [PATCH 2/2] iwlegacy: merge and fix reclaim for 3945

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/iwlegacy/3945-mac.c |    9 +--------
 drivers/net/wireless/iwlegacy/4965-mac.c |   12 +-----------
 drivers/net/wireless/iwlegacy/common.h   |   14 ++++++++++++++
 3 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index dea3b50..d7c8dd3 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -1248,14 +1248,7 @@ il3945_rx_handle(struct il_priv *il)
 		len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK;
 		len += sizeof(u32);	/* account for status word */
 
-		/* Reclaim a command buffer only if this packet is a response
-		 *   to a (driver-originated) command.
-		 * If the packet (e.g. Rx frame) originated from uCode,
-		 *   there is no command buffer to reclaim.
-		 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
-		 *   but apparently a few don't get set; catch them here. */
-		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
-		    pkt->hdr.cmd != N_STATS && pkt->hdr.cmd != C_TX;
+		reclaim = il_need_reclaim(il, pkt);
 
 		/* Based on type of command response or notification,
 		 *   handle those that need handling via function in
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 86812b9..97cfaa9 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -4274,17 +4274,7 @@ il4965_rx_handle(struct il_priv *il)
 		len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK;
 		len += sizeof(u32);	/* account for status word */
 
-		/* Reclaim a command buffer only if this packet is a response
-		 *   to a (driver-originated) command.
-		 * If the packet (e.g. Rx frame) originated from uCode,
-		 *   there is no command buffer to reclaim.
-		 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
-		 *   but apparently a few don't get set; catch them here. */
-		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
-		    (pkt->hdr.cmd != N_RX_PHY) && (pkt->hdr.cmd != N_RX) &&
-		    (pkt->hdr.cmd != N_RX_MPDU) &&
-		    (pkt->hdr.cmd != N_COMPRESSED_BA) &&
-		    (pkt->hdr.cmd != N_STATS) && (pkt->hdr.cmd != C_TX);
+		reclaim = il_need_reclaim(il, pkt);
 
 		/* Based on type of command response or notification,
 		 *   handle those that need handling via function in
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index 83f8ed8..eccd6a4 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1978,6 +1978,20 @@ extern void il_wr_prph(struct il_priv *il, u32 addr, u32 val);
 extern u32 il_read_targ_mem(struct il_priv *il, u32 addr);
 extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val);
 
+static inline bool il_need_reclaim(struct il_priv *il, struct il_rx_pkt *pkt)
+{
+	/* Reclaim a command buffer only if this packet is a response
+	 * to a (driver-originated) command. If the packet (e.g. Rx frame)
+	 * originated from uCode, there is no command buffer to reclaim.
+	 * Ucode should set SEQ_RX_FRAME bit if ucode-originated, but
+	 * apparently a few don't get set; catch them here.
+	 */
+	return !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
+	       pkt->hdr.cmd != N_STATS && pkt->hdr.cmd != C_TX &&
+	       pkt->hdr.cmd != N_RX_PHY && pkt->hdr.cmd != N_RX &&
+	       pkt->hdr.cmd != N_RX_MPDU && pkt->hdr.cmd != N_COMPRESSED_BA;
+}
+
 static inline void
 _il_write8(struct il_priv *il, u32 ofs, u8 val)
 {
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH 3.12] mac80211: disable WMM with invalid parameters
From: Eliad Peller @ 2013-10-17  9:41 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linux-wireless@vger.kernel.org, Antonio Quartulli, Johannes Berg
In-Reply-To: <1381995881-16935-1-git-send-email-johannes@sipsolutions.net>

On Thu, Oct 17, 2013 at 10:44 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Some APs (notably a Sitecom WL-153 v1 with firmware 1.45) are sending
> invalid WMM parameters setting AIFSN, ECWmin and ECWmax to zero. The
> spec mandates that the value of AIFSN is at least 2, and some cards
> (e.g. Intel with the iwldvm driver) can't transmit when the invalid
> QoS parameters are actually uploaded to the firmware.
>
> Since there's little chance of being able to guess the values that
> the AP actually meant, disable WMM if such an invalid case is found.
> Since ECWmin/ECWmax are allowed to be zero, only verify AIFSN >= 2
> and ECWmin <= ECWmax.
>
> Reported-by: Antonio Quartulli <antonio@meshcoding.com>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
[...]

> @@ -4192,9 +4231,36 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
>         }
>
>         /* prepare assoc data */
> -
> +
>         ifmgd->beacon_crc_valid = false;
>
> +       assoc_data->wmm = bss->wmm_used &&
> +                         (local->hw.queues >= IEEE80211_NUM_ACS);
> +       if (assoc_data->wmm) {
> +               /* try to check validity of WMM params IE */
> +               const struct cfg80211_bss_ies *ies;
> +               const u8 *wp, *start;
> +               int len;
> +
> +               rcu_read_lock();
> +               ies = rcu_dereference(req->bss->ies);
> +               start = ies->data;
> +               len = ies->len;
> +
> +               do {
> +                       wp = cfg80211_find_vendor_ie(0x0050F2, 2, start, len);
> +                       start = wp;
> +                       len -= wp[1];
you might NULL deref here.
but i don't really see how this calculation makes sense anyway (you
should probably increase start and take care of the  ie's id+len (i.e.
wp[1] + 2) as well)?

Eliad.

^ permalink raw reply

* [PATCH 3.12] rt2800usb: slow down TX status polling
From: Stanislaw Gruszka @ 2013-10-17 10:04 UTC (permalink / raw)
  To: linux-wireless; +Cc: users

Polling TX statuses too frequently has two negative effects. First is
randomly peek CPU usage, causing overall system functioning delays.
Second bad effect is that device is not able to fill TX statuses in
H/W register on some workloads and we get lot of timeouts like below:

ieee80211 phy4: rt2800usb_entry_txstatus_timeout: Warning - TX status timeout for entry 7 in queue 2
ieee80211 phy4: rt2800usb_entry_txstatus_timeout: Warning - TX status timeout for entry 7 in queue 2
ieee80211 phy4: rt2800usb_txdone: Warning - Got TX status for an empty queue 2, dropping

This not only cause flood of messages in dmesg, but also bad throughput,
since rate scaling algorithm can not work optimally.

In the future, we should probably make polling interval be adjusted
automatically, but for now just increase values, this make mentioned
problems gone.

Resolve:
https://bugzilla.kernel.org/show_bug.cgi?id=62781

Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/rt2x00/rt2800usb.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 96677ce5..e095e61 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -176,8 +176,8 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
 		queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
 
 	if (rt2800usb_txstatus_pending(rt2x00dev)) {
-		/* Read register after 250 us */
-		hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000),
+		/* Read register after 1 ms */
+		hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 1000000),
 			      HRTIMER_MODE_REL);
 		return false;
 	}
@@ -202,8 +202,8 @@ static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev)
 	if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags))
 		return;
 
-	/* Read TX_STA_FIFO register after 500 us */
-	hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000),
+	/* Read TX_STA_FIFO register after 2 ms */
+	hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 2000000),
 		      HRTIMER_MODE_REL);
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH 3.12] mac80211: disable WMM with invalid parameters
From: Johannes Berg @ 2013-10-17 11:10 UTC (permalink / raw)
  To: Eliad Peller; +Cc: linux-wireless@vger.kernel.org, Antonio Quartulli
In-Reply-To: <CAB3XZEff+Xguf_Bk7p4S2N3j03dT1tB0u1u8enP4cd8NtD2jnA@mail.gmail.com>

On Thu, 2013-10-17 at 11:41 +0200, Eliad Peller wrote:

> > +               do {
> > +                       wp = cfg80211_find_vendor_ie(0x0050F2, 2, start, len);
> > +                       start = wp;
> > +                       len -= wp[1];
> you might NULL deref here.
> but i don't really see how this calculation makes sense anyway (you
> should probably increase start and take care of the  ie's id+len (i.e.
> wp[1] + 2) as well)?

Yeah, that loop was pretty bogus ...

while (true) {
        wp = cfg80211_find_vendor_ie(
                WLAN_OUI_MICROSOFT,
                WLAN_OUI_TYPE_MICROSOFT_WMM,
                start, len);
        if (!wp)
                break;
        start = wp;
        len -= wp[1] + 2;
        /* if this IE is too short, try the next */
        if (wp[1] <= 4)
                continue;
        /* if this IE is WMM params, we found what we wanted */
        if (wp[6] == 1)
                break;
}

is better, I think?

johannes


^ permalink raw reply

* Re: [PATCH 3.12 1/3] mac80211: fix honouring rate flags in low-rate transmit
From: Johannes Berg @ 2013-10-17 11:35 UTC (permalink / raw)
  To: linux-wireless; +Cc: Andrei Otcheretianski
In-Reply-To: <1381843030-12260-1-git-send-email-johannes@sipsolutions.net>

On Tue, 2013-10-15 at 15:17 +0200, Johannes Berg wrote:
> From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
> 
> Transmissions with the IEEE80211_TX_CTL_NO_CCK_RATE flag set
> (which can come from userspace) were no longer guaranteed to
> be transmitted with allowed rates since commit 2103dec14792b
> ("mac80211: select and adjust bitrates according to channel
> mode") due to a missing rate_flags check in that commit. The
> commit also introduced the need to check the 5/10 MHz flags
> but accidentally didn't. Fix it by adding the missing check.

Applied 1 and 2.

johannes


^ permalink raw reply

* Re: [PATCH 5/5] net: rfkill: gpio: add ACPI support
From: Rafael J. Wysocki @ 2013-10-17 11:48 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Heikki Krogerus, John W. Linville, Johannes Berg, Rhyland Klein,
	linux-acpi, linux-wireless, netdev
In-Reply-To: <20131017074426.GG3521@intel.com>

On Thursday, October 17, 2013 10:44:26 AM Mika Westerberg wrote:
> On Wed, Oct 16, 2013 at 10:55:01PM +0200, Rafael J. Wysocki wrote:
> > On Wednesday, October 16, 2013 01:53:43 PM Heikki Krogerus wrote:
> > > Including ACPI ID for Broadcom GPS receiver BCM4752.
> > > 
> > > Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> > > ---
> > >  net/rfkill/rfkill-gpio.c | 31 ++++++++++++++++++++++++++++++-
> > >  1 file changed, 30 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
> > > index 2dd78c6..5620d3c 100644
> > > --- a/net/rfkill/rfkill-gpio.c
> > > +++ b/net/rfkill/rfkill-gpio.c
> > > @@ -24,6 +24,8 @@
> > >  #include <linux/platform_device.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/slab.h>
> > > +#include <linux/acpi.h>
> > > +#include <linux/acpi_gpio.h>
> > >  
> > >  #include <linux/rfkill-gpio.h>
> > >  
> > > @@ -70,6 +72,23 @@ static const struct rfkill_ops rfkill_gpio_ops = {
> > >  	.set_block = rfkill_gpio_set_power,
> > >  };
> > >  
> > > +static int rfkill_gpio_acpi_probe(struct device *dev,
> > > +				  struct rfkill_gpio_data *rfkill)
> > > +{
> > > +	const struct acpi_device_id *id;
> > > +
> > > +	id = acpi_match_device(dev->driver->acpi_match_table, dev);
> > > +	if (!id)
> > > +		return -ENODEV;
> > > +
> > > +	rfkill->name = dev_name(dev);
> > > +	rfkill->type = (unsigned)id->driver_data;
> > > +	rfkill->reset_gpio = acpi_get_gpio_by_index(dev, 0, NULL);
> > > +	rfkill->shutdown_gpio = acpi_get_gpio_by_index(dev, 1, NULL);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static int rfkill_gpio_probe(struct platform_device *pdev)
> > >  {
> > >  	struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data;
> > > @@ -82,7 +101,11 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
> > >  	if (!rfkill)
> > >  		return -ENOMEM;
> > >  
> > > -	if (pdata) {
> > > +	if (ACPI_HANDLE(&pdev->dev)) {
> > > +		ret = rfkill_gpio_acpi_probe(&pdev->dev, rfkill);
> > > +		if (ret)
> > > +			return ret;
> > > +	} else if (pdata) {
> > >  		clk_name = pdata->power_clk_name;
> > >  		rfkill->name = pdata->name;
> > >  		rfkill->type = pdata->type;
> > > @@ -170,12 +193,18 @@ static int rfkill_gpio_remove(struct platform_device *pdev)
> > >  	return 0;
> > >  }
> > >  
> > > +static const struct acpi_device_id rfkill_acpi_match[] = {
> > > +	{ "BCM4752", RFKILL_TYPE_GPS },
> > > +	{ },
> > > +};
> > > +
> > >  static struct platform_driver rfkill_gpio_driver = {
> > >  	.probe = rfkill_gpio_probe,
> > >  	.remove = rfkill_gpio_remove,
> > >  	.driver = {
> > >  		.name = "rfkill_gpio",
> > >  		.owner = THIS_MODULE,
> > > +		.acpi_match_table = ACPI_PTR(rfkill_acpi_match),
> > >  	},
> > >  };
> > 
> > Looks good to me.
> > 
> > Has Mika seen this?
> 
> Yes, saw it now and looks good to me as well.
> 
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> for the whole series, for what it's worth.

OK, so

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

for the ACPI-related changes.

Thanks!

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply

* Re: Power saving features for iwl4965
From: Stanislaw Gruszka @ 2013-10-17 13:32 UTC (permalink / raw)
  To: Pedro Francisco; +Cc: Tino Keitel, ML linux-wireless
In-Reply-To: <20131017090654.GA21496@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 307 bytes --]

On Thu, Oct 17, 2013 at 11:06:55AM +0200, Stanislaw Gruszka wrote:
> Sorry for late answer. I have two more patches, which perhaps make
> powersave stop crashing on 3945. Please test them (note that I only
> compile tested, be carefull :-)

First patch has a bug. I'm attaching improved version.

Stanislaw

[-- Attachment #2: 0001-iwlegacy-poke-device-when-waiting-for-hcmd.patch --]
[-- Type: text/plain, Size: 2045 bytes --]

>From dae9f167853f266d5efe688f965968725375e2ae Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Thu, 17 Oct 2013 15:30:07 +0200
Subject: [PATCH] iwlegacy poke device when waiting for hcmd

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/iwlegacy/common.c | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index b03e22e..3d8dae3c 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -254,8 +254,6 @@ il_get_cmd_string(u8 cmd)
 }
 EXPORT_SYMBOL(il_get_cmd_string);
 
-#define HOST_COMPLETE_TIMEOUT (HZ / 2)
-
 static void
 il_generic_cmd_callback(struct il_priv *il, struct il_device_cmd *cmd,
 			struct il_rx_pkt *pkt)
@@ -305,11 +303,15 @@ il_send_cmd_async(struct il_priv *il, struct il_host_cmd *cmd)
 	return 0;
 }
 
+#define HOST_COMPLETE_TIMEOUT (HZ / 2)
+#define COMMAND_POKE_TIMEOUT  (HZ / 10)
+
 int
 il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd)
 {
-	int cmd_idx;
-	int ret;
+	unsigned long flags;
+	int cmd_idx, ret;
+	int timeout = HOST_COMPLETE_TIMEOUT;
 
 	lockdep_assert_held(&il->mutex);
 
@@ -333,9 +335,22 @@ il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd)
 		goto out;
 	}
 
-	ret = wait_event_timeout(il->wait_command_queue,
-				 !test_bit(S_HCMD_ACTIVE, &il->status),
-				 HOST_COMPLETE_TIMEOUT);
+	while (timeout > 0) {
+		ret = wait_event_timeout(il->wait_command_queue,
+					 !test_bit(S_HCMD_ACTIVE, &il->status),
+					 COMMAND_POKE_TIMEOUT);
+		if (ret)
+			break;
+
+		/* Poke the device, it may have lost the command. */
+		spin_lock_irqsave(&il->reg_lock, flags);
+		_il_grab_nic_access(il);
+		_il_release_nic_access(il);
+		spin_unlock_irqrestore(&il->reg_lock, flags);
+
+		timeout -= COMMAND_POKE_TIMEOUT;
+	}
+
 	if (!ret) {
 		if (test_bit(S_HCMD_ACTIVE, &il->status)) {
 			IL_ERR("Error sending %s: time out after %dms.\n",
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH 3.12] mac80211: disable WMM with invalid parameters
From: Johannes Berg @ 2013-10-17 13:39 UTC (permalink / raw)
  To: linux-wireless; +Cc: Antonio Quartulli
In-Reply-To: <1381995881-16935-1-git-send-email-johannes@sipsolutions.net>

On Thu, 2013-10-17 at 09:44 +0200, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
> 
> Some APs (notably a Sitecom WL-153 v1 with firmware 1.45) are sending
> invalid WMM parameters setting AIFSN, ECWmin and ECWmax to zero. The
> spec mandates that the value of AIFSN is at least 2, and some cards
> (e.g. Intel with the iwldvm driver) can't transmit when the invalid
> QoS parameters are actually uploaded to the firmware.
> 
> Since there's little chance of being able to guess the values that
> the AP actually meant, disable WMM if such an invalid case is found.
> Since ECWmin/ECWmax are allowed to be zero, only verify AIFSN >= 2
> and ECWmin <= ECWmax.

I've applied a fixed version.

johannes


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox