[PATCH] wlcore: Allow scans when in AP mode

2016-10-07 Thread Xander Huff
From: James Minor 

When in AP mode, scans can be done without changing firmware to
the multi-role firmware. Allow the interface to scan if forced
in the scan request.

Signed-off-by: James Minor 
Signed-off-by: Xander Huff 
Reviewed-by: Ben Shelton 
Reviewed-by: Jaeden Amero 
---
 drivers/net/wireless/ti/wlcore/main.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ti/wlcore/main.c 
b/drivers/net/wireless/ti/wlcore/main.c
index 471521a..01ca370 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -6120,6 +6120,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
WIPHY_FLAG_SUPPORTS_SCHED_SCAN |
WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 
+   wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;
+
/* make sure all our channels fit in the scanned_ch bitmask */
BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) +
 ARRAY_SIZE(wl1271_channels_5ghz) >
-- 
1.9.1



[PATCH] net: macb: NULL out phydev after removing mdio bus

2016-10-07 Thread Xander Huff
From: Nathan Sullivan 

To ensure the dev->phydev pointer is not used after becoming invalid in
mdiobus_unregister, set it to NULL. This happens when removing the macb
driver without first taking its interface down, since unregister_netdev
will end up calling macb_close.

Signed-off-by: Xander Huff 
Signed-off-by: Nathan Sullivan 
Signed-off-by: Brad Mouring 
---
 drivers/net/ethernet/cadence/macb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 63144bb..b32444a 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -3117,6 +3117,7 @@ static int macb_remove(struct platform_device *pdev)
if (dev->phydev)
phy_disconnect(dev->phydev);
mdiobus_unregister(bp->mii_bus);
+   dev->phydev = NULL;
mdiobus_free(bp->mii_bus);
 
/* Shutdown the PHY if there is a GPIO reset */
-- 
1.9.1



[PATCH v2] net: macb: Increase DMA TX buffer size

2016-08-24 Thread Xander Huff
From: Nathan Sullivan 

In recent testing with the RT patchset, we have seen cases where the
transmit ring can fill even with up to 200 txbds in the ring. Increase the
size of the DMA TX ring to avoid overruns.

Signed-off-by: Xander Huff 
Signed-off-by: Nathan Sullivan 
---
 drivers/net/ethernet/cadence/macb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 3256839..3efddb7 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -40,7 +40,7 @@
 #define RX_RING_SIZE   512 /* must be power of 2 */
 #define RX_RING_BYTES  (sizeof(struct macb_dma_desc) * RX_RING_SIZE)
 
-#define TX_RING_SIZE   128 /* must be power of 2 */
+#define TX_RING_SIZE   512 /* must be power of 2 */
 #define TX_RING_BYTES  (sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
 /* level of occupied TX descriptors under which we wake up TX process */
-- 
1.9.1



[PATCH v2] Revert "phy: IRQ cannot be shared"

2016-08-24 Thread Xander Huff
This reverts:
  commit 33c133cc7598 ("phy: IRQ cannot be shared")

On hardware with multiple PHY devices hooked up to the same IRQ line, allow
them to share it.

Sergei Shtylyov says:
  "I'm not sure now what was the reason I concluded that the IRQ sharing
  was impossible... most probably I thought that the kernel IRQ handling
  code exited the loop over the IRQ actions once IRQ_HANDLED was returned
  -- which is obviously not so in reality..."

