2013-01-28 16:32:31

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 00/14] wil6210: assorted fixes

Following is collection of ready for integration fixes,
tested in the lab.

Vladimir Kondratiev (14):
wil6210: Detect FW error
wil6210: rearrange IRQ debug printing
wil6210: remove raw wil_dbg() calls
wil6210: Refactor rx init/fini
wil6210: Count Tx statistics on Tx completion
wil6210: Fix: Tx stall
wil6210: Call skb_orphan() right before Rx indication
wil6210: Fix "don't scan after connect" logic
wil6210: Separate common code for mbox regs caching to function
wil6210: Reorder reset preparation sequence
wil6210: fix checkpatch CamelCase warnings
wil6210: checkpatch warnings
wil6210: Never delete Rx chain with firmware
wil6210: fix wil_vring_init_tx status

drivers/net/wireless/ath/wil6210/cfg80211.c | 9 +--
drivers/net/wireless/ath/wil6210/interrupt.c | 55 ++++++++-----
drivers/net/wireless/ath/wil6210/main.c | 63 +++++++--------
drivers/net/wireless/ath/wil6210/netdev.c | 31 +-------
drivers/net/wireless/ath/wil6210/pcie_bus.c | 4 +-
drivers/net/wireless/ath/wil6210/txrx.c | 107 ++++++++------------------
drivers/net/wireless/ath/wil6210/wil6210.h | 22 +++---
drivers/net/wireless/ath/wil6210/wmi.c | 107 +++++++++++++++++++-------
8 files changed, 199 insertions(+), 199 deletions(-)

--
1.7.10.4



2013-01-28 16:38:31

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 08/14] wil6210: Fix "don't scan after connect" logic

When connect times out, scan was not re-enabled.

Strictly say, it is firmware issue - it should issue "disconnect"
event but it does not. Compensate in the driver.

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/main.c | 2 ++
drivers/net/wireless/ath/wil6210/wmi.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 90786df..3e9a71f 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -85,6 +85,8 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)

for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
wil_vring_fini_tx(wil, i);
+
+ clear_bit(wil_status_dontscan, &wil->status);
}

static void wil_disconnect_worker(struct work_struct *work)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index d109c3f..dffb002 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -459,7 +459,6 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
wil->sinfo_gen++;

wil6210_disconnect(wil, evt->bssid);
- clear_bit(wil_status_dontscan, &wil->status);
}

static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
--
1.7.10.4


2013-01-28 16:32:42

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 05/14] wil6210: Count Tx statistics on Tx completion

This allows to account for Tx errors

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/txrx.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index f3b523b..e7ea538 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -752,8 +752,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
}
switch (rc) {
case 0:
- ndev->stats.tx_packets++;
- ndev->stats.tx_bytes += skb->len;
+ /* statistics will be updated on the tx_complete */
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
case -ENOMEM:
@@ -777,6 +776,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
*/
void wil_tx_complete(struct wil6210_priv *wil, int ringid)
{
+ struct net_device *ndev = wil_to_ndev(wil);
struct device *dev = wil_to_dev(wil);
struct vring *vring = &wil->vring_tx[ringid];

@@ -804,6 +804,13 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
skb = vring->ctx[vring->swtail];
if (skb) {
+ if (d->dma.error == 0) {
+ ndev->stats.tx_packets++;
+ ndev->stats.tx_bytes += skb->len;
+ } else {
+ ndev->stats.tx_errors++;
+ }
+
dma_unmap_single(dev, pa, d->dma.length, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
vring->ctx[vring->swtail] = NULL;
--
1.7.10.4


2013-01-28 16:38:23

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 03/14] wil6210: remove raw wil_dbg() calls

Introduce debug category "MISC", convert all raw wil_dbg() to this category.
This improves dynamic debug manageability

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 8 ++++----
drivers/net/wireless/ath/wil6210/main.c | 28 +++++++++++++--------------
drivers/net/wireless/ath/wil6210/pcie_bus.c | 4 ++--
drivers/net/wireless/ath/wil6210/txrx.c | 8 ++++----
drivers/net/wireless/ath/wil6210/wil6210.h | 1 +
5 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 116f4e8..56f39b6 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -228,8 +228,8 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
}
/* 0-based channel indexes */
cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
- wil_dbg(wil, "Scan for ch %d : %d MHz\n", ch,
- request->channels[i]->center_freq);
+ wil_dbg_MISC(wil, "Scan for ch %d : %d MHz\n", ch,
+ request->channels[i]->center_freq);
}

return wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
@@ -425,8 +425,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
return -EINVAL;
}

- wil_dbg(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
- channel->center_freq, info->privacy ? "secure" : "open");
+ wil_dbg_MISC(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
+ channel->center_freq, info->privacy ? "secure" : "open");
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
info->ssid, info->ssid_len);

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 95fcd36..90786df 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -64,7 +64,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
struct net_device *ndev = wil_to_ndev(wil);
struct wireless_dev *wdev = wil->wdev;

- wil_dbg(wil, "%s()\n", __func__);
+ wil_dbg_MISC(wil, "%s()\n", __func__);

