From: Hauke Mehrtens Date: Mon, 11 Nov 2013 00:13:31 +0000 (+0000) Subject: kernel: bgmac: make it send and receive some packages on BCM4708 X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=7444a626e2edd01e2bbab97d9aa78e98cc604bf4;p=openwrt%2Fstaging%2Fblocktrron.git kernel: bgmac: make it send and receive some packages on BCM4708 This adds some more code for bgmac core rev 4 and it now restarts all cores when initializing the first one on BCM4708. I am just able to send under 100 packages and then DMA TX does not work any more. Signed-off-by: Hauke Mehrtens SVN-Revision: 38714 --- diff --git a/target/linux/generic/patches-3.10/026-bcma-export-bcma_find_core_unit.patch b/target/linux/generic/patches-3.10/026-bcma-export-bcma_find_core_unit.patch new file mode 100644 index 0000000000..86bce67fbf --- /dev/null +++ b/target/linux/generic/patches-3.10/026-bcma-export-bcma_find_core_unit.patch @@ -0,0 +1,69 @@ +From 0fc9d696e4855f1e03910c431499d68e75904929 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 10 Nov 2013 20:43:46 +0100 +Subject: [PATCH] bcma: export bcma_find_core_unit() + +--- + drivers/bcma/bcma_private.h | 2 -- + drivers/bcma/main.c | 13 +------------ + include/linux/bcma/bcma.h | 9 ++++++++- + 3 files changed, 9 insertions(+), 15 deletions(-) + +--- a/drivers/bcma/bcma_private.h ++++ b/drivers/bcma/bcma_private.h +@@ -33,8 +33,6 @@ int __init bcma_bus_early_register(struc + int bcma_bus_suspend(struct bcma_bus *bus); + int bcma_bus_resume(struct bcma_bus *bus); + #endif +-struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, +- u8 unit); + + /* scan.c */ + int bcma_bus_scan(struct bcma_bus *bus); +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -69,18 +69,6 @@ static u16 bcma_cc_core_id(struct bcma_b + return BCMA_CORE_CHIPCOMMON; + } + +-struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) +-{ +- struct bcma_device *core; +- +- list_for_each_entry(core, &bus->cores, list) { +- if (core->id.id == coreid) +- return core; +- } +- return NULL; +-} +-EXPORT_SYMBOL_GPL(bcma_find_core); +- + struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, + u8 unit) + { +@@ -92,6 +80,7 @@ struct bcma_device *bcma_find_core_unit( + } + return NULL; + } ++EXPORT_SYMBOL_GPL(bcma_find_core_unit); + + bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, + int timeout) +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -418,7 +418,14 @@ static inline void bcma_maskset16(struct + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); + } + +-extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid); ++extern struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, ++ u8 unit); ++static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus, ++ u16 coreid) ++{ ++ return bcma_find_core_unit(bus, coreid, 0); ++} ++ + extern bool bcma_core_is_enabled(struct bcma_device *core); + extern void bcma_core_disable(struct bcma_device *core, u32 flags); + extern int bcma_core_enable(struct bcma_device *core, u32 flags); diff --git a/target/linux/generic/patches-3.10/772-bgmac-add-supprot-for-BCM4707.patch b/target/linux/generic/patches-3.10/772-bgmac-add-supprot-for-BCM4707.patch index eb1708a2c4..a4e51774d5 100644 --- a/target/linux/generic/patches-3.10/772-bgmac-add-supprot-for-BCM4707.patch +++ b/target/linux/generic/patches-3.10/772-bgmac-add-supprot-for-BCM4707.patch @@ -97,6 +97,32 @@ Signed-off-by: Hauke Mehrtens } /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ +@@ -1488,6 +1512,25 @@ static int bgmac_probe(struct bcma_devic + goto err_netdev_free; + } + ++ /* Northstar, take all GMAC cores out of reset */ ++ if (core->id.id == BCMA_CHIP_ID_BCM4707 || ++ core->id.id == BCMA_CHIP_ID_BCM53018) { ++ struct bcma_device *ns_core; ++ int ns_gmac; ++ ++ for (ns_gmac = 0; ns_gmac < 4; ns_gmac++) { ++ /* As northstar requirement, we have to reset all GAMCs before ++ * accessing them. et_probe() call pci_enable_device() for etx ++ * and do si_core_reset for GAMCx only. Then the other three ++ * GAMCs didn't reset. We do it here. ++ */ ++ ns_core = bcma_find_core_unit(core->bus, BCMA_CORE_MAC_GBIT, ns_gmac); ++ if (!bcma_core_is_enabled(ns_core)) { ++ bcma_core_enable(ns_core, 0); ++ } ++ } ++ } ++ + bgmac_chip_reset(bgmac); + + err = bgmac_dma_alloc(bgmac); --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -185,6 +185,7 @@ diff --git a/target/linux/generic/patches-3.10/773-bgmac-add-srab-switch.patch b/target/linux/generic/patches-3.10/773-bgmac-add-srab-switch.patch index e5ec78d59f..be253064b1 100644 --- a/target/linux/generic/patches-3.10/773-bgmac-add-srab-switch.patch +++ b/target/linux/generic/patches-3.10/773-bgmac-add-srab-switch.patch @@ -30,7 +30,7 @@ Signed-off-by: Hauke Mehrtens /************************************************** * BCMA bus ops **************************************************/ -@@ -1542,6 +1554,16 @@ static int bgmac_probe(struct bcma_devic +@@ -1561,6 +1573,16 @@ static int bgmac_probe(struct bcma_devic goto err_dma_free; } @@ -47,7 +47,7 @@ Signed-off-by: Hauke Mehrtens err = register_netdev(bgmac->net_dev); if (err) { bgmac_err(bgmac, "Cannot register net device\n"); -@@ -1571,6 +1593,10 @@ static void bgmac_remove(struct bcma_dev +@@ -1590,6 +1612,10 @@ static void bgmac_remove(struct bcma_dev { struct bgmac *bgmac = bcma_get_drvdata(core); diff --git a/target/linux/generic/patches-3.10/774-bgmac-add-some-workaround-for-rev-4.patch b/target/linux/generic/patches-3.10/774-bgmac-add-some-workaround-for-rev-4.patch new file mode 100644 index 0000000000..4e1a449b90 --- /dev/null +++ b/target/linux/generic/patches-3.10/774-bgmac-add-some-workaround-for-rev-4.patch @@ -0,0 +1,163 @@ +From ec12b94d22fa8715561bdffe6da0781dac08423e Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 10 Nov 2013 21:23:57 +0100 +Subject: [PATCH] bgmac: add some workaround for rev 4 + +--- + drivers/net/ethernet/broadcom/bgmac.c | 8 ++++---- + drivers/net/ethernet/broadcom/bgmac.h | 4 +++- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -97,6 +97,16 @@ static void bgmac_dma_tx_enable(struct b + u32 ctl; + + ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL); ++ if (bgmac->core->id.rev == 4) { ++ ctl &= ~BGMAC_DMA_TX_BL_MASK; ++ ctl |= BGMAC_DMA_TX_BL_128 << BGMAC_DMA_TX_BL_SHIFT; ++ ctl &= ~BGMAC_DMA_TX_MR_MASK; ++ ctl |= BGMAC_DMA_TX_MR_2 << BGMAC_DMA_TX_MR_SHIFT; ++ ctl &= ~BGMAC_DMA_TX_PC_MASK; ++ ctl |= BGMAC_DMA_TX_PC_16 << BGMAC_DMA_TX_PC_SHIFT; ++ ctl &= ~BGMAC_DMA_TX_PT_MASK; ++ ctl |= BGMAC_DMA_TX_PT_8 << BGMAC_DMA_TX_PT_SHIFT; ++ } + ctl |= BGMAC_DMA_TX_ENABLE; + ctl |= BGMAC_DMA_TX_PARITY_DISABLE; + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl); +@@ -246,6 +256,17 @@ static void bgmac_dma_rx_enable(struct b + ctl |= BGMAC_DMA_RX_PARITY_DISABLE; + ctl |= BGMAC_DMA_RX_OVERFLOW_CONT; + ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT; ++ ++ if (bgmac->core->id.rev == 4) { ++ ctl &= ~BGMAC_DMA_RX_BL_MASK; ++ ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT; ++ ++ ctl &= ~BGMAC_DMA_RX_PC_MASK; ++ ctl |= BGMAC_DMA_RX_PC_8 << BGMAC_DMA_RX_PC_SHIFT; ++ ++ ctl &= ~BGMAC_DMA_RX_PT_MASK; ++ ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT; ++ } + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl); + } + +@@ -812,13 +833,13 @@ static void bgmac_cmdcfg_maskset(struct + u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG); + u32 new_val = (cmdcfg & mask) | set; + +- bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR); ++ bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR(bgmac->core->id.rev)); + udelay(2); + + if (new_val != cmdcfg || force) + bgmac_write(bgmac, BGMAC_CMDCFG, new_val); + +- bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR); ++ bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR(bgmac->core->id.rev)); + udelay(2); + } + +@@ -1029,7 +1050,7 @@ static void bgmac_chip_reset(struct bgma + BGMAC_CMDCFG_PROM | + BGMAC_CMDCFG_NLC | + BGMAC_CMDCFG_CFE | +- BGMAC_CMDCFG_SR, ++ BGMAC_CMDCFG_SR(core->id.rev), + false); + + bgmac_clear_mib(bgmac); +@@ -1070,7 +1091,7 @@ static void bgmac_enable(struct bgmac *b + + cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG); + bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE), +- BGMAC_CMDCFG_SR, true); ++ BGMAC_CMDCFG_SR(bgmac->core->id.rev), true); + udelay(2); + cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE; + bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg); +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -194,7 +194,9 @@ + #define BGMAC_CMDCFG_TAI 0x00000200 + #define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */ + #define BGMAC_CMDCFG_HD_SHIFT 10 +-#define BGMAC_CMDCFG_SR 0x00000800 /* Set to reset mode */ ++#define BGMAC_CMDCFG_SR_REVO 0x00000800 /* Set to reset mode, for other revs */ ++#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, only for core rev 4 */ ++#define BGMAC_CMDCFG_SR(rev) ((rev == 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REVO) + #define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */ + #define BGMAC_CMDCFG_AE 0x00400000 + #define BGMAC_CMDCFG_CFE 0x00800000 +@@ -255,9 +257,34 @@ + #define BGMAC_DMA_TX_SUSPEND 0x00000002 + #define BGMAC_DMA_TX_LOOPBACK 0x00000004 + #define BGMAC_DMA_TX_FLUSH 0x00000010 ++#define BGMAC_DMA_TX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++#define BGMAC_DMA_TX_MR_SHIFT 6 ++#define BGMAC_DMA_TX_MR_1 0 ++#define BGMAC_DMA_TX_MR_2 1 + #define BGMAC_DMA_TX_PARITY_DISABLE 0x00000800 + #define BGMAC_DMA_TX_ADDREXT_MASK 0x00030000 + #define BGMAC_DMA_TX_ADDREXT_SHIFT 16 ++#define BGMAC_DMA_TX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define BGMAC_DMA_TX_BL_SHIFT 18 ++#define BGMAC_DMA_TX_BL_16 0 ++#define BGMAC_DMA_TX_BL_32 1 ++#define BGMAC_DMA_TX_BL_64 2 ++#define BGMAC_DMA_TX_BL_128 3 ++#define BGMAC_DMA_TX_BL_256 4 ++#define BGMAC_DMA_TX_BL_512 5 ++#define BGMAC_DMA_TX_BL_1024 6 ++#define BGMAC_DMA_TX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define BGMAC_DMA_TX_PC_SHIFT 21 ++#define BGMAC_DMA_TX_PC_0 0 ++#define BGMAC_DMA_TX_PC_4 1 ++#define BGMAC_DMA_TX_PC_8 2 ++#define BGMAC_DMA_TX_PC_16 3 ++#define BGMAC_DMA_TX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define BGMAC_DMA_TX_PT_SHIFT 24 ++#define BGMAC_DMA_TX_PT_1 0 ++#define BGMAC_DMA_TX_PT_2 1 ++#define BGMAC_DMA_TX_PT_4 2 ++#define BGMAC_DMA_TX_PT_8 3 + #define BGMAC_DMA_TX_INDEX 0x04 + #define BGMAC_DMA_TX_RINGLO 0x08 + #define BGMAC_DMA_TX_RINGHI 0x0C +@@ -285,8 +312,33 @@ + #define BGMAC_DMA_RX_DIRECT_FIFO 0x00000100 + #define BGMAC_DMA_RX_OVERFLOW_CONT 0x00000400 + #define BGMAC_DMA_RX_PARITY_DISABLE 0x00000800 ++#define BGMAC_DMA_RX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++#define BGMAC_DMA_RX_MR_SHIFT 6 ++#define BGMAC_DMA_TX_MR_1 0 ++#define BGMAC_DMA_TX_MR_2 1 + #define BGMAC_DMA_RX_ADDREXT_MASK 0x00030000 + #define BGMAC_DMA_RX_ADDREXT_SHIFT 16 ++#define BGMAC_DMA_RX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define BGMAC_DMA_RX_BL_SHIFT 18 ++#define BGMAC_DMA_RX_BL_16 0 ++#define BGMAC_DMA_RX_BL_32 1 ++#define BGMAC_DMA_RX_BL_64 2 ++#define BGMAC_DMA_RX_BL_128 3 ++#define BGMAC_DMA_RX_BL_256 4 ++#define BGMAC_DMA_RX_BL_512 5 ++#define BGMAC_DMA_RX_BL_1024 6 ++#define BGMAC_DMA_RX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define BGMAC_DMA_RX_PC_SHIFT 21 ++#define BGMAC_DMA_RX_PC_0 0 ++#define BGMAC_DMA_RX_PC_4 1 ++#define BGMAC_DMA_RX_PC_8 2 ++#define BGMAC_DMA_RX_PC_16 3 ++#define BGMAC_DMA_RX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define BGMAC_DMA_RX_PT_SHIFT 24 ++#define BGMAC_DMA_RX_PT_1 0 ++#define BGMAC_DMA_RX_PT_2 1 ++#define BGMAC_DMA_RX_PT_4 2 ++#define BGMAC_DMA_RX_PT_8 3 + #define BGMAC_DMA_RX_INDEX 0x24 + #define BGMAC_DMA_RX_RINGLO 0x28 + #define BGMAC_DMA_RX_RINGHI 0x2C diff --git a/target/linux/generic/patches-3.12/026-bcma-export-bcma_find_core_unit.patch b/target/linux/generic/patches-3.12/026-bcma-export-bcma_find_core_unit.patch new file mode 100644 index 0000000000..86bce67fbf --- /dev/null +++ b/target/linux/generic/patches-3.12/026-bcma-export-bcma_find_core_unit.patch @@ -0,0 +1,69 @@ +From 0fc9d696e4855f1e03910c431499d68e75904929 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 10 Nov 2013 20:43:46 +0100 +Subject: [PATCH] bcma: export bcma_find_core_unit() + +--- + drivers/bcma/bcma_private.h | 2 -- + drivers/bcma/main.c | 13 +------------ + include/linux/bcma/bcma.h | 9 ++++++++- + 3 files changed, 9 insertions(+), 15 deletions(-) + +--- a/drivers/bcma/bcma_private.h ++++ b/drivers/bcma/bcma_private.h +@@ -33,8 +33,6 @@ int __init bcma_bus_early_register(struc + int bcma_bus_suspend(struct bcma_bus *bus); + int bcma_bus_resume(struct bcma_bus *bus); + #endif +-struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, +- u8 unit); + + /* scan.c */ + int bcma_bus_scan(struct bcma_bus *bus); +--- a/drivers/bcma/main.c ++++ b/drivers/bcma/main.c +@@ -69,18 +69,6 @@ static u16 bcma_cc_core_id(struct bcma_b + return BCMA_CORE_CHIPCOMMON; + } + +-struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) +-{ +- struct bcma_device *core; +- +- list_for_each_entry(core, &bus->cores, list) { +- if (core->id.id == coreid) +- return core; +- } +- return NULL; +-} +-EXPORT_SYMBOL_GPL(bcma_find_core); +- + struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, + u8 unit) + { +@@ -92,6 +80,7 @@ struct bcma_device *bcma_find_core_unit( + } + return NULL; + } ++EXPORT_SYMBOL_GPL(bcma_find_core_unit); + + bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, + int timeout) +--- a/include/linux/bcma/bcma.h ++++ b/include/linux/bcma/bcma.h +@@ -418,7 +418,14 @@ static inline void bcma_maskset16(struct + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set); + } + +-extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid); ++extern struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, ++ u8 unit); ++static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus, ++ u16 coreid) ++{ ++ return bcma_find_core_unit(bus, coreid, 0); ++} ++ + extern bool bcma_core_is_enabled(struct bcma_device *core); + extern void bcma_core_disable(struct bcma_device *core, u32 flags); + extern int bcma_core_enable(struct bcma_device *core, u32 flags); diff --git a/target/linux/generic/patches-3.12/772-bgmac-add-supprot-for-BCM4707.patch b/target/linux/generic/patches-3.12/772-bgmac-add-supprot-for-BCM4707.patch index eb1708a2c4..a4e51774d5 100644 --- a/target/linux/generic/patches-3.12/772-bgmac-add-supprot-for-BCM4707.patch +++ b/target/linux/generic/patches-3.12/772-bgmac-add-supprot-for-BCM4707.patch @@ -97,6 +97,32 @@ Signed-off-by: Hauke Mehrtens } /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ +@@ -1488,6 +1512,25 @@ static int bgmac_probe(struct bcma_devic + goto err_netdev_free; + } + ++ /* Northstar, take all GMAC cores out of reset */ ++ if (core->id.id == BCMA_CHIP_ID_BCM4707 || ++ core->id.id == BCMA_CHIP_ID_BCM53018) { ++ struct bcma_device *ns_core; ++ int ns_gmac; ++ ++ for (ns_gmac = 0; ns_gmac < 4; ns_gmac++) { ++ /* As northstar requirement, we have to reset all GAMCs before ++ * accessing them. et_probe() call pci_enable_device() for etx ++ * and do si_core_reset for GAMCx only. Then the other three ++ * GAMCs didn't reset. We do it here. ++ */ ++ ns_core = bcma_find_core_unit(core->bus, BCMA_CORE_MAC_GBIT, ns_gmac); ++ if (!bcma_core_is_enabled(ns_core)) { ++ bcma_core_enable(ns_core, 0); ++ } ++ } ++ } ++ + bgmac_chip_reset(bgmac); + + err = bgmac_dma_alloc(bgmac); --- a/drivers/net/ethernet/broadcom/bgmac.h +++ b/drivers/net/ethernet/broadcom/bgmac.h @@ -185,6 +185,7 @@ diff --git a/target/linux/generic/patches-3.12/773-bgmac-add-srab-switch.patch b/target/linux/generic/patches-3.12/773-bgmac-add-srab-switch.patch index e5ec78d59f..be253064b1 100644 --- a/target/linux/generic/patches-3.12/773-bgmac-add-srab-switch.patch +++ b/target/linux/generic/patches-3.12/773-bgmac-add-srab-switch.patch @@ -30,7 +30,7 @@ Signed-off-by: Hauke Mehrtens /************************************************** * BCMA bus ops **************************************************/ -@@ -1542,6 +1554,16 @@ static int bgmac_probe(struct bcma_devic +@@ -1561,6 +1573,16 @@ static int bgmac_probe(struct bcma_devic goto err_dma_free; } @@ -47,7 +47,7 @@ Signed-off-by: Hauke Mehrtens err = register_netdev(bgmac->net_dev); if (err) { bgmac_err(bgmac, "Cannot register net device\n"); -@@ -1571,6 +1593,10 @@ static void bgmac_remove(struct bcma_dev +@@ -1590,6 +1612,10 @@ static void bgmac_remove(struct bcma_dev { struct bgmac *bgmac = bcma_get_drvdata(core); diff --git a/target/linux/generic/patches-3.12/774-bgmac-add-some-workaround-for-rev-4.patch b/target/linux/generic/patches-3.12/774-bgmac-add-some-workaround-for-rev-4.patch new file mode 100644 index 0000000000..4e1a449b90 --- /dev/null +++ b/target/linux/generic/patches-3.12/774-bgmac-add-some-workaround-for-rev-4.patch @@ -0,0 +1,163 @@ +From ec12b94d22fa8715561bdffe6da0781dac08423e Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Sun, 10 Nov 2013 21:23:57 +0100 +Subject: [PATCH] bgmac: add some workaround for rev 4 + +--- + drivers/net/ethernet/broadcom/bgmac.c | 8 ++++---- + drivers/net/ethernet/broadcom/bgmac.h | 4 +++- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bgmac.c ++++ b/drivers/net/ethernet/broadcom/bgmac.c +@@ -97,6 +97,16 @@ static void bgmac_dma_tx_enable(struct b + u32 ctl; + + ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL); ++ if (bgmac->core->id.rev == 4) { ++ ctl &= ~BGMAC_DMA_TX_BL_MASK; ++ ctl |= BGMAC_DMA_TX_BL_128 << BGMAC_DMA_TX_BL_SHIFT; ++ ctl &= ~BGMAC_DMA_TX_MR_MASK; ++ ctl |= BGMAC_DMA_TX_MR_2 << BGMAC_DMA_TX_MR_SHIFT; ++ ctl &= ~BGMAC_DMA_TX_PC_MASK; ++ ctl |= BGMAC_DMA_TX_PC_16 << BGMAC_DMA_TX_PC_SHIFT; ++ ctl &= ~BGMAC_DMA_TX_PT_MASK; ++ ctl |= BGMAC_DMA_TX_PT_8 << BGMAC_DMA_TX_PT_SHIFT; ++ } + ctl |= BGMAC_DMA_TX_ENABLE; + ctl |= BGMAC_DMA_TX_PARITY_DISABLE; + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_CTL, ctl); +@@ -246,6 +256,17 @@ static void bgmac_dma_rx_enable(struct b + ctl |= BGMAC_DMA_RX_PARITY_DISABLE; + ctl |= BGMAC_DMA_RX_OVERFLOW_CONT; + ctl |= BGMAC_RX_FRAME_OFFSET << BGMAC_DMA_RX_FRAME_OFFSET_SHIFT; ++ ++ if (bgmac->core->id.rev == 4) { ++ ctl &= ~BGMAC_DMA_RX_BL_MASK; ++ ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT; ++ ++ ctl &= ~BGMAC_DMA_RX_PC_MASK; ++ ctl |= BGMAC_DMA_RX_PC_8 << BGMAC_DMA_RX_PC_SHIFT; ++ ++ ctl &= ~BGMAC_DMA_RX_PT_MASK; ++ ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT; ++ } + bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL, ctl); + } + +@@ -812,13 +833,13 @@ static void bgmac_cmdcfg_maskset(struct + u32 cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG); + u32 new_val = (cmdcfg & mask) | set; + +- bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR); ++ bgmac_set(bgmac, BGMAC_CMDCFG, BGMAC_CMDCFG_SR(bgmac->core->id.rev)); + udelay(2); + + if (new_val != cmdcfg || force) + bgmac_write(bgmac, BGMAC_CMDCFG, new_val); + +- bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR); ++ bgmac_mask(bgmac, BGMAC_CMDCFG, ~BGMAC_CMDCFG_SR(bgmac->core->id.rev)); + udelay(2); + } + +@@ -1029,7 +1050,7 @@ static void bgmac_chip_reset(struct bgma + BGMAC_CMDCFG_PROM | + BGMAC_CMDCFG_NLC | + BGMAC_CMDCFG_CFE | +- BGMAC_CMDCFG_SR, ++ BGMAC_CMDCFG_SR(core->id.rev), + false); + + bgmac_clear_mib(bgmac); +@@ -1070,7 +1091,7 @@ static void bgmac_enable(struct bgmac *b + + cmdcfg = bgmac_read(bgmac, BGMAC_CMDCFG); + bgmac_cmdcfg_maskset(bgmac, ~(BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE), +- BGMAC_CMDCFG_SR, true); ++ BGMAC_CMDCFG_SR(bgmac->core->id.rev), true); + udelay(2); + cmdcfg |= BGMAC_CMDCFG_TE | BGMAC_CMDCFG_RE; + bgmac_write(bgmac, BGMAC_CMDCFG, cmdcfg); +--- a/drivers/net/ethernet/broadcom/bgmac.h ++++ b/drivers/net/ethernet/broadcom/bgmac.h +@@ -194,7 +194,9 @@ + #define BGMAC_CMDCFG_TAI 0x00000200 + #define BGMAC_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */ + #define BGMAC_CMDCFG_HD_SHIFT 10 +-#define BGMAC_CMDCFG_SR 0x00000800 /* Set to reset mode */ ++#define BGMAC_CMDCFG_SR_REVO 0x00000800 /* Set to reset mode, for other revs */ ++#define BGMAC_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, only for core rev 4 */ ++#define BGMAC_CMDCFG_SR(rev) ((rev == 4) ? BGMAC_CMDCFG_SR_REV4 : BGMAC_CMDCFG_SR_REVO) + #define BGMAC_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */ + #define BGMAC_CMDCFG_AE 0x00400000 + #define BGMAC_CMDCFG_CFE 0x00800000 +@@ -255,9 +257,34 @@ + #define BGMAC_DMA_TX_SUSPEND 0x00000002 + #define BGMAC_DMA_TX_LOOPBACK 0x00000004 + #define BGMAC_DMA_TX_FLUSH 0x00000010 ++#define BGMAC_DMA_TX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++#define BGMAC_DMA_TX_MR_SHIFT 6 ++#define BGMAC_DMA_TX_MR_1 0 ++#define BGMAC_DMA_TX_MR_2 1 + #define BGMAC_DMA_TX_PARITY_DISABLE 0x00000800 + #define BGMAC_DMA_TX_ADDREXT_MASK 0x00030000 + #define BGMAC_DMA_TX_ADDREXT_SHIFT 16 ++#define BGMAC_DMA_TX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define BGMAC_DMA_TX_BL_SHIFT 18 ++#define BGMAC_DMA_TX_BL_16 0 ++#define BGMAC_DMA_TX_BL_32 1 ++#define BGMAC_DMA_TX_BL_64 2 ++#define BGMAC_DMA_TX_BL_128 3 ++#define BGMAC_DMA_TX_BL_256 4 ++#define BGMAC_DMA_TX_BL_512 5 ++#define BGMAC_DMA_TX_BL_1024 6 ++#define BGMAC_DMA_TX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define BGMAC_DMA_TX_PC_SHIFT 21 ++#define BGMAC_DMA_TX_PC_0 0 ++#define BGMAC_DMA_TX_PC_4 1 ++#define BGMAC_DMA_TX_PC_8 2 ++#define BGMAC_DMA_TX_PC_16 3 ++#define BGMAC_DMA_TX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define BGMAC_DMA_TX_PT_SHIFT 24 ++#define BGMAC_DMA_TX_PT_1 0 ++#define BGMAC_DMA_TX_PT_2 1 ++#define BGMAC_DMA_TX_PT_4 2 ++#define BGMAC_DMA_TX_PT_8 3 + #define BGMAC_DMA_TX_INDEX 0x04 + #define BGMAC_DMA_TX_RINGLO 0x08 + #define BGMAC_DMA_TX_RINGHI 0x0C +@@ -285,8 +312,33 @@ + #define BGMAC_DMA_RX_DIRECT_FIFO 0x00000100 + #define BGMAC_DMA_RX_OVERFLOW_CONT 0x00000400 + #define BGMAC_DMA_RX_PARITY_DISABLE 0x00000800 ++#define BGMAC_DMA_RX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++#define BGMAC_DMA_RX_MR_SHIFT 6 ++#define BGMAC_DMA_TX_MR_1 0 ++#define BGMAC_DMA_TX_MR_2 1 + #define BGMAC_DMA_RX_ADDREXT_MASK 0x00030000 + #define BGMAC_DMA_RX_ADDREXT_SHIFT 16 ++#define BGMAC_DMA_RX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define BGMAC_DMA_RX_BL_SHIFT 18 ++#define BGMAC_DMA_RX_BL_16 0 ++#define BGMAC_DMA_RX_BL_32 1 ++#define BGMAC_DMA_RX_BL_64 2 ++#define BGMAC_DMA_RX_BL_128 3 ++#define BGMAC_DMA_RX_BL_256 4 ++#define BGMAC_DMA_RX_BL_512 5 ++#define BGMAC_DMA_RX_BL_1024 6 ++#define BGMAC_DMA_RX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define BGMAC_DMA_RX_PC_SHIFT 21 ++#define BGMAC_DMA_RX_PC_0 0 ++#define BGMAC_DMA_RX_PC_4 1 ++#define BGMAC_DMA_RX_PC_8 2 ++#define BGMAC_DMA_RX_PC_16 3 ++#define BGMAC_DMA_RX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define BGMAC_DMA_RX_PT_SHIFT 24 ++#define BGMAC_DMA_RX_PT_1 0 ++#define BGMAC_DMA_RX_PT_2 1 ++#define BGMAC_DMA_RX_PT_4 2 ++#define BGMAC_DMA_RX_PT_8 3 + #define BGMAC_DMA_RX_INDEX 0x24 + #define BGMAC_DMA_RX_RINGLO 0x28 + #define BGMAC_DMA_RX_RINGHI 0x2C