diff options
author | Felix Fietkau <nbd@nbd.name> | 2016-05-21 22:16:56 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2016-05-22 16:04:37 +0200 |
commit | df98acc6a1252456608958fc17f7da3ae4cfb46c (patch) | |
tree | 2ed792928e0aa18d5dc3a8031b670629fa175167 /target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch | |
parent | e90245237c971cda70e9c1752e9bce4cc3cbef4f (diff) | |
download | upstream-df98acc6a1252456608958fc17f7da3ae4cfb46c.tar.gz upstream-df98acc6a1252456608958fc17f7da3ae4cfb46c.tar.bz2 upstream-df98acc6a1252456608958fc17f7da3ae4cfb46c.zip |
mvebu: backport upstream ethernet driver improvements and enable buffer manager support
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch')
-rw-r--r-- | target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch b/target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch new file mode 100644 index 0000000000..5b35b6442b --- /dev/null +++ b/target/linux/mvebu/patches-4.4/035-net-mvneta-Configure-XPS-support.patch @@ -0,0 +1,124 @@ +From: Gregory CLEMENT <gregory.clement@free-electrons.com> +Date: Wed, 9 Dec 2015 18:23:51 +0100 +Subject: [PATCH] net: mvneta: Configure XPS support + +With this patch each CPU is associated with its own set of TX queues. + +It also setup the XPS with an initial configuration which set the +affinity matching the hardware configuration. + +Suggested-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -111,6 +111,7 @@ + #define MVNETA_CPU_RXQ_ACCESS_ALL_MASK 0x000000ff + #define MVNETA_CPU_TXQ_ACCESS_ALL_MASK 0x0000ff00 + #define MVNETA_CPU_RXQ_ACCESS(rxq) BIT(rxq) ++#define MVNETA_CPU_TXQ_ACCESS(txq) BIT(txq + 8) + #define MVNETA_RXQ_TIME_COAL_REG(q) (0x2580 + ((q) << 2)) + + /* Exception Interrupt Port/Queue Cause register +@@ -514,6 +515,9 @@ struct mvneta_tx_queue { + + /* DMA address of TSO headers */ + dma_addr_t tso_hdrs_phys; ++ ++ /* Affinity mask for CPUs*/ ++ cpumask_t affinity_mask; + }; + + struct mvneta_rx_queue { +@@ -1062,20 +1066,30 @@ static void mvneta_defaults_set(struct m + /* Enable MBUS Retry bit16 */ + mvreg_write(pp, MVNETA_MBUS_RETRY, 0x20); + +- /* Set CPU queue access map. CPUs are assigned to the RX +- * queues modulo their number and all the TX queues are +- * assigned to the CPU associated to the default RX queue. ++ /* Set CPU queue access map. CPUs are assigned to the RX and ++ * TX queues modulo their number. If there is only one TX ++ * queue then it is assigned to the CPU associated to the ++ * default RX queue. + */ + for_each_present_cpu(cpu) { + int rxq_map = 0, txq_map = 0; +- int rxq; ++ int rxq, txq; + + for (rxq = 0; rxq < rxq_number; rxq++) + if ((rxq % max_cpu) == cpu) + rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); + +- if (cpu == pp->rxq_def) +- txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; ++ for (txq = 0; txq < txq_number; txq++) ++ if ((txq % max_cpu) == cpu) ++ txq_map |= MVNETA_CPU_TXQ_ACCESS(txq); ++ ++ /* With only one TX queue we configure a special case ++ * which will allow to get all the irq on a single ++ * CPU ++ */ ++ if (txq_number == 1) ++ txq_map = (cpu == pp->rxq_def) ? ++ MVNETA_CPU_TXQ_ACCESS(1) : 0; + + mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); + } +@@ -2362,6 +2376,8 @@ static void mvneta_rxq_deinit(struct mvn + static int mvneta_txq_init(struct mvneta_port *pp, + struct mvneta_tx_queue *txq) + { ++ int cpu; ++ + txq->size = pp->tx_ring_size; + + /* A queue must always have room for at least one skb. +@@ -2414,6 +2430,14 @@ static int mvneta_txq_init(struct mvneta + } + mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal); + ++ /* Setup XPS mapping */ ++ if (txq_number > 1) ++ cpu = txq->id % num_present_cpus(); ++ else ++ cpu = pp->rxq_def % num_present_cpus(); ++ cpumask_set_cpu(cpu, &txq->affinity_mask); ++ netif_set_xps_queue(pp->dev, &txq->affinity_mask, txq->id); ++ + return 0; + } + +@@ -2836,13 +2860,23 @@ static void mvneta_percpu_elect(struct m + if ((rxq % max_cpu) == cpu) + rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq); + +- if (i == online_cpu_idx) { +- /* Map the default receive queue and transmit +- * queue to the elected CPU ++ if (i == online_cpu_idx) ++ /* Map the default receive queue queue to the ++ * elected CPU + */ + rxq_map |= MVNETA_CPU_RXQ_ACCESS(pp->rxq_def); +- txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK; +- } ++ ++ /* We update the TX queue map only if we have one ++ * queue. In this case we associate the TX queue to ++ * the CPU bound to the default RX queue ++ */ ++ if (txq_number == 1) ++ txq_map = (i == online_cpu_idx) ? ++ MVNETA_CPU_TXQ_ACCESS(1) : 0; ++ else ++ txq_map = mvreg_read(pp, MVNETA_CPU_MAP(cpu)) & ++ MVNETA_CPU_TXQ_ACCESS_ALL_MASK; ++ + mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map); + + /* Update the interrupt mask on each CPU according the |