Message ID | 625ef961b7fd7bda4f92180afce299fc9c887e77.1489661229.git.jpinto@synopsys.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
On 03/16/2017 03:56 AM, Joao Pinto wrote: > This patch adds the configuration of RX queues' routing. > > Signed-off-by: Joao Pinto <jpinto@synopsys.com> > --- > Documentation/devicetree/bindings/net/stmmac.txt | 19 ++++++- > drivers/net/ethernet/stmicro/stmmac/common.h | 9 ++++ > drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 18 +++++++ > drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 63 ++++++++++++++++++++++ > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++++ > drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 +++ > .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 49 +++++++++++++++++ > include/linux/stmmac.h | 12 +++++ > 8 files changed, 202 insertions(+), 1 deletion(-) > > diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt > index b9a9ae9..9c9e774 100644 > --- a/Documentation/devicetree/bindings/net/stmmac.txt > +++ b/Documentation/devicetree/bindings/net/stmmac.txt > @@ -84,6 +84,16 @@ Optional properties: > - snps,avb-algorithm: Queue to be enabled as AVB > - snps,map-to-dma-channel: Channel to map > - snps,priority: RX queue priority > + - Specifiy RX Queue for processing certain types of packets: > + - snps,avcp-to-queue: AV Untagged Control packets > + - snps,ptp-to-queue: PTP Packets > + - snps,dcbcp-to-queue: DCB Control Packets > + - snps,up-to-queue: Untagged Packets > + - snps,multi-broad-cast-queue: Multicast & Broadcast Packets > + - snps,tpqc-queue: Tagged PTPoE Packets Queuing Control. Values: > + 0x0 - Priority based (RX queues non-AV) > + 0x1 - Routes to queue indicated in "snps,ptp-to-queue" > + 0x2 - Priority based (RX queues AV enabled) > - Multiple TX Queues parameters: below the list of all the parameters to > configure the multiple TX queues: > - snps,tx-queues-to-use: number of TX queues to be used in the driver You are allowing a policy to be defined with Device Tree here which is usually frowned upon. Can you look into existing facilities offered by tc offloads, e.g: mqprio etc. to allow users to dynamically configure the queue mappings at runtime? > @@ -112,8 +122,15 @@ Examples: > }; > > mtl_rx_setup: rx-queues-config { > - snps,rx-queues-to-use = <1>; > + snps,rx-queues-to-use = <0>; > snps,rx-sched-sp; > + snps,avcp-to-queue = <0>; > + snps,ptp-to-queue = <0>; > + snps,dcbcp-to-queue = <0>; > + snps,up-to-queue = <0>; > + snps,multi-broad-cast-queue = <0>; > + snps,tpqc-queue = <0>; > + > queue0 { > snps,dcb-algorithm; > snps,map-to-dma-channel = <0x0>; > diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h > index e0b31e7..e08c4c4 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/common.h > +++ b/drivers/net/ethernet/stmicro/stmmac/common.h > @@ -473,6 +473,15 @@ struct stmmac_ops { > void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue); > /* TX Queues Priority */ > void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue); > + /* RX Queues Routing */ > + void (*rx_queue_routing)(struct mac_device_info *hw, > + bool route_avcp_enable, u8 route_avcp_queue, > + bool route_ptp_enable, u8 route_ptp_queue, > + bool route_dcbcp_enable, u8 route_dcbcp_queue, > + bool route_up_enable, u8 route_up_queue, > + bool route_multi_broad_enable, > + u8 route_multi_broad_queue, > + bool route_tpqc_enable, u8 route_tpqc_queue); > /* Program RX Algorithms */ > void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); > /* Program TX Algorithms */ > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h > index a6c382d..93cc3f6 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h > @@ -44,6 +44,24 @@ > #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8) > #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) > > +/* RX Queues Routing */ > +#define GMAC_RXQCTRL_AVCPQ_MASK GENMASK(2, 0) > +#define GMAC_RXQCTRL_AVCPQ_SHIFT 0 > +#define GMAC_RXQCTRL_PTPQ_MASK GENMASK(6, 4) > +#define GMAC_RXQCTRL_PTPQ_SHIFT 4 > +#define GMAC_RXQCTRL_DCBCPQ_MASK GENMASK(10, 8) > +#define GMAC_RXQCTRL_DCBCPQ_SHIFT 8 > +#define GMAC_RXQCTRL_UPQ_MASK GENMASK(14, 12) > +#define GMAC_RXQCTRL_UPQ_SHIFT 12 > +#define GMAC_RXQCTRL_MCBCQ_MASK GENMASK(18, 16) > +#define GMAC_RXQCTRL_MCBCQ_SHIFT 16 > +#define GMAC_RXQCTRL_MCBCQEN BIT(20) > +#define GMAC_RXQCTRL_MCBCQEN_SHIFT 20 > +#define GMAC_RXQCTRL_TACPQE BIT(21) > +#define GMAC_RXQCTRL_TACPQE_SHIFT 21 > +#define GMAC_RXQCTRL_TPQC_MASK GENMASK(24, 22) > +#define GMAC_RXQCTRL_TPQC_SHIFT 22 > + > /* MAC Packet Filtering */ > #define GMAC_PACKET_FILTER_PR BIT(0) > #define GMAC_PACKET_FILTER_HMC BIT(2) > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c > index 342f62a..8fc1f56 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c > @@ -109,6 +109,68 @@ static void dwmac4_tx_queue_priority(struct mac_device_info *hw, > writel(value, ioaddr + base_register); > } > > +static void dwmac4_tx_queue_routing(struct mac_device_info *hw, > + bool route_avcp_enable, > + u8 route_avcp_queue, > + bool route_ptp_enable, > + u8 route_ptp_queue, > + bool route_dcbcp_enable, > + u8 route_dcbcp_queue, > + bool route_up_enable, > + u8 route_up_queue, > + bool route_multi_broad_enable, > + u8 route_multi_broad_queue, > + bool route_tpqc_enable, > + u8 route_tpqc_queue) > +{ This is not looking good at all 13 parameters passed here... thankfully this is not called in a hot path. So here is what I would suggest: - put the bool, u8, and masks, shifts, offsets parameters in a structure, define an array of structures holding these variables in your driver's private context, index them with an enumeration for each queue - pass a reference to this structure here, and iterate over the array of structures and do the programming based on what this structure contains for MASK, SHIFT, base register etc... > + void __iomem *ioaddr = hw->pcsr; > + u32 value; > + > + value = readl(ioaddr + GMAC_RXQ_CTRL1); > + > static int quark_default_data(struct plat_stmmacenet_data *plat, > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > index 77b0468..5e82379 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c > @@ -165,6 +165,55 @@ static void stmmac_mtl_setup(struct platform_device *pdev, > else > plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; > > + /* RX routing configuration */ > + if (of_property_read_u8(rx_node, "snps,avcp-to-queue", > + &plat->route_avcp_queue)) { > + plat->route_avcp_queue = 0; > + plat->route_avcp_enable = false; > + } else { > + plat->route_avcp_enable = true; > + } This is very redundant too, see the suggestion above, define an array of property names and look them up in a loop using the queue enumeration. > + > + if (of_property_read_u8(rx_node, "snps,ptp-to-queue", > + &plat->route_ptp_queue)) { > + plat->route_ptp_queue = 0; > + plat->route_ptp_enable = false; > + } else { > + plat->route_ptp_enable = true; > + } > + > + if (of_property_read_u8(rx_node, "snps,dcbcp-to-queue", > + &plat->route_dcbcp_queue)) { > + plat->route_dcbcp_queue = 0; > + plat->route_dcbcp_enable = false; > + } else { > + plat->route_dcbcp_enable = true; > + } > + > + if (of_property_read_u8(rx_node, "snps,up-to-queue", > + &plat->route_up_queue)) { > + plat->route_up_queue = 0; > + plat->route_up_enable = false; > + } else { > + plat->route_up_enable = true; > + } > + > + if (of_property_read_u8(rx_node, "snps,multi-broad-cast-queue", > + &plat->route_multi_broad_queue)) { > + plat->route_multi_broad_queue = 0; > + plat->route_multi_broad_enable = false; > + } else { > + plat->route_multi_broad_enable = true; > + } > + > + if (of_property_read_u8(rx_node, "snps,tpqc-queue", > + &plat->route_tpqc_queue)) { > + plat->route_tpqc_queue = 0; > + plat->route_tpqc_enable = false; > + } else { > + plat->route_tpqc_enable = true; > + } > + > /* Processing individual RX queue config */ > for_each_child_of_node(rx_node, q_node) { > if (queue >= plat->rx_queues_to_use) > diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h > index b7d5e7a..8f5ebf5 100644 > --- a/include/linux/stmmac.h > +++ b/include/linux/stmmac.h > @@ -171,6 +171,18 @@ struct plat_stmmacenet_data { > u8 tx_queues_to_use; > u8 rx_sched_algorithm; > u8 tx_sched_algorithm; > + bool route_avcp_enable; > + u8 route_avcp_queue; > + bool route_ptp_enable; > + u8 route_ptp_queue; > + bool route_dcbcp_enable; > + u8 route_dcbcp_queue; > + bool route_up_enable; > + u8 route_up_queue; > + bool route_multi_broad_enable; > + u8 route_multi_broad_queue; > + bool route_tpqc_enable; > + u8 route_tpqc_queue; Same here, this absolutely does not scale. > struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES]; > struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES]; > void (*fix_mac_speed)(void *priv, unsigned int speed); >
Às 5:12 PM de 3/16/2017, Florian Fainelli escreveu: > On 03/16/2017 03:56 AM, Joao Pinto wrote: >> This patch adds the configuration of RX queues' routing. >> >> Signed-off-by: Joao Pinto <jpinto@synopsys.com> >> --- >> Documentation/devicetree/bindings/net/stmmac.txt | 19 ++++++- >> drivers/net/ethernet/stmicro/stmmac/common.h | 9 ++++ >> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 18 +++++++ >> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 63 ++++++++++++++++++++++ >> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++++ >> drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 +++ >> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 49 +++++++++++++++++ >> include/linux/stmmac.h | 12 +++++ >> 8 files changed, 202 insertions(+), 1 deletion(-) >> >> diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt >> index b9a9ae9..9c9e774 100644 >> --- a/Documentation/devicetree/bindings/net/stmmac.txt >> +++ b/Documentation/devicetree/bindings/net/stmmac.txt >> @@ -84,6 +84,16 @@ Optional properties: >> - snps,avb-algorithm: Queue to be enabled as AVB >> - snps,map-to-dma-channel: Channel to map >> - snps,priority: RX queue priority >> + - Specifiy RX Queue for processing certain types of packets: >> + - snps,avcp-to-queue: AV Untagged Control packets >> + - snps,ptp-to-queue: PTP Packets >> + - snps,dcbcp-to-queue: DCB Control Packets >> + - snps,up-to-queue: Untagged Packets >> + - snps,multi-broad-cast-queue: Multicast & Broadcast Packets >> + - snps,tpqc-queue: Tagged PTPoE Packets Queuing Control. Values: >> + 0x0 - Priority based (RX queues non-AV) >> + 0x1 - Routes to queue indicated in "snps,ptp-to-queue" >> + 0x2 - Priority based (RX queues AV enabled) >> - Multiple TX Queues parameters: below the list of all the parameters to >> configure the multiple TX queues: >> - snps,tx-queues-to-use: number of TX queues to be used in the driver > > You are allowing a policy to be defined with Device Tree here which is > usually frowned upon. Can you look into existing facilities offered by > tc offloads, e.g: mqprio etc. to allow users to dynamically configure > the queue mappings at runtime? We are planning also to have these configurable in runtime by a standard tool like ethtool, but I think we should have the DT possibility also. Makes sense for you? > >> @@ -112,8 +122,15 @@ Examples: >> }; >> >> mtl_rx_setup: rx-queues-config { >> - snps,rx-queues-to-use = <1>; >> + snps,rx-queues-to-use = <0>; >> snps,rx-sched-sp; >> + snps,avcp-to-queue = <0>; >> + snps,ptp-to-queue = <0>; >> + snps,dcbcp-to-queue = <0>; >> + snps,up-to-queue = <0>; >> + snps,multi-broad-cast-queue = <0>; >> + snps,tpqc-queue = <0>; >> + >> queue0 { >> snps,dcb-algorithm; >> snps,map-to-dma-channel = <0x0>; >> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h >> index e0b31e7..e08c4c4 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/common.h >> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h >> @@ -473,6 +473,15 @@ struct stmmac_ops { >> void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue); >> /* TX Queues Priority */ >> void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue); >> + /* RX Queues Routing */ >> + void (*rx_queue_routing)(struct mac_device_info *hw, >> + bool route_avcp_enable, u8 route_avcp_queue, >> + bool route_ptp_enable, u8 route_ptp_queue, >> + bool route_dcbcp_enable, u8 route_dcbcp_queue, >> + bool route_up_enable, u8 route_up_queue, >> + bool route_multi_broad_enable, >> + u8 route_multi_broad_queue, >> + bool route_tpqc_enable, u8 route_tpqc_queue); >> /* Program RX Algorithms */ >> void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); >> /* Program TX Algorithms */ >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >> index a6c382d..93cc3f6 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h >> @@ -44,6 +44,24 @@ >> #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8) >> #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) >> >> +/* RX Queues Routing */ >> +#define GMAC_RXQCTRL_AVCPQ_MASK GENMASK(2, 0) >> +#define GMAC_RXQCTRL_AVCPQ_SHIFT 0 >> +#define GMAC_RXQCTRL_PTPQ_MASK GENMASK(6, 4) >> +#define GMAC_RXQCTRL_PTPQ_SHIFT 4 >> +#define GMAC_RXQCTRL_DCBCPQ_MASK GENMASK(10, 8) >> +#define GMAC_RXQCTRL_DCBCPQ_SHIFT 8 >> +#define GMAC_RXQCTRL_UPQ_MASK GENMASK(14, 12) >> +#define GMAC_RXQCTRL_UPQ_SHIFT 12 >> +#define GMAC_RXQCTRL_MCBCQ_MASK GENMASK(18, 16) >> +#define GMAC_RXQCTRL_MCBCQ_SHIFT 16 >> +#define GMAC_RXQCTRL_MCBCQEN BIT(20) >> +#define GMAC_RXQCTRL_MCBCQEN_SHIFT 20 >> +#define GMAC_RXQCTRL_TACPQE BIT(21) >> +#define GMAC_RXQCTRL_TACPQE_SHIFT 21 >> +#define GMAC_RXQCTRL_TPQC_MASK GENMASK(24, 22) >> +#define GMAC_RXQCTRL_TPQC_SHIFT 22 >> + >> /* MAC Packet Filtering */ >> #define GMAC_PACKET_FILTER_PR BIT(0) >> #define GMAC_PACKET_FILTER_HMC BIT(2) >> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >> index 342f62a..8fc1f56 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c >> @@ -109,6 +109,68 @@ static void dwmac4_tx_queue_priority(struct mac_device_info *hw, >> writel(value, ioaddr + base_register); >> } >> >> +static void dwmac4_tx_queue_routing(struct mac_device_info *hw, >> + bool route_avcp_enable, >> + u8 route_avcp_queue, >> + bool route_ptp_enable, >> + u8 route_ptp_queue, >> + bool route_dcbcp_enable, >> + u8 route_dcbcp_queue, >> + bool route_up_enable, >> + u8 route_up_queue, >> + bool route_multi_broad_enable, >> + u8 route_multi_broad_queue, >> + bool route_tpqc_enable, >> + u8 route_tpqc_queue) >> +{ > > This is not looking good at all 13 parameters passed here... thankfully > this is not called in a hot path. > > So here is what I would suggest: > > - put the bool, u8, and masks, shifts, offsets parameters in a > structure, define an array of structures holding these variables in your > driver's private context, index them with an enumeration for each queue > > - pass a reference to this structure here, and iterate over the array of > structures and do the programming based on what this structure contains > for MASK, SHIFT, base register etc... Good suggestion, I will follow that, thanks. > >> + void __iomem *ioaddr = hw->pcsr; >> + u32 value; >> + >> + value = readl(ioaddr + GMAC_RXQ_CTRL1); >> + > >> static int quark_default_data(struct plat_stmmacenet_data *plat, >> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c >> index 77b0468..5e82379 100644 >> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c >> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c >> @@ -165,6 +165,55 @@ static void stmmac_mtl_setup(struct platform_device *pdev, >> else >> plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; >> >> + /* RX routing configuration */ >> + if (of_property_read_u8(rx_node, "snps,avcp-to-queue", >> + &plat->route_avcp_queue)) { >> + plat->route_avcp_queue = 0; >> + plat->route_avcp_enable = false; >> + } else { >> + plat->route_avcp_enable = true; >> + } > > This is very redundant too, see the suggestion above, define an array of > property names and look them up in a loop using the queue enumeration. > >> + >> + if (of_property_read_u8(rx_node, "snps,ptp-to-queue", >> + &plat->route_ptp_queue)) { >> + plat->route_ptp_queue = 0; >> + plat->route_ptp_enable = false; >> + } else { >> + plat->route_ptp_enable = true; >> + } >> + >> + if (of_property_read_u8(rx_node, "snps,dcbcp-to-queue", >> + &plat->route_dcbcp_queue)) { >> + plat->route_dcbcp_queue = 0; >> + plat->route_dcbcp_enable = false; >> + } else { >> + plat->route_dcbcp_enable = true; >> + } >> + >> + if (of_property_read_u8(rx_node, "snps,up-to-queue", >> + &plat->route_up_queue)) { >> + plat->route_up_queue = 0; >> + plat->route_up_enable = false; >> + } else { >> + plat->route_up_enable = true; >> + } >> + >> + if (of_property_read_u8(rx_node, "snps,multi-broad-cast-queue", >> + &plat->route_multi_broad_queue)) { >> + plat->route_multi_broad_queue = 0; >> + plat->route_multi_broad_enable = false; >> + } else { >> + plat->route_multi_broad_enable = true; >> + } >> + >> + if (of_property_read_u8(rx_node, "snps,tpqc-queue", >> + &plat->route_tpqc_queue)) { >> + plat->route_tpqc_queue = 0; >> + plat->route_tpqc_enable = false; >> + } else { >> + plat->route_tpqc_enable = true; >> + } >> + >> /* Processing individual RX queue config */ >> for_each_child_of_node(rx_node, q_node) { >> if (queue >= plat->rx_queues_to_use) >> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h >> index b7d5e7a..8f5ebf5 100644 >> --- a/include/linux/stmmac.h >> +++ b/include/linux/stmmac.h >> @@ -171,6 +171,18 @@ struct plat_stmmacenet_data { >> u8 tx_queues_to_use; >> u8 rx_sched_algorithm; >> u8 tx_sched_algorithm; >> + bool route_avcp_enable; >> + u8 route_avcp_queue; >> + bool route_ptp_enable; >> + u8 route_ptp_queue; >> + bool route_dcbcp_enable; >> + u8 route_dcbcp_queue; >> + bool route_up_enable; >> + u8 route_up_queue; >> + bool route_multi_broad_enable; >> + u8 route_multi_broad_queue; >> + bool route_tpqc_enable; >> + u8 route_tpqc_queue; > > Same here, this absolutely does not scale. > >> struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES]; >> struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES]; >> void (*fix_mac_speed)(void *priv, unsigned int speed); >> > >
diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index b9a9ae9..9c9e774 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -84,6 +84,16 @@ Optional properties: - snps,avb-algorithm: Queue to be enabled as AVB - snps,map-to-dma-channel: Channel to map - snps,priority: RX queue priority + - Specifiy RX Queue for processing certain types of packets: + - snps,avcp-to-queue: AV Untagged Control packets + - snps,ptp-to-queue: PTP Packets + - snps,dcbcp-to-queue: DCB Control Packets + - snps,up-to-queue: Untagged Packets + - snps,multi-broad-cast-queue: Multicast & Broadcast Packets + - snps,tpqc-queue: Tagged PTPoE Packets Queuing Control. Values: + 0x0 - Priority based (RX queues non-AV) + 0x1 - Routes to queue indicated in "snps,ptp-to-queue" + 0x2 - Priority based (RX queues AV enabled) - Multiple TX Queues parameters: below the list of all the parameters to configure the multiple TX queues: - snps,tx-queues-to-use: number of TX queues to be used in the driver @@ -112,8 +122,15 @@ Examples: }; mtl_rx_setup: rx-queues-config { - snps,rx-queues-to-use = <1>; + snps,rx-queues-to-use = <0>; snps,rx-sched-sp; + snps,avcp-to-queue = <0>; + snps,ptp-to-queue = <0>; + snps,dcbcp-to-queue = <0>; + snps,up-to-queue = <0>; + snps,multi-broad-cast-queue = <0>; + snps,tpqc-queue = <0>; + queue0 { snps,dcb-algorithm; snps,map-to-dma-channel = <0x0>; diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index e0b31e7..e08c4c4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -473,6 +473,15 @@ struct stmmac_ops { void (*rx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue); /* TX Queues Priority */ void (*tx_queue_prio)(struct mac_device_info *hw, u32 prio, u32 queue); + /* RX Queues Routing */ + void (*rx_queue_routing)(struct mac_device_info *hw, + bool route_avcp_enable, u8 route_avcp_queue, + bool route_ptp_enable, u8 route_ptp_queue, + bool route_dcbcp_enable, u8 route_dcbcp_queue, + bool route_up_enable, u8 route_up_queue, + bool route_multi_broad_enable, + u8 route_multi_broad_queue, + bool route_tpqc_enable, u8 route_tpqc_queue); /* Program RX Algorithms */ void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg); /* Program TX Algorithms */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index a6c382d..93cc3f6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -44,6 +44,24 @@ #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8) #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) +/* RX Queues Routing */ +#define GMAC_RXQCTRL_AVCPQ_MASK GENMASK(2, 0) +#define GMAC_RXQCTRL_AVCPQ_SHIFT 0 +#define GMAC_RXQCTRL_PTPQ_MASK GENMASK(6, 4) +#define GMAC_RXQCTRL_PTPQ_SHIFT 4 +#define GMAC_RXQCTRL_DCBCPQ_MASK GENMASK(10, 8) +#define GMAC_RXQCTRL_DCBCPQ_SHIFT 8 +#define GMAC_RXQCTRL_UPQ_MASK GENMASK(14, 12) +#define GMAC_RXQCTRL_UPQ_SHIFT 12 +#define GMAC_RXQCTRL_MCBCQ_MASK GENMASK(18, 16) +#define GMAC_RXQCTRL_MCBCQ_SHIFT 16 +#define GMAC_RXQCTRL_MCBCQEN BIT(20) +#define GMAC_RXQCTRL_MCBCQEN_SHIFT 20 +#define GMAC_RXQCTRL_TACPQE BIT(21) +#define GMAC_RXQCTRL_TACPQE_SHIFT 21 +#define GMAC_RXQCTRL_TPQC_MASK GENMASK(24, 22) +#define GMAC_RXQCTRL_TPQC_SHIFT 22 + /* MAC Packet Filtering */ #define GMAC_PACKET_FILTER_PR BIT(0) #define GMAC_PACKET_FILTER_HMC BIT(2) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 342f62a..8fc1f56 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -109,6 +109,68 @@ static void dwmac4_tx_queue_priority(struct mac_device_info *hw, writel(value, ioaddr + base_register); } +static void dwmac4_tx_queue_routing(struct mac_device_info *hw, + bool route_avcp_enable, + u8 route_avcp_queue, + bool route_ptp_enable, + u8 route_ptp_queue, + bool route_dcbcp_enable, + u8 route_dcbcp_queue, + bool route_up_enable, + u8 route_up_queue, + bool route_multi_broad_enable, + u8 route_multi_broad_queue, + bool route_tpqc_enable, + u8 route_tpqc_queue) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value; + + value = readl(ioaddr + GMAC_RXQ_CTRL1); + + if (route_avcp_enable) { + value &= ~GMAC_RXQCTRL_AVCPQ_MASK; + value |= (route_avcp_queue << GMAC_RXQCTRL_AVCPQ_SHIFT) & + GMAC_RXQCTRL_AVCPQ_MASK; + value &= ~GMAC_RXQCTRL_TACPQE; + value |= 0x1 << GMAC_RXQCTRL_TACPQE_SHIFT; + } + + if (route_ptp_enable) { + value &= ~GMAC_RXQCTRL_PTPQ_MASK; + value |= (route_ptp_queue << GMAC_RXQCTRL_PTPQ_SHIFT) & + GMAC_RXQCTRL_PTPQ_MASK; + } + + if (route_dcbcp_enable) { + value &= ~GMAC_RXQCTRL_DCBCPQ_MASK; + value |= (route_dcbcp_queue << GMAC_RXQCTRL_DCBCPQ_SHIFT) & + GMAC_RXQCTRL_DCBCPQ_MASK; + } + + if (route_up_enable) { + value &= ~GMAC_RXQCTRL_UPQ_MASK; + value |= (route_up_queue << GMAC_RXQCTRL_UPQ_SHIFT) & + GMAC_RXQCTRL_UPQ_MASK; + } + + if (route_multi_broad_enable) { + value &= ~GMAC_RXQCTRL_MCBCQ_MASK; + value |= (route_multi_broad_queue << GMAC_RXQCTRL_MCBCQ_SHIFT) & + GMAC_RXQCTRL_MCBCQ_MASK; + value &= ~GMAC_RXQCTRL_MCBCQEN; + value |= 0x1 << GMAC_RXQCTRL_MCBCQEN_SHIFT; + } + + if (route_tpqc_enable) { + value &= ~GMAC_RXQCTRL_TPQC_MASK; + value |= (route_tpqc_queue << GMAC_RXQCTRL_TPQC_SHIFT) & + GMAC_RXQCTRL_TPQC_MASK; + } + + writel(value, ioaddr + GMAC_RXQ_CTRL1); +} + static void dwmac4_prog_mtl_rx_algorithms(struct mac_device_info *hw, u32 rx_alg) { @@ -640,6 +702,7 @@ static const struct stmmac_ops dwmac4_ops = { .rx_queue_enable = dwmac4_rx_queue_enable, .rx_queue_prio = dwmac4_rx_queue_priority, .tx_queue_prio = dwmac4_tx_queue_priority, + .rx_queue_routing = dwmac4_tx_queue_routing, .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms, .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms, .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 0f2c0d7..07c8ad1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2333,6 +2333,27 @@ static void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv) } /** + * stmmac_mac_config_rx_queues_routing - Configure RX Queue Routing + * @priv: driver private structure + * Description: It is used for configuring the RX queue routing + */ +static void stmmac_mac_config_rx_queues_routing(struct stmmac_priv *priv) +{ + priv->hw->mac->rx_queue_routing(priv->hw, priv->plat->route_avcp_enable, + priv->plat->route_avcp_queue, + priv->plat->route_ptp_enable, + priv->plat->route_ptp_queue, + priv->plat->route_dcbcp_enable, + priv->plat->route_dcbcp_queue, + priv->plat->route_up_enable, + priv->plat->route_up_queue, + priv->plat->route_multi_broad_enable, + priv->plat->route_multi_broad_queue, + priv->plat->route_tpqc_enable, + priv->plat->route_tpqc_queue); +} + +/** * stmmac_mtl_configuration - Configure MTL * @priv: driver private structure * Description: It is used for configurring MTL @@ -2377,6 +2398,10 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv) /* Set TX priorities */ if (tx_queues_count > 1 && priv->hw->mac->tx_queue_prio) stmmac_mac_config_tx_queues_prio(priv); + + /* Set RX routing */ + if (rx_queues_count > 1 && priv->hw->mac->rx_queue_routing) + stmmac_mac_config_rx_queues_routing(priv); } /** diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index ffe4fac..119ff0c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -96,6 +96,14 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat) /* Disable Priority config by default */ plat->tx_queues_cfg[0].use_prio = false; plat->rx_queues_cfg[0].use_prio = false; + + /* Disable RX queues routing by default */ + plat->route_avcp_enable = false; + plat->route_ptp_enable = false; + plat->route_dcbcp_enable = false; + plat->route_up_enable = false; + plat->route_multi_broad_enable = false; + plat->route_tpqc_enable = false; } static int quark_default_data(struct plat_stmmacenet_data *plat, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 77b0468..5e82379 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -165,6 +165,55 @@ static void stmmac_mtl_setup(struct platform_device *pdev, else plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP; + /* RX routing configuration */ + if (of_property_read_u8(rx_node, "snps,avcp-to-queue", + &plat->route_avcp_queue)) { + plat->route_avcp_queue = 0; + plat->route_avcp_enable = false; + } else { + plat->route_avcp_enable = true; + } + + if (of_property_read_u8(rx_node, "snps,ptp-to-queue", + &plat->route_ptp_queue)) { + plat->route_ptp_queue = 0; + plat->route_ptp_enable = false; + } else { + plat->route_ptp_enable = true; + } + + if (of_property_read_u8(rx_node, "snps,dcbcp-to-queue", + &plat->route_dcbcp_queue)) { + plat->route_dcbcp_queue = 0; + plat->route_dcbcp_enable = false; + } else { + plat->route_dcbcp_enable = true; + } + + if (of_property_read_u8(rx_node, "snps,up-to-queue", + &plat->route_up_queue)) { + plat->route_up_queue = 0; + plat->route_up_enable = false; + } else { + plat->route_up_enable = true; + } + + if (of_property_read_u8(rx_node, "snps,multi-broad-cast-queue", + &plat->route_multi_broad_queue)) { + plat->route_multi_broad_queue = 0; + plat->route_multi_broad_enable = false; + } else { + plat->route_multi_broad_enable = true; + } + + if (of_property_read_u8(rx_node, "snps,tpqc-queue", + &plat->route_tpqc_queue)) { + plat->route_tpqc_queue = 0; + plat->route_tpqc_enable = false; + } else { + plat->route_tpqc_enable = true; + } + /* Processing individual RX queue config */ for_each_child_of_node(rx_node, q_node) { if (queue >= plat->rx_queues_to_use) diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index b7d5e7a..8f5ebf5 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -171,6 +171,18 @@ struct plat_stmmacenet_data { u8 tx_queues_to_use; u8 rx_sched_algorithm; u8 tx_sched_algorithm; + bool route_avcp_enable; + u8 route_avcp_queue; + bool route_ptp_enable; + u8 route_ptp_queue; + bool route_dcbcp_enable; + u8 route_dcbcp_queue; + bool route_up_enable; + u8 route_up_queue; + bool route_multi_broad_enable; + u8 route_multi_broad_queue; + bool route_tpqc_enable; + u8 route_tpqc_queue; struct stmmac_rxq_cfg rx_queues_cfg[MTL_MAX_RX_QUEUES]; struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES]; void (*fix_mac_speed)(void *priv, unsigned int speed);
This patch adds the configuration of RX queues' routing. Signed-off-by: Joao Pinto <jpinto@synopsys.com> --- Documentation/devicetree/bindings/net/stmmac.txt | 19 ++++++- drivers/net/ethernet/stmicro/stmmac/common.h | 9 ++++ drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 18 +++++++ drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 63 ++++++++++++++++++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++++ drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 8 +++ .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 49 +++++++++++++++++ include/linux/stmmac.h | 12 +++++ 8 files changed, 202 insertions(+), 1 deletion(-)