Skip to contentSkip to conversation

brcmfmac: pcie fixes and debugfs cleanup

PATCH In review Arend van Spriel 2 participants 6 messages Jun 8, 2015 – Jun 15, 2015 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

cover brcmfmac: pcie fixes and debugfs cleanup

Summary of this series:

* fix module reload issue for PCIe.
* improving msgbuf protocol for PCIe devices.
* cleanup of the debugfs code.

This series is intended for v4.2 kernel and applies to the master branch of the wireless-drivers-next repository.

Arend van Spriel (3):
brcmfmac: remove chipinfo debugfs entry
brcmfmac: remove watchdog reset from brcmf_pcie_buscoreprep()
brcmfmac: use debugfs_create_devm_seqfile() helper function

Hante Meuleman (1):
brcmfmac: Update msgbuf read pointer quicker.

 .../net/wireless/brcm80211/brcmfmac/commonring.c   | 19 ++++----
 .../net/wireless/brcm80211/brcmfmac/commonring.h   |  3 +-
 drivers/net/wireless/brcm80211/brcmfmac/debug.c    | 50 ++--------------------
 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c   | 12 +++++-
 drivers/net/wireless/brcm80211/brcmfmac/pcie.c     | 16 +------
 5 files changed, 27 insertions(+), 73 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/4 brcmfmac: Update msgbuf read pointer quicker.

From: Hante Meuleman <[email protected]>

On device to host data using msgbuf the read pointer gets updated once all data is processed. Updating this pointer more frequently allows the firmware to add more data quicker. This will result in slightly higher and more stable throughput on CPU bounded host processors.

---
 drivers/net/wireless/brcm80211/brcmfmac/commonring.c | 19 ++++++++-----------
 drivers/net/wireless/brcm80211/brcmfmac/commonring.h |  3 ++-
 drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c     | 12 +++++++++++-
 3 files changed, 21 insertions(+), 13 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/commonring.c +8 -11
index 26c6587..7b0e521 100644
@@ -223,8 +223,6 @@ void brcmf_commonring_write_cancel(struct brcmf_commonring *commonring,
 void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
 				    u16 *n_items)
 {
-	void *ret_addr;
-
 	if (commonring->cr_update_wptr)
 		commonring->cr_update_wptr(commonring->cr_ctx);
 
@@ -235,19 +233,18 @@ void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
 	if (*n_items == 0)
 		return NULL;
 
-	ret_addr = commonring->buf_addr +
-		   (commonring->r_ptr * commonring->item_len);
-
-	commonring->r_ptr += *n_items;
-	if (commonring->r_ptr == commonring->depth)
-		commonring->r_ptr = 0;
-
-	return ret_addr;
+	return commonring->buf_addr +
+	       (commonring->r_ptr * commonring->item_len);
 }
 
 
-int brcmf_commonring_read_complete(struct brcmf_commonring *commonring)
+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring,
+				   u16 n_items)
 {
+	commonring->r_ptr += n_items;
+	if (commonring->r_ptr == commonring->depth)
+		commonring->r_ptr = 0;
+
 	if (commonring->cr_write_rptr)
 		return commonring->cr_write_rptr(commonring->cr_ctx);
 
drivers/net/wireless/brcm80211/brcmfmac/commonring.h +2 -1
index 3d40401..b850336 100644
@@ -62,7 +62,8 @@ void brcmf_commonring_write_cancel(struct brcmf_commonring *commonring,
 				   u16 n_items);
 void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
 				    u16 *n_items);
-int brcmf_commonring_read_complete(struct brcmf_commonring *commonring);
+int brcmf_commonring_read_complete(struct brcmf_commonring *commonring,
+				   u16 n_items);
 
 #define brcmf_commonring_n_items(commonring) (commonring->depth)
 #define brcmf_commonring_len_item(commonring) (commonring->item_len)
drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c +11 -1
index 1b47de0..898c380 100644
@@ -75,6 +75,8 @@
 
 #define BRCMF_MSGBUF_DELAY_TXWORKER_THRS	96
 #define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS	32
+#define BRCMF_MSGBUF_UPDATE_RX_PTR_THRS		48
+
 
 struct msgbuf_common_hdr {
 	u8				msgtype;
@@ -1257,19 +1259,27 @@ static void brcmf_msgbuf_process_rx(struct brcmf_msgbuf *msgbuf,
 {
 	void *buf;
 	u16 count;
+	u16 processed;
 
 again:
 	buf = brcmf_commonring_get_read_ptr(commonring, &count);
 	if (buf == NULL)
 		return;
 
+	processed = 0;
 	while (count) {
 		brcmf_msgbuf_process_msgtype(msgbuf,
 					     buf + msgbuf->rx_dataoffset);
 		buf += brcmf_commonring_len_item(commonring);
+		processed++;
+		if (processed == BRCMF_MSGBUF_UPDATE_RX_PTR_THRS) {
+			brcmf_commonring_read_complete(commonring, processed);
+			processed = 0;
+		}
 		count--;
 	}
-	brcmf_commonring_read_complete(commonring);
+	if (processed)
+		brcmf_commonring_read_complete(commonring, processed);
 
 	if (commonring->r_ptr == 0)
 		goto again;
Signature · 1 line
1.9.1
#2 lore raw

Re: [1/4] brcmfmac: Update msgbuf read pointer quicker.

Quoted 9 lines

From: Hante Meuleman <[email protected]>

On device to host data using msgbuf the read pointer gets updated once all data is processed. Updating this pointer more frequently allows the firmware to add more data quicker. This will result in slightly higher and more stable throughput on CPU bounded host processors.

Quoted 5 lines

Thanks, 4 patches applied to wireless-drivers-next.git:

df738c2f0cbf brcmfmac: Update msgbuf read pointer quicker. dbf967537dce brcmfmac: remove chipinfo debugfs entry c161f29bd69f brcmfmac: remove watchdog reset from brcmf_pcie_buscoreprep() 5b18ffb2d725 brcmfmac: use debugfs_create_devm_seqfile() helper function

Kalle Valo

#3 lore raw

PATCH 2/4 brcmfmac: remove chipinfo debugfs entry

In reply to Arend van Spriel

The information provided by chipinfo is also provided by the revinfo debugfs entry. Removing it from debugfs.

---
 drivers/net/wireless/brcm80211/brcmfmac/debug.c | 10 ----------
 1 file changed, 10 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/debug.c +0 -10
index 9b473d5..10a9221 100644
@@ -41,15 +41,6 @@ void brcmf_debugfs_exit(void)
 	root_folder = NULL;
 }
 
-static int brcmf_debugfs_chipinfo_read(struct seq_file *seq, void *data)
-{
-	struct brcmf_bus *bus = dev_get_drvdata(seq->private);
-
-	seq_printf(seq, "chip: %x(%u) rev %u\n",
-		   bus->chip, bus->chip, bus->chiprev);
-	return 0;
-}
-
 int brcmf_debugfs_attach(struct brcmf_pub *drvr)
 {
 	struct device *dev = drvr->bus_if->dev;
@@ -58,7 +49,6 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
 		return -ENODEV;
 
 	drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
-	brcmf_debugfs_add_entry(drvr, "chipinfo", brcmf_debugfs_chipinfo_read);
 
 	return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
 }
Signature · 1 line
1.9.1
#4 lore raw

PATCH 3/4 brcmfmac: remove watchdog reset from brcmf_pcie_buscoreprep()

In reply to Arend van Spriel

The watchdog reset as done in brcmf_pcie_buscoreprep() is not sufficient. It needs to modify PCIe core registers as well which is properly done by brcmf_pcie_reset_device() after the chip recognition is done. So the faulty watchdog reset can be removed as it was causing driver reload to fail and hang the system requiring a power-cycle. Instead the call to to the brcmf_pcie_reset_device() function is done twice in the unload.

---
 drivers/net/wireless/brcm80211/brcmfmac/pcie.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/pcie.c +2 -14
index 37a2624..3a98c43 100644
@@ -1629,20 +1629,7 @@ static void brcmf_pcie_buscore_write32(void *ctx, u32 addr, u32 value)
 
 static int brcmf_pcie_buscoreprep(void *ctx)
 {
-	struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
-	int err;
-
-	err = brcmf_pcie_get_resource(devinfo);
-	if (err == 0) {
-		/* Set CC watchdog to reset all the cores on the chip to bring
-		 * back dongle to a sane state.
-		 */
-		brcmf_pcie_buscore_write32(ctx, CORE_CC_REG(SI_ENUM_BASE,
-							    watchdog), 4);
-		msleep(100);
-	}
-
-	return err;
+	return brcmf_pcie_get_resource(ctx);
 }
 
 
@@ -1824,6 +1811,7 @@ brcmf_pcie_remove(struct pci_dev *pdev)
 		brcmf_pcie_intr_disable(devinfo);
 
 	brcmf_detach(&pdev->dev);
+	brcmf_pcie_reset_device(devinfo);
 
 	kfree(bus->bus_priv.pcie);
 	kfree(bus->msgbuf->flowrings);
Signature · 1 line
1.9.1
#5 lore raw

PATCH 4/4 brcmfmac: use debugfs_create_devm_seqfile() helper function

In reply to Arend van Spriel

Some time ago the function debugfs_create_devm_seqfile() was introduced in debugfs. The caller simply needs to provide a device pointer and read function. The function brcmf_debugfs_add_entry() is now simply a wrapper only doing the work for CONFIG_BRCMDBG.

---
 drivers/net/wireless/brcm80211/brcmfmac/debug.c | 40 +++----------------------
 1 file changed, 4 insertions(+), 36 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/debug.c +4 -36
index 10a9221..2d6d005 100644
@@ -64,44 +64,12 @@ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr)
 	return drvr->dbgfs_dir;
 }
 
