Skip to content

Commit 7c588c7

Browse files
committed
Merge branch 'net-systemport-Unmap-queues-upon-DSA-unregister-event'
Florian Fainelli says: ==================== net: systemport: Unmap queues upon DSA unregister event This patch series fixes the unbinding/binding of the bcm_sf2 switch driver along with bcmsysport which monitors the switch port queues. Because the driver was not processing the DSA_PORT_UNREGISTER event, we would not be unmapping switch port/queues, which could cause incorrect decisions to be made by the HW (e.g: queue always back-pressured). ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5882d52 + da106a1 commit 7c588c7

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

drivers/net/dsa/bcm_sf2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,12 +1095,16 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
10951095
return ret;
10961096
}
10971097

1098+
bcm_sf2_gphy_enable_set(priv->dev->ds, true);
1099+
10981100
ret = bcm_sf2_mdio_register(ds);
10991101
if (ret) {
11001102
pr_err("failed to register MDIO bus\n");
11011103
return ret;
11021104
}
11031105

1106+
bcm_sf2_gphy_enable_set(priv->dev->ds, false);
1107+
11041108
ret = bcm_sf2_cfp_rst(priv);
11051109
if (ret) {
11061110
pr_err("failed to reset CFP\n");

drivers/net/ethernet/broadcom/bcmsysport.c

Lines changed: 58 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,7 +2324,7 @@ static int bcm_sysport_map_queues(struct notifier_block *nb,
23242324
struct bcm_sysport_priv *priv;
23252325
struct net_device *slave_dev;
23262326
unsigned int num_tx_queues;
2327-
unsigned int q, start, port;
2327+
unsigned int q, qp, port;
23282328
struct net_device *dev;
23292329

23302330
priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier);
@@ -2363,20 +2363,61 @@ static int bcm_sysport_map_queues(struct notifier_block *nb,
23632363

23642364
priv->per_port_num_tx_queues = num_tx_queues;
23652365

2366-
start = find_first_zero_bit(&priv->queue_bitmap, dev->num_tx_queues);
2367-
for (q = 0; q < num_tx_queues; q++) {
2368-
ring = &priv->tx_rings[q + start];
2366+
for (q = 0, qp = 0; q < dev->num_tx_queues && qp < num_tx_queues;
2367+
q++) {
2368+
ring = &priv->tx_rings[q];
2369+
2370+
if (ring->inspect)
2371+
continue;
23692372

23702373
/* Just remember the mapping actual programming done
23712374
* during bcm_sysport_init_tx_ring
23722375
*/
2373-
ring->switch_queue = q;
2376+
ring->switch_queue = qp;
23742377
ring->switch_port = port;
23752378
ring->inspect = true;
23762379
priv->ring_map[q + port * num_tx_queues] = ring;
2380+
qp++;
2381+
}
2382+
2383+
return 0;
2384+
}
2385+
2386+
static int bcm_sysport_unmap_queues(struct notifier_block *nb,
2387+
struct dsa_notifier_register_info *info)
2388+
{
2389+
struct bcm_sysport_tx_ring *ring;
2390+
struct bcm_sysport_priv *priv;
2391+
struct net_device *slave_dev;
2392+
unsigned int num_tx_queues;
2393+
struct net_device *dev;
2394+
unsigned int q, port;
23772395

2378-
/* Set all queues as being used now */
2379-
set_bit(q + start, &priv->queue_bitmap);
2396+
priv = container_of(nb, struct bcm_sysport_priv, dsa_notifier);
2397+
if (priv->netdev != info->master)
2398+
return 0;
2399+
2400+
dev = info->master;
2401+
2402+
if (dev->netdev_ops != &bcm_sysport_netdev_ops)
2403+
return 0;
2404+
2405+
port = info->port_number;
2406+
slave_dev = info->info.dev;
2407+
2408+
num_tx_queues = slave_dev->real_num_tx_queues;
2409+
2410+
for (q = 0; q < dev->num_tx_queues; q++) {
2411+
ring = &priv->tx_rings[q];
2412+
2413+
if (ring->switch_port != port)
2414+
continue;
2415+
2416+
if (!ring->inspect)
2417+
continue;
2418+
2419+
ring->inspect = false;
2420+
priv->ring_map[q + port * num_tx_queues] = NULL;
23802421
}
23812422

23822423
return 0;
@@ -2385,14 +2426,18 @@ static int bcm_sysport_map_queues(struct notifier_block *nb,
23852426
static int bcm_sysport_dsa_notifier(struct notifier_block *nb,
23862427
unsigned long event, void *ptr)
23872428
{
2388-
struct dsa_notifier_register_info *info;
2429+
int ret = NOTIFY_DONE;
23892430

2390-
if (event != DSA_PORT_REGISTER)
2391-
return NOTIFY_DONE;
2392-
2393-
info = ptr;
2431+
switch (event) {
2432+
case DSA_PORT_REGISTER:
2433+
ret = bcm_sysport_map_queues(nb, ptr);
2434+
break;
2435+
case DSA_PORT_UNREGISTER:
2436+
ret = bcm_sysport_unmap_queues(nb, ptr);
2437+
break;
2438+
}
23942439

2395-
return notifier_from_errno(bcm_sysport_map_queues(nb, info));
2440+
return notifier_from_errno(ret);
23962441
}
23972442

23982443
#define REV_FMT "v%2x.%02x"

drivers/net/ethernet/broadcom/bcmsysport.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,6 @@ struct bcm_sysport_priv {
796796
/* map information between switch port queues and local queues */
797797
struct notifier_block dsa_notifier;
798798
unsigned int per_port_num_tx_queues;
799-
unsigned long queue_bitmap;
800799
struct bcm_sysport_tx_ring *ring_map[DSA_MAX_PORTS * 8];
801800

802801
};

0 commit comments

Comments
 (0)