Commit 9e776f22 authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-tx-queues'

Florian Fainelli says:

====================
net: dsa: Allow switch drivers to indicate number of TX queues

This patch series extracts the parts of the patch set that are likely not to be
controversial and actually bringing multi-queue support to DSA-created network
devices.

With these patches, we can now use sch_multiq as documented under
Documentation/networking/multique.txt and let applications dedice the switch
port output queue they want to use. Currently only Broadcom tags utilize that
information.

Resending based on David's feedback regarding the patches not in patchwork.

Changes in v2:
- use a proper define for the number of TX queues in bcm_sf2.c (Andrew)

Changes from RFC:

- dropped the ability to configure RX queues since we don't do anything with
  those just yet
- dropped the patches that dealt with binding the DSA slave network devices
  queues with their master network devices queues this will be worked on
  separately.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f1c2eddf c837fc81
...@@ -103,6 +103,7 @@ static void bcm_sf2_brcm_hdr_setup(struct bcm_sf2_priv *priv, int port) ...@@ -103,6 +103,7 @@ static void bcm_sf2_brcm_hdr_setup(struct bcm_sf2_priv *priv, int port)
static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
{ {
struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
unsigned int i;
u32 reg, offset; u32 reg, offset;
if (priv->type == BCM7445_DEVICE_ID) if (priv->type == BCM7445_DEVICE_ID)
...@@ -129,6 +130,14 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) ...@@ -129,6 +130,14 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
reg |= MII_DUMB_FWDG_EN; reg |= MII_DUMB_FWDG_EN;
core_writel(priv, reg, CORE_SWITCH_CTRL); core_writel(priv, reg, CORE_SWITCH_CTRL);
/* Configure Traffic Class to QoS mapping, allow each priority to map
* to a different queue number
*/
reg = core_readl(priv, CORE_PORT_TC2_QOS_MAP_PORT(port));
for (i = 0; i < SF2_NUM_EGRESS_QUEUES; i++)
reg |= i << (PRT_TO_QID_SHIFT * i);
core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
bcm_sf2_brcm_hdr_setup(priv, port); bcm_sf2_brcm_hdr_setup(priv, port);
/* Force link status for IMP port */ /* Force link status for IMP port */
...@@ -244,7 +253,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port, ...@@ -244,7 +253,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
* to a different queue number * to a different queue number
*/ */
reg = core_readl(priv, CORE_PORT_TC2_QOS_MAP_PORT(port)); reg = core_readl(priv, CORE_PORT_TC2_QOS_MAP_PORT(port));
for (i = 0; i < 8; i++) for (i = 0; i < SF2_NUM_EGRESS_QUEUES; i++)
reg |= i << (PRT_TO_QID_SHIFT * i); reg |= i << (PRT_TO_QID_SHIFT * i);
core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port)); core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
...@@ -1151,6 +1160,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev) ...@@ -1151,6 +1160,9 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
ds = dev->ds; ds = dev->ds;
ds->ops = &bcm_sf2_ops; ds->ops = &bcm_sf2_ops;
/* Advertise the 8 egress queues */
ds->num_tx_queues = SF2_NUM_EGRESS_QUEUES;
dev_set_drvdata(&pdev->dev, priv); dev_set_drvdata(&pdev->dev, priv);
spin_lock_init(&priv->indir_lock); spin_lock_init(&priv->indir_lock);
......
...@@ -401,4 +401,7 @@ enum bcm_sf2_reg_offs { ...@@ -401,4 +401,7 @@ enum bcm_sf2_reg_offs {
#define CFP_NUM_RULES 256 #define CFP_NUM_RULES 256
/* Number of egress queues per port */
#define SF2_NUM_EGRESS_QUEUES 8
#endif /* __BCM_SF2_REGS_H */ #endif /* __BCM_SF2_REGS_H */
...@@ -243,6 +243,9 @@ struct dsa_switch { ...@@ -243,6 +243,9 @@ struct dsa_switch {
/* devlink used to represent this switch device */ /* devlink used to represent this switch device */
struct devlink *devlink; struct devlink *devlink;
/* Number of switch port queues */
unsigned int num_tx_queues;
/* Dynamically allocated ports, keep last */ /* Dynamically allocated ports, keep last */
size_t num_ports; size_t num_ports;
struct dsa_port ports[]; struct dsa_port ports[];
......
...@@ -1259,8 +1259,12 @@ int dsa_slave_create(struct dsa_port *port, const char *name) ...@@ -1259,8 +1259,12 @@ int dsa_slave_create(struct dsa_port *port, const char *name)
cpu_dp = ds->dst->cpu_dp; cpu_dp = ds->dst->cpu_dp;
master = cpu_dp->netdev; master = cpu_dp->netdev;
slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv), name, if (!ds->num_tx_queues)
NET_NAME_UNKNOWN, ether_setup); ds->num_tx_queues = 1;
slave_dev = alloc_netdev_mqs(sizeof(struct dsa_slave_priv), name,
NET_NAME_UNKNOWN, ether_setup,
ds->num_tx_queues, 1);
if (slave_dev == NULL) if (slave_dev == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev) static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
u16 queue = skb_get_queue_mapping(skb);
u8 *brcm_tag; u8 *brcm_tag;
if (skb_cow_head(skb, BRCM_TAG_LEN) < 0) if (skb_cow_head(skb, BRCM_TAG_LEN) < 0)
...@@ -78,7 +79,7 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev ...@@ -78,7 +79,7 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev
* deprecated * deprecated
*/ */
brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) | brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) |
((skb->priority << BRCM_IG_TC_SHIFT) & BRCM_IG_TC_MASK); ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT);
brcm_tag[1] = 0; brcm_tag[1] = 0;
brcm_tag[2] = 0; brcm_tag[2] = 0;
if (p->dp->index == 8) if (p->dp->index == 8)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment