aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch')
-rw-r--r--target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch278
1 files changed, 0 insertions, 278 deletions
diff --git a/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch b/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch
deleted file mode 100644
index 636c6cf364..0000000000
--- a/target/linux/mvebu/patches-4.4/033-net-mvneta-Associate-RX-queues-with-each-CPU.patch
+++ /dev/null
@@ -1,278 +0,0 @@
-From: Gregory CLEMENT <gregory.clement@free-electrons.com>
-Date: Wed, 9 Dec 2015 18:23:49 +0100
-Subject: [PATCH] net: mvneta: Associate RX queues with each CPU
-
-We enable the percpu interrupt for all the CPU and we just associate a
-CPU to a few queue at the neta level. The mapping between the CPUs and
-the queues is static. The queues are associated to the CPU module the
-number of CPUs. However currently we only use on RX queue for a given
-Ethernet port.
-
-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
-@@ -110,9 +110,16 @@
- #define MVNETA_CPU_MAP(cpu) (0x2540 + ((cpu) << 2))
- #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_RXQ_TIME_COAL_REG(q) (0x2580 + ((q) << 2))
-
--/* Exception Interrupt Port/Queue Cause register */
-+/* Exception Interrupt Port/Queue Cause register
-+ *
-+ * Their behavior depend of the mapping done using the PCPX2Q
-+ * registers. For a given CPU if the bit associated to a queue is not
-+ * set, then for the register a read from this CPU will always return
-+ * 0 and a write won't do anything
-+ */
-
- #define MVNETA_INTR_NEW_CAUSE 0x25a0
- #define MVNETA_INTR_NEW_MASK 0x25a4
-@@ -820,7 +827,13 @@ static void mvneta_port_up(struct mvneta
- mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
-
- /* Enable all initialized RXQs. */
-- mvreg_write(pp, MVNETA_RXQ_CMD, BIT(pp->rxq_def));
-+ for (queue = 0; queue < rxq_number; queue++) {
-+ struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
-+
-+ if (rxq->descs != NULL)
-+ q_map |= (1 << queue);
-+ }
-+ mvreg_write(pp, MVNETA_RXQ_CMD, q_map);
- }
-
- /* Stop the Ethernet port activity */
-@@ -1026,6 +1039,7 @@ static void mvneta_defaults_set(struct m
- int cpu;
- int queue;
- u32 val;
-+ int max_cpu = num_present_cpus();
-
- /* Clear all Cause registers */
- mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
-@@ -1041,13 +1055,23 @@ static void mvneta_defaults_set(struct m
- /* Enable MBUS Retry bit16 */
- mvreg_write(pp, MVNETA_MBUS_RETRY, 0x20);
-
-- /* Set CPU queue access map - all CPUs have access to all RX
-- * queues and to all TX queues
-+ /* 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.
- */
-- for_each_present_cpu(cpu)
-- mvreg_write(pp, MVNETA_CPU_MAP(cpu),
-- (MVNETA_CPU_RXQ_ACCESS_ALL_MASK |
-- MVNETA_CPU_TXQ_ACCESS_ALL_MASK));
-+ for_each_present_cpu(cpu) {
-+ int rxq_map = 0, txq_map = 0;
-+ int rxq;
-+
-+ for (rxq = 0; rxq < rxq_number; rxq++)
-+ if ((rxq % max_cpu) == cpu)
-+ rxq_map |= MVNETA_CPU_RXQ_ACCESS(rxq);
-+
-+ if (cpu == rxq_def)
-+ txq_map = MVNETA_CPU_TXQ_ACCESS_ALL_MASK;
-+
-+ mvreg_write(pp, MVNETA_CPU_MAP(cpu), rxq_map | txq_map);
-+ }
-
- /* Reset RX and TX DMAs */
- mvreg_write(pp, MVNETA_PORT_RX_RESET, MVNETA_PORT_RX_DMA_RESET);
-@@ -2174,6 +2198,7 @@ static int mvneta_poll(struct napi_struc
- {
- int rx_done = 0;
- u32 cause_rx_tx;
-+ int rx_queue;
- struct mvneta_port *pp = netdev_priv(napi->dev);
- struct mvneta_pcpu_port *port = this_cpu_ptr(pp->ports);
-
-@@ -2205,8 +2230,15 @@ static int mvneta_poll(struct napi_struc
- /* For the case where the last mvneta_poll did not process all
- * RX packets
- */
-+ rx_queue = fls(((cause_rx_tx >> 8) & 0xff));
-+
- cause_rx_tx |= port->cause_rx_tx;
-- rx_done = mvneta_rx(pp, budget, &pp->rxqs[pp->rxq_def]);
-+
-+ if (rx_queue) {
-+ rx_queue = rx_queue - 1;
-+ rx_done = mvneta_rx(pp, budget, &pp->rxqs[rx_queue]);
-+ }
-+
- budget -= rx_done;
-
- if (budget > 0) {
-@@ -2419,19 +2451,27 @@ static void mvneta_cleanup_txqs(struct m
- /* Cleanup all Rx queues */
- static void mvneta_cleanup_rxqs(struct mvneta_port *pp)
- {
-- mvneta_rxq_deinit(pp, &pp->rxqs[pp->rxq_def]);
-+ int queue;
-+
-+ for (queue = 0; queue < txq_number; queue++)
-+ mvneta_rxq_deinit(pp, &pp->rxqs[queue]);
- }
-
-
- /* Init all Rx queues */
- static int mvneta_setup_rxqs(struct mvneta_port *pp)
- {
-- int err = mvneta_rxq_init(pp, &pp->rxqs[pp->rxq_def]);
-- if (err) {
-- netdev_err(pp->dev, "%s: can't create rxq=%d\n",
-- __func__, pp->rxq_def);
-- mvneta_cleanup_rxqs(pp);
-- return err;
-+ int queue;
-+
-+ for (queue = 0; queue < rxq_number; queue++) {
-+ int err = mvneta_rxq_init(pp, &pp->rxqs[queue]);
-+
-+ if (err) {
-+ netdev_err(pp->dev, "%s: can't create rxq=%d\n",
-+ __func__, queue);
-+ mvneta_cleanup_rxqs(pp);
-+ return err;
-+ }
- }
-
- return 0;
-@@ -2455,6 +2495,19 @@ static int mvneta_setup_txqs(struct mvne
- return 0;
- }
-
-+static void mvneta_percpu_unmask_interrupt(void *arg)
-+{
-+ struct mvneta_port *pp = arg;
-+
-+ /* All the queue are unmasked, but actually only the ones
-+ * maped to this CPU will be unmasked
-+ */
-+ mvreg_write(pp, MVNETA_INTR_NEW_MASK,
-+ MVNETA_RX_INTR_MASK_ALL |
-+ MVNETA_TX_INTR_MASK_ALL |
-+ MVNETA_MISCINTR_INTR_MASK);
-+}
-+
- static void mvneta_start_dev(struct mvneta_port *pp)
- {
- unsigned int cpu;
-@@ -2472,11 +2525,10 @@ static void mvneta_start_dev(struct mvne
- napi_enable(&port->napi);
- }
-
-- /* Unmask interrupts */
-- mvreg_write(pp, MVNETA_INTR_NEW_MASK,
-- MVNETA_RX_INTR_MASK(rxq_number) |
-- MVNETA_TX_INTR_MASK(txq_number) |
-- MVNETA_MISCINTR_INTR_MASK);
-+ /* Unmask interrupts. It has to be done from each CPU */
-+ for_each_online_cpu(cpu)
-+ smp_call_function_single(cpu, mvneta_percpu_unmask_interrupt,
-+ pp, true);
- mvreg_write(pp, MVNETA_INTR_MISC_MASK,
- MVNETA_CAUSE_PHY_STATUS_CHANGE |
- MVNETA_CAUSE_LINK_CHANGE |
-@@ -2752,22 +2804,35 @@ static void mvneta_percpu_disable(void *
-
- static void mvneta_percpu_elect(struct mvneta_port *pp)
- {
-- int online_cpu_idx, cpu, i = 0;
-+ int online_cpu_idx, max_cpu, cpu, i = 0;
-
- online_cpu_idx = pp->rxq_def % num_online_cpus();
-+ max_cpu = num_present_cpus();
-
- for_each_online_cpu(cpu) {
-- if (i == online_cpu_idx)
-- /* Enable per-CPU interrupt on the one CPU we
-- * just elected
-+ int rxq_map = 0, txq_map = 0;
-+ int rxq;
-+
-+ for (rxq = 0; rxq < rxq_number; rxq++)
-+ 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
- */
-- smp_call_function_single(cpu, mvneta_percpu_enable,
-- pp, true);
-- else
-- /* Disable per-CPU interrupt on all the other CPU */
-- smp_call_function_single(cpu, mvneta_percpu_disable,
-- pp, true);
-+ rxq_map |= MVNETA_CPU_RXQ_ACCESS(pp->rxq_def);
-+ txq_map = 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
-+ * new mapping
-+ */
-+ smp_call_function_single(cpu, mvneta_percpu_unmask_interrupt,
-+ pp, true);
- i++;
-+
- }
- };
-
-@@ -2802,12 +2867,22 @@ static int mvneta_percpu_notifier(struct
- mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
- napi_enable(&port->napi);
-
-+
-+ /* Enable per-CPU interrupts on the CPU that is
-+ * brought up.
-+ */
-+ smp_call_function_single(cpu, mvneta_percpu_enable,
-+ pp, true);
-+
- /* Enable per-CPU interrupt on the one CPU we care
- * about.
- */
- mvneta_percpu_elect(pp);
-
-- /* Unmask all ethernet port interrupts */
-+ /* Unmask all ethernet port interrupts, as this
-+ * notifier is called for each CPU then the CPU to
-+ * Queue mapping is applied
-+ */
- mvreg_write(pp, MVNETA_INTR_NEW_MASK,
- MVNETA_RX_INTR_MASK(rxq_number) |
- MVNETA_TX_INTR_MASK(txq_number) |
-@@ -2858,7 +2933,7 @@ static int mvneta_percpu_notifier(struct
- static int mvneta_open(struct net_device *dev)
- {
- struct mvneta_port *pp = netdev_priv(dev);
-- int ret;
-+ int ret, cpu;
-
- pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
- pp->frag_size = SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(pp->pkt_size)) +
-@@ -2888,8 +2963,13 @@ static int mvneta_open(struct net_device
- */
- mvneta_percpu_disable(pp);
-
-- /* Elect a CPU to handle our RX queue interrupt */
-- mvneta_percpu_elect(pp);
-+ /* Enable per-CPU interrupt on all the CPU to handle our RX
-+ * queue interrupts
-+ */
-+ for_each_online_cpu(cpu)
-+ smp_call_function_single(cpu, mvneta_percpu_enable,
-+ pp, true);
-+
-
- /* Register a CPU notifier to handle the case where our CPU
- * might be taken offline.