-struct brcmf_debugfs_entry {
-	int (*read)(struct seq_file *seq, void *data);
-	struct brcmf_pub *drvr;
-};
-
-static int brcmf_debugfs_entry_open(struct inode *inode, struct file *f)
-{
-	struct brcmf_debugfs_entry *entry = inode->i_private;
-
-	return single_open(f, entry->read, entry->drvr->bus_if->dev);
-}
-
-static const struct file_operations brcmf_debugfs_def_ops = {
-	.owner = THIS_MODULE,
-	.open = brcmf_debugfs_entry_open,
-	.release = single_release,
-	.read = seq_read,
-	.llseek = seq_lseek
-};
-
 int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
 			    int (*read_fn)(struct seq_file *seq, void *data))
 {
-	struct dentry *dentry =  drvr->dbgfs_dir;
-	struct brcmf_debugfs_entry *entry;
-
-	if (IS_ERR_OR_NULL(dentry))
-		return -ENOENT;
-
-	entry = devm_kzalloc(drvr->bus_if->dev, sizeof(*entry), GFP_KERNEL);
-	if (!entry)
-		return -ENOMEM;
-
-	entry->read = read_fn;
-	entry->drvr = drvr;
-
-	dentry = debugfs_create_file(fn, S_IRUGO, dentry, entry,
-				     &brcmf_debugfs_def_ops);
+	struct dentry *e;
 
-	return PTR_ERR_OR_ZERO(dentry);
+	e = debugfs_create_devm_seqfile(drvr->bus_if->dev, fn,
+					drvr->dbgfs_dir, read_fn);
+	return PTR_ERR_OR_ZERO(e);
 }
Signature · 1 line
1.9.1