Signed-off-by: Xander Huff 
Signed-off-by: Nathan Sullivan 
---
Note: this reverted code fails "CHECK: Alignment should match open
parentesis"
---
 drivers/net/phy/phy.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c5dc2c36..c6f6683 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -722,8 +722,10 @@ phy_err:
 int phy_start_interrupts(struct phy_device *phydev)
 {
atomic_set(&phydev->irq_disable, 0);
-   if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt",
-   phydev) < 0) {
+   if (request_irq(phydev->irq, phy_interrupt,
+   IRQF_SHARED,
+   "phy_interrupt",
+   phydev) < 0) {
pr_warn("%s: Can't get IRQ %d (PHY)\n",
phydev->mdio.bus->name, phydev->irq);
phydev->irq = PHY_POLL;
-- 
1.9.1



Re: [PATCH] phy: request shared IRQ

2016-08-24 Thread Xander Huff

On 8/24/2016 1:41 PM, Sergei Shtylyov wrote:

Hello.

On 08/24/2016 08:53 PM, Xander Huff wrote:


From: Nathan Sullivan 

On hardware with multiple PHY devices hooked up to the same IRQ line, allow
them to share it.


Note that it had been allowed until my (erroneous?) commit
33c133cc7598e60976a069344910d63e56cc4401 ("phy: IRQ cannot be shared"), so I'd
like this commit just reverted instead...
I'm not sure now what was the reason I concluded that the IRQ sharing was
impossible... most probably I thought that the kernel IRQ handling code exited
the loop over the IRQ actions once IRQ_HANDLED was returned -- which is
obviously not so in reality...

MBR, Sergei


Thanks for the suggestion, Sergei. I'll do just that.

--
Xander Huff
Staff Software Engineer
National Instruments


[PATCH] net: macb: Increase DMA buffer size

2016-08-24 Thread Xander Huff
From: Nathan Sullivan 

In recent testing with the RT patchset, we have seen cases where the
transmit ring can fill even with up to 200 txbds in the ring.  Increase
the size of the DMA rings to avoid overruns.

Signed-off-by: Nathan Sullivan 
Acked-by: Ben Shelton 
Acked-by: Jaeden Amero 
Natinst-ReviewBoard-ID: 83662
---
 drivers/net/ethernet/cadence/macb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 3256839..86a8e20 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -35,12 +35,12 @@
 
 #include "macb.h"
 
-#define MACB_RX_BUFFER_SIZE128
+#define MACB_RX_BUFFER_SIZE1536
 #define RX_BUFFER_MULTIPLE 64  /* bytes */
 #define RX_RING_SIZE   512 /* must be power of 2 */
 #define RX_RING_BYTES  (sizeof(struct macb_dma_desc) * RX_RING_SIZE)
 
-#define TX_RING_SIZE   128 /* must be power of 2 */
+#define TX_RING_SIZE   512 /* must be power of 2 */
 #define TX_RING_BYTES  (sizeof(struct macb_dma_desc) * TX_RING_SIZE)
 
 /* level of occupied TX descriptors under which we wake up TX process */
-- 
1.9.1



[PATCH] phy: request shared IRQ

2016-08-24 Thread Xander Huff
From: Nathan Sullivan 

On hardware with multiple PHY devices hooked up to the same IRQ line, allow
them to share it.

Signed-off-by: Nathan Sullivan 
Signed-off-by: Xander Huff 
Acked-by: Ben Shelton 
Acked-by: Jaeden Amero 
---
 drivers/net/phy/phy.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index c5dc2c36..0050531 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -722,8 +722,8 @@ phy_err:
 int phy_start_interrupts(struct phy_device *phydev)
 {
atomic_set(&phydev->irq_disable, 0);
-   if (request_irq(phydev->irq, phy_interrupt, 0, "phy_interrupt",
-   phydev) < 0) {
+   if (request_irq(phydev->irq, phy_interrupt, IRQF_SHARED,
+   "phy_interrupt", phydev) < 0) {
pr_warn("%s: Can't get IRQ %d (PHY)\n",
phydev->mdio.bus->name, phydev->irq);
phydev->irq = PHY_POLL;
-- 
1.9.1



Re: [PATCH] net: phy: micrel: remove suspend/resume

2016-08-23 Thread Xander Huff

On 8/23/2016 2:03 PM, Florian Fainelli wrote:

+others,

On 08/23/2016 04:13 AM, Christophe Leroy wrote:

In ERRATA DS8700A dated 05 May 2016, Microship recommends to
not use software power down mode on KSZ8041 family.


s/Microship/Microchip/


They say they have no plan to fix this ERRATA in future releases.


The errata applies to specific revisions, is this revision present in
the lower 4 bits of the MII_PHYSID2 register such that it could be used
to key the disabling of the power down?



http://ww1.microchip.com/downloads/en/DeviceDoc/8700A.pdf

Signed-off-by: Christophe Leroy 
---
  drivers/net/phy/micrel.c | 4 
  1 file changed, 4 deletions(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 053e879..f456c55 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -837,8 +837,6 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
-   .suspend= genphy_suspend,
-   .resume = genphy_resume,
  }, {
.phy_id = PHY_ID_KSZ8041RNLI,
.phy_id_mask= MICREL_PHY_ID_MASK,
@@ -856,8 +854,6 @@ static struct phy_driver ksphy_driver[] = {
.get_sset_count = kszphy_get_sset_count,
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
-   .suspend= genphy_suspend,
-   .resume = genphy_resume,
  }, {
.phy_id = PHY_ID_KSZ8051,
.phy_id_mask= MICREL_PHY_ID_MASK,





It doesn't appear that KSZ9031 is affected by this errata; no mention of 
suspend:

http://ww1.microchip.com/downloads/en/DeviceDoc/KSZ9031MNX_Errata_Rev%20A_A2_032515.pdf

--
Xander Huff
Staff Software Engineer
National Instruments


Re: [PATCH] phy: micrel: Reenable interrupts during on resume for ksz9031

2016-08-22 Thread Xander Huff

On 8/22/2016 3:43 PM, Xander Huff wrote:

Like the ksz8081, the ksz9031 has the behavior where it will clear the interrupt
enable bits when leaving power down. This takes advantage of the solution
provided by f5aba91.

Signed-off-by: Xander Huff 
Signed-off-by: Nathan Sullivan 
Natinst-ReviewBoard-ID: 149877
---
  drivers/net/phy/micrel.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 053e879..885ac9c 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -964,7 +964,7 @@ static struct phy_driver ksphy_driver[] = {
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
.suspend= genphy_suspend,
-   .resume = genphy_resume,
+   .resume = kszphy_resume,
  }, {
.phy_id = PHY_ID_KSZ8873MLL,
.phy_id_mask= MICREL_PHY_ID_MASK,

Please disregard this patch as it was accidentally sent. Please instead refer to 
my subsequent email with the subject:

"[PATCH] phy: micrel: Reenable interrupts during resume for ksz9031"

--
Xander Huff
Staff Software Engineer
National Instruments


[PATCH] phy: micrel: Reenable interrupts during on resume for ksz9031

2016-08-22 Thread Xander Huff
Like the ksz8081, the ksz9031 has the behavior where it will clear the interrupt
enable bits when leaving power down. This takes advantage of the solution
provided by f5aba91.

Signed-off-by: Xander Huff 
Signed-off-by: Nathan Sullivan 
Natinst-ReviewBoard-ID: 149877
---
 drivers/net/phy/micrel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 053e879..885ac9c 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -964,7 +964,7 @@ static struct phy_driver ksphy_driver[] = {
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
.suspend= genphy_suspend,
-   .resume = genphy_resume,
+   .resume = kszphy_resume,
 }, {
.phy_id = PHY_ID_KSZ8873MLL,
.phy_id_mask= MICREL_PHY_ID_MASK,
-- 
1.9.1



[PATCH] phy: micrel: Reenable interrupts during resume for ksz9031

2016-08-22 Thread Xander Huff
Like the ksz8081, the ksz9031 has the behavior where it will clear the
interrupt enable bits when leaving power down. This takes advantage of the
solution provided by f5aba91.

Signed-off-by: Xander Huff 
Signed-off-by: Nathan Sullivan 
---
 drivers/net/phy/micrel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 053e879..885ac9c 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -964,7 +964,7 @@ static struct phy_driver ksphy_driver[] = {
.get_strings= kszphy_get_strings,
.get_stats  = kszphy_get_stats,
.suspend= genphy_suspend,
-   .resume = genphy_resume,
+   .resume = kszphy_resume,
 }, {
.phy_id = PHY_ID_KSZ8873MLL,
.phy_id_mask= MICREL_PHY_ID_MASK,
-- 
1.9.1



Re: [RESEND RESEND RESEND PATCH v2] mtd: nand_bbt: scan for next free bbt block if writing bbt fails

2015-09-04 Thread Xander Huff

On 8/26/2015 7:07 PM, Brian Norris wrote:

On Wed, Aug 26, 2015 at 03:57:00PM +, Bean Huo 霍斌斌 (beanhuo) wrote:

On Tue, Aug 25, 2015 at 12:49:26PM -0500, Xander Huff wrote:



diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 63a1a36..09f9e62 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c



-787,13 +788,42 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
einfo.addr = to;
einfo.len = 1 << this->bbt_erase_shift;
res = nand_erase_nand(mtd, &einfo, 1);
-   if (res < 0)
+   if (res == -EIO && einfo.state == MTD_ERASE_FAILED
+   && einfo.priv == NAND_ERASE_BLOCK_ERASE_FAILED) {


Do you actually need that last condition? What's wrong with the first two?



The intent of the extra condition is to distinguish from other erase failures 
due to write protection or an already known bad block. We don't want to mark a 
write protected block as bad simply because we failed to erase it, for example.



+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when writing

BBT\n",

+   block);
+   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+
+   res = this->block_markbad(mtd, block);
+   if (res)
+   pr_warn("nand_bbt: error %d while marking block 
%d

bad\n",

+   res, block);
+   goto next;
+   } else if (res < 0)
goto outerr;



For my knowledge , we don't directly mark this block be a bad block,
Just like ubi layer,this block also need to further testing and verify if
It is real bad block.right?


That's a good point...we might want some kind of separate function for a
torture test. Might look at UBI's torture_peb() for inspiration.



Hmm, I'll look into this. Any performance concerns if we're torturing for every 
potential bad block we come across?




res = scan_write_bbt(mtd, to, len, buf,
td->options & NAND_BBT_NO_OOB ? NULL :
&buf[len]);
-   if (res < 0)
+   if (res == -EIO) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when writing

BBT\n",

+   block);
+   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+
+   res = this->block_markbad(mtd, block);
+   if (res)
+   pr_warn("nand_bbt: error %d while marking block 
%d

bad\n",

+   res, block);
+   goto next;
+   } else if (res < 0)
goto outerr;

pr_info("Bad block table written to 0x%012llx, version 
0x%02X\n",>
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index
272f429..86e11f6 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -1030,4 +1030,11 @@ struct nand_sdr_timings {

 /* get timing characteristics from ONFI timing mode. */  const struct
nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
+
+/* reasons for erase failures */
+#define NAND_ERASE_OK  0
+#define NAND_ERASE_WRITE_PROTECTED 1
+#define NAND_ERASE_BAD_BLOCK   2
+#define NAND_ERASE_BLOCK_ERASE_FAILED  3


Why exactly do you need these statuses? I thought the existing error codes
were sufficient..


This goes along with why we were originally using the 'priv' field. Lots of 
places use MTD_ERASE_FAILED to see if an erase failed, but we want to check 
specifically what type of erase failure occurred. Do ya'll have any suggestions 
on how better to accomplish this? I'm thinking maybe adding a new member to the 
erase_info struct like 'fail_info' to get this information to nand_bbt.



--
Xander Huff
Staff Software Engineer
National Instruments
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RESEND RESEND RESEND PATCH v2] mtd: nand_bbt: scan for next free bbt block if writing bbt fails

2015-08-25 Thread Xander Huff
From: Ben Shelton 

If erasing or writing the BBT fails, we should mark the current BBT
block as bad and use the BBT descriptor to scan for the next available
unused block in the BBT. We should only return a failure if there isn't
any space left.

Based on original code implemented by Jeff Westfahl
.

Signed-off-by: Ben Shelton 
Reviewed-by: Jaeden Amero 
Suggested-by: Jeff Westfahl 
Signed-off-by: Xander Huff 
---
This v2 patch is in reply to comments from Brian Norris on 7/22/13. See
the following links for context:
http://lists.infradead.org/pipermail/linux-mtd/2013-July/047596.html
http://patchwork.ozlabs.org/patch/244324/
---
 drivers/mtd/nand/nand_base.c |  4 
 drivers/mtd/nand/nand_bbt.c  | 34 --
 include/linux/mtd/nand.h |  7 +++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ceb68ca..48299dc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2761,6 +2761,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_debug("%s: device is write protected!\n",
__func__);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_WRITE_PROTECTED;
goto erase_exit;
}
 
@@ -2776,6 +2777,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_warn("%s: attempt to erase a bad block at page 
0x%08x\n",
__func__, page);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_BAD_BLOCK;
goto erase_exit;
}
 
@@ -2802,6 +2804,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_debug("%s: failed erase, page 0x%08x\n",
__func__, page);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_BLOCK_ERASE_FAILED;
instr->fail_addr =
((loff_t)page << chip->page_shift);
goto erase_exit;
@@ -2819,6 +2822,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
}
}
instr->state = MTD_ERASE_DONE;
+   instr->priv = NAND_ERASE_OK;
 
 erase_exit:
 
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 63a1a36..09f9e62 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -662,6 +662,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
page = td->pages[chip];
goto write;
}
+next:
 
/*
 * Automatic placement of the bad block table. Search direction
@@ -787,13 +788,42 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
einfo.addr = to;
einfo.len = 1 << this->bbt_erase_shift;
res = nand_erase_nand(mtd, &einfo, 1);
-   if (res < 0)
+   if (res == -EIO && einfo.state == MTD_ERASE_FAILED
+   && einfo.priv == NAND_ERASE_BLOCK_ERASE_FAILED) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when 
writing BBT\n",
+   block);
+   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+
+   res = this->block_markbad(mtd, block);
+   if (res)
+   pr_warn("nand_bbt: error %d while marking block 
%d bad\n",
+   res, block);
+   goto next;
+   } else if (res < 0)
goto outerr;
 
res = scan_write_bbt(mtd, to, len, buf,
td->options & NAND_BBT_NO_OOB ? NULL :
&buf[len]);
-   if (res < 0)
+   if (res == -EIO) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when 
writing BBT\n",
+   block);
+   

[PATCH v4] iio: adc: xilinx-xadc: Push interrupts into hardirq context

2015-08-11 Thread Xander Huff
The driver currently registers a pair of irq handlers using
request_threaded_irq(), however the synchronization mechanism between the
hardirq and the threadedirq handler is a regular spinlock.

Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
and is thus not able to be acquired from a hardirq handler. This patch gets
rid of the threaded handler and pushes all interrupt handling into the
hardirq context, and uses request_irq().

To validate that this change has no impact on RT performance, here are
cyclictest values with no processes running:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.00 0.01 0.05 1/174 2539
T: 0 ( 1405) P:98 I:1000 C:167010520 Min: 9 Act: 12 Avg: 12 Max: 75
T: 1 ( 1862) P:98 I:1500 C:111340339 Min: 9 Act: 12 Avg: 12 Max: 73

Then, all xadc raw handles were accessed in a continuous loop via
/sys/bus/iio/devices/iio:device0:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 7.84 7.70 7.63 3/182 4260
T: 0 ( 2559) P:98 I:1000 C:241557018 Min: 11 Act: 18 Avg: 21 Max: 74
T: 1 ( 2560) P:98 I:1500 C:161038006 Min: 10 Act: 21 Avg: 20 Max: 73

Signed-off-by: Xander Huff 
---
 drivers/iio/adc/xilinx-xadc-core.c | 37 ++---
 drivers/iio/adc/xilinx-xadc.h  |  2 --
 2 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/drivers/iio/adc/xilinx-xadc-core.c 
b/drivers/iio/adc/xilinx-xadc-core.c
index ce93bd8..0370624 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -273,33 +273,13 @@ static void xadc_zynq_unmask_worker(struct work_struct 
*work)
schedule_delayed_work(&xadc->zynq_unmask_work,
msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
}
-}
-
-static irqreturn_t xadc_zynq_threaded_interrupt_handler(int irq, void *devid)
-{
-   struct iio_dev *indio_dev = devid;
-   struct xadc *xadc = iio_priv(indio_dev);
-   unsigned int alarm;
-
-   spin_lock_irq(&xadc->lock);
-   alarm = xadc->zynq_alarm;
-   xadc->zynq_alarm = 0;
-   spin_unlock_irq(&xadc->lock);
-
-   xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
 
-   /* unmask the required interrupts in timer. */
-   schedule_delayed_work(&xadc->zynq_unmask_work,
-   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
-
-   return IRQ_HANDLED;
 }
 
 static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
 {
struct iio_dev *indio_dev = devid;
struct xadc *xadc = iio_priv(indio_dev);
-   irqreturn_t ret = IRQ_HANDLED;
uint32_t status;
 
xadc_read_reg(xadc, XADC_ZYNQ_REG_INTSTS, &status);
@@ -321,18 +301,23 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, 
void *devid)
 
status &= XADC_ZYNQ_INT_ALARM_MASK;
if (status) {
-   xadc->zynq_alarm |= status;
xadc->zynq_masked_alarm |= status;
/*
 * mask the current event interrupt,
 * unmask it when the interrupt is no more active.
 */
xadc_zynq_update_intmsk(xadc, 0, 0);
-   ret = IRQ_WAKE_THREAD;
+
+   xadc_handle_events(indio_dev,
+   xadc_zynq_transform_alarm(status));
+
+   /* unmask the required interrupts in timer. */
+   schedule_delayed_work(&xadc->zynq_unmask_work,
+   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
}
spin_unlock(&xadc->lock);
 
-   return ret;
+   return IRQ_HANDLED;
 }
 
 #define XADC_ZYNQ_TCK_RATE_MAX 5000
@@ -437,7 +422,6 @@ static const struct xadc_ops xadc_zynq_ops = {
.setup = xadc_zynq_setup,
.get_dclk_rate = xadc_zynq_get_dclk_rate,
.interrupt_handler = xadc_zynq_interrupt_handler,
-   .threaded_interrupt_handler = xadc_zynq_threaded_interrupt_handler,
.update_alarm = xadc_zynq_update_alarm,
 };
 
@@ -1225,9 +1209,8 @@ static int xadc_probe(struct platform_device *pdev)
if (ret)
goto err_free_samplerate_trigger;
 
-   ret = request_threaded_irq(irq, xadc->ops->interrupt_handler,
-   xadc->ops->threaded_interrupt_handler,
-   0, dev_name(&pdev->dev), indio_dev);
+   ret = request_irq(irq, xadc->ops->interrupt_handler, 0,
+   dev_name(&pdev->dev), indio_dev);
if (ret)
goto err_clk_disable_unprepare;
 
diff --git a/drivers/iio/adc/xilinx-xadc.h b/drivers/iio/adc/xilinx-xadc.h
index 54adc50..f6f0819 100644
--- a/drivers/iio/adc/xilinx-xadc.h
+++ b/drivers/iio/adc/xilinx-xadc.h
@@ -60,7 +60,6 @@ struct xadc {
 
enum xadc_external_mux_mode external_mux_mode;
 
-   unsigned int zynq_alarm;

[RESEND RESEND PATCH v2] mtd: nand_bbt: scan for next free bbt block if writing bbt fails

2015-08-11 Thread Xander Huff
From: Ben Shelton 

If erasing or writing the BBT fails, we should mark the current BBT
block as bad and use the BBT descriptor to scan for the next available
unused block in the BBT. We should only return a failure if there isn't
any space left.

Based on original code implemented by Jeff Westfahl
.

Signed-off-by: Ben Shelton 
Reviewed-by: Jaeden Amero 
Suggested-by: Jeff Westfahl 
Signed-off-by: Xander Huff 
---
This v2 patch is in reply to comments from Brian Norris on 7/22/13. See
the following links for context:
http://lists.infradead.org/pipermail/linux-mtd/2013-July/047596.html
http://patchwork.ozlabs.org/patch/244324/
---
 drivers/mtd/nand/nand_base.c |  4 
 drivers/mtd/nand/nand_bbt.c  | 34 --
 include/linux/mtd/nand.h |  7 +++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ceb68ca..48299dc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2761,6 +2761,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_debug("%s: device is write protected!\n",
__func__);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_WRITE_PROTECTED;
goto erase_exit;
}
 
@@ -2776,6 +2777,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_warn("%s: attempt to erase a bad block at page 
0x%08x\n",
__func__, page);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_BAD_BLOCK;
goto erase_exit;
}
 
@@ -2802,6 +2804,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_debug("%s: failed erase, page 0x%08x\n",
__func__, page);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_BLOCK_ERASE_FAILED;
instr->fail_addr =
((loff_t)page << chip->page_shift);
goto erase_exit;
@@ -2819,6 +2822,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
}
}
instr->state = MTD_ERASE_DONE;
+   instr->priv = NAND_ERASE_OK;
 
 erase_exit:
 
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 63a1a36..09f9e62 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -662,6 +662,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
page = td->pages[chip];
goto write;
}
+next:
 
