From 518960de5fe311f05e1aeb030601e314af4f3f0c Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 8 Jan 2013 22:20:16 +0000 Subject: mvebu: add inital support for Marvell Armada XP/370 SoCs This brings in the initial support for the Marvell Armada XP/370 SoCs. Successfully tested on RD-A370-A1 and DB-MV784MP-GP boards the following interfaces: - Ethernet - SDIO - GPIOs - SATA Signed-off-by: Florian Fainelli git-svn-id: svn://svn.openwrt.org/openwrt/trunk@35058 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../004-net_mvneta_fix_driver_operations_smp.patch | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch (limited to 'target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch') diff --git a/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch b/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch new file mode 100644 index 000000000..c7e992fc4 --- /dev/null +++ b/target/linux/mvebu/patches-3.8/004-net_mvneta_fix_driver_operations_smp.patch @@ -0,0 +1,75 @@ +From: Dmitri Epshtein + +In order for the driver to behave properly in a SMP context, the same +transmit queue should be used by the kernel in dev_queue_xmit() and in +the driver's mvneta_tx() function. To achieve that, the driver now +implements the ->ndo_select_txq() operation. + +For now, it always returns the same transmit queue, txq_def, until the +driver is expanded to properly take advantage of the multiqueue +capabilities of the hardware. + +Without this patch, the network driver crashes the kernel almost +immediately on Armada XP platforms, if the network load is at least a +little bit parallel (i.e several threads). + +[Thomas Petazzoni: reword commit message] +Signed-off-by: Dmitri Epshtein +Signed-off-by: Thomas Petazzoni +--- +This is 3.8-rc material. +--- + drivers/net/ethernet/marvell/mvneta.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index b6025c3..af2c421 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -1310,6 +1310,17 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb) + return MVNETA_TX_L4_CSUM_NOT; + } + ++static u16 mvneta_tx_policy(struct mvneta_port *pp, struct sk_buff *skb) ++{ ++ return (u16)txq_def; ++} ++ ++static u16 mvneta_select_txq(struct net_device *dev, struct sk_buff *skb) ++{ ++ struct mvneta_port *pp = netdev_priv(dev); ++ return mvneta_tx_policy(pp, skb); ++} ++ + /* Returns rx queue pointer (find last set bit) according to causeRxTx + * value + */ +@@ -1476,7 +1487,8 @@ error: + static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + { + struct mvneta_port *pp = netdev_priv(dev); +- struct mvneta_tx_queue *txq = &pp->txqs[txq_def]; ++ u16 txq_id = mvneta_tx_policy(pp, skb); ++ struct mvneta_tx_queue *txq = &pp->txqs[txq_id]; + struct mvneta_tx_desc *tx_desc; + struct netdev_queue *nq; + int frags = 0; +@@ -1486,7 +1498,7 @@ static int mvneta_tx(struct sk_buff *skb, struct net_device *dev) + goto out; + + frags = skb_shinfo(skb)->nr_frags + 1; +- nq = netdev_get_tx_queue(dev, txq_def); ++ nq = netdev_get_tx_queue(dev, txq_id); + + /* Get a descriptor for the first part of the packet */ + tx_desc = mvneta_txq_next_desc_get(txq); +@@ -2550,6 +2562,7 @@ static const struct net_device_ops mvneta_netdev_ops = { + .ndo_change_mtu = mvneta_change_mtu, + .ndo_tx_timeout = mvneta_tx_timeout, + .ndo_get_stats64 = mvneta_get_stats64, ++ .ndo_select_queue = mvneta_select_txq, + }; + + const struct ethtool_ops mvneta_eth_tool_ops = { +-- +1.7.9.5 -- cgit v1.2.3