summaryrefslogtreecommitdiffstats
path: root/target/linux/bcm53xx
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2013-09-25 21:47:25 +0000
committerHauke Mehrtens <hauke@hauke-m.de>2013-09-25 21:47:25 +0000
commit0bdc137636ec10b39dad18abe25a946323155b9c (patch)
tree0e9f6987050e9e90133f10cd3bbd9232f529eaec /target/linux/bcm53xx
parentc75a970337175d123c3989f473052f4919b5fd91 (diff)
downloadmaster-31e0f0ae-0bdc137636ec10b39dad18abe25a946323155b9c.tar.gz
master-31e0f0ae-0bdc137636ec10b39dad18abe25a946323155b9c.tar.bz2
master-31e0f0ae-0bdc137636ec10b39dad18abe25a946323155b9c.zip
bcm53xx: update bgmac driver
Update the bgmac driver with the patches already used for bcm47xx target. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> SVN-Revision: 38199
Diffstat (limited to 'target/linux/bcm53xx')
-rw-r--r--target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch19
-rw-r--r--target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch51
-rw-r--r--target/linux/bcm53xx/patches-3.10/210-bgmac_fix_internal_switch_initialization.patch33
-rw-r--r--target/linux/bcm53xx/patches-3.10/211-bgmac_fix_parsing_of_et_swtype.patch14
-rw-r--r--target/linux/bcm53xx/patches-3.10/212-bgmac_implement_unaligned_addressing.patch140
-rw-r--r--target/linux/bcm53xx/patches-3.10/213-bgmac-add-support-for-Byte-Queue-Limits.patch50
6 files changed, 259 insertions, 48 deletions
diff --git a/target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch b/target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch
deleted file mode 100644
index a0abae9c24..0000000000
--- a/target/linux/bcm53xx/patches-3.10/201-bgmac-add-dependency-to-phylib.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-bgmac: add dependency to phylib
-
-bgmac is using functions from phylib, add the dependency.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/ethernet/broadcom/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/broadcom/Kconfig
-+++ b/drivers/net/ethernet/broadcom/Kconfig
-@@ -133,6 +133,7 @@ config BNX2X_SRIOV
- config BGMAC
- tristate "BCMA bus GBit core support"
- depends on BCMA_HOST_SOC && HAS_DMA
-+ select PHYLIB
- ---help---
- This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
- They can be found on BCM47xx SoCs and provide gigabit ethernet.
diff --git a/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch b/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch
index 4467d2365a..6a00cdf0fb 100644
--- a/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch
+++ b/target/linux/bcm53xx/patches-3.10/203-bgmac-register-phy.patch
@@ -1,11 +1,13 @@
-bgmac: register phy
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/net/ethernet/broadcom/bgmac.c | 137 ++++++++++++++++-----------------
- drivers/net/ethernet/broadcom/bgmac.h | 3 +
- 2 files changed, 71 insertions(+), 69 deletions(-)
-
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -133,6 +133,7 @@ config BNX2X_SRIOV
+ config BGMAC
+ tristate "BCMA bus GBit core support"
+ depends on BCMA_HOST_SOC && HAS_DMA
++ select PHYLIB
+ ---help---
+ This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus.
+ They can be found on BCM47xx SoCs and provide gigabit ethernet.
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1205,27 +1205,14 @@ static int bgmac_set_mac_address(struct
@@ -33,8 +35,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
- default:
- return -EOPNOTSUPP;
- }
-+ if (!netif_running(net_dev))
-+ return -EINVAL;
++ if (!netif_running(net_dev))
++ return -EINVAL;
+
+ if (!bgmac->phydev)
+ return -EINVAL;
@@ -43,7 +45,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
}
static const struct net_device_ops bgmac_netdev_ops = {
-@@ -1247,61 +1234,18 @@ static int bgmac_get_settings(struct net
+@@ -1247,61 +1234,16 @@ static int bgmac_get_settings(struct net
{
struct bgmac *bgmac = netdev_priv(net_dev);
@@ -95,7 +97,6 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
}
-#if 0
-+
static int bgmac_set_settings(struct net_device *net_dev,
struct ethtool_cmd *cmd)
{
@@ -105,11 +106,10 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ return phy_ethtool_sset(bgmac->phydev, cmd);
}
-#endif
-+
static void bgmac_get_drvinfo(struct net_device *net_dev,
struct ethtool_drvinfo *info)
-@@ -1312,6 +1256,7 @@ static void bgmac_get_drvinfo(struct net
+@@ -1312,6 +1254,7 @@ static void bgmac_get_drvinfo(struct net
static const struct ethtool_ops bgmac_ethtool_ops = {
.get_settings = bgmac_get_settings,
@@ -117,7 +117,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
.get_drvinfo = bgmac_get_drvinfo,
};
-@@ -1330,10 +1275,42 @@ static int bgmac_mii_write(struct mii_bu
+@@ -1330,10 +1273,36 @@ static int bgmac_mii_write(struct mii_bu
return bgmac_phy_write(bus->priv, mii_id, regnum, value);
}
@@ -125,7 +125,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+{
+ struct bgmac *bgmac = netdev_priv(dev);
+ struct phy_device *phydev = bgmac->phydev;
-+ int status_changed = 0;
++ bool status_changed = 0;
+
+ BUG_ON(!phydev);
+
@@ -140,14 +140,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ bgmac->old_duplex = phydev->duplex;
+ }
+
-+ if (status_changed) {
-+ pr_info("%s: link %s", dev->name, phydev->link ?
-+ "UP" : "DOWN");
-+ if (phydev->link)
-+ pr_cont(" - %d/%s", phydev->speed,
-+ phydev->duplex == DUPLEX_FULL ? "full" : "half");
-+ pr_cont("\n");
-+ }
++ if (status_changed)
++ phy_print_status(phydev);
+}
+
static int bgmac_mii_register(struct bgmac *bgmac)
@@ -160,7 +154,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
mii_bus = mdiobus_alloc();
if (!mii_bus)
-@@ -1364,7 +1341,29 @@ static int bgmac_mii_register(struct bgm
+@@ -1364,7 +1333,28 @@ static int bgmac_mii_register(struct bgm
bgmac->mii_bus = mii_bus;
@@ -173,7 +167,7 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ PHY_INTERFACE_MODE_MII);
+
+ if (IS_ERR(phydev)) {
-+ netdev_err(net_dev, "could not attach PHY: %s", phy_id);
++ netdev_err(net_dev, "could not attach PHY: %s\n", phy_id);
+ bgmac->phyaddr = BGMAC_PHY_NOREGS;
+ return PTR_ERR(phydev);
+ }
@@ -183,9 +177,8 @@ Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
+ bgmac->old_duplex = -1;
+ bgmac->phyaddr = phydev->addr;
+
-+ netdev_info(net_dev, "attached PHY driver [%s] "
-+ "(mii_bus:phy_addr=%s)\n",
-+ phydev->drv->name, dev_name(&phydev->dev));
++ netdev_info(net_dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
++ phydev->drv->name, dev_name(&phydev->dev));
+
+ return 0;
diff --git a/target/linux/bcm53xx/patches-3.10/210-bgmac_fix_internal_switch_initialization.patch b/target/linux/bcm53xx/patches-3.10/210-bgmac_fix_internal_switch_initialization.patch
new file mode 100644
index 0000000000..a5ace95636
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.10/210-bgmac_fix_internal_switch_initialization.patch
@@ -0,0 +1,33 @@
+bgmac: fix internal switch initialization
+
+Some devices (BCM4749, BCM5357, BCM53572) have internal switch that
+requires initialization. We already have code for this, but because
+of the typo in code it was never working. This resulted in network not
+working for some routers and possibility of soft-bricking them.
+
+Use correct bit for switch initialization and fix typo in the define.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -931,7 +931,7 @@ static void bgmac_chip_reset(struct bgma
+ struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
+ u8 et_swtype = 0;
+ u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
+- BGMAC_CHIPCTL_1_IF_TYPE_RMII;
++ BGMAC_CHIPCTL_1_IF_TYPE_MII;
+ char buf[2];
+
+ if (bcm47xx_nvram_getenv("et_swtype", buf, 1) > 0) {
+--- a/drivers/net/ethernet/broadcom/bgmac.h
++++ b/drivers/net/ethernet/broadcom/bgmac.h
+@@ -334,7 +334,7 @@
+
+ #define BGMAC_CHIPCTL_1_IF_TYPE_MASK 0x00000030
+ #define BGMAC_CHIPCTL_1_IF_TYPE_RMII 0x00000000
+-#define BGMAC_CHIPCTL_1_IF_TYPE_MI 0x00000010
++#define BGMAC_CHIPCTL_1_IF_TYPE_MII 0x00000010
+ #define BGMAC_CHIPCTL_1_IF_TYPE_RGMII 0x00000020
+ #define BGMAC_CHIPCTL_1_SW_TYPE_MASK 0x000000C0
+ #define BGMAC_CHIPCTL_1_SW_TYPE_EPHY 0x00000000
diff --git a/target/linux/bcm53xx/patches-3.10/211-bgmac_fix_parsing_of_et_swtype.patch b/target/linux/bcm53xx/patches-3.10/211-bgmac_fix_parsing_of_et_swtype.patch
new file mode 100644
index 0000000000..2f79b8d823
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.10/211-bgmac_fix_parsing_of_et_swtype.patch
@@ -0,0 +1,14 @@
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -932,9 +932,9 @@ static void bgmac_chip_reset(struct bgma
+ u8 et_swtype = 0;
+ u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
+ BGMAC_CHIPCTL_1_IF_TYPE_MII;
+- char buf[2];
++ char buf[4];
+
+- if (bcm47xx_nvram_getenv("et_swtype", buf, 1) > 0) {
++ if (bcm47xx_nvram_getenv("et_swtype", buf, sizeof(buf)) > 0) {
+ if (kstrtou8(buf, 0, &et_swtype))
+ bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
+ buf);
diff --git a/target/linux/bcm53xx/patches-3.10/212-bgmac_implement_unaligned_addressing.patch b/target/linux/bcm53xx/patches-3.10/212-bgmac_implement_unaligned_addressing.patch
new file mode 100644
index 0000000000..4987e5e720
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.10/212-bgmac_implement_unaligned_addressing.patch
@@ -0,0 +1,140 @@
+bgmac: implement unaligned addressing for DMA rings that support it
+
+This is important patch for new devices that support unaligned
+addressing. That devices suffer from the backward-compatibility bug in
+DMA engine. In theory we should be able to use old mechanism, but in
+practice DMA address seems to be randomly copied into status register
+when hardware reaches end of a ring. This breaks reading slot number
+from status register and we can't use DMA anymore.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -162,6 +162,7 @@ static netdev_tx_t bgmac_dma_tx_add(stru
+ if (++ring->end >= BGMAC_TX_RING_SLOTS)
+ ring->end = 0;
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_INDEX,
++ ring->index_base +
+ ring->end * sizeof(struct bgmac_dma_desc));
+
+ /* Always keep one slot free to allow detecting bugged calls. */
+@@ -186,6 +187,8 @@ static void bgmac_dma_tx_free(struct bgm
+ /* The last slot that hardware didn't consume yet */
+ empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
+ empty_slot &= BGMAC_DMA_TX_STATDPTR;
++ empty_slot -= ring->index_base;
++ empty_slot &= BGMAC_DMA_TX_STATDPTR;
+ empty_slot /= sizeof(struct bgmac_dma_desc);
+
+ while (ring->start != empty_slot) {
+@@ -279,6 +282,8 @@ static int bgmac_dma_rx_read(struct bgma
+
+ end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
+ end_slot &= BGMAC_DMA_RX_STATDPTR;
++ end_slot -= ring->index_base;
++ end_slot &= BGMAC_DMA_RX_STATDPTR;
+ end_slot /= sizeof(struct bgmac_dma_desc);
+
+ ring->end = end_slot;
+@@ -423,9 +428,6 @@ static int bgmac_dma_alloc(struct bgmac
+ ring = &bgmac->tx_ring[i];
+ ring->num_slots = BGMAC_TX_RING_SLOTS;
+ ring->mmio_base = ring_base[i];
+- if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_TX))
+- bgmac_warn(bgmac, "TX on ring 0x%X supports unaligned addressing but this feature is not implemented\n",
+- ring->mmio_base);
+
+ /* Alloc ring of descriptors */
+ size = ring->num_slots * sizeof(struct bgmac_dma_desc);
+@@ -440,6 +442,13 @@ static int bgmac_dma_alloc(struct bgmac
+ if (ring->dma_base & 0xC0000000)
+ bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
+
++ ring->unaligned = bgmac_dma_unaligned(bgmac, ring,
++ BGMAC_DMA_RING_TX);
++ if (ring->unaligned)
++ ring->index_base = lower_32_bits(ring->dma_base);
++ else
++ ring->index_base = 0;
++
+ /* No need to alloc TX slots yet */
+ }
+
+@@ -449,9 +458,6 @@ static int bgmac_dma_alloc(struct bgmac
+ ring = &bgmac->rx_ring[i];
+ ring->num_slots = BGMAC_RX_RING_SLOTS;
+ ring->mmio_base = ring_base[i];
+- if (bgmac_dma_unaligned(bgmac, ring, BGMAC_DMA_RING_RX))
+- bgmac_warn(bgmac, "RX on ring 0x%X supports unaligned addressing but this feature is not implemented\n",
+- ring->mmio_base);
+
+ /* Alloc ring of descriptors */
+ size = ring->num_slots * sizeof(struct bgmac_dma_desc);
+@@ -467,6 +473,13 @@ static int bgmac_dma_alloc(struct bgmac
+ if (ring->dma_base & 0xC0000000)
+ bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
+
++ ring->unaligned = bgmac_dma_unaligned(bgmac, ring,
++ BGMAC_DMA_RING_RX);
++ if (ring->unaligned)
++ ring->index_base = lower_32_bits(ring->dma_base);
++ else
++ ring->index_base = 0;
++
+ /* Alloc RX slots */
+ for (j = 0; j < ring->num_slots; j++) {
+ err = bgmac_dma_rx_skb_for_slot(bgmac, &ring->slots[j]);
+@@ -494,12 +507,14 @@ static void bgmac_dma_init(struct bgmac
+ for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
+ ring = &bgmac->tx_ring[i];
+
+- /* We don't implement unaligned addressing, so enable first */
+- bgmac_dma_tx_enable(bgmac, ring);
++ if (!ring->unaligned)
++ bgmac_dma_tx_enable(bgmac, ring);
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGLO,
+ lower_32_bits(ring->dma_base));
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_TX_RINGHI,
+ upper_32_bits(ring->dma_base));
++ if (ring->unaligned)
++ bgmac_dma_tx_enable(bgmac, ring);
+
+ ring->start = 0;
+ ring->end = 0; /* Points the slot that should *not* be read */
+@@ -510,12 +525,14 @@ static void bgmac_dma_init(struct bgmac
+
+ ring = &bgmac->rx_ring[i];
+
+- /* We don't implement unaligned addressing, so enable first */
+- bgmac_dma_rx_enable(bgmac, ring);
++ if (!ring->unaligned)
++ bgmac_dma_rx_enable(bgmac, ring);
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGLO,
+ lower_32_bits(ring->dma_base));
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_RINGHI,
+ upper_32_bits(ring->dma_base));
++ if (ring->unaligned)
++ bgmac_dma_rx_enable(bgmac, ring);
+
+ for (j = 0, dma_desc = ring->cpu_base; j < ring->num_slots;
+ j++, dma_desc++) {
+@@ -536,6 +553,7 @@ static void bgmac_dma_init(struct bgmac
+ }
+
+ bgmac_write(bgmac, ring->mmio_base + BGMAC_DMA_RX_INDEX,
++ ring->index_base +
+ ring->num_slots * sizeof(struct bgmac_dma_desc));
+
+ ring->start = 0;
+--- a/drivers/net/ethernet/broadcom/bgmac.h
++++ b/drivers/net/ethernet/broadcom/bgmac.h
+@@ -386,6 +386,8 @@ struct bgmac_dma_ring {
+ u16 mmio_base;
+ struct bgmac_dma_desc *cpu_base;
+ dma_addr_t dma_base;
++ u32 index_base; /* Used for unaligned rings only, otherwise 0 */
++ bool unaligned;
+
+ struct bgmac_slot_info slots[BGMAC_RX_RING_SLOTS];
+ };
diff --git a/target/linux/bcm53xx/patches-3.10/213-bgmac-add-support-for-Byte-Queue-Limits.patch b/target/linux/bcm53xx/patches-3.10/213-bgmac-add-support-for-Byte-Queue-Limits.patch
new file mode 100644
index 0000000000..440461ae1e
--- /dev/null
+++ b/target/linux/bcm53xx/patches-3.10/213-bgmac-add-support-for-Byte-Queue-Limits.patch
@@ -0,0 +1,50 @@
+From: Hauke Mehrtens <hauke@hauke-m.de>
+bgmac: add support for Byte Queue Limits
+
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -183,6 +183,7 @@ static void bgmac_dma_tx_free(struct bgm
+ struct device *dma_dev = bgmac->core->dma_dev;
+ int empty_slot;
+ bool freed = false;
++ unsigned bytes_compl = 0, pkts_compl = 0;
+
+ /* The last slot that hardware didn't consume yet */
+ empty_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_TX_STATUS);
+@@ -200,6 +201,9 @@ static void bgmac_dma_tx_free(struct bgm
+ slot->skb->len, DMA_TO_DEVICE);
+ slot->dma_addr = 0;
+
++ bytes_compl += slot->skb->len;
++ pkts_compl++;
++
+ /* Free memory! :) */
+ dev_kfree_skb(slot->skb);
+ slot->skb = NULL;
+@@ -213,6 +217,8 @@ static void bgmac_dma_tx_free(struct bgm
+ freed = true;
+ }
+
++ netdev_completed_queue(bgmac->net_dev, pkts_compl, bytes_compl);
++
+ if (freed && netif_queue_stopped(bgmac->net_dev))
+ netif_wake_queue(bgmac->net_dev);
+ }
+@@ -1013,6 +1019,8 @@ static void bgmac_chip_reset(struct bgma
+ bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
+ bgmac_miiconfig(bgmac);
+ bgmac_phy_init(bgmac);
++
++ netdev_reset_queue(bgmac->net_dev);
+
+ bgmac->int_status = 0;
+ }
+@@ -1227,6 +1235,8 @@ static netdev_tx_t bgmac_start_xmit(stru
+ struct bgmac *bgmac = netdev_priv(net_dev);
+ struct bgmac_dma_ring *ring;
+
++ netdev_sent_queue(net_dev, skb->len);
++
+ /* No QOS support yet */
+ ring = &bgmac->tx_ring[0];
+ return bgmac_dma_tx_add(bgmac, ring, skb);