/*
 * Automatic placement of the bad block table. Search direction
@@ -787,13 +788,42 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
einfo.addr = to;
einfo.len = 1 << this->bbt_erase_shift;
res = nand_erase_nand(mtd, &einfo, 1);
-   if (res < 0)
+   if (res == -EIO && einfo.state == MTD_ERASE_FAILED
+   && einfo.priv == NAND_ERASE_BLOCK_ERASE_FAILED) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when 
writing BBT\n",
+   block);
+   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+
+   res = this->block_markbad(mtd, block);
+   if (res)
+   pr_warn("nand_bbt: error %d while marking block 
%d bad\n",
+   res, block);
+   goto next;
+   } else if (res < 0)
goto outerr;
 
res = scan_write_bbt(mtd, to, len, buf,
td->options & NAND_BBT_NO_OOB ? NULL :
&buf[len]);
-   if (res < 0)
+   if (res == -EIO) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when 
writing BBT\n",
+   block);
+   

Re: [PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded context

2015-08-03 Thread Xander Huff

On 7/24/2015 7:38 AM, Lars-Peter Clausen wrote:

Hi,

Sorry, but I don't think this patch has been sufficiently tested against a
mainline kernel. The driver wont even probe the way it is right now.

Thanks for your responses. I'm not sure why it doesn't probe for you since I was 
able to do a fair amount of tests with it on our device.


I'll get to work on your suggestions and hopefully having a v4 out sometime next 
week.


--
Xander Huff
Staff Software Engineer
National Instruments
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RESEND PATCH v2] mtd: nand_bbt: scan for next free bbt block if writing bbt fails

2015-07-22 Thread Xander Huff
From: Ben Shelton 

If erasing or writing the BBT fails, we should mark the current BBT
block as bad and use the BBT descriptor to scan for the next available
unused block in the BBT. We should only return a failure if there isn't
any space left.

Based on original code implemented by Jeff Westfahl
.

Signed-off-by: Ben Shelton 
Reviewed-by: Jaeden Amero 
Suggested-by: Jeff Westfahl 
Signed-off-by: Xander Huff 
---
This v2 patch is in reply to comments from Brian Norris on 7/22/13. See
the following links for context:
http://lists.infradead.org/pipermail/linux-mtd/2013-July/047596.html
http://patchwork.ozlabs.org/patch/244324/
---
 drivers/mtd/nand/nand_base.c |  4 
 drivers/mtd/nand/nand_bbt.c  | 34 --
 include/linux/mtd/nand.h |  7 +++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index ceb68ca..48299dc 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -2761,6 +2761,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_debug("%s: device is write protected!\n",
__func__);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_WRITE_PROTECTED;
goto erase_exit;
}
 
@@ -2776,6 +2777,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_warn("%s: attempt to erase a bad block at page 
0x%08x\n",
__func__, page);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_BAD_BLOCK;
goto erase_exit;
}
 
@@ -2802,6 +2804,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
pr_debug("%s: failed erase, page 0x%08x\n",
__func__, page);
instr->state = MTD_ERASE_FAILED;
+   instr->priv = NAND_ERASE_BLOCK_ERASE_FAILED;
instr->fail_addr =
((loff_t)page << chip->page_shift);
goto erase_exit;
@@ -2819,6 +2822,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct 
erase_info *instr,
}
}
instr->state = MTD_ERASE_DONE;
+   instr->priv = NAND_ERASE_OK;
 
 erase_exit:
 
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 63a1a36..09f9e62 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -662,6 +662,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
page = td->pages[chip];
goto write;
}
+next:
 
/*
 * Automatic placement of the bad block table. Search direction
@@ -787,13 +788,42 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
einfo.addr = to;
einfo.len = 1 << this->bbt_erase_shift;
res = nand_erase_nand(mtd, &einfo, 1);
-   if (res < 0)
+   if (res == -EIO && einfo.state == MTD_ERASE_FAILED
+   && einfo.priv == NAND_ERASE_BLOCK_ERASE_FAILED) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when 
writing BBT\n",
+   block);
+   bbt_mark_entry(this, block, BBT_BLOCK_WORN);
+
+   res = this->block_markbad(mtd, block);
+   if (res)
+   pr_warn("nand_bbt: error %d while marking block 
%d bad\n",
+   res, block);
+   goto next;
+   } else if (res < 0)
goto outerr;
 
res = scan_write_bbt(mtd, to, len, buf,
td->options & NAND_BBT_NO_OOB ? NULL :
&buf[len]);
-   if (res < 0)
+   if (res == -EIO) {
+   /* This block is bad. Mark it as such and see if
+* there's another block available in the BBT area. */
+   int block = page >>
+   (this->bbt_erase_shift - this->page_shift);
+   pr_info("nand_bbt: failed to erase block %d when 
writing BBT\n",
+   block);
+   

[PATCH v3] iio: adc: xilinx-xadc: Push interrupts into threaded context

2015-07-20 Thread Xander Huff
The driver currently registers a pair of irq handlers using
request_threaded_irq(), however the synchronization mechanism between the
hardirq and the threadedirq handler is a regular spinlock.

Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
and is thus not able to be acquired from a hardirq handler. This patch gets
rid of the hardirq handler and pushes all interrupt handling into the
threaded context.

To validate that this change has no impact on RT performance, here are
cyclictest values with no processes running:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.05 0.04 0.05 1/237 828
T: 0 ( 1861) P:98 I:1000 C:56925046 Min: 9 Act: 12 Avg: 12 Max: 71
T: 1 ( 1862) P:98 I:1500 C:37950030 Min: 9 Act: 12 Avg: 13 Max: 74

Then, all xadc raw handles were accessed in a continuous loop via
/sys/bus/iio/devices/iio:device0:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 7.81 7.64 7.541 2/247 5751
T: 0 ( 1568) P:98 I:1000 C:23845515 Min: 11 Act: 22 Avg: 21 Max: 71
T: 1 ( 1569) P:98 I:1500 C:15897239 Min: 11 Act: 21 Avg: 22 Max: 68

Signed-off-by: Xander Huff 
---
 drivers/iio/adc/xilinx-xadc-core.c | 37 -
 1 file changed, 8 insertions(+), 29 deletions(-)

diff --git a/drivers/iio/adc/xilinx-xadc-core.c 
b/drivers/iio/adc/xilinx-xadc-core.c
index ce93bd8..e16afdb 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -267,40 +267,15 @@ static void xadc_zynq_unmask_worker(struct work_struct 
*work)
xadc_zynq_update_intmsk(xadc, 0, 0);
 
spin_unlock_irq(&xadc->lock);
-
-   /* if still pending some alarm re-trigger the timer */
-   if (xadc->zynq_masked_alarm) {
-   schedule_delayed_work(&xadc->zynq_unmask_work,
-   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
-   }
 }
 
 static irqreturn_t xadc_zynq_threaded_interrupt_handler(int irq, void *devid)
 {
struct iio_dev *indio_dev = devid;
struct xadc *xadc = iio_priv(indio_dev);
-   unsigned int alarm;
-
-   spin_lock_irq(&xadc->lock);
-   alarm = xadc->zynq_alarm;
-   xadc->zynq_alarm = 0;
-   spin_unlock_irq(&xadc->lock);
-
-   xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
-
-   /* unmask the required interrupts in timer. */
-   schedule_delayed_work(&xadc->zynq_unmask_work,
-   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
-{
-   struct iio_dev *indio_dev = devid;
-   struct xadc *xadc = iio_priv(indio_dev);
irqreturn_t ret = IRQ_HANDLED;
uint32_t status;
+   unsigned int alarm;
 
xadc_read_reg(xadc, XADC_ZYNQ_REG_INTSTS, &status);
 
@@ -312,7 +287,6 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, 
void *devid)
spin_lock(&xadc->lock);
 
xadc_write_reg(xadc, XADC_ZYNQ_REG_INTSTS, status);
-
if (status & XADC_ZYNQ_INT_DFIFO_GTH) {
xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH,
XADC_ZYNQ_INT_DFIFO_GTH);
@@ -330,8 +304,14 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, 
void *devid)
xadc_zynq_update_intmsk(xadc, 0, 0);
ret = IRQ_WAKE_THREAD;
}
+
+   alarm = xadc->zynq_alarm;
+   xadc->zynq_alarm = 0;
+
spin_unlock(&xadc->lock);
 
+   xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
+
return ret;
 }
 
@@ -436,7 +416,6 @@ static const struct xadc_ops xadc_zynq_ops = {
.write = xadc_zynq_write_adc_reg,
.setup = xadc_zynq_setup,
.get_dclk_rate = xadc_zynq_get_dclk_rate,
-   .interrupt_handler = xadc_zynq_interrupt_handler,
.threaded_interrupt_handler = xadc_zynq_threaded_interrupt_handler,
.update_alarm = xadc_zynq_update_alarm,
 };
@@ -1225,7 +1204,7 @@ static int xadc_probe(struct platform_device *pdev)
if (ret)
goto err_free_samplerate_trigger;
 
-   ret = request_threaded_irq(irq, xadc->ops->interrupt_handler,
+   ret = request_threaded_irq(irq, NULL,
xadc->ops->threaded_interrupt_handler,
0, dev_name(&pdev->dev), indio_dev);
if (ret)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] iio: adc: xilinx-xadc: Push interrupts into threaded context

2015-07-15 Thread Xander Huff

On 7/9/2015 12:03 AM, Shubhrajyoti Datta wrote:

@@ -330,8 +310,18 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq,
void *devid)
 xadc_zynq_update_intmsk(xadc, 0, 0);
 ret = IRQ_WAKE_THREAD;
 }
+
+   alarm = xadc->zynq_alarm;
+   xadc->zynq_alarm = 0;
+
 spin_unlock(&xadc->lock);

+   xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
+
+   /* unmask the required interrupts in timer. */
+   schedule_delayed_work(&xadc->zynq_unmask_work,
+   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
+

Now that we are in the threaded context do we need the  work queue stuff.
Seems reasonable to try to remove it. I'll do some testing and send out a v3 if 
it works, thanks.


--
Xander Huff
Staff Software Engineer
National Instruments
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] iio: adc: xilinx-xadc: Push interrupts into threaded context

2015-07-15 Thread Xander Huff

On 7/14/2015 9:28 AM, Sebastian Andrzej Siewior wrote:

* Xander Huff | 2015-07-08 16:38:22 [-0500]:


drivers/iio/adc/xilinx-xadc-core.c | 35 ---
1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/adc/xilinx-xadc-core.c 
b/drivers/iio/adc/xilinx-xadc-core.c
index ce93bd8..b309ad3 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -1225,7 +1214,7 @@ static int xadc_probe(struct platform_device *pdev)
if (ret)
goto err_free_samplerate_trigger;

-   ret = request_threaded_irq(irq, xadc->ops->interrupt_handler,
+   ret = request_threaded_irq(irq, 0,


NULL not 0
Other than that, it looks good. Thanks.
If you managed to get this merged upstream then feel free to ping me and
I pick this into -RT.


xadc->ops->threaded_interrupt_handler,
0, dev_name(&pdev->dev), indio_dev);
if (ret)


Sebastian

Haven't got this merged in yet. I'm addressing another concern from Shubhrajyoti 
Datta and will include this change in my v3 I'll send out sometime next week, 
thanks!


--
Xander Huff
Staff Software Engineer
National Instruments
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] iio: adc: xilinx-xadc: Push interrupts into threaded context

2015-07-08 Thread Xander Huff
The driver currently registers a pair of irq handlers using
request_threaded_irq(), however the synchronization mechanism between the
hardirq and the threadedirq handler is a regular spinlock.

Unfortunately, this breaks PREEMPT_RT builds, where a spinlock can sleep,
and is thus not able to be acquired from a hardirq handler. This patch gets
rid of the hardirq handler and pushes all interrupt handling into the
threaded context.

To validate that this change has no impact on RT performance, here are
cyclictest values with no processes running:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 0.05 0.04 0.05 1/237 828
T: 0 ( 1861) P:98 I:1000 C:56925046 Min: 9 Act: 12 Avg: 12 Max: 71
T: 1 ( 1862) P:98 I:1500 C:37950030 Min: 9 Act: 12 Avg: 13 Max: 74

Then, all xadc raw handles were accessed in a continuous loop via
/sys/bus/iio/devices/iio:device0:

$ sudo cyclictest -S -m -p 98
# /dev/cpu_dma_latency set to 0us
policy: fifo: loadavg: 7.81 7.64 7.541 2/247 5751
T: 0 ( 1568) P:98 I:1000 C:23845515 Min: 11 Act: 22 Avg: 21 Max: 71
T: 1 ( 1569) P:98 I:1500 C:15897239 Min: 11 Act: 21 Avg: 22 Max: 68

Signed-off-by: Xander Huff 
---
 drivers/iio/adc/xilinx-xadc-core.c | 35 ---
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/drivers/iio/adc/xilinx-xadc-core.c 
b/drivers/iio/adc/xilinx-xadc-core.c
index ce93bd8..b309ad3 100644
--- a/drivers/iio/adc/xilinx-xadc-core.c
+++ b/drivers/iio/adc/xilinx-xadc-core.c
@@ -279,28 +279,9 @@ static irqreturn_t 
xadc_zynq_threaded_interrupt_handler(int irq, void *devid)
 {
struct iio_dev *indio_dev = devid;
struct xadc *xadc = iio_priv(indio_dev);
-   unsigned int alarm;
-
-   spin_lock_irq(&xadc->lock);
-   alarm = xadc->zynq_alarm;
-   xadc->zynq_alarm = 0;
-   spin_unlock_irq(&xadc->lock);
-
-   xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
-
-   /* unmask the required interrupts in timer. */
-   schedule_delayed_work(&xadc->zynq_unmask_work,
-   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
-
-   return IRQ_HANDLED;
-}
-
-static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
-{
-   struct iio_dev *indio_dev = devid;
-   struct xadc *xadc = iio_priv(indio_dev);
irqreturn_t ret = IRQ_HANDLED;
uint32_t status;
+   unsigned int alarm;
 
xadc_read_reg(xadc, XADC_ZYNQ_REG_INTSTS, &status);
 
@@ -312,7 +293,6 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, 
void *devid)
spin_lock(&xadc->lock);
 
xadc_write_reg(xadc, XADC_ZYNQ_REG_INTSTS, status);
-
if (status & XADC_ZYNQ_INT_DFIFO_GTH) {
xadc_zynq_update_intmsk(xadc, XADC_ZYNQ_INT_DFIFO_GTH,
XADC_ZYNQ_INT_DFIFO_GTH);
@@ -330,8 +310,18 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, 
void *devid)
xadc_zynq_update_intmsk(xadc, 0, 0);
ret = IRQ_WAKE_THREAD;
}
+
+   alarm = xadc->zynq_alarm;
+   xadc->zynq_alarm = 0;
+
spin_unlock(&xadc->lock);
 
+   xadc_handle_events(indio_dev, xadc_zynq_transform_alarm(alarm));
+
+   /* unmask the required interrupts in timer. */
+   schedule_delayed_work(&xadc->zynq_unmask_work,
+   msecs_to_jiffies(XADC_ZYNQ_UNMASK_TIMEOUT));
+
return ret;
 }
 
@@ -436,7 +426,6 @@ static const struct xadc_ops xadc_zynq_ops = {
.write = xadc_zynq_write_adc_reg,
.setup = xadc_zynq_setup,
.get_dclk_rate = xadc_zynq_get_dclk_rate,
-   .interrupt_handler = xadc_zynq_interrupt_handler,
.threaded_interrupt_handler = xadc_zynq_threaded_interrupt_handler,
.update_alarm = xadc_zynq_update_alarm,
 };
@@ -1225,7 +1214,7 @@ static int xadc_probe(struct platform_device *pdev)
if (ret)
goto err_free_samplerate_trigger;
 
-   ret = request_threaded_irq(irq, xadc->ops->interrupt_handler,
+   ret = request_threaded_irq(irq, 0,
xadc->ops->threaded_interrupt_handler,
0, dev_name(&pdev->dev), indio_dev);
if (ret)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RFC] wext: Add event stream wrappers that return E2BIG when values don't fit

2015-01-29 Thread Xander Huff
From: James Minor 

These issues show up when using the WEXT <-> NL80211 conversion layer and
scanning with that. When the scan results come back, some of the IEs
(information elements) are missing, those that specifically advertise the
network security type. This happens due to the IEs getting chopped off in
if the buffer that's passed in isn't large enough to get the full IE. The
fix is to instead return E2BIG. Without this fix, the advertised security
type is misinterpreted, since it appears to be a WPA or WEP network.

Testing with this fix resulted in a network which previously showed up as a
PSK network now correctly showing up as EAP.

Side effects: A user space app which before did not get E2BIG and instead
got a clipped off buffer might now get E2BIG instead, if the passed buffer
is not large enough.

Signed-off-by: James Minor 
Signed-off-by: Xander Huff 
Acked-by: Joe Hershberger 
Acked-by: Ben Shelton 
---
RFC because we're subtlely changing the user/kernel interface
---
 include/net/iw_handler.h |  87 ++
 net/wireless/scan.c  | 187 ++-
 2 files changed, 208 insertions(+), 66 deletions(-)

diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index a830b01..f07415a 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -521,6 +521,33 @@ iwe_stream_add_event(struct iw_request_info *info, char 
*stream, char *ends,
 
 /*--*/
 /*
+ * Wrapper to add an Wireless Event to a stream of events.
+ * Also returns indication of overflow conditions.
+ */
+static inline int
+iwe_stream_add_event_check(struct iw_request_info *info, char **stream,
+  char *ends, struct iw_event *iwe, int event_len)
+{
+   int lcp_len = iwe_stream_lcp_len(info);
+
+   event_len = iwe_stream_event_len_adjust(info, event_len);
+
+   /* Check if it's possible */
+   if (likely((*stream + event_len) < ends)) {
+   iwe->len = event_len;
+   /* Beware of alignement issues on 64 bits */
+   memcpy(*stream, (char *) iwe, IW_EV_LCP_PK_LEN);
+   memcpy(*stream + lcp_len, &iwe->u,
+  event_len - lcp_len);
+   *stream += event_len;
+   return 0;
+   } else {
+   return -E2BIG;
+   }
+}
+
+/*--*/
+/*
  * Wrapper to add an short Wireless Event containing a pointer to a
  * stream of events.
  */
@@ -547,6 +574,35 @@ iwe_stream_add_point(struct iw_request_info *info, char 
*stream, char *ends,
 
 /*--*/
 /*
+ * Wrapper to add an short Wireless Event containing a pointer to a
+ * stream of events.
+ * Also returns indication of overflow conditions.
+ */
+static inline int
+iwe_stream_add_point_check(struct iw_request_info *info, char **stream,
+  char *ends, struct iw_event *iwe, char *extra)
+{
+   int event_len = iwe_stream_point_len(info) + iwe->u.data.length;
+   int point_len = iwe_stream_point_len(info);
+   int lcp_len   = iwe_stream_lcp_len(info);
+
+   /* Check if it's possible */
+   if (likely((*stream + event_len) < ends)) {
+   iwe->len = event_len;
+   memcpy(*stream, (char *) iwe, IW_EV_LCP_PK_LEN);
+   memcpy(*stream + lcp_len,
+  ((char *) &iwe->u) + IW_EV_POINT_OFF,
+  IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
+   memcpy(*stream + point_len, extra, iwe->u.data.length);
+   *stream += event_len;
+   return 0;
+   } else {
+   return -E2BIG;
+   }
+}
+
+/*--*/
+/*
  * Wrapper to add a value to a Wireless Event in a stream of events.
  * Be careful, this one is tricky to use properly :
  * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
@@ -572,4 +628,35 @@ iwe_stream_add_value(struct iw_request_info *info, char 
*event, char *value,
return value;
 }
 
+/*--*/
+/*
+ * Wrapper to add a value to a Wireless Event in a stream of events.
+ * Be careful, this one is tricky to use properly :
+ * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
+ * Also returns indication of overflow conditions.
+ */
+static inline int
+iwe_stream_add_value_check(struct iw_request_info *info, char *event,
+  char **value, char *ends, struct iw_event *iwe,
+  int event_len)
+{
+   int lcp_len = iwe_stream_lcp_len(info);
+
+   /* Don't duplicate LCP */
+   event_len -= IW_EV_LCP_LEN;
+
+   /* Check if it's possible */
+   if

Re: [PATCH -rt] lockdep: selftest: fix warnings due to missing PREEMPT_RT conditionals

2015-01-28 Thread Xander Huff

On 1/28/2015 1:08 PM, Xander Huff wrote:

From: Josh Cartwright 

"lockdep: Selftest: Only do hardirq context test for raw spinlock"
disabled the execution of certain tests with PREEMPT_RT_FULL, but did
not prevent the tests from still being defined.  This leads to warnings
like:

   ./linux/lib/locking-selftest.c:574:1: warning: 'irqsafe1_hard_rlock_12' 
defined but not used [-Wunused-function]
   ./linux/lib/locking-selftest.c:574:1: warning: 'irqsafe1_hard_rlock_21' 
defined but not used [-Wunused-function]
   ./linux/lib/locking-selftest.c:577:1: warning: 'irqsafe1_hard_wlock_12' 
defined but not used [-Wunused-function]
   ./linux/lib/locking-selftest.c:577:1: warning: 'irqsafe1_hard_wlock_21' 
defined but not used [-Wunused-function]
   ./linux/lib/locking-selftest.c:580:1: warning: 'irqsafe1_soft_spin_12' 
defined but not used [-Wunused-function]
   ...

Fixed by wrapping the test definitions in #ifndef CONFIG_PREEMPT_RT_FULL
conditionals.

Signed-off-by: Josh Cartwright 
Signed-off-by: Xander Huff 
Acked-by: Gratian Crisan 


FYI: To be clearer, this should apply to all stable RT releases 3.4 and later.

--
Xander Huff
Staff Software Engineer
National Instruments
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH -rt] lockdep: selftest: fix warnings due to missing PREEMPT_RT conditionals

2015-01-28 Thread Xander Huff
From: Josh Cartwright 

"lockdep: Selftest: Only do hardirq context test for raw spinlock"
disabled the execution of certain tests with PREEMPT_RT_FULL, but did
not prevent the tests from still being defined.  This leads to warnings
like:

  ./linux/lib/locking-selftest.c:574:1: warning: 'irqsafe1_hard_rlock_12' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:574:1: warning: 'irqsafe1_hard_rlock_21' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:577:1: warning: 'irqsafe1_hard_wlock_12' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:577:1: warning: 'irqsafe1_hard_wlock_21' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:580:1: warning: 'irqsafe1_soft_spin_12' 
defined but not used [-Wunused-function]
  ...

Fixed by wrapping the test definitions in #ifndef CONFIG_PREEMPT_RT_FULL
conditionals.

Signed-off-by: Josh Cartwright 
Signed-off-by: Xander Huff 
Acked-by: Gratian Crisan 
---
 lib/locking-selftest.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 507a22f..51e558f 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -570,6 +570,8 @@ GENERATE_TESTCASE(init_held_rsem)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
 
@@ -585,9 +587,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 
+#ifndef CONFIG_PREEMPT_RT_FULL
 /*
  * Enabling hardirqs with a softirq-safe lock held:
  */
@@ -620,6 +625,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
 #undef E1
 #undef E2
 
+#endif
+
 /*
  * Enabling irqs with an irq-safe lock held:
  */
@@ -643,6 +650,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
 
@@ -658,6 +667,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 
@@ -689,6 +700,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
 
@@ -704,6 +717,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 #undef E3
@@ -737,6 +752,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
 
@@ -752,10 +769,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 #undef E3
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 /*
  * read-lock / write-lock irq inversion.
  *
@@ -818,6 +839,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
 #undef E2
 #undef E3
 
+#endif
+
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 /*
  * read-lock / write-lock recursion that is actually safe.
  */
@@ -856,6 +881,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
 #undef E2
 #undef E3
 
+#endif
+
 /*
  * read-lock / write-lock recursion that is unsafe.
  */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] lockdep: selftest: fix warnings due to missing PREEMPT_RT conditionals

2015-01-27 Thread Xander Huff
From: Josh Cartwright 

"lockdep: Selftest: Only do hardirq context test for raw spinlock"
disabled the execution of certain tests with PREEMPT_RT_FULL, but did
not prevent the tests from still being defined.  This leads to warnings
like:

  ./linux/lib/locking-selftest.c:574:1: warning: 'irqsafe1_hard_rlock_12' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:574:1: warning: 'irqsafe1_hard_rlock_21' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:577:1: warning: 'irqsafe1_hard_wlock_12' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:577:1: warning: 'irqsafe1_hard_wlock_21' 
defined but not used [-Wunused-function]
  ./linux/lib/locking-selftest.c:580:1: warning: 'irqsafe1_soft_spin_12' 
defined but not used [-Wunused-function]
  ...

Fixed by wrapping the test definitions in #ifndef CONFIG_PREEMPT_RT_FULL
conditionals.

Signed-off-by: Josh Cartwright 
Signed-off-by: Xander Huff 
Acked-by: Gratian Crisan 
---
 lib/locking-selftest.c | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index 507a22f..51e558f 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -570,6 +570,8 @@ GENERATE_TESTCASE(init_held_rsem)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
 
@@ -585,9 +587,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 
+#ifndef CONFIG_PREEMPT_RT_FULL
 /*
  * Enabling hardirqs with a softirq-safe lock held:
  */
@@ -620,6 +625,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
 #undef E1
 #undef E2
 
+#endif
+
 /*
  * Enabling irqs with an irq-safe lock held:
  */
@@ -643,6 +650,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A_rlock)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
 
@@ -658,6 +667,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 
@@ -689,6 +700,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
 
@@ -704,6 +717,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 #undef E3
@@ -737,6 +752,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
 #include "locking-selftest-spin-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 #include "locking-selftest-rlock-hardirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
 
@@ -752,10 +769,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_rlock)
 #include "locking-selftest-wlock-softirq.h"
 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
 
+#endif
+
 #undef E1
 #undef E2
 #undef E3
 
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 /*
  * read-lock / write-lock irq inversion.
  *
@@ -818,6 +839,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inversion_soft_wlock)
 #undef E2
 #undef E3
 
+#endif
+
+#ifndef CONFIG_PREEMPT_RT_FULL
+
 /*
  * read-lock / write-lock recursion that is actually safe.
  */
@@ -856,6 +881,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
 #undef E2
 #undef E3
 
+#endif
+
 /*
  * read-lock / write-lock recursion that is unsafe.
  */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] net: add device_poll functionality common to all net devices

2015-01-26 Thread Xander Huff
From: Jeff Westfahl 

The device_poll feature is generic to any device. Most net devices should
be able to use a set of common functionality to implement device_poll, such
as CAP_NET_ADMIN and rtnl_lock. Add this common functionality for all net
devices to use.

This is a standalone feature that should be submitted for review and
possible inclusion in mainline, or maybe in the RT patch.

Signed-off-by: Jeff Westfahl 
---
 include/linux/netdev_poll.h | 26 ++
 net/Kconfig |  3 +++
 net/core/Makefile   |  1 +
 net/core/dev_poll.c | 64 +
 4 files changed, 94 insertions(+)
 create mode 100644 include/linux/netdev_poll.h
 create mode 100644 net/core/dev_poll.c