wil_link_off(wil);
clear_bit(wil_status_fwconnected, &wil->status);
@@ -99,7 +99,7 @@ static void wil_connect_timer_fn(ulong x)
{
struct wil6210_priv *wil = (void *)x;

- wil_dbg(wil, "Connect timeout\n");
+ wil_dbg_MISC(wil, "Connect timeout\n");

/* reschedule to thread context - disconnect won't
* run from atomic context
@@ -109,7 +109,7 @@ static void wil_connect_timer_fn(ulong x)

int wil_priv_init(struct wil6210_priv *wil)
{
- wil_dbg(wil, "%s()\n", __func__);
+ wil_dbg_MISC(wil, "%s()\n", __func__);

mutex_init(&wil->mutex);
mutex_init(&wil->wmi_mutex);
@@ -162,7 +162,7 @@ void wil_priv_deinit(struct wil6210_priv *wil)

static void wil_target_reset(struct wil6210_priv *wil)
{
- wil_dbg(wil, "Resetting...\n");
+ wil_dbg_MISC(wil, "Resetting...\n");

/* register write */
#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a))
@@ -202,7 +202,7 @@ static void wil_target_reset(struct wil6210_priv *wil)

msleep(2000);

- wil_dbg(wil, "Reset completed\n");
+ wil_dbg_MISC(wil, "Reset completed\n");

#undef W
#undef S
@@ -225,8 +225,8 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
wil_err(wil, "Firmware not ready\n");
return -ETIME;
} else {
- wil_dbg(wil, "FW ready after %d ms\n",
- jiffies_to_msecs(to-left));
+ wil_dbg_MISC(wil, "FW ready after %d ms\n",
+ jiffies_to_msecs(to-left));
}
return 0;
}
@@ -278,7 +278,7 @@ void wil_link_on(struct wil6210_priv *wil)
{
struct net_device *ndev = wil_to_ndev(wil);

- wil_dbg(wil, "%s()\n", __func__);
+ wil_dbg_MISC(wil, "%s()\n", __func__);

netif_carrier_on(ndev);
netif_tx_wake_all_queues(ndev);
@@ -288,7 +288,7 @@ void wil_link_off(struct wil6210_priv *wil)
{
struct net_device *ndev = wil_to_ndev(wil);

- wil_dbg(wil, "%s()\n", __func__);
+ wil_dbg_MISC(wil, "%s()\n", __func__);

netif_tx_stop_all_queues(ndev);
netif_carrier_off(ndev);
@@ -311,27 +311,27 @@ static int __wil_up(struct wil6210_priv *wil)
wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
switch (wdev->iftype) {
case NL80211_IFTYPE_STATION:
- wil_dbg(wil, "type: STATION\n");
+ wil_dbg_MISC(wil, "type: STATION\n");
bi = 0;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_AP:
- wil_dbg(wil, "type: AP\n");
+ wil_dbg_MISC(wil, "type: AP\n");
bi = 100;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_P2P_CLIENT:
- wil_dbg(wil, "type: P2P_CLIENT\n");
+ wil_dbg_MISC(wil, "type: P2P_CLIENT\n");
bi = 0;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_P2P_GO:
- wil_dbg(wil, "type: P2P_GO\n");
+ wil_dbg_MISC(wil, "type: P2P_GO\n");
bi = 100;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_MONITOR:
- wil_dbg(wil, "type: Monitor\n");
+ wil_dbg_MISC(wil, "type: Monitor\n");
bi = 0;
ndev->type = ARPHRD_IEEE80211_RADIOTAP;
/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 0fc83ed..ab1cade 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -53,7 +53,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
}
wil->n_msi = use_msi;
if (wil->n_msi) {
- wil_dbg(wil, "Setup %d MSI interrupts\n", use_msi);
+ wil_dbg_MISC(wil, "Setup %d MSI interrupts\n", use_msi);
rc = pci_enable_msi_block(pdev, wil->n_msi);
if (rc && (wil->n_msi == 3)) {
wil_err(wil, "3 MSI mode failed, try 1 MSI\n");
@@ -65,7 +65,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
wil->n_msi = 0;
}
} else {
- wil_dbg(wil, "MSI interrupts disabled, use INTx\n");
+ wil_dbg_MISC(wil, "MSI interrupts disabled, use INTx\n");
}

rc = wil6210_init_irq(wil, pdev->irq);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index f29c294..241dd0e 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -100,8 +100,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
d->dma.status = TX_DMA_STATUS_DU;
}

- wil_dbg(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
- vring->va, (unsigned long long)vring->pa, vring->ctx);
+ wil_dbg_MISC(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
+ vring->va, (unsigned long long)vring->pa, vring->ctx);

return 0;
}
@@ -528,8 +528,8 @@ int wil_rx_init(struct wil6210_priv *wil)

vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);

- wil_dbg(wil, "Rx init: status %d tail 0x%08x\n",
- le32_to_cpu(evt.evt.status), vring->hwtail);
+ wil_dbg_MISC(wil, "Rx init: status %d tail 0x%08x\n",
+ le32_to_cpu(evt.evt.status), vring->hwtail);

rc = wil_rx_refill(wil, vring->size);
if (rc)
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 3bd2447..a9b6f70 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -275,6 +275,7 @@ struct wil6210_priv {
#define wil_dbg_IRQ(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
#define wil_dbg_TXRX(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
#define wil_dbg_WMI(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg)
+#define wil_dbg_MISC(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg)

#define wil_hex_dump_TXRX(prefix_str, prefix_type, rowsize, \
groupsize, buf, len, ascii) \
--
1.7.10.4


2013-01-28 16:38:42

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 12/14] wil6210: checkpatch warnings

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 1 -
drivers/net/wireless/ath/wil6210/interrupt.c | 1 -
drivers/net/wireless/ath/wil6210/main.c | 4 ++--
drivers/net/wireless/ath/wil6210/netdev.c | 4 ++--
drivers/net/wireless/ath/wil6210/txrx.c | 3 +--
drivers/net/wireless/ath/wil6210/wmi.c | 1 -
6 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 4b48f2e..002851f 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -204,7 +204,6 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
break;
default:
return -EOPNOTSUPP;
-
}

/* FW don't support scan after connection attempt */
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 865c33f..dc97e7b 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -52,7 +52,6 @@

static inline void wil_icr_clear(u32 x, void __iomem *addr)
{
-
}
#else /* defined(CONFIG_WIL6210_ISR_COR) */
/* configure to Write-1-to-Clear mode */
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index d160ea8..761c389 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -80,7 +80,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
GFP_KERNEL);
break;
default:
- ;
+ break;
}

for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++)
@@ -357,7 +357,7 @@ static int __wil_up(struct wil6210_priv *wil)
wmi_set_channel(wil, channel->hw_value);
break;
default:
- ;
+ break;
}

/* MAC address - pre-requisite for other commands */
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 073dc7d..8ce2e33 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -39,8 +39,8 @@ static const struct net_device_ops wil_netdev_ops = {
.ndo_open = wil_open,
.ndo_stop = wil_stop,
.ndo_start_xmit = wil_start_xmit,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_validate_addr = eth_validate_addr,
};

void *wil_if_alloc(struct device *dev, void __iomem *csr)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index f0d0913..48cfa7e 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -758,8 +758,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
case -ENOMEM:
return NETDEV_TX_BUSY;
default:
- ; /* goto drop; */
- break;
+ break; /* goto drop; */
}
drop:
netif_tx_stop_all_queues(ndev);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 91f41a7..8178cc0 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -188,7 +188,6 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
(int)(sizeof(cmd) + len), r->entry_size);
return -ERANGE;
-
}

might_sleep();
--
1.7.10.4


2013-01-28 16:38:37

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 10/14] wil6210: Reorder reset preparation sequence

Disable interrupts first to prevent spurious WMI events arrival

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/main.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 4c15330..aa598f3 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -250,13 +250,13 @@ int wil_reset(struct wil6210_priv *wil)
cancel_work_sync(&wil->disconnect_worker);
wil6210_disconnect(wil, NULL);

+ wil6210_disable_irq(wil);
+ wil->status = 0;
+
wmi_event_flush(wil);

- flush_workqueue(wil->wmi_wq);
flush_workqueue(wil->wmi_wq_conn);
-
- wil6210_disable_irq(wil);
- wil->status = 0;
+ flush_workqueue(wil->wmi_wq);

/* TODO: put MAC in reset */
wil_target_reset(wil);
--
1.7.10.4


2013-01-28 16:32:51

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 09/14] wil6210: Separate common code for mbox regs caching to function

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/main.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 3e9a71f..4c15330 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -109,6 +109,15 @@ static void wil_connect_timer_fn(ulong x)
schedule_work(&wil->disconnect_worker);
}

+static void wil_cache_mbox_regs(struct wil6210_priv *wil)
+{
+ /* make shadow copy of registers that should not change on run time */
+ wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
+ sizeof(struct wil6210_mbox_ctl));
+ wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
+ wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
+}
+
int wil_priv_init(struct wil6210_priv *wil)
{
wil_dbg_MISC(wil, "%s()\n", __func__);
@@ -138,11 +147,7 @@ int wil_priv_init(struct wil6210_priv *wil)
return -EAGAIN;
}

- /* make shadow copy of registers that should not change on run time */
- wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
- sizeof(struct wil6210_mbox_ctl));
- wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
- wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
+ wil_cache_mbox_regs(wil);

return 0;
}
@@ -260,11 +265,7 @@ int wil_reset(struct wil6210_priv *wil)
wil->pending_connect_cid = -1;
INIT_COMPLETION(wil->wmi_ready);

- /* make shadow copy of registers that should not change on run time */
- wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
- sizeof(struct wil6210_mbox_ctl));
- wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
- wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
+ wil_cache_mbox_regs(wil);

/* TODO: release MAC reset */
wil6210_enable_irq(wil);
--
1.7.10.4


2013-01-28 16:38:49

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 07/14] wil6210: Call skb_orphan() right before Rx indication

Other parts of Rx path (BACK logic) will need to access associated data

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/txrx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index e7ea538..649f504 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -430,6 +430,8 @@ static void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
int rc;
unsigned int len = skb->len;

+ skb_orphan(skb);
+
if (in_interrupt())
rc = netif_rx(skb);
else
@@ -464,8 +466,6 @@ void wil_rx_handle(struct wil6210_priv *wil)
wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);

- skb_orphan(skb);
-
if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
skb->dev = ndev;
skb_reset_mac_header(skb);
--
1.7.10.4


2013-01-28 16:38:41

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 01/14] wil6210: Detect FW error

In the firmware, added is ability to report internal errors using IRQ.

Catch this IRQ and notify user space via netlink

User space get notified like (udevadm monitor --kernel --property):

KERNEL[12660.320520] change /devices/pci0000:00/0000:00:1c.1/0000:02:00.0/0000:03:01.0/0000:05:00.0/net/wlan12 (net)
ACTION=change
DEVPATH=/devices/pci0000:00/0000:00:1c.1/0000:02:00.0/0000:03:01.0/0000:05:00.0/net/wlan12
DEVTYPE=wlan
EVENT=FW_ERROR
IFINDEX=6
INTERFACE=wlan12
SEQNUM=2489
SOURCE=wil6210
SUBSYSTEM=net

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/interrupt.c | 22 +++++++++++++++++++++-
drivers/net/wireless/ath/wil6210/wil6210.h | 8 ++++----
2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 38049da..d2109d5 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -38,7 +38,9 @@
#define WIL6210_IMC_RX BIT_DMA_EP_RX_ICR_RX_DONE
#define WIL6210_IMC_TX (BIT_DMA_EP_TX_ICR_TX_DONE | \
BIT_DMA_EP_TX_ICR_TX_DONE_N(0))
-#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | ISR_MISC_MBOX_EVT)
+#define WIL6210_IMC_MISC (ISR_MISC_FW_READY | \
+ ISR_MISC_MBOX_EVT | \
+ ISR_MISC_FW_ERROR)

#define WIL6210_IRQ_PSEUDO_MASK (u32)(~(BIT_DMA_PSEUDO_CAUSE_RX | \
BIT_DMA_PSEUDO_CAUSE_TX | \
@@ -228,6 +230,17 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
return IRQ_HANDLED;
}

+static void wil_notify_fw_error(struct wil6210_priv *wil)
+{
+ struct device *dev = &wil_to_ndev(wil)->dev;
+ char *envp[3] = {
+ [0] = "SOURCE=wil6210",
+ [1] = "EVENT=FW_ERROR",
+ [2] = NULL,
+ };
+ kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
+}
+
static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
{
struct wil6210_priv *wil = cookie;
@@ -244,6 +257,13 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)

wil6210_mask_irq_misc(wil);

+ if (isr & ISR_MISC_FW_ERROR) {
+ wil_dbg_IRQ(wil, "IRQ: Firmware error\n");
+ clear_bit(wil_status_fwready, &wil->status);
+ wil_notify_fw_error(wil);
+ isr &= ~ISR_MISC_FW_ERROR;
+ }
+
if (isr & ISR_MISC_FW_READY) {
wil_dbg_IRQ(wil, "IRQ: FW ready\n");
/**
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 9bcfffa..3bd2447 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -101,8 +101,7 @@ struct RGF_ICR {
#define RGF_DMA_EP_MISC_ICR (0x881bec) /* struct RGF_ICR */
#define BIT_DMA_EP_MISC_ICR_RX_HTRSH BIT(0)
#define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1)
- #define BIT_DMA_EP_MISC_ICR_FW_INT0 BIT(28)
- #define BIT_DMA_EP_MISC_ICR_FW_INT1 BIT(29)
+ #define BIT_DMA_EP_MISC_ICR_FW_INT(n) BIT(28+n) /* n = [0..3] */

/* Interrupt moderation control */
#define RGF_DMA_ITR_CNT_TRSH (0x881c5c)
@@ -121,8 +120,9 @@ struct RGF_ICR {
#define SW_INT_MBOX BIT_USER_USER_ICR_SW_INT_2

/* ISR register bits */
-#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT0
-#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT1
+#define ISR_MISC_FW_READY BIT_DMA_EP_MISC_ICR_FW_INT(0)
+#define ISR_MISC_MBOX_EVT BIT_DMA_EP_MISC_ICR_FW_INT(1)
+#define ISR_MISC_FW_ERROR BIT_DMA_EP_MISC_ICR_FW_INT(3)

/* Hardware definitions end */

--
1.7.10.4


2013-01-28 16:38:40

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 11/14] wil6210: fix checkpatch CamelCase warnings

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 4 +-
drivers/net/wireless/ath/wil6210/interrupt.c | 32 +++++++--------
drivers/net/wireless/ath/wil6210/main.c | 26 ++++++------
drivers/net/wireless/ath/wil6210/pcie_bus.c | 4 +-
drivers/net/wireless/ath/wil6210/txrx.c | 30 +++++++-------
drivers/net/wireless/ath/wil6210/wil6210.h | 12 +++---
drivers/net/wireless/ath/wil6210/wmi.c | 56 +++++++++++++-------------
7 files changed, 82 insertions(+), 82 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 56f39b6..4b48f2e 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -228,7 +228,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
}
/* 0-based channel indexes */
cmd.cmd.channel_list[cmd.cmd.num_channels++].channel = ch - 1;
- wil_dbg_MISC(wil, "Scan for ch %d : %d MHz\n", ch,
+ wil_dbg_misc(wil, "Scan for ch %d : %d MHz\n", ch,
request->channels[i]->center_freq);
}

@@ -425,7 +425,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
return -EINVAL;
}

- wil_dbg_MISC(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
+ wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
channel->center_freq, info->privacy ? "secure" : "open");
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
info->ssid, info->ssid_len);
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 660bacf..865c33f 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -96,7 +96,7 @@ static void wil6210_mask_irq_misc(struct wil6210_priv *wil)

