| From 26f2112f26e8c39b67b70a6282c5014514b6240b Mon Sep 17 00:00:00 2001 |
| From: Florian Fainelli <f.fainelli@gmail.com> |
| Date: Thu, 16 Jan 2020 13:08:58 -0800 |
| Subject: [PATCH] net: systemport: Fixed queue mapping in internal ring map |
| |
| commit 5a9ef19454cd5daec8041bc7c3c11deb7456d9a0 upstream. |
| |
| We would not be transmitting using the correct SYSTEMPORT transmit queue |
| during ndo_select_queue() which looks up the internal TX ring map |
| because while establishing the mapping we would be off by 4, so for |
| instance, when we populate switch port mappings we would be doing: |
| |
| switch port 0, queue 0 -> ring index #0 |
| switch port 0, queue 1 -> ring index #1 |
| ... |
| switch port 0, queue 3 -> ring index #3 |
| switch port 1, queue 0 -> ring index #8 (4 + 4 * 1) |
| ... |
| |
| instead of using ring index #4. This would cause our ndo_select_queue() |
| to use the fallback queue mechanism which would pick up an incorrect |
| ring for that switch port. Fix this by using the correct switch queue |
| number instead of SYSTEMPORT queue number. |
| |
| Fixes: 25c440704661 ("net: systemport: Simplify queue mapping logic") |
| Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c |
| index cae9b77ff44b..be2d1f41bc0c 100644 |
| --- a/drivers/net/ethernet/broadcom/bcmsysport.c |
| +++ b/drivers/net/ethernet/broadcom/bcmsysport.c |
| @@ -2324,7 +2324,7 @@ static int bcm_sysport_map_queues(struct notifier_block *nb, |
| ring->switch_queue = qp; |
| ring->switch_port = port; |
| ring->inspect = true; |
| - priv->ring_map[q + port * num_tx_queues] = ring; |
| + priv->ring_map[qp + port * num_tx_queues] = ring; |
| qp++; |
| } |
| |
| @@ -2339,7 +2339,7 @@ static int bcm_sysport_unmap_queues(struct notifier_block *nb, |
| struct net_device *slave_dev; |
| unsigned int num_tx_queues; |
| struct net_device *dev; |
| - unsigned int q, port; |
| + unsigned int q, qp, port; |
| |
| priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier); |
| if (priv->netdev != info->master) |
| @@ -2365,7 +2365,8 @@ static int bcm_sysport_unmap_queues(struct notifier_block *nb, |
| continue; |
| |
| ring->inspect = false; |
| - priv->ring_map[q + port * num_tx_queues] = NULL; |
| + qp = ring->switch_queue; |
| + priv->ring_map[qp + port * num_tx_queues] = NULL; |
| } |
| |
| return 0; |
| -- |
| 2.7.4 |
| |