diff --git a/include/linux/netdev_poll.h b/include/linux/netdev_poll.h
new file mode 100644
index 000..3785454
--- /dev/null
+++ b/include/linux/netdev_poll.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2014 National Instruments Corp.
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_NETDEV_POLL_H_
+#define _LINUX_NETDEV_POLL_H_
+
+#ifdef CONFIG_NETDEV_POLL
+
+#include 
+
+int netdev_poll_init(struct device_poll *device_poll);
+
+#endif
+
+#endif /* _LINUX_NETDEV_POLL_H_ */
diff --git a/net/Kconfig b/net/Kconfig
index a073148..6e6ec69 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -324,5 +324,8 @@ source "net/caif/Kconfig"
 source "net/ceph/Kconfig"
 source "net/nfc/Kconfig"
 
+config NETDEV_POLL
+   bool
+   select DEVICE_POLL
 
 endif   # if NET
diff --git a/net/core/Makefile b/net/core/Makefile
index 0d357b1..4255163 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -19,3 +19,4 @@ obj-$(CONFIG_FIB_RULES) += fib_rules.o
 obj-$(CONFIG_TRACEPOINTS) += net-traces.o
 obj-$(CONFIG_NET_DROP_MONITOR) += drop_monitor.o
 obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += timestamping.o
+obj-$(CONFIG_NETDEV_POLL) += dev_poll.o
diff --git a/net/core/dev_poll.c b/net/core/dev_poll.c
new file mode 100644
index 000..1f2d455
--- /dev/null
+++ b/net/core/dev_poll.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 National Instruments Corp.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+
+/* netdev_poll internal functions */
+
+static int netdev_poll_reinit(struct device_poll *device_poll)
+{
+   int ret = 0;
+   struct net_device *netdev = to_net_dev(device_poll->device);
+
+   if (netif_running(netdev)) {
+   netdev->netdev_ops->ndo_stop(netdev);
+   ret = netdev->netdev_ops->ndo_open(netdev);
+   }
+
+   return ret;
+}
+
+static void netdev_poll_lock(struct device_poll *device_poll)
+{
+   rtnl_lock();
+}
+
+static void netdev_poll_unlock(struct device_poll *device_poll)
+{
+   rtnl_unlock();
+}
+
+/* netdev_poll external functions */
+
+int netdev_poll_init(struct device_poll *device_poll)
+{
+   if (!device_poll || !device_poll->device || !device_poll->ops)
+   return -EINVAL;
+
+   if (!device_poll->ops->reinit)
+   device_poll->ops->reinit = netdev_poll_reinit;
+   if (!device_poll->ops->lock)
+   device_poll->ops->lock = netdev_poll_lock;
+   if (!device_poll->ops->unlock)
+   device_poll->ops->unlock = netdev_poll_unlock;
+
+   /* Allow changes from any process with CAP_NET_ADMIN. */
+   device_poll->use_capability = 1;
+   device_poll->capability = CAP_NET_ADMIN;
+
+   return device_poll_init(device_poll);
+}
+EXPORT_SYMBOL(netdev_poll_init);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] driver core: add device_poll interface

2015-01-26 Thread Xander Huff
From: Jeff Westfahl 

Add the device_poll interface to the driver core. This is a generic
interface that any struct device can take advantage of to dynamically
switch between using interrupts and polling. Many drivers can be easily
modified to take advantage of this feature if desired.

This interface is most likely to be used along with the RT patch. It has
only been used thus far on Ethernet interfaces. Even with the standard
RT change to threaded interrupts for all devices, some RT applications
can be sensitive to even the minimal hardware interrupt that still occurs
with threaded interrupt handlers. The device_poll interface can be used
to completely eliminate all hardware interrupts for a device and the
associated jitter.

This is a standalone feature that should be submitted for review and
possible inclusion in mainline, or maybe in the RT patch.

Signed-off-by: Jeff Westfahl 
---
 drivers/base/Kconfig|   3 +
 drivers/base/Makefile   |   1 +
 drivers/base/poll.c | 327 
 include/linux/device_poll.h | 105 ++
 4 files changed, 436 insertions(+)
 create mode 100644 drivers/base/poll.c
 create mode 100644 include/linux/device_poll.h

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 21cf46f..d23df71 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -174,4 +174,7 @@ config SYS_HYPERVISOR
 
 source "drivers/base/regmap/Kconfig"
 
+config DEVICE_POLL
+   bool
+
 endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 99a375a..92ab7f3 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_MODULES) += module.o
 endif
 obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
 obj-$(CONFIG_REGMAP)   += regmap/
+obj-$(CONFIG_DEVICE_POLL) += poll.o
 
 ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
 
diff --git a/drivers/base/poll.c b/drivers/base/poll.c
new file mode 100644
index 000..911a296
--- /dev/null
+++ b/drivers/base/poll.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2014 National Instruments Corp.
+ *
+ * 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.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* sysfs attributes */
+
+#define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
+
+/* get sysfs attributes */
+
+ssize_t device_poll_get_interval(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct dev_ext_attribute *ea = to_ext_attr(attr);
+   struct device_poll *device_poll = ea->var;
+
+   return sprintf(buf, "%d\n", device_poll->interval);
+}
+
+static ssize_t device_poll_get_policy(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+   struct dev_ext_attribute *ea = to_ext_attr(attr);
+   struct device_poll *device_poll = ea->var;
+
+   switch (device_poll->policy) {
+   case SCHED_NORMAL:
+   return sprintf(buf, "SCHED_NORMAL (SCHED_OTHER)\n");
+   case SCHED_FIFO:
+   return sprintf(buf, "SCHED_FIFO\n");
+   case SCHED_RR:
+   return sprintf(buf, "SCHED_RR\n");
+   case SCHED_BATCH:
+   return sprintf(buf, "SCHED_BATCH\n");
+   case SCHED_IDLE:
+   return sprintf(buf, "SCHED_IDLE\n");
+   default:
+   return sprintf(buf, "unknown\n");
+   }
+}
+
+static ssize_t device_poll_get_priority(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct dev_ext_attribute *ea = to_ext_attr(attr);
+   struct device_poll *device_poll = ea->var;
+
+   return sprintf(buf, "%d\n", device_poll->priority);
+}
+
+/* set sysfs attributes */
+
+static ssize_t device_poll_set_interval(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t size)
+{
+   struct dev_ext_attribute *ea = to_ext_attr(attr);
+   struct device_poll *device_poll = ea->var;
+   int interval;
+   int ret = 0;
+
+   if (device_poll->use_capability && !capable(device_poll->capability))
+   return -EPERM;
+
+   if (0 > kstrtoint(buf, 0, &interval))
+   return -EINVAL;
+
+   device_poll->ops->lock(device_poll);
+   if (device_poll->interval != interval) {
+   device_poll->interval = interval;
+
+  

Re: [PATCH RESEND] igb: Reset TXPBSIZE to default value

2015-01-16 Thread Xander Huff

On 1/16/2015 1:41 PM, Vick, Matthew wrote:

On 1/16/15, 10:59 AM, "Xander Huff"  wrote:


From: Jeff Westfahl 

The TXPBSIZE register of the i210 resets to its default value only
at power-on. It doesn't reset if you reboot the system, only if you
pull power. If something (another driver, another OS, etc.) modifies
this register from its default value, the igb driver doesn't function
correctly. It detects a hang of the transmitter and continuously resets
the adapter. Here we set this value to its default when resetting the
i210 to resolve this issue.


This should have already been resolved last May in commit
27dff8b2f680ce966b5d959be9d69dd0edd92e3b ("igb: add defaults for i210
TX/RX PBSIZE"). Are you running the latest upstream kernel?

Cheers,
Matthew


Looks like you're correct. Please disregard this patch.

--
Xander Huff
Staff Software Engineer
National Instruments
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND] igb: Reset TXPBSIZE to default value

2015-01-16 Thread Xander Huff
From: Jeff Westfahl 

The TXPBSIZE register of the i210 resets to its default value only
at power-on. It doesn't reset if you reboot the system, only if you
pull power. If something (another driver, another OS, etc.) modifies
this register from its default value, the igb driver doesn't function
correctly. It detects a hang of the transmitter and continuously resets
the adapter. Here we set this value to its default when resetting the
i210 to resolve this issue.

Signed-off-by: Jeff Westfahl 
Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/intel/igb/e1000_82575.c   | 4 
 drivers/net/ethernet/intel/igb/e1000_defines.h | 3 +++
 drivers/net/ethernet/intel/igb/e1000_regs.h| 1 +
 3 files changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c 
b/drivers/net/ethernet/intel/igb/e1000_82575.c
index 0f69ef8..855a39e 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -2238,6 +2238,10 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw)
wr32(E1000_TCTL, E1000_TCTL_PSP);
wrfl();
 
+   if (hw->mac.type == e1000_i210)
+   /* TXPBSIZE resets only on power-up. */
+   wr32(E1000_TXPBSIZE, E1000_TXPBSIZE_RESET);
+
usleep_range(1, 11000);
 
/* Determine whether or not a global dev reset is requested */
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h 
b/drivers/net/ethernet/intel/igb/e1000_defines.h
index 217f813..d8e3c59 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -305,6 +305,9 @@
 #define E1000_TCTL_COLD   0x003ff000/* collision distance */
 #define E1000_TCTL_RTLC   0x0100/* Re-transmit on late collision */
 
+/* Transmit Packet Buffer Size */
+#define E1000_TXPBSIZE_RESET 0x0414
+
 /* DMA Coalescing register fields */
 #define E1000_DMACR_DMACWT_MASK 0x3FFF /* DMA Coal Watchdog Timer 
*/
 #define E1000_DMACR_DMACTHR_MASK0x00FF /* DMA Coal Rx Threshold */
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h 
b/drivers/net/ethernet/intel/igb/e1000_regs.h
index 6f0490d..7e2325b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -60,6 +60,7 @@
 #define E1000_TCTL 0x00400  /* TX Control - RW */
 #define E1000_TCTL_EXT 0x00404  /* Extended TX Control - RW */
 #define E1000_TIPG 0x00410  /* TX Inter-packet gap -RW */
+#define E1000_TXPBSIZE 0x03404  /* Transmit Packet Buffer Size - RW */
 #define E1000_AIT  0x00458  /* Adaptive Interframe Spacing Throttle - RW */
 #define E1000_LEDCTL   0x00E00  /* LED Control - RW */
 #define E1000_LEDMUX   0x08130  /* LED MUX Control */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/3] net/macb: Create gem_ethtool_ops for new statistics functions

2015-01-15 Thread Xander Huff
10/100 MACB does not have the same statistics possibilities as GEM. Separate
macb_ethtool_ops to make a new GEM-specific struct with the new statistics
functions included.

Signed-off-by: Xander Huff 
---
Re-sending to properly include David Laight

 drivers/net/ethernet/cadence/macb.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 9edd787..f2f9ca0 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -2032,11 +2032,21 @@ const struct ethtool_ops macb_ethtool_ops = {
.get_regs   = macb_get_regs,
.get_link   = ethtool_op_get_link,
.get_ts_info= ethtool_op_get_ts_info,
+};
+EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+
+const struct ethtool_ops gem_ethtool_ops = {
+   .get_settings   = macb_get_settings,
+   .set_settings   = macb_set_settings,
+   .get_regs_len   = macb_get_regs_len,
+   .get_regs   = macb_get_regs,
+   .get_link   = ethtool_op_get_link,
+   .get_ts_info= ethtool_op_get_ts_info,
.get_ethtool_stats  = gem_get_ethtool_stats,
.get_strings= gem_get_ethtool_strings,
.get_sset_count = gem_get_sset_count,
 };
-EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+EXPORT_SYMBOL_GPL(gem_ethtool_ops);
 
 int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
@@ -2325,7 +2335,6 @@ static int __init macb_probe(struct platform_device *pdev)
 
dev->netdev_ops = &macb_netdev_ops;
netif_napi_add(dev, &bp->napi, macb_poll, 64);
-   dev->ethtool_ops = &macb_ethtool_ops;
 
dev->base_addr = regs->start;
 
@@ -2339,12 +2348,14 @@ static int __init macb_probe(struct platform_device 
*pdev)
bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = gem_init_rings;
bp->macbgem_ops.mog_rx = gem_rx;
+   dev->ethtool_ops = &gem_ethtool_ops;
} else {
bp->max_tx_length = MACB_MAX_TX_LEN;
bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = macb_init_rings;
bp->macbgem_ops.mog_rx = macb_rx;
+   dev->ethtool_ops = &macb_ethtool_ops;
}
 
/* Set features */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/3] net/macb: Add whitespace around arithmetic operators

2015-01-15 Thread Xander Huff
Spaces should surround add, multiply, and bitshift operators.

Signed-off-by: Xander Huff 
---
Re-sending to properly include David Laight

 drivers/net/ethernet/cadence/macb.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index dd8c202..9edd787 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1691,7 +1691,7 @@ static int hash_get_index(__u8 *addr)
 
for (j = 0; j < 6; j++) {
for (i = 0, bitval = 0; i < 8; i++)
-   bitval ^= hash_bit_value(i*6 + j, addr);
+   bitval ^= hash_bit_value(i * 6 + j, addr);
 
hash_index |= (bitval << j);
}
@@ -1832,15 +1832,15 @@ static void gem_update_stats(struct macb *bp)
 
for (i = 0; i < GEM_STATS_LEN; ++i, ++p) {
u32 offset = gem_statistics[i].offset;
-   u64 val = __raw_readl(bp->regs+offset);
+   u64 val = __raw_readl(bp->regs + offset);
 
bp->ethtool_stats[i] += val;
*p += val;
 
if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) {
/* Add GEM_OCTTXH, GEM_OCTRXH */
-   val = __raw_readl(bp->regs+offset+4);
-   bp->ethtool_stats[i] += ((u64)val)<<32;
+   val = __raw_readl(bp->regs + offset + 4);
+   bp->ethtool_stats[i] += ((u64)val) << 32;
*(++p) += val;
}
}
@@ -1891,7 +1891,7 @@ static void gem_get_ethtool_stats(struct net_device *dev,
 
bp = netdev_priv(dev);
gem_update_stats(bp);
-   memcpy(data, &bp->ethtool_stats, sizeof(u64)*GEM_STATS_LEN);
+   memcpy(data, &bp->ethtool_stats, sizeof(u64) * GEM_STATS_LEN);
 }
 
 static int gem_get_sset_count(struct net_device *dev, int sset)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/3] net/macb: Fix comments to meet style guidelines

2015-01-15 Thread Xander Huff
Change comments to not exceed 80 characters per line.
Update block comments in macb.h to start on the line after /*.

Signed-off-by: Xander Huff 
---
Re-sending to properly include David Laight

 drivers/net/ethernet/cadence/macb.h | 734 ++--
 1 file changed, 284 insertions(+), 450 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index 378b218..31dc080 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -15,471 +15,309 @@
 #define MACB_MAX_QUEUES 8
 
 /* MACB register offsets */
-#define MACB_NCR   0x /* Network Control */
-#define MACB_NCFGR 0x0004 /* Network Config */
-#define MACB_NSR   0x0008 /* Network Status */
-#define MACB_TAR   0x000c /* AT91RM9200 only */
-#define MACB_TCR   0x0010 /* AT91RM9200 only */
-#define MACB_TSR   0x0014 /* Transmit Status */
-#define MACB_RBQP  0x0018 /* RX Q Base Address */
-#define MACB_TBQP  0x001c /* TX Q Base Address */
-#define MACB_RSR   0x0020 /* Receive Status */
-#define MACB_ISR   0x0024 /* Interrupt Status */
-#define MACB_IER   0x0028 /* Interrupt Enable */
-#define MACB_IDR   0x002c /* Interrupt Disable */
-#define MACB_IMR   0x0030 /* Interrupt Mask */
-#define MACB_MAN   0x0034 /* PHY Maintenance */
-#define MACB_PTR   0x0038
-#define MACB_PFR   0x003c
-#define MACB_FTO   0x0040
-#define MACB_SCF   0x0044
-#define MACB_MCF   0x0048
-#define MACB_FRO   0x004c
-#define MACB_FCSE  0x0050
-#define MACB_ALE   0x0054
-#define MACB_DTF   0x0058
-#define MACB_LCOL  0x005c
-#define MACB_EXCOL 0x0060
-#define MACB_TUND  0x0064
-#define MACB_CSE   0x0068
-#define MACB_RRE   0x006c
-#define MACB_ROVR  0x0070
-#define MACB_RSE   0x0074
-#define MACB_ELE   0x0078
-#define MACB_RJA   0x007c
-#define MACB_USF   0x0080
-#define MACB_STE   0x0084
-#define MACB_RLE   0x0088
-#define MACB_TPF   0x008c
-#define MACB_HRB   0x0090
-#define MACB_HRT   0x0094
-#define MACB_SA1B  0x0098
-#define MACB_SA1T  0x009c
-#define MACB_SA2B  0x00a0
-#define MACB_SA2T  0x00a4
-#define MACB_SA3B  0x00a8
-#define MACB_SA3T  0x00ac
-#define MACB_SA4B  0x00b0
-#define MACB_SA4T  0x00b4
-#define MACB_TID   0x00b8
-#define MACB_TPQ   0x00bc
-#define MACB_USRIO 0x00c0
-#define MACB_WOL   0x00c4
-#define MACB_MID   0x00fc
+#define MACB_NCR   0x /* Network Control */
+#define MACB_NCFGR 0x0004 /* Network Config */
+#define MACB_NSR   0x0008 /* Network Status */
+#define MACB_TAR   0x000c /* AT91RM9200 only */
+#define MACB_TCR   0x0010 /* AT91RM9200 only */
+#define MACB_TSR   0x0014 /* Transmit Status */
+#define MACB_RBQP  0x0018 /* RX Q Base Address */
+#define MACB_TBQP  0x001c /* TX Q Base Address */
+#define MACB_RSR   0x0020 /* Receive Status */
+#define MACB_ISR   0x0024 /* Interrupt Status */
+#define MACB_IER   0x0028 /* Interrupt Enable */
+#define MACB_IDR   0x002c /* Interrupt Disable */
+#define MACB_IMR   0x0030 /* Interrupt Mask */
+#define MACB_MAN   0x0034 /* PHY Maintenance */
+#define MACB_PTR   0x0038
+#define MACB_PFR   0x003c
+#define MACB_FTO   0x0040
+#define MACB_SCF   0x0044
+#define MACB_MCF   0x0048
+#define MACB_FRO   0x004c
+#define MACB_FCSE  0x0050
+#define MACB_ALE   0x0054
+#define MACB_DTF   0x0058
+#define MACB_LCOL  0x005c
+#define MACB_EXCOL

[PATCH v3 1/3] net/macb: Fix comments to meet style guidelines

2015-01-15 Thread Xander Huff
Change comments to not exceed 80 characters per line.
Update block comments in macb.h to start on the line after /*.

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.h | 734 ++--
 1 file changed, 284 insertions(+), 450 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index 378b218..31dc080 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -15,471 +15,309 @@
 #define MACB_MAX_QUEUES 8
 
 /* MACB register offsets */
-#define MACB_NCR   0x /* Network Control */
-#define MACB_NCFGR 0x0004 /* Network Config */
-#define MACB_NSR   0x0008 /* Network Status */
-#define MACB_TAR   0x000c /* AT91RM9200 only */
-#define MACB_TCR   0x0010 /* AT91RM9200 only */
-#define MACB_TSR   0x0014 /* Transmit Status */
-#define MACB_RBQP  0x0018 /* RX Q Base Address */
-#define MACB_TBQP  0x001c /* TX Q Base Address */
-#define MACB_RSR   0x0020 /* Receive Status */
-#define MACB_ISR   0x0024 /* Interrupt Status */
-#define MACB_IER   0x0028 /* Interrupt Enable */
-#define MACB_IDR   0x002c /* Interrupt Disable */
-#define MACB_IMR   0x0030 /* Interrupt Mask */
-#define MACB_MAN   0x0034 /* PHY Maintenance */
-#define MACB_PTR   0x0038
-#define MACB_PFR   0x003c
-#define MACB_FTO   0x0040
-#define MACB_SCF   0x0044
-#define MACB_MCF   0x0048
-#define MACB_FRO   0x004c
-#define MACB_FCSE  0x0050
-#define MACB_ALE   0x0054
-#define MACB_DTF   0x0058
-#define MACB_LCOL  0x005c
-#define MACB_EXCOL 0x0060
-#define MACB_TUND  0x0064
-#define MACB_CSE   0x0068
-#define MACB_RRE   0x006c
-#define MACB_ROVR  0x0070
-#define MACB_RSE   0x0074
-#define MACB_ELE   0x0078
-#define MACB_RJA   0x007c
-#define MACB_USF   0x0080
-#define MACB_STE   0x0084
-#define MACB_RLE   0x0088
-#define MACB_TPF   0x008c
-#define MACB_HRB   0x0090
-#define MACB_HRT   0x0094
-#define MACB_SA1B  0x0098
-#define MACB_SA1T  0x009c
-#define MACB_SA2B  0x00a0
-#define MACB_SA2T  0x00a4
-#define MACB_SA3B  0x00a8
-#define MACB_SA3T  0x00ac
-#define MACB_SA4B  0x00b0
-#define MACB_SA4T  0x00b4
-#define MACB_TID   0x00b8
-#define MACB_TPQ   0x00bc
-#define MACB_USRIO 0x00c0
-#define MACB_WOL   0x00c4
-#define MACB_MID   0x00fc
+#define MACB_NCR   0x /* Network Control */
+#define MACB_NCFGR 0x0004 /* Network Config */
+#define MACB_NSR   0x0008 /* Network Status */
+#define MACB_TAR   0x000c /* AT91RM9200 only */
+#define MACB_TCR   0x0010 /* AT91RM9200 only */
+#define MACB_TSR   0x0014 /* Transmit Status */
+#define MACB_RBQP  0x0018 /* RX Q Base Address */
+#define MACB_TBQP  0x001c /* TX Q Base Address */
+#define MACB_RSR   0x0020 /* Receive Status */
+#define MACB_ISR   0x0024 /* Interrupt Status */
+#define MACB_IER   0x0028 /* Interrupt Enable */
+#define MACB_IDR   0x002c /* Interrupt Disable */
+#define MACB_IMR   0x0030 /* Interrupt Mask */
+#define MACB_MAN   0x0034 /* PHY Maintenance */
+#define MACB_PTR   0x0038
+#define MACB_PFR   0x003c
+#define MACB_FTO   0x0040
+#define MACB_SCF   0x0044
+#define MACB_MCF   0x0048
+#define MACB_FRO   0x004c
+#define MACB_FCSE  0x0050
+#define MACB_ALE   0x0054
+#define MACB_DTF   0x0058
+#define MACB_LCOL  0x005c
+#define MACB_EXCOL 0x0060
+#define MACB_TUND

[PATCH v3 2/3] net/macb: Add whitespace around arithmetic operators

2015-01-15 Thread Xander Huff
Spaces should surround add, multiply, and bitshift operators.

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index dd8c202..9edd787 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1691,7 +1691,7 @@ static int hash_get_index(__u8 *addr)
 
for (j = 0; j < 6; j++) {
for (i = 0, bitval = 0; i < 8; i++)
-   bitval ^= hash_bit_value(i*6 + j, addr);
+   bitval ^= hash_bit_value(i * 6 + j, addr);
 
hash_index |= (bitval << j);
}
@@ -1832,15 +1832,15 @@ static void gem_update_stats(struct macb *bp)
 
for (i = 0; i < GEM_STATS_LEN; ++i, ++p) {
u32 offset = gem_statistics[i].offset;
-   u64 val = __raw_readl(bp->regs+offset);
+   u64 val = __raw_readl(bp->regs + offset);
 
bp->ethtool_stats[i] += val;
*p += val;
 
if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) {
/* Add GEM_OCTTXH, GEM_OCTRXH */
-   val = __raw_readl(bp->regs+offset+4);
-   bp->ethtool_stats[i] += ((u64)val)<<32;
+   val = __raw_readl(bp->regs + offset + 4);
+   bp->ethtool_stats[i] += ((u64)val) << 32;
*(++p) += val;
}
}
@@ -1891,7 +1891,7 @@ static void gem_get_ethtool_stats(struct net_device *dev,
 
bp = netdev_priv(dev);
gem_update_stats(bp);
-   memcpy(data, &bp->ethtool_stats, sizeof(u64)*GEM_STATS_LEN);
+   memcpy(data, &bp->ethtool_stats, sizeof(u64) * GEM_STATS_LEN);
 }
 
 static int gem_get_sset_count(struct net_device *dev, int sset)
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/3] net/macb: Create gem_ethtool_ops for new statistics functions

2015-01-15 Thread Xander Huff
10/100 MACB does not have the same statistics possibilities as GEM. Separate
macb_ethtool_ops to make a new GEM-specific struct with the new statistics
functions included.

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 9edd787..f2f9ca0 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -2032,11 +2032,21 @@ const struct ethtool_ops macb_ethtool_ops = {
.get_regs   = macb_get_regs,
.get_link   = ethtool_op_get_link,
.get_ts_info= ethtool_op_get_ts_info,
+};
+EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+
+const struct ethtool_ops gem_ethtool_ops = {
+   .get_settings   = macb_get_settings,
+   .set_settings   = macb_set_settings,
+   .get_regs_len   = macb_get_regs_len,
+   .get_regs   = macb_get_regs,
+   .get_link   = ethtool_op_get_link,
+   .get_ts_info= ethtool_op_get_ts_info,
.get_ethtool_stats  = gem_get_ethtool_stats,
.get_strings= gem_get_ethtool_strings,
.get_sset_count = gem_get_sset_count,
 };
-EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+EXPORT_SYMBOL_GPL(gem_ethtool_ops);
 
 int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