static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
{
- wil_dbg_IRQ(wil, "%s()\n", __func__);
+ wil_dbg_irq(wil, "%s()\n", __func__);

iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
@@ -127,7 +127,7 @@ static void wil6210_unmask_irq_misc(struct wil6210_priv *wil)

static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
{
- wil_dbg_IRQ(wil, "%s()\n", __func__);
+ wil_dbg_irq(wil, "%s()\n", __func__);

set_bit(wil_status_irqen, &wil->status);

@@ -137,7 +137,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)

void wil6210_disable_irq(struct wil6210_priv *wil)
{
- wil_dbg_IRQ(wil, "%s()\n", __func__);
+ wil_dbg_irq(wil, "%s()\n", __func__);

wil6210_mask_irq_tx(wil);
wil6210_mask_irq_rx(wil);
@@ -147,7 +147,7 @@ void wil6210_disable_irq(struct wil6210_priv *wil)

void wil6210_enable_irq(struct wil6210_priv *wil)
{
- wil_dbg_IRQ(wil, "%s()\n", __func__);
+ wil_dbg_irq(wil, "%s()\n", __func__);

iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_RX_ICR) +
offsetof(struct RGF_ICR, ICC));
@@ -169,7 +169,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
HOSTADDR(RGF_DMA_EP_RX_ICR) +
offsetof(struct RGF_ICR, ICR));

- wil_dbg_IRQ(wil, "ISR RX 0x%08x\n", isr);
+ wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);

if (!isr) {
wil_err(wil, "spurious IRQ: RX\n");
@@ -179,7 +179,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
wil6210_mask_irq_rx(wil);

if (isr & BIT_DMA_EP_RX_ICR_RX_DONE) {
- wil_dbg_IRQ(wil, "RX done\n");
+ wil_dbg_irq(wil, "RX done\n");
isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
wil_rx_handle(wil);
}
@@ -199,7 +199,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
HOSTADDR(RGF_DMA_EP_TX_ICR) +
offsetof(struct RGF_ICR, ICR));

- wil_dbg_IRQ(wil, "ISR TX 0x%08x\n", isr);
+ wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);

if (!isr) {
wil_err(wil, "spurious IRQ: TX\n");
@@ -210,13 +210,13 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)

if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) {
uint i;
- wil_dbg_IRQ(wil, "TX done\n");
+ wil_dbg_irq(wil, "TX done\n");
isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
for (i = 0; i < 24; i++) {
u32 mask = BIT_DMA_EP_TX_ICR_TX_DONE_N(i);
if (isr & mask) {
isr &= ~mask;
- wil_dbg_IRQ(wil, "TX done(%i)\n", i);
+ wil_dbg_irq(wil, "TX done(%i)\n", i);
wil_tx_complete(wil, i);
}
}
@@ -248,7 +248,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
HOSTADDR(RGF_DMA_EP_MISC_ICR) +
offsetof(struct RGF_ICR, ICR));

- wil_dbg_IRQ(wil, "ISR MISC 0x%08x\n", isr);
+ wil_dbg_irq(wil, "ISR MISC 0x%08x\n", isr);