@@ -2325,7 +2335,6 @@ static int __init macb_probe(struct platform_device *pdev)
 
dev->netdev_ops = &macb_netdev_ops;
netif_napi_add(dev, &bp->napi, macb_poll, 64);
-   dev->ethtool_ops = &macb_ethtool_ops;
 
dev->base_addr = regs->start;
 
@@ -2339,12 +2348,14 @@ static int __init macb_probe(struct platform_device 
*pdev)
bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = gem_init_rings;
bp->macbgem_ops.mog_rx = gem_rx;
+   dev->ethtool_ops = &gem_ethtool_ops;
} else {
bp->max_tx_length = MACB_MAX_TX_LEN;
bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = macb_init_rings;
bp->macbgem_ops.mog_rx = macb_rx;
+   dev->ethtool_ops = &macb_ethtool_ops;
}
 
/* Set features */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] fixup! net/macb: improved ethtool statistics support

2015-01-15 Thread Xander Huff

On 1/15/2015 4:35 AM, Nicolas Ferre wrote:

  #define GEM_OTX   0x0100 /* Octets 
transmitted */

I see, it's modified hereafter! Why not integrate this part in previous
patch?




I split these up the way I did by using the --fixup argument to allow the rebase 
--autosquash to work. I could instead have a series of fixup commits to fix each 
type of style issue and then also the functional issue if you'd prefer, but 
--autosquash will no longer work.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/2] fixup! net/macb: Adding comments to various #defs to make interpretation easier

2015-01-14 Thread Xander Huff
Put #define comments into a single line.

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.h | 107 +---
 1 file changed, 26 insertions(+), 81 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index 378b218..d7b93d0 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -275,9 +275,7 @@
 #define MACB_THALT_SIZE1
 #define MACB_NCR_TPF_OFFSET11 /* Transmit pause frame */
 #define MACB_NCR_TPF_SIZE  1
-#define MACB_TZQ_OFFSET12 /* Transmit zero 
quantum
-   * pause frame
-   */
+#define MACB_TZQ_OFFSET12 /* Transmit zero 
quantum pause frame */
 #define MACB_TZQ_SIZE  1
 
 /* Bitfields in NCFGR */
@@ -299,9 +297,7 @@
 #define MACB_UNI_SIZE  1
 #define MACB_BIG_OFFSET8 /* Receive 1536 byte 
frames */
 #define MACB_BIG_SIZE  1
-#define MACB_EAE_OFFSET9 /* External address 
match
-  * enable
-  */
+#define MACB_EAE_OFFSET9 /* External address 
match enable */
 #define MACB_EAE_SIZE  1
 #define MACB_CLK_OFFSET10
 #define MACB_CLK_SIZE  2
@@ -313,9 +309,7 @@
 #define MACB_RM9200_RMII_SIZE  1  /* AT91RM9200 only */
 #define MACB_RBOF_OFFSET   14 /* Receive buffer offset */
 #define MACB_RBOF_SIZE 2
-#define MACB_RLCE_OFFSET   16 /* Length field error frame
-   * discard
-   */
+#define MACB_RLCE_OFFSET   16 /* Length field error frame 
discard */
 #define MACB_RLCE_SIZE 1
 #define MACB_DRFCS_OFFSET  17 /* FCS remove */
 #define MACB_DRFCS_SIZE1
@@ -335,41 +329,22 @@
 #define GEM_RXCOEN_SIZE1
 
 /* Constants for data bus width. */
-#define GEM_DBW32  0 /* 32 bit AMBA AHB data bus
-  * width
-  */
-#define GEM_DBW64  1 /* 64 bit AMBA AHB data bus
-  * width
-  */
-#define GEM_DBW128 2 /* 128 bit AMBA AHB data bus
-  * width
-  */
+#define GEM_DBW32  0 /* 32 bit AMBA AHB data bus 
width */
+#define GEM_DBW64  1 /* 64 bit AMBA AHB data bus 
width */
+#define GEM_DBW128 2 /* 128 bit AMBA AHB data bus 
width */
 
 /* Bitfields in DMACFG. */
-#define GEM_FBLDO_OFFSET   0 /* AHB fixed burst length for
-  * DMA data operations
-  */
+#define GEM_FBLDO_OFFSET   0 /* AHB fixed burst length for 
DMA data operations */
 #define GEM_FBLDO_SIZE 5
-#define GEM_ENDIA_OFFSET   7 /* AHB endian swap mode enable
-  * for packet data accesses
-  */
+#define GEM_ENDIA_OFFSET   7 /* AHB endian swap mode 
enable for packet data accesses */
 #define GEM_ENDIA_SIZE 1
-#define GEM_RXBMS_OFFSET   8 /* Receiver packet buffer
-  * memory size select
-  */
+#define GEM_RXBMS_OFFSET   8 /* Receiver packet buffer 
memory size select */
 #define GEM_RXBMS_SIZE 2
-#define GEM_TXPBMS_OFFSET  10 /* Transmitter packet buffer
-   * memory size select
-   */
+#define GEM_TXPBMS_OFFSET  10 /* Transmitter packet buffer 
memory size select */
 #define GEM_TXPBMS_SIZE1
-#define GEM_TXCOEN_OFFSET  11 /* Transmitter IP, TCP and
-   * UDP checksum generation

[PATCH v2 2/2] fixup! net/macb: improved ethtool statistics support

2015-01-14 Thread Xander Huff
Add spaces around arithmetic operators.
Make a separate gem_ethtool_ops for the new statistics functions.
Adjust new block comments to match the existing comments in macb.h.

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.c |  25 +++--
 drivers/net/ethernet/cadence/macb.h | 203 +---
 2 files changed, 68 insertions(+), 160 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index dd8c202..f60f8f8 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1832,15 +1832,15 @@ static void gem_update_stats(struct macb *bp)
 
for (i = 0; i < GEM_STATS_LEN; ++i, ++p) {
u32 offset = gem_statistics[i].offset;
-   u64 val = __raw_readl(bp->regs+offset);
+   u64 val = __raw_readl(bp->regs + offset);
 
bp->ethtool_stats[i] += val;
*p += val;
 
if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) {
/* Add GEM_OCTTXH, GEM_OCTRXH */
-   val = __raw_readl(bp->regs+offset+4);
-   bp->ethtool_stats[i] += ((u64)val)<<32;
+   val = __raw_readl(bp->regs+offset + 4);
+   bp->ethtool_stats[i] += ((u64)val) << 32;
*(++p) += val;
}
}
@@ -1891,7 +1891,7 @@ static void gem_get_ethtool_stats(struct net_device *dev,
 
bp = netdev_priv(dev);
gem_update_stats(bp);
-   memcpy(data, &bp->ethtool_stats, sizeof(u64)*GEM_STATS_LEN);
+   memcpy(data, &bp->ethtool_stats, sizeof(u64) * GEM_STATS_LEN);
 }
 
 static int gem_get_sset_count(struct net_device *dev, int sset)
@@ -2032,11 +2032,21 @@ const struct ethtool_ops macb_ethtool_ops = {
.get_regs   = macb_get_regs,
.get_link   = ethtool_op_get_link,
.get_ts_info= ethtool_op_get_ts_info,
+};
+EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+
+const struct ethtool_ops gem_ethtool_ops = {
+   .get_settings   = macb_get_settings,
+   .set_settings   = macb_set_settings,
+   .get_regs_len   = macb_get_regs_len,
+   .get_regs   = macb_get_regs,
+   .get_link   = ethtool_op_get_link,
+   .get_ts_info= ethtool_op_get_ts_info,
.get_ethtool_stats  = gem_get_ethtool_stats,
.get_strings= gem_get_ethtool_strings,
.get_sset_count = gem_get_sset_count,
 };
-EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+EXPORT_SYMBOL_GPL(gem_ethtool_ops);
 
 int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
@@ -2325,7 +2335,10 @@ static int __init macb_probe(struct platform_device 
*pdev)
 
dev->netdev_ops = &macb_netdev_ops;
netif_napi_add(dev, &bp->napi, macb_poll, 64);
-   dev->ethtool_ops = &macb_ethtool_ops;
+   if (macb_is_gem(bp))
+   dev->ethtool_ops = &gem_ethtool_ops;
+   else
+   dev->ethtool_ops = &macb_ethtool_ops;
 
dev->base_addr = regs->start;
 
diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index d7b93d0..2ea5355 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -82,159 +82,52 @@
 #define GEM_SA4B   0x00A0 /* Specific4 Bottom */
 #define GEM_SA4T   0x00A4 /* Specific4 Top */
 #define GEM_OTX0x0100 /* Octets 
transmitted */
-#define GEM_OCTTXL 0x0100 /* Octets transmitted
-   * [31:0]
-   */
-#define GEM_OCTTXH 0x0104 /* Octets transmitted
-   * [47:32]
-   */
-#define GEM_TXCNT  0x0108 /* Error-free Frames
-   * Transmitted counter
-   */
-#define GEM_TXBCCNT0x010c /* Error-free Broadcast
-   * Frames counter
-   */
-#define GEM_TXMCCNT0x0110 /* Error-free Multicast
-   * Frames counter
-   */
-#define GEM_TXPAUSECNT 0x0114 /* Pause Frames
-   * Transmitted Counter
-   */
-#define GEM_TX64CNT0x

Re: [PATCH 1/2] fixup! net/macb: Adding comments to various #defs to make interpretation easier

2015-01-14 Thread Xander Huff

On 1/14/2015 3:09 PM, David Miller wrote:


As I mentioned, this won't do.

I've already applied your original patches to net-next, therefore you will
have to submit fixups relative to that.

These fixup commits are relative to an updated net-next, specifically "237de6e 
Merge branch 'hip04'".


Do you need them relative to (what I'm seeing is the latest) "2733135 Merge 
branch 'vxlan_rco'"?

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] fixup! net/macb: improved ethtool statistics support

2015-01-14 Thread Xander Huff
Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.c |  25 +++--
 drivers/net/ethernet/cadence/macb.h | 203 +---
 2 files changed, 68 insertions(+), 160 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index dd8c202..f60f8f8 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1832,15 +1832,15 @@ static void gem_update_stats(struct macb *bp)
 
for (i = 0; i < GEM_STATS_LEN; ++i, ++p) {
u32 offset = gem_statistics[i].offset;
-   u64 val = __raw_readl(bp->regs+offset);
+   u64 val = __raw_readl(bp->regs + offset);
 
bp->ethtool_stats[i] += val;
*p += val;
 
if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) {
/* Add GEM_OCTTXH, GEM_OCTRXH */
-   val = __raw_readl(bp->regs+offset+4);
-   bp->ethtool_stats[i] += ((u64)val)<<32;
+   val = __raw_readl(bp->regs+offset + 4);
+   bp->ethtool_stats[i] += ((u64)val) << 32;
*(++p) += val;
}
}
@@ -1891,7 +1891,7 @@ static void gem_get_ethtool_stats(struct net_device *dev,
 
bp = netdev_priv(dev);
gem_update_stats(bp);
-   memcpy(data, &bp->ethtool_stats, sizeof(u64)*GEM_STATS_LEN);
+   memcpy(data, &bp->ethtool_stats, sizeof(u64) * GEM_STATS_LEN);
 }
 
 static int gem_get_sset_count(struct net_device *dev, int sset)
@@ -2032,11 +2032,21 @@ const struct ethtool_ops macb_ethtool_ops = {
.get_regs   = macb_get_regs,
.get_link   = ethtool_op_get_link,
.get_ts_info= ethtool_op_get_ts_info,
+};
+EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+
+const struct ethtool_ops gem_ethtool_ops = {
+   .get_settings   = macb_get_settings,
+   .set_settings   = macb_set_settings,
+   .get_regs_len   = macb_get_regs_len,
+   .get_regs   = macb_get_regs,
+   .get_link   = ethtool_op_get_link,
+   .get_ts_info= ethtool_op_get_ts_info,
.get_ethtool_stats  = gem_get_ethtool_stats,
.get_strings= gem_get_ethtool_strings,
.get_sset_count = gem_get_sset_count,
 };
-EXPORT_SYMBOL_GPL(macb_ethtool_ops);
+EXPORT_SYMBOL_GPL(gem_ethtool_ops);
 
 int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
@@ -2325,7 +2335,10 @@ static int __init macb_probe(struct platform_device 
*pdev)
 
dev->netdev_ops = &macb_netdev_ops;
netif_napi_add(dev, &bp->napi, macb_poll, 64);
-   dev->ethtool_ops = &macb_ethtool_ops;
+   if (macb_is_gem(bp))
+   dev->ethtool_ops = &gem_ethtool_ops;
+   else
+   dev->ethtool_ops = &macb_ethtool_ops;
 
dev->base_addr = regs->start;
 
diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index d7b93d0..2ea5355 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -82,159 +82,52 @@
 #define GEM_SA4B   0x00A0 /* Specific4 Bottom */
 #define GEM_SA4T   0x00A4 /* Specific4 Top */
 #define GEM_OTX0x0100 /* Octets 
transmitted */
-#define GEM_OCTTXL 0x0100 /* Octets transmitted
-   * [31:0]
-   */
-#define GEM_OCTTXH 0x0104 /* Octets transmitted
-   * [47:32]
-   */
-#define GEM_TXCNT  0x0108 /* Error-free Frames
-   * Transmitted counter
-   */
-#define GEM_TXBCCNT0x010c /* Error-free Broadcast
-   * Frames counter
-   */
-#define GEM_TXMCCNT0x0110 /* Error-free Multicast
-   * Frames counter
-   */
-#define GEM_TXPAUSECNT 0x0114 /* Pause Frames
-   * Transmitted Counter
-   */
-#define GEM_TX64CNT0x0118 /* Error-free 64 byte
-   * Frames Transmitted
- 

[PATCH 1/2] fixup! net/macb: Adding comments to various #defs to make interpretation easier

2015-01-14 Thread Xander Huff
Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.h | 107 +---
 1 file changed, 26 insertions(+), 81 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index 378b218..d7b93d0 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -275,9 +275,7 @@
 #define MACB_THALT_SIZE1
 #define MACB_NCR_TPF_OFFSET11 /* Transmit pause frame */
 #define MACB_NCR_TPF_SIZE  1
-#define MACB_TZQ_OFFSET12 /* Transmit zero 
quantum
-   * pause frame
-   */
+#define MACB_TZQ_OFFSET12 /* Transmit zero 
quantum pause frame */
 #define MACB_TZQ_SIZE  1
 
 /* Bitfields in NCFGR */
@@ -299,9 +297,7 @@
 #define MACB_UNI_SIZE  1
 #define MACB_BIG_OFFSET8 /* Receive 1536 byte 
frames */
 #define MACB_BIG_SIZE  1
-#define MACB_EAE_OFFSET9 /* External address 
match
-  * enable
-  */
+#define MACB_EAE_OFFSET9 /* External address 
match enable */
 #define MACB_EAE_SIZE  1
 #define MACB_CLK_OFFSET10
 #define MACB_CLK_SIZE  2
@@ -313,9 +309,7 @@
 #define MACB_RM9200_RMII_SIZE  1  /* AT91RM9200 only */
 #define MACB_RBOF_OFFSET   14 /* Receive buffer offset */
 #define MACB_RBOF_SIZE 2
-#define MACB_RLCE_OFFSET   16 /* Length field error frame
-   * discard
-   */
+#define MACB_RLCE_OFFSET   16 /* Length field error frame 
discard */
 #define MACB_RLCE_SIZE 1
 #define MACB_DRFCS_OFFSET  17 /* FCS remove */
 #define MACB_DRFCS_SIZE1
@@ -335,41 +329,22 @@
 #define GEM_RXCOEN_SIZE1
 
 /* Constants for data bus width. */
-#define GEM_DBW32  0 /* 32 bit AMBA AHB data bus
-  * width
-  */
-#define GEM_DBW64  1 /* 64 bit AMBA AHB data bus
-  * width
-  */
-#define GEM_DBW128 2 /* 128 bit AMBA AHB data bus
-  * width
-  */
+#define GEM_DBW32  0 /* 32 bit AMBA AHB data bus 
width */
+#define GEM_DBW64  1 /* 64 bit AMBA AHB data bus 
width */
+#define GEM_DBW128 2 /* 128 bit AMBA AHB data bus 
width */
 
 /* Bitfields in DMACFG. */
-#define GEM_FBLDO_OFFSET   0 /* AHB fixed burst length for
-  * DMA data operations
-  */
+#define GEM_FBLDO_OFFSET   0 /* AHB fixed burst length for 
DMA data operations */
 #define GEM_FBLDO_SIZE 5
-#define GEM_ENDIA_OFFSET   7 /* AHB endian swap mode enable
-  * for packet data accesses
-  */
+#define GEM_ENDIA_OFFSET   7 /* AHB endian swap mode 
enable for packet data accesses */
 #define GEM_ENDIA_SIZE 1
-#define GEM_RXBMS_OFFSET   8 /* Receiver packet buffer
-  * memory size select
-  */
+#define GEM_RXBMS_OFFSET   8 /* Receiver packet buffer 
memory size select */
 #define GEM_RXBMS_SIZE 2
-#define GEM_TXPBMS_OFFSET  10 /* Transmitter packet buffer
-   * memory size select
-   */
+#define GEM_TXPBMS_OFFSET  10 /* Transmitter packet buffer 
memory size select */
 #define GEM_TXPBMS_SIZE1
-#define GEM_TXCOEN_OFFSET  11 /* Transmitter IP, TCP and
-   * UDP checksum generation
-   * offload enable

[PATCH 2/2] net/macb: improved ethtool statistics support

2015-01-13 Thread Xander Huff
Currently `ethtool -S` simply returns "no stats available". It
would be more useful to see what the various ethtool statistics
registers' values are. This change implements get_ethtool_stats,
get_strings, and get_sset_count functions to accomplish this.

Read all GEM statistics registers and sum them into
macb.ethtool_stats. Add the necessary infrastructure to make this
accessible via `ethtool -S`.

Update gem_update_stats to utilize ethtool_stats.

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.c |  55 +++-
 drivers/net/ethernet/cadence/macb.h | 256 
 2 files changed, 307 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c 
b/drivers/net/ethernet/cadence/macb.c
index 3767271..dd8c202 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1827,12 +1827,23 @@ static int macb_close(struct net_device *dev)
 
 static void gem_update_stats(struct macb *bp)
 {
-   u32 __iomem *reg = bp->regs + GEM_OTX;
+   int i;
u32 *p = &bp->hw_stats.gem.tx_octets_31_0;
-   u32 *end = &bp->hw_stats.gem.rx_udp_checksum_errors + 1;
 
-   for (; p < end; p++, reg++)
-   *p += __raw_readl(reg);
+   for (i = 0; i < GEM_STATS_LEN; ++i, ++p) {
+   u32 offset = gem_statistics[i].offset;
+   u64 val = __raw_readl(bp->regs+offset);
+
+   bp->ethtool_stats[i] += val;
+   *p += val;
+
+   if (offset == GEM_OCTTXL || offset == GEM_OCTRXL) {
+   /* Add GEM_OCTTXH, GEM_OCTRXH */
+   val = __raw_readl(bp->regs+offset+4);
+   bp->ethtool_stats[i] += ((u64)val)<<32;
+   *(++p) += val;
+   }
+   }
 }
 
 static struct net_device_stats *gem_get_stats(struct macb *bp)
@@ -1873,6 +1884,39 @@ static struct net_device_stats *gem_get_stats(struct 
macb *bp)
return nstat;
 }
 
+static void gem_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+   struct macb *bp;
+
+   bp = netdev_priv(dev);
+   gem_update_stats(bp);
+   memcpy(data, &bp->ethtool_stats, sizeof(u64)*GEM_STATS_LEN);
+}
+
+static int gem_get_sset_count(struct net_device *dev, int sset)
+{
+   switch (sset) {
+   case ETH_SS_STATS:
+   return GEM_STATS_LEN;
+   default:
+   return -EOPNOTSUPP;
+   }
+}
+
+static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
+{
+   int i;
+
+   switch (sset) {
+   case ETH_SS_STATS:
+   for (i = 0; i < GEM_STATS_LEN; i++, p += ETH_GSTRING_LEN)
+   memcpy(p, gem_statistics[i].stat_string,
+  ETH_GSTRING_LEN);
+   break;
+   }
+}
+
 struct net_device_stats *macb_get_stats(struct net_device *dev)
 {
struct macb *bp = netdev_priv(dev);
@@ -1988,6 +2032,9 @@ const struct ethtool_ops macb_ethtool_ops = {
.get_regs   = macb_get_regs,
.get_link   = ethtool_op_get_link,
.get_ts_info= ethtool_op_get_ts_info,
+   .get_ethtool_stats  = gem_get_ethtool_stats,
+   .get_strings= gem_get_ethtool_strings,
+   .get_sset_count = gem_get_sset_count,
 };
 EXPORT_SYMBOL_GPL(macb_ethtool_ops);
 
diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index 8e8c3c9..378b218 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -82,6 +82,159 @@
 #define GEM_SA4B   0x00A0 /* Specific4 Bottom */
 #define GEM_SA4T   0x00A4 /* Specific4 Top */
 #define GEM_OTX0x0100 /* Octets 
transmitted */
+#define GEM_OCTTXL 0x0100 /* Octets transmitted
+   * [31:0]
+   */
+#define GEM_OCTTXH 0x0104 /* Octets transmitted
+   * [47:32]
+   */
+#define GEM_TXCNT  0x0108 /* Error-free Frames
+   * Transmitted counter
+   */
+#define GEM_TXBCCNT0x010c /* Error-free Broadcast
+   * Frames counter
+   */
+#define GEM_TXMCCNT0x0110 /* Error-free Multicast
+   * Frames counter
+   

[PATCH 1/2] net/macb: Adding comments to various #defs to make interpretation easier

2015-01-13 Thread Xander Huff
This change is to help improve at-a-glace knowledge of the purpose of the
various Cadence MACB/GEM registers. Comments are more helpful for human
readability than short acronyms.

Describe various #define varibles Cadence MACB/GEM registers as documented
in Xilinix's "Zynq-7000 All Programmable SoC TechnicalReference Manual, v1.9.1
(UG-585)"

Signed-off-by: Xander Huff 
---
 drivers/net/ethernet/cadence/macb.h | 269 ++--
 1 file changed, 162 insertions(+), 107 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.h 
b/drivers/net/ethernet/cadence/macb.h
index 084191b..8e8c3c9 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -15,20 +15,20 @@
 #define MACB_MAX_QUEUES 8
 
 /* MACB register offsets */
-#define MACB_NCR   0x
-#define MACB_NCFGR 0x0004
-#define MACB_NSR   0x0008
+#define MACB_NCR   0x /* Network Control */
+#define MACB_NCFGR 0x0004 /* Network Config */
+#define MACB_NSR   0x0008 /* Network Status */
 #define MACB_TAR   0x000c /* AT91RM9200 only */
 #define MACB_TCR   0x0010 /* AT91RM9200 only */
-#define MACB_TSR   0x0014
-#define MACB_RBQP  0x0018
-#define MACB_TBQP  0x001c
-#define MACB_RSR   0x0020
-#define MACB_ISR   0x0024
-#define MACB_IER   0x0028
-#define MACB_IDR   0x002c
-#define MACB_IMR   0x0030
-#define MACB_MAN   0x0034
+#define MACB_TSR   0x0014 /* Transmit Status */
+#define MACB_RBQP  0x0018 /* RX Q Base Address */
+#define MACB_TBQP  0x001c /* TX Q Base Address */
+#define MACB_RSR   0x0020 /* Receive Status */
+#define MACB_ISR   0x0024 /* Interrupt Status */
+#define MACB_IER   0x0028 /* Interrupt Enable */
+#define MACB_IDR   0x002c /* Interrupt Disable */
+#define MACB_IMR   0x0030 /* Interrupt Mask */
+#define MACB_MAN   0x0034 /* PHY Maintenance */
 #define MACB_PTR   0x0038
 #define MACB_PFR   0x003c
 #define MACB_FTO   0x0040
@@ -68,27 +68,27 @@
 #define MACB_MID   0x00fc
 
 /* GEM register offsets. */
-#define GEM_NCFGR  0x0004
-#define GEM_USRIO  0x000c
-#define GEM_DMACFG 0x0010
-#define GEM_HRB0x0080
-#define GEM_HRT0x0084
-#define GEM_SA1B   0x0088
-#define GEM_SA1T   0x008C
-#define GEM_SA2B   0x0090
-#define GEM_SA2T   0x0094
-#define GEM_SA3B   0x0098
-#define GEM_SA3T   0x009C
-#define GEM_SA4B   0x00A0
-#define GEM_SA4T   0x00A4
-#define GEM_OTX0x0100
-#define GEM_DCFG1  0x0280
-#define GEM_DCFG2  0x0284
-#define GEM_DCFG3  0x0288
-#define GEM_DCFG4  0x028c
-#define GEM_DCFG5  0x0290
-#define GEM_DCFG6  0x0294
-#define GEM_DCFG7  0x0298
+#define GEM_NCFGR  0x0004 /* Network Config */
+#define GEM_USRIO  0x000c /* User IO */
+#define GEM_DMACFG 0x0010 /* DMA Configuration */
+#define GEM_HRB0x0080 /* Hash Bottom */
+#define GEM_HRT0x0084 /* Hash Top */
+#define GEM_SA1B   0x0088 /* Specific1 Bottom */
+#define GEM_SA1T   0x008C /* Specific1 Top */
+#define GEM_SA2B   0x0090 /* Specific2 Bottom */
+#define GEM_SA2T   0x0094 /* Specific2 Top */
+#define GEM_SA3B   0x0098 /* Specific3 Bottom */
+#define GEM_SA3T   0x009C /* Specific3 Top */
+#define GEM_SA4B   0x00A0 /* Specific4 Bottom */
+#define GEM_SA4T   0x00A4 /* Specific4 Top */
+