if (!isr) {
wil_err(wil, "spurious IRQ: MISC\n");
@@ -258,14 +258,14 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
wil6210_mask_irq_misc(wil);

if (isr & ISR_MISC_FW_ERROR) {
- wil_dbg_IRQ(wil, "IRQ: Firmware error\n");
+ wil_dbg_irq(wil, "IRQ: Firmware error\n");
clear_bit(wil_status_fwready, &wil->status);
wil_notify_fw_error(wil);
isr &= ~ISR_MISC_FW_ERROR;
}

if (isr & ISR_MISC_FW_READY) {
- wil_dbg_IRQ(wil, "IRQ: FW ready\n");
+ wil_dbg_irq(wil, "IRQ: FW ready\n");
/**
* Actual FW ready indicated by the
* WMI_FW_READY_EVENTID
@@ -288,10 +288,10 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
struct wil6210_priv *wil = cookie;
u32 isr = wil->isr_misc;

- wil_dbg_IRQ(wil, "Thread ISR MISC 0x%08x\n", isr);
+ wil_dbg_irq(wil, "Thread ISR MISC 0x%08x\n", isr);

if (isr & ISR_MISC_MBOX_EVT) {
- wil_dbg_IRQ(wil, "MBOX event\n");
+ wil_dbg_irq(wil, "MBOX event\n");
wmi_recv_cmd(wil);
isr &= ~ISR_MISC_MBOX_EVT;
}
@@ -313,7 +313,7 @@ static irqreturn_t wil6210_thread_irq(int irq, void *cookie)
{
struct wil6210_priv *wil = cookie;

- wil_dbg_IRQ(wil, "Thread IRQ\n");
+ wil_dbg_irq(wil, "Thread IRQ\n");
/* Discover real IRQ cause */
if (wil->isr_misc)
wil6210_irq_misc_thread(irq, cookie);
@@ -390,7 +390,7 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
if (wil6210_debug_irq_mask(wil, pseudo_cause))
return IRQ_NONE;

- wil_dbg_IRQ(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);
+ wil_dbg_irq(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);

wil6210_mask_irq_pseudo(wil);

diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index aa598f3..d160ea8 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -64,7 +64,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, void *bssid)
struct net_device *ndev = wil_to_ndev(wil);
struct wireless_dev *wdev = wil->wdev;

- wil_dbg_MISC(wil, "%s()\n", __func__);
+ wil_dbg_misc(wil, "%s()\n", __func__);

wil_link_off(wil);
clear_bit(wil_status_fwconnected, &wil->status);
@@ -101,7 +101,7 @@ static void wil_connect_timer_fn(ulong x)
{
struct wil6210_priv *wil = (void *)x;

- wil_dbg_MISC(wil, "Connect timeout\n");
+ wil_dbg_misc(wil, "Connect timeout\n");

/* reschedule to thread context - disconnect won't
* run from atomic context
@@ -120,7 +120,7 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil)

int wil_priv_init(struct wil6210_priv *wil)
{
- wil_dbg_MISC(wil, "%s()\n", __func__);
+ wil_dbg_misc(wil, "%s()\n", __func__);

mutex_init(&wil->mutex);
mutex_init(&wil->wmi_mutex);
@@ -169,7 +169,7 @@ void wil_priv_deinit(struct wil6210_priv *wil)

static void wil_target_reset(struct wil6210_priv *wil)
{
- wil_dbg_MISC(wil, "Resetting...\n");
+ wil_dbg_misc(wil, "Resetting...\n");

/* register write */
#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a))
@@ -209,7 +209,7 @@ static void wil_target_reset(struct wil6210_priv *wil)

msleep(2000);

- wil_dbg_MISC(wil, "Reset completed\n");
+ wil_dbg_misc(wil, "Reset completed\n");

#undef W
#undef S
@@ -232,7 +232,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
wil_err(wil, "Firmware not ready\n");
return -ETIME;
} else {
- wil_dbg_MISC(wil, "FW ready after %d ms\n",
+ wil_dbg_misc(wil, "FW ready after %d ms\n",
jiffies_to_msecs(to-left));
}
return 0;
@@ -281,7 +281,7 @@ void wil_link_on(struct wil6210_priv *wil)
{
struct net_device *ndev = wil_to_ndev(wil);

- wil_dbg_MISC(wil, "%s()\n", __func__);
+ wil_dbg_misc(wil, "%s()\n", __func__);

netif_carrier_on(ndev);
netif_tx_wake_all_queues(ndev);
@@ -291,7 +291,7 @@ void wil_link_off(struct wil6210_priv *wil)
{
struct net_device *ndev = wil_to_ndev(wil);

- wil_dbg_MISC(wil, "%s()\n", __func__);
+ wil_dbg_misc(wil, "%s()\n", __func__);

netif_tx_stop_all_queues(ndev);
netif_carrier_off(ndev);
@@ -314,27 +314,27 @@ static int __wil_up(struct wil6210_priv *wil)
wmi_nettype = wil_iftype_nl2wmi(NL80211_IFTYPE_ADHOC);
switch (wdev->iftype) {
case NL80211_IFTYPE_STATION:
- wil_dbg_MISC(wil, "type: STATION\n");
+ wil_dbg_misc(wil, "type: STATION\n");
bi = 0;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_AP:
- wil_dbg_MISC(wil, "type: AP\n");
+ wil_dbg_misc(wil, "type: AP\n");
bi = 100;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_P2P_CLIENT:
- wil_dbg_MISC(wil, "type: P2P_CLIENT\n");
+ wil_dbg_misc(wil, "type: P2P_CLIENT\n");
bi = 0;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_P2P_GO:
- wil_dbg_MISC(wil, "type: P2P_GO\n");
+ wil_dbg_misc(wil, "type: P2P_GO\n");
bi = 100;
ndev->type = ARPHRD_ETHER;
break;
case NL80211_IFTYPE_MONITOR:
- wil_dbg_MISC(wil, "type: Monitor\n");
+ wil_dbg_misc(wil, "type: Monitor\n");
bi = 0;
ndev->type = ARPHRD_IEEE80211_RADIOTAP;
/* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_RADIOTAP ? */
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index ab1cade..81c35c6 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -53,7 +53,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
}
wil->n_msi = use_msi;
if (wil->n_msi) {
- wil_dbg_MISC(wil, "Setup %d MSI interrupts\n", use_msi);
+ wil_dbg_misc(wil, "Setup %d MSI interrupts\n", use_msi);
rc = pci_enable_msi_block(pdev, wil->n_msi);
if (rc && (wil->n_msi == 3)) {
wil_err(wil, "3 MSI mode failed, try 1 MSI\n");
@@ -65,7 +65,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
wil->n_msi = 0;
}
} else {
- wil_dbg_MISC(wil, "MSI interrupts disabled, use INTx\n");
+ wil_dbg_misc(wil, "MSI interrupts disabled, use INTx\n");
}

rc = wil6210_init_irq(wil, pdev->irq);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 649f504..f0d0913 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -100,7 +100,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
d->dma.status = TX_DMA_STATUS_DU;
}

- wil_dbg_MISC(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
+ wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,
vring->va, (unsigned long long)vring->pa, vring->ctx);

return 0;
@@ -353,8 +353,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
wil_rx_add_radiotap_header(wil, skb, d);

- wil_dbg_TXRX(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
- wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_NONE, 32, 4,
+ wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, d->dma.length);
+ wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);

wil_vring_advance_head(vring, 1);
@@ -369,7 +369,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
*/
ftype = wil_rxdesc_ftype(d) << 2;
if (ftype != IEEE80211_FTYPE_DATA) {
- wil_dbg_TXRX(wil, "Non-data frame ftype 0x%08x\n", ftype);
+ wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
/* TODO: process it */
kfree_skb(skb);
return NULL;
@@ -461,9 +461,9 @@ void wil_rx_handle(struct wil6210_priv *wil)
wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
return;
}
- wil_dbg_TXRX(wil, "%s()\n", __func__);
+ wil_dbg_txrx(wil, "%s()\n", __func__);
while (NULL != (skb = wil_vring_reap_rx(wil, v))) {
- wil_hex_dump_TXRX("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
+ wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);

if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
@@ -639,7 +639,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
uint i = swhead;
dma_addr_t pa;

- wil_dbg_TXRX(wil, "%s()\n", __func__);
+ wil_dbg_txrx(wil, "%s()\n", __func__);

if (avail < vring->size/8)
netif_tx_stop_all_queues(wil_to_ndev(wil));
@@ -656,9 +656,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
pa = dma_map_single(dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);

- wil_dbg_TXRX(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb),
+ wil_dbg_txrx(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb),
skb->data, (unsigned long long)pa);
- wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_OFFSET, 16, 1,
+ wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);

if (unlikely(dma_mapping_error(dev, pa)))
@@ -687,12 +687,12 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);

- wil_hex_dump_TXRX("Tx ", DUMP_PREFIX_NONE, 32, 4,
+ wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);

/* advance swhead */
wil_vring_advance_head(vring, nr_frags + 1);
- wil_dbg_TXRX(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
+ wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
/* hold reference to skb
* to prevent skb release before accounting
@@ -725,7 +725,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct vring *vring;
int rc;

- wil_dbg_TXRX(wil, "%s()\n", __func__);
+ wil_dbg_txrx(wil, "%s()\n", __func__);
if (!test_bit(wil_status_fwready, &wil->status)) {
wil_err(wil, "FW not ready\n");
goto drop;
@@ -785,7 +785,7 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
return;
}

- wil_dbg_TXRX(wil, "%s(%d)\n", __func__, ringid);
+ wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);

while (!wil_vring_is_empty(vring)) {
volatile struct vring_tx_desc *d = &vring->va[vring->swtail].tx;
@@ -794,11 +794,11 @@ void wil_tx_complete(struct wil6210_priv *wil, int ringid)
if (!(d->dma.status & TX_DMA_STATUS_DU))
break;

- wil_dbg_TXRX(wil,
+ wil_dbg_txrx(wil,
"Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n",
vring->swtail, d->dma.length, d->dma.status,
d->dma.error);
- wil_hex_dump_TXRX("TxC ", DUMP_PREFIX_NONE, 32, 4,
+ wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);

pa = d->dma.addr_low | ((u64)d->dma.addr_high << 32);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index d957286..69e5162 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -270,18 +270,18 @@ struct wil6210_priv {
#define wil_info(wil, fmt, arg...) netdev_info(wil_to_ndev(wil), fmt, ##arg)
#define wil_err(wil, fmt, arg...) netdev_err(wil_to_ndev(wil), fmt, ##arg)

-#define wil_dbg_IRQ(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
-#define wil_dbg_TXRX(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
-#define wil_dbg_WMI(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg)
-#define wil_dbg_MISC(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg)
+#define wil_dbg_irq(wil, fmt, arg...) wil_dbg(wil, "DBG[ IRQ]" fmt, ##arg)
+#define wil_dbg_txrx(wil, fmt, arg...) wil_dbg(wil, "DBG[TXRX]" fmt, ##arg)
+#define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg)
+#define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg)

-#define wil_hex_dump_TXRX(prefix_str, prefix_type, rowsize, \
+#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \
groupsize, buf, len, ascii) \
wil_print_hex_dump_debug("DBG[TXRX]" prefix_str,\
prefix_type, rowsize, \
groupsize, buf, len, ascii)

-#define wil_hex_dump_WMI(prefix_str, prefix_type, rowsize, \
+#define wil_hex_dump_wmi(prefix_str, prefix_type, rowsize, \
groupsize, buf, len, ascii) \
wil_print_hex_dump_debug("DBG[ WMI]" prefix_str,\
prefix_type, rowsize, \
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index dffb002..91f41a7 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -215,7 +215,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
}
/* next head */
next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size);
- wil_dbg_WMI(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
+ wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
/* wait till FW finish with previous command */
for (retry = 5; retry > 0; retry--) {
r->tail = ioread32(wil->csr + HOST_MBOX +
@@ -236,10 +236,10 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
}
cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq);
/* set command */
- wil_dbg_WMI(wil, "WMI command 0x%04x [%d]\n", cmdid, len);
- wil_hex_dump_WMI("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd,
+ wil_dbg_wmi(wil, "WMI command 0x%04x [%d]\n", cmdid, len);
+ wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd,
sizeof(cmd), true);
- wil_hex_dump_WMI("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf,
+ wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf,
len, true);
wil_memcpy_toio_32(dst, &cmd, sizeof(cmd));
wil_memcpy_toio_32(dst + sizeof(cmd), buf, len);
@@ -275,7 +275,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
struct wmi_ready_event *evt = d;
u32 ver = le32_to_cpu(evt->sw_version);

- wil_dbg_WMI(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac);
+ wil_dbg_wmi(wil, "FW ver. %d; MAC %pM\n", ver, evt->mac);

if (!is_valid_ether_addr(ndev->dev_addr)) {
memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
@@ -288,7 +288,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
int len)
{
- wil_dbg_WMI(wil, "WMI: FW ready\n");
+ wil_dbg_wmi(wil, "WMI: FW ready\n");

set_bit(wil_status_fwready, &wil->status);
/* reuse wmi_ready for the firmware ready indication */
@@ -311,11 +311,11 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
u32 d_len = le32_to_cpu(data->info.len);
u16 d_status = le16_to_cpu(data->info.status);

- wil_dbg_WMI(wil, "MGMT: channel %d MCS %d SNR %d\n",
+ wil_dbg_wmi(wil, "MGMT: channel %d MCS %d SNR %d\n",
data->info.channel, data->info.mcs, data->info.snr);
- wil_dbg_WMI(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len,
+ wil_dbg_wmi(wil, "status 0x%04x len %d stype %04x\n", d_status, d_len,
le16_to_cpu(data->info.stype));
- wil_dbg_WMI(wil, "qid %d mid %d cid %d\n",
+ wil_dbg_wmi(wil, "qid %d mid %d cid %d\n",
data->info.qid, data->info.mid, data->info.cid);

if (!channel) {
@@ -331,13 +331,13 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
u.beacon.variable);
- wil_dbg_WMI(wil, "Capability info : 0x%04x\n", cap);
+ wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);

bss = cfg80211_inform_bss(wiphy, channel, rx_mgmt_frame->bssid,
tsf, cap, bi, ie_buf, ie_len,
signal, GFP_KERNEL);
if (bss) {
- wil_dbg_WMI(wil, "Added BSS %pM\n",
+ wil_dbg_wmi(wil, "Added BSS %pM\n",
rx_mgmt_frame->bssid);
cfg80211_put_bss(bss);
} else {
@@ -353,7 +353,7 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
struct wmi_scan_complete_event *data = d;
bool aborted = (data->status != 0);

- wil_dbg_WMI(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
+ wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
cfg80211_scan_done(wil->scan_request, aborted);
wil->scan_request = NULL;
} else {
@@ -388,9 +388,9 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
return;
}
ch = evt->channel + 1;
- wil_dbg_WMI(wil, "Connect %pM channel [%d] cid %d\n",
+ wil_dbg_wmi(wil, "Connect %pM channel [%d] cid %d\n",
evt->bssid, ch, evt->cid);
- wil_hex_dump_WMI("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
+ wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
evt->assoc_info, len - sizeof(*evt), true);

/* figure out IE's */
@@ -452,7 +452,7 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
{
struct wmi_disconnect_event *evt = d;

- wil_dbg_WMI(wil, "Disconnect %pM reason %d proto %d wmi\n",
+ wil_dbg_wmi(wil, "Disconnect %pM reason %d proto %d wmi\n",
evt->bssid,
evt->protocol_reason_status, evt->disconnect_reason);

@@ -477,7 +477,7 @@ static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector);
wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector);
wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector);
- wil_dbg_WMI(wil, "Link status, MCS %d TSF 0x%016llx\n"
+ wil_dbg_wmi(wil, "Link status, MCS %d TSF 0x%016llx\n"
"BF status 0x%08x SNR 0x%08x\n"
"Tx Tpt %d goodput %d Rx goodput %d\n"
"Sectors(rx:tx) my %d:%d peer %d:%d\n",
@@ -502,7 +502,7 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
struct sk_buff *skb;
struct ethhdr *eth;

- wil_dbg_WMI(wil, "EAPOL len %d from %pM\n", eapol_len,
+ wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len,
evt->src_mac);

if (eapol_len > 196) { /* TODO: revisit size limit */
@@ -600,15 +600,15 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
iowrite32(0, wil->csr + HOSTADDR(r->tail) +
offsetof(struct wil6210_mbox_ring_desc, sync));
/* indicate */
- wil_dbg_WMI(wil, "Mbox evt %04x %04x %04x %02x\n",
+ wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n",
le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type),
hdr.flags);
if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
(len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
- wil_dbg_WMI(wil, "WMI event 0x%04x\n",
+ wil_dbg_wmi(wil, "WMI event 0x%04x\n",
evt->event.wmi.id);
}
- wil_hex_dump_WMI("evt ", DUMP_PREFIX_OFFSET, 16, 1,
+ wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
&evt->event.hdr, sizeof(hdr) + len, true);

/* advance tail */
@@ -624,7 +624,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
{
int q = queue_work(wil->wmi_wq,
&wil->wmi_event_worker);
- wil_dbg_WMI(wil, "queue_work -> %d\n", q);
+ wil_dbg_wmi(wil, "queue_work -> %d\n", q);
}
}
}
@@ -651,7 +651,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
cmdid, reply_id, to_msec);
rc = -ETIME;
} else {
- wil_dbg_WMI(wil,
+ wil_dbg_wmi(wil,
"wmi_call(0x%04x->0x%04x) completed in %d msec\n",
cmdid, reply_id,
to_msec - jiffies_to_msecs(remain));
@@ -681,7 +681,7 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)

memcpy(cmd.mac, addr, ETH_ALEN);

- wil_dbg_WMI(wil, "Set MAC %pM\n", addr);
+ wil_dbg_wmi(wil, "Set MAC %pM\n", addr);

return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
}
@@ -779,7 +779,7 @@ int wmi_tx_eapol(struct wil6210_priv *wil, struct sk_buff *skb)

skb_set_mac_header(skb, 0);
eth = eth_hdr(skb);
- wil_dbg_WMI(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest);
+ wil_dbg_wmi(wil, "EAPOL %d bytes to %pM\n", eapol_len, eth->h_dest);
for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
if (memcmp(wil->dst_addr[i], eth->h_dest, ETH_ALEN) == 0)
goto found_dest;
@@ -894,7 +894,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)

vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);

- wil_dbg_MISC(wil, "Rx init: status %d tail 0x%08x\n",
+ wil_dbg_misc(wil, "Rx init: status %d tail 0x%08x\n",
le32_to_cpu(evt.evt.status), vring->hwtail);

if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS)
@@ -929,7 +929,7 @@ void wmi_event_flush(struct wil6210_priv *wil)
{
struct pending_wmi_event *evt, *t;

- wil_dbg_WMI(wil, "%s()\n", __func__);
+ wil_dbg_wmi(wil, "%s()\n", __func__);

list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
list_del(&evt->list);
@@ -971,7 +971,7 @@ static void wmi_event_handle(struct wil6210_priv *wil,
wmi_evt_call_handler(wil, id, evt_data,
len - sizeof(*wmi));
}
- wil_dbg_WMI(wil, "Complete WMI 0x%04x\n", id);
+ wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id);
complete(&wil->wmi_ready);
return;
}
@@ -1036,7 +1036,7 @@ void wmi_connect_worker(struct work_struct *work)
return;
}

- wil_dbg_WMI(wil, "Configure for connection CID %d\n",
+ wil_dbg_wmi(wil, "Configure for connection CID %d\n",
wil->pending_connect_cid);

rc = wil_vring_init_tx(wil, 0, WIL6210_TX_RING_SIZE,
--
1.7.10.4


2013-01-28 16:38:21

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 02/14] wil6210: rearrange IRQ debug printing

Make printings from IRQ appears in dmesg in chronological order

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/interrupt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index d2109d5..660bacf 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -390,6 +390,8 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
if (wil6210_debug_irq_mask(wil, pseudo_cause))
return IRQ_NONE;

+ wil_dbg_IRQ(wil, "Pseudo IRQ 0x%08x\n", pseudo_cause);
+
wil6210_mask_irq_pseudo(wil);

/* Discover real IRQ cause
@@ -421,8 +423,6 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
if (rc != IRQ_WAKE_THREAD)
wil6210_unmask_irq_pseudo(wil);

- wil_dbg_IRQ(wil, "Hard IRQ 0x%08x\n", pseudo_cause);
-
return rc;
}

--
1.7.10.4


2013-01-28 16:32:57

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 14/14] wil6210: fix wil_vring_init_tx status

In case vring setup with the firmware failed,
success status was returned. fix it.

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/txrx.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 1985951..64b971f 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -565,6 +565,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
if (reply.cmd.status != WMI_VRING_CFG_SUCCESS) {
wil_err(wil, "Tx config failed, status 0x%02x\n",
reply.cmd.status);
+ rc = -EINVAL;
goto out_free;
}
vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
--
1.7.10.4


2013-01-28 16:38:53

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 13/14] wil6210: Never delete Rx chain with firmware

Firmware crash on attempt to delete Rx chain.
Driver part of Rx chain removed only in preparation for the target reset;
as reset is the only flow that removes Rx chain in the firmware.

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/txrx.c | 4 +---
drivers/net/wireless/ath/wil6210/wil6210.h | 1 -
drivers/net/wireless/ath/wil6210/wmi.c | 22 ----------------------
3 files changed, 1 insertion(+), 26 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 48cfa7e..1985951 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -511,10 +511,8 @@ void wil_rx_fini(struct wil6210_priv *wil)
{
struct vring *vring = &wil->vring_rx;

- if (vring->va) {
- wmi_rx_chain_del(wil);
+ if (vring->va)
wil_vring_free(wil, vring, 0);
- }
}

int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 69e5162..aea961f 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -327,7 +327,6 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
const void *mac_addr, int key_len, const void *key);
int wmi_echo(struct wil6210_priv *wil);
int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
-int wmi_rx_chain_del(struct wil6210_priv *wil);
int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);

int wil6210_init_irq(struct wil6210_priv *wil, int irq);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 8178cc0..0b70e17 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -902,28 +902,6 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
return rc;
}

-int wmi_rx_chain_del(struct wil6210_priv *wil)
-{
- int rc;
- struct wmi_cfg_rx_chain_cmd cmd = {
- .action = cpu_to_le32(WMI_RX_CHAIN_DEL),
- .rx_sw_ring = {
- .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
- },
- };
- struct {
- struct wil6210_mbox_hdr_wmi wmi;
- struct wmi_cfg_rx_chain_done_event cfg;
- } __packed wmi_rx_cfg_reply;
-
- rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
- WMI_CFG_RX_CHAIN_DONE_EVENTID,
- &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply),
- 100);
-
- return rc;
-}
-
void wmi_event_flush(struct wil6210_priv *wil)
{
struct pending_wmi_event *evt, *t;
--
1.7.10.4


2013-01-28 16:32:40

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 04/14] wil6210: Refactor rx init/fini

Move WMI related operations to wmi.c as helper functions

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/txrx.c | 54 +-------------------
drivers/net/wireless/ath/wil6210/wil6210.h | 2 +
drivers/net/wireless/ath/wil6210/wmi.c | 73 ++++++++++++++++++++++++++++
3 files changed, 77 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 241dd0e..f3b523b 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -484,53 +484,18 @@ void wil_rx_handle(struct wil6210_priv *wil)

int wil_rx_init(struct wil6210_priv *wil)
{
- struct net_device *ndev = wil_to_ndev(wil);
- struct wireless_dev *wdev = wil->wdev;
struct vring *vring = &wil->vring_rx;
int rc;
- struct wmi_cfg_rx_chain_cmd cmd = {
- .action = WMI_RX_CHAIN_ADD,
- .rx_sw_ring = {
- .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
- },
- .mid = 0, /* TODO - what is it? */
- .decap_trans_type = WMI_DECAP_TYPE_802_3,
- };
- struct {
- struct wil6210_mbox_hdr_wmi wmi;
- struct wmi_cfg_rx_chain_done_event evt;
- } __packed evt;

vring->size = WIL6210_RX_RING_SIZE;
rc = wil_vring_alloc(wil, vring);
if (rc)
return rc;

- cmd.rx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
- cmd.rx_sw_ring.ring_size = cpu_to_le16(vring->size);
- if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
- struct ieee80211_channel *ch = wdev->preset_chandef.chan;
-
- cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
- if (ch)
- cmd.sniffer_cfg.channel = ch->hw_value - 1;
- cmd.sniffer_cfg.phy_info_mode =
- cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
- cmd.sniffer_cfg.phy_support =
- cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
- ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
- }
- /* typical time for secure PCP is 840ms */
- rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
- WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
+ rc = wmi_rx_chain_add(wil, vring);
if (rc)
goto err_free;

- vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
-
- wil_dbg_MISC(wil, "Rx init: status %d tail 0x%08x\n",
- le32_to_cpu(evt.evt.status), vring->hwtail);
-
rc = wil_rx_refill(wil, vring->size);
if (rc)
goto err_free;
@@ -547,22 +512,7 @@ void wil_rx_fini(struct wil6210_priv *wil)
struct vring *vring = &wil->vring_rx;

if (vring->va) {
- int rc;
- struct wmi_cfg_rx_chain_cmd cmd = {
- .action = cpu_to_le32(WMI_RX_CHAIN_DEL),
- .rx_sw_ring = {
- .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
- },
- };
- struct {
- struct wil6210_mbox_hdr_wmi wmi;
- struct wmi_cfg_rx_chain_done_event cfg;
- } __packed wmi_rx_cfg_reply;
-
- rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
- WMI_CFG_RX_CHAIN_DONE_EVENTID,
- &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply),
- 100);
+ wmi_rx_chain_del(wil);
wil_vring_free(wil, vring, 0);
}
}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index a9b6f70..9b2ebdd 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -329,6 +329,8 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
const void *mac_addr, int key_len, const void *key);
int wmi_echo(struct wil6210_priv *wil);
int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
+int wmi_rx_chain_del(struct wil6210_priv *wil);
+int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);

int wil6210_init_irq(struct wil6210_priv *wil, int irq);
void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 12915f6..d109c3f 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -18,8 +18,10 @@
#include <linux/io.h>
#include <linux/list.h>
#include <linux/etherdevice.h>
+#include <linux/if_arp.h>

#include "wil6210.h"
+#include "txrx.h"
#include "wmi.h"

/**
@@ -853,6 +855,77 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
return rc;
}

+int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
+{
+ struct wireless_dev *wdev = wil->wdev;
+ struct net_device *ndev = wil_to_ndev(wil);
+ struct wmi_cfg_rx_chain_cmd cmd = {
+ .action = WMI_RX_CHAIN_ADD,
+ .rx_sw_ring = {
+ .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
+ .ring_mem_base = cpu_to_le64(vring->pa),
+ .ring_size = cpu_to_le16(vring->size),
+ },
+ .mid = 0, /* TODO - what is it? */
+ .decap_trans_type = WMI_DECAP_TYPE_802_3,
+ };
+ struct {
+ struct wil6210_mbox_hdr_wmi wmi;
+ struct wmi_cfg_rx_chain_done_event evt;
+ } __packed evt;
+ int rc;
+
+ if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
+ struct ieee80211_channel *ch = wdev->preset_chandef.chan;
+
+ cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
+ if (ch)
+ cmd.sniffer_cfg.channel = ch->hw_value - 1;
+ cmd.sniffer_cfg.phy_info_mode =
+ cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
+ cmd.sniffer_cfg.phy_support =
+ cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
+ ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
+ }
+ /* typical time for secure PCP is 840ms */
+ rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
+ WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
+ if (rc)
+ return rc;
+
+ vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
+
+ wil_dbg_MISC(wil, "Rx init: status %d tail 0x%08x\n",
+ le32_to_cpu(evt.evt.status), vring->hwtail);
+
+ if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS)
+ rc = -EINVAL;
+
+ return rc;
+}
+
+int wmi_rx_chain_del(struct wil6210_priv *wil)
+{
+ int rc;
+ struct wmi_cfg_rx_chain_cmd cmd = {
+ .action = cpu_to_le32(WMI_RX_CHAIN_DEL),
+ .rx_sw_ring = {
+ .max_mpdu_size = cpu_to_le16(RX_BUF_LEN),
+ },
+ };
+ struct {
+ struct wil6210_mbox_hdr_wmi wmi;
+ struct wmi_cfg_rx_chain_done_event cfg;
+ } __packed wmi_rx_cfg_reply;
+
+ rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
+ WMI_CFG_RX_CHAIN_DONE_EVENTID,
+ &wmi_rx_cfg_reply, sizeof(wmi_rx_cfg_reply),
+ 100);
+
+ return rc;
+}
+
void wmi_event_flush(struct wil6210_priv *wil)
{
struct pending_wmi_event *evt, *t;
--
1.7.10.4


2013-01-28 16:38:29

by Vladimir Kondratiev

[permalink] [raw]
Subject: [PATCH 06/14] wil6210: Fix: Tx stall

Due to multi-tx-queue design, wil_start_xmit() used to be executed
concurrently for different queues. Then, these transmits delivered
to the same queue, creating race.

As result, Tx descriptor may be skipped, causing stall in hardware.

Convert to single Tx queue fixes it.

Signed-off-by: Vladimir Kondratiev <[email protected]>
---
drivers/net/wireless/ath/wil6210/netdev.c | 27 +--------------------------
drivers/net/wireless/ath/wil6210/wil6210.h | 2 --
2 files changed, 1 insertion(+), 28 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 3068b5c..073dc7d 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -35,35 +35,10 @@ static int wil_stop(struct net_device *ndev)
return wil_down(wil);
}

-/*
- * AC to queue mapping
- *
- * AC_VO -> queue 3
- * AC_VI -> queue 2
- * AC_BE -> queue 1
- * AC_BK -> queue 0
- */
-static u16 wil_select_queue(struct net_device *ndev, struct sk_buff *skb)
-{
- static const u16 wil_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
- struct wil6210_priv *wil = ndev_to_wil(ndev);
- u16 rc;
-
- skb->priority = cfg80211_classify8021d(skb);
-
- rc = wil_1d_to_queue[skb->priority];
-
- wil_dbg_TXRX(wil, "%s() %d -> %d\n", __func__, (int)skb->priority,
- (int)rc);
-
- return rc;
-}
-
static const struct net_device_ops wil_netdev_ops = {
.ndo_open = wil_open,
.ndo_stop = wil_stop,
.ndo_start_xmit = wil_start_xmit,
- .ndo_select_queue = wil_select_queue,
.ndo_set_mac_address = eth_mac_addr,
.ndo_validate_addr = eth_validate_addr,
};
@@ -97,7 +72,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);

- ndev = alloc_netdev_mqs(0, "wlan%d", ether_setup, WIL6210_TX_QUEUES, 1);
+ ndev = alloc_netdev(0, "wlan%d", ether_setup);
if (!ndev) {
dev_err(dev, "alloc_netdev_mqs failed\n");
rc = -ENOMEM;
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 9b2ebdd..d957286 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -36,8 +36,6 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)

#define WIL6210_MEM_SIZE (2*1024*1024UL)

-#define WIL6210_TX_QUEUES (4)
-
#define WIL6210_RX_RING_SIZE (128)
#define WIL6210_TX_RING_SIZE (128)
#define WIL6210_MAX_TX_RINGS (24)
--
1.7.10.4