From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:30:48
This series is the final step of a long process of porting 80+ devices
to use the new qca8k driver instead of the hacky qca one based on never
merged swconfig platform.
Some background to justify all these additions.
QCA used a special binding to declare raw initval to set the swich. I
made a script to convert all these magic values and convert 80+ dts and
scan all the needed "unsupported regs". We find a baseline where we
manage to find the common and used regs so in theory hopefully we don't
have to add anymore things.
We discovered lots of things with this, especially about how differently
qca8327 works compared to qca8337.
In short, we found that qca8327 have some problem with suspend/resume for
their internal phy. It instead sets some dedicated regs that suspend the
phy without setting the standard bit. First 4 patch are to fix this.
There is also a patch about preferring master. This is directly from the
original driver and it seems to be needed to prevent some problem with
the pause frame.
Every ipq806x target sets the mac power sel and this specific reg
regulates the output voltage of the regulator. Without this some
instability can occur.
Some configuration (for some reason) swap mac6 with mac0. We add support
for this.
Also, we discovered that some device doesn't work at all with pll enabled
for sgmii line. In the original code this was based on the switch
revision. In later revision the pll regs were decided based on the switch
type (disabled for qca8327 and enabled for qca8337) but still some
device had that disabled in the initval regs.
Considering we found at least one qca8337 device that required pll
disabled to work (no traffic problem) we decided to introduce a binding
to enable pll and set it only with that.
Lastly, we add support for led open drain that require the power-on-sel
to set. Also, some device have only the power-on-sel set in the initval
so we add also support for that. This is needed for the correct function
of the switch leds.
Qca8327 have a special reg in the pws regs that set it to a reduced
48pin layout. This is needed or the switch doesn't work.
These are all the special configuration we find on all these devices that
are from various targets. Mostly ath79, ipq806x and bcm53xx.
Changes v5:
- Swap patch. Document first then implement.
- Fix some grammar error reported.
- Rework function. Remove phylink mac_config DT scan and move everything
to dedicated function in probe.
- Introduce new logic for delay selection where is also supported with
internal delay declared and rgmii set as phy mode
- Start working on ymal conversion. Will later post this in v6 when we
finally take final decision about mac swap.
Changes v4:
- Fix typo in SGMII falling edge about using PHY id instead of
switch id
Changes v3:
- Drop phy patches (proposed separateley)
- Drop special pwr binding. Rework to ipq806x specific
- Better describe compatible and add serial print on switch chip
- Drop mac exchange. Rework falling edge and move it to mac_config
- Add support for port 6 cpu port. Drop hardcoded cpu port to port0
- Improve port stability with sgmii. QCA source have intenal delay also
for sgmii
- Add warning with pll enabled on wrong configuration
Changes v2:
- Reword Documentation patch to dt-bindings
- Propose first 2 phy patch to net
- Better describe and add hint on how to use all the new
bindings
- Rework delay scan function and move to phylink mac_config
- Drop package48 wrong binding
- Introduce support for qca8328 switch
- Fix wrong binding name power-on-sel
- Return error on wrong config with led open drain and
ignore-power-on-sel not set
Ansuel Smith (14):
net: dsa: qca8k: add mac_power_sel support
dt-bindings: net: dsa: qca8k: Add SGMII clock phase properties
net: dsa: qca8k: add support for sgmii falling edge
dt-bindings: net: dsa: qca8k: Document support for CPU port 6
drivers: net: dsa: qca8k: add support for cpu port 6
net: dsa: qca8k: rework rgmii delay logic and scan for cpu port 6
dt-bindings: net: dsa: qca8k: Document qca,sgmii-enable-pll
net: dsa: qca8k: add explicit SGMII PLL enable
dt-bindings: net: dsa: qca8k: Document qca,led-open-drain binding
drivers: net: dsa: qca8k: add support for pws config reg
dt-bindings: net: dsa: qca8k: document support for qca8328
drivers: net: dsa: qca8k: add support for QCA8328
drivers: net: dsa: qca8k: set internal delay also for sgmii
drivers: net: dsa: qca8k: move port config to dedicated struct
.../devicetree/bindings/net/dsa/qca8k.txt | 38 +-
drivers/net/dsa/qca8k.c | 350 ++++++++++++++----
drivers/net/dsa/qca8k.h | 35 +-
3 files changed, 339 insertions(+), 84 deletions(-)
--
2.32.0
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:30:53
Add missing mac power sel support needed for ipq8064/5 SoC that require
1.8v for the internal regulator port instead of the default 1.5v.
If other device needs this, consider adding a dedicated binding to
support this.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
---
drivers/net/dsa/qca8k.c | 31 +++++++++++++++++++++++++++++++
drivers/net/dsa/qca8k.h | 5 +++++
2 files changed, 36 insertions(+)
@@ -950,6 +950,33 @@ qca8k_setup_of_rgmii_delay(struct qca8k_priv *priv)return0;}+staticint+qca8k_setup_mac_pwr_sel(structqca8k_priv*priv)+{+u32mask=0;+intret=0;++/* SoC specific settings for ipq8064.+*Ifmoredevicerequirethisconsideradding+*adedicatedbinding.+*/+if(of_machine_is_compatible("qcom,ipq8064"))+mask|=QCA8K_MAC_PWR_RGMII0_1_8V;++/* SoC specific settings for ipq8065 */+if(of_machine_is_compatible("qcom,ipq8065"))+mask|=QCA8K_MAC_PWR_RGMII1_1_8V;++if(mask){+ret=qca8k_rmw(priv,QCA8K_REG_MAC_PWR_SEL,+QCA8K_MAC_PWR_RGMII0_1_8V|+QCA8K_MAC_PWR_RGMII1_1_8V,+mask);+}++returnret;+}+staticintqca8k_setup(structdsa_switch*ds){
@@ -979,6 +1006,10 @@ qca8k_setup(struct dsa_switch *ds)if(ret)returnret;+ret=qca8k_setup_mac_pwr_sel(priv);+if(ret)+returnret;+/* Enable CPU Port */ret=qca8k_reg_set(priv,QCA8K_REG_GLOBAL_FW_CTRL0,QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:30:55
Add names and descriptions of additional PORT0_PAD_CTRL properties.
qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
phase to failling edge.
Signed-off-by: Matthew Hagan <redacted>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 4 ++++
1 file changed, 4 insertions(+)
@@ -37,6 +37,10 @@ A CPU port node has the following optional node: managed entity. See Documentation/devicetree/bindings/net/fixed-link.txt for details.+- qca,sgmii-rxclk-falling-edge: Set the receive clock phase to falling edge.+ Mostly used in qca8327 with CPU port 0 set to+ sgmii.+- qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge. For QCA8K the 'fixed-link' sub-node supports only the following properties:
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:30:58
Add support for this in the qca8k driver. Also add support for SGMII
rx/tx clock falling edge. This is only present for pad0, pad5 and
pad6 have these bit reserved from Documentation. Add a comment that this
is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
setting falling in port0 applies to both configuration with sgmii used
for port0 or port6.
Signed-off-by: Matthew Hagan <redacted>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 57 +++++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/qca8k.h | 4 +++
2 files changed, 61 insertions(+)
@@ -977,6 +977,36 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)returnret;}+staticint+qca8k_parse_port_config(structqca8k_priv*priv)+{+structdevice_node*port_dn;+phy_interface_tmode;+structdsa_port*dp;+intport;++/* We have 2 CPU port. Check them */+for(port=0;port<QCA8K_NUM_PORTS;port++){+/* Skip every other port */+if(port!=0&&port!=6)+continue;++dp=dsa_to_port(priv->ds,port);+port_dn=dp->dn;++of_get_phy_mode(port_dn,&mode);+if(mode==PHY_INTERFACE_MODE_SGMII){+if(of_property_read_bool(port_dn,"qca,sgmii-txclk-falling-edge"))+priv->sgmii_tx_clk_falling_edge=true;++if(of_property_read_bool(port_dn,"qca,sgmii-rxclk-falling-edge"))+priv->sgmii_rx_clk_falling_edge=true;+}+}++return0;+}+staticintqca8k_setup(structdsa_switch*ds){
@@ -990,6 +1020,11 @@ qca8k_setup(struct dsa_switch *ds)return-EINVAL;}+/* Parse CPU port config to be later used in phy_link mac_config */+ret=qca8k_parse_port_config(priv);+if(ret)+returnret;+mutex_init(&priv->reg_mutex);/* Start by setting up the register mapping */
@@ -1274,6 +1309,28 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,}qca8k_write(priv,QCA8K_REG_SGMII_CTRL,val);++/* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and+*fallingedgeissetwritinginthePORT0PADreg+*/+if(priv->switch_id==QCA8K_ID_QCA8327||+priv->switch_id==QCA8K_ID_QCA8337)+reg=QCA8K_REG_PORT0_PAD_CTRL;++val=0;++/* SGMII Clock phase configuration */+if(priv->sgmii_rx_clk_falling_edge)+val|=QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;++if(priv->sgmii_tx_clk_falling_edge)+val|=QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;++if(val)+ret=qca8k_rmw(priv,reg,+QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE|+QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,+val);break;default:dev_err(ds->dev,"xMII mode %s not supported for port %d\n",
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:00
Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
port. The original intention of this driver seems to be use the
mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
where device have connected only the CPU port 6. To skip the
introduction of a new binding, rework the driver to address the
secondary CPU port as primary and drop any reference of hardcoded port.
With configuration of mac06 exchange, just skip the definition of port0
and define the CPU port as a secondary. The driver will autoconfigure
the switch to use that as the primary CPU port.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 50 +++++++++++++++++++++++++++++------------
drivers/net/dsa/qca8k.h | 2 --
2 files changed, 36 insertions(+), 16 deletions(-)
@@ -977,6 +977,22 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)returnret;}+staticintqca8k_find_cpu_port(structdsa_switch*ds)+{+structqca8k_priv*priv=(structqca8k_priv*)ds->priv;++/* Find the connected cpu port. Valid port are 0 or 6 */+if(dsa_is_cpu_port(ds,0))+return0;++dev_dbg(priv->dev,"port 0 is not the CPU port. Checking port 6");++if(dsa_is_cpu_port(ds,6))+return6;++return-EINVAL;+}+staticintqca8k_parse_port_config(structqca8k_priv*priv){
@@ -1011,13 +1027,14 @@ static intqca8k_setup(structdsa_switch*ds){structqca8k_priv*priv=(structqca8k_priv*)ds->priv;+u8cpu_port;intret,i;u32mask;-/* Make sure that port 0 is the cpu port */-if(!dsa_is_cpu_port(ds,0)){-dev_err(priv->dev,"port 0 is not the CPU port");-return-EINVAL;+cpu_port=qca8k_find_cpu_port(ds);+if(cpu_port<0){+dev_err(priv->dev,"No cpu port configured in both cpu port0 and port6");+returncpu_port;}/* Parse CPU port config to be later used in phy_link mac_config */
@@ -1059,7 +1076,7 @@ qca8k_setup(struct dsa_switch *ds)dev_warn(priv->dev,"mib init failed");/* Enable QCA header mode on the cpu port */-ret=qca8k_write(priv,QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),+ret=qca8k_write(priv,QCA8K_REG_PORT_HDR_CTRL(cpu_port),QCA8K_PORT_HDR_CTRL_ALL<<QCA8K_PORT_HDR_CTRL_TX_S|QCA8K_PORT_HDR_CTRL_ALL<<QCA8K_PORT_HDR_CTRL_RX_S);if(ret){
@@ -1081,10 +1098,10 @@ qca8k_setup(struct dsa_switch *ds)/* Forward all unknown frames to CPU port for Linux processing */ret=qca8k_write(priv,QCA8K_REG_GLOBAL_FW_CTRL1,-BIT(0)<<QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S|-BIT(0)<<QCA8K_GLOBAL_FW_CTRL1_BC_DP_S|-BIT(0)<<QCA8K_GLOBAL_FW_CTRL1_MC_DP_S|-BIT(0)<<QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);+BIT(cpu_port)<<QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S|+BIT(cpu_port)<<QCA8K_GLOBAL_FW_CTRL1_BC_DP_S|+BIT(cpu_port)<<QCA8K_GLOBAL_FW_CTRL1_MC_DP_S|+BIT(cpu_port)<<QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);if(ret)returnret;
@@ -1092,7 +1109,7 @@ qca8k_setup(struct dsa_switch *ds)for(i=0;i<QCA8K_NUM_PORTS;i++){/* CPU port gets connected to all user ports of the switch */if(dsa_is_cpu_port(ds,i)){-ret=qca8k_rmw(priv,QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT),+ret=qca8k_rmw(priv,QCA8K_PORT_LOOKUP_CTRL(cpu_port),QCA8K_PORT_LOOKUP_MEMBER,dsa_user_ports(ds));if(ret)returnret;
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:02
The switch now support CPU port to be set 6 instead of be hardcoded to
0. Document support for it and describe logic selection.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -29,7 +29,11 @@ the mdio MASTER is used as communication. Don't use mixed external and internal mdio-bus configurations, as this is not supported by the hardware.-The CPU port of this switch is always port 0.+This switch support 2 CPU port. Normally and advised configuration is with+CPU port set to port 0. It is also possible to set the CPU port to port 6+if the device requires it. The driver will configure the switch to the defined+port. With both CPU port declared the first CPU port is selected as primary+and the secondary CPU ignored. A CPU port node has the following optional node:
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:07
Document qca,sgmii-enable-pll binding used in the CPU nodes to
enable SGMII PLL on MAC config.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 10 ++++++++++
1 file changed, 10 insertions(+)
@@ -45,6 +45,16 @@ A CPU port node has the following optional node: Mostly used in qca8327 with CPU port 0 set to sgmii. - qca,sgmii-txclk-falling-edge: Set the transmit clock phase to falling edge.+- qca,sgmii-enable-pll : For SGMII CPU port, explicitly enable PLL, TX and RX+ chain along with Signal Detection.+ This should NOT be enabled for qca8327. If enabled with+ qca8327 the sgmii port won't correctly init and an err+ is printed.+ This can be required for qca8337 switch with revision 2.+ A warning is displayed when used with revision greater+ 2.+ With CPU port set to sgmii and qca8337 it is advised+ to set this unless a communication problem is observed. For QCA8K the 'fixed-link' sub-node supports only the following properties:
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:10
Future proof commit. This switch have 2 CPU port and one valid
configuration is first CPU port set to sgmii and second CPU port set to
regmii-id. The current implementation detects delay only for CPU port
zero set to rgmii and doesn't count any delay set in a secondary CPU
port. Drop the current delay scan function and move it to the sgmii
parser function to generilize and implicitly add support for secondary
CPU port set to rgmii-id. Introduce new logic where delay is enabled
also with internal delay binding declared and rgmii set as PHY mode.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 162 ++++++++++++++++++++--------------------
drivers/net/dsa/qca8k.h | 10 ++-
2 files changed, 87 insertions(+), 85 deletions(-)
@@ -888,68 +888,6 @@ qca8k_setup_mdio_bus(struct qca8k_priv *priv)return0;}-staticint-qca8k_setup_of_rgmii_delay(structqca8k_priv*priv)-{-structdevice_node*port_dn;-phy_interface_tmode;-structdsa_port*dp;-u32val;--/* CPU port is already checked */-dp=dsa_to_port(priv->ds,0);--port_dn=dp->dn;--/* Check if port 0 is set to the correct type */-of_get_phy_mode(port_dn,&mode);-if(mode!=PHY_INTERFACE_MODE_RGMII_ID&&-mode!=PHY_INTERFACE_MODE_RGMII_RXID&&-mode!=PHY_INTERFACE_MODE_RGMII_TXID){-return0;-}--switch(mode){-casePHY_INTERFACE_MODE_RGMII_ID:-casePHY_INTERFACE_MODE_RGMII_RXID:-if(of_property_read_u32(port_dn,"rx-internal-delay-ps",&val))-val=2;-else-/* Switch regs accept value in ns, convert ps to ns */-val=val/1000;--if(val>QCA8K_MAX_DELAY){-dev_err(priv->dev,"rgmii rx delay is limited to a max value of 3ns, setting to the max value");-val=3;-}--priv->rgmii_rx_delay=val;-/* Stop here if we need to check only for rx delay */-if(mode!=PHY_INTERFACE_MODE_RGMII_ID)-break;--fallthrough;-casePHY_INTERFACE_MODE_RGMII_TXID:-if(of_property_read_u32(port_dn,"tx-internal-delay-ps",&val))-val=1;-else-/* Switch regs accept value in ns, convert ps to ns */-val=val/1000;--if(val>QCA8K_MAX_DELAY){-dev_err(priv->dev,"rgmii tx delay is limited to a max value of 3ns, setting to the max value");-val=3;-}--priv->rgmii_tx_delay=val;-break;-default:-return0;-}--return0;-}-staticintqca8k_setup_mac_pwr_sel(structqca8k_priv*priv){
@@ -996,10 +934,11 @@ static int qca8k_find_cpu_port(struct dsa_switch *ds)staticintqca8k_parse_port_config(structqca8k_priv*priv){+intport,cpu_port_index=0;structdevice_node*port_dn;phy_interface_tmode;structdsa_port*dp;-intport;+u32delay;/* We have 2 CPU port. Check them */for(port=0;port<QCA8K_NUM_PORTS;port++){
@@ -1009,14 +948,56 @@ qca8k_parse_port_config(struct qca8k_priv *priv)dp=dsa_to_port(priv->ds,port);port_dn=dp->dn;+cpu_port_index++;of_get_phy_mode(port_dn,&mode);-if(mode==PHY_INTERFACE_MODE_SGMII){+switch(mode){+casePHY_INTERFACE_MODE_RGMII:+casePHY_INTERFACE_MODE_RGMII_ID:+casePHY_INTERFACE_MODE_RGMII_TXID:+casePHY_INTERFACE_MODE_RGMII_RXID:+delay=0;++if(!of_property_read_u32(port_dn,"tx-internal-delay-ps",&delay))+/* Switch regs accept value in ns, convert ps to ns */+delay=delay/1000;+elseif(mode==PHY_INTERFACE_MODE_RGMII_ID||+mode==PHY_INTERFACE_MODE_RGMII_TXID)+delay=1;++if(delay>QCA8K_MAX_DELAY){+dev_err(priv->dev,"rgmii tx delay is limited to a max value of 3ns, setting to the max value");+delay=3;+}++priv->rgmii_tx_delay[cpu_port_index]=delay;++delay=0;++if(!of_property_read_u32(port_dn,"rx-internal-delay-ps",&delay))+/* Switch regs accept value in ns, convert ps to ns */+delay=delay/1000;+elseif(mode==PHY_INTERFACE_MODE_RGMII_ID||+mode==PHY_INTERFACE_MODE_RGMII_RXID)+delay=2;++if(delay>QCA8K_MAX_DELAY){+dev_err(priv->dev,"rgmii rx delay is limited to a max value of 3ns, setting to the max value");+delay=3;+}++priv->rgmii_rx_delay[cpu_port_index]=delay;++break;+casePHY_INTERFACE_MODE_SGMII:if(of_property_read_bool(port_dn,"qca,sgmii-txclk-falling-edge"))priv->sgmii_tx_clk_falling_edge=true;if(of_property_read_bool(port_dn,"qca,sgmii-rxclk-falling-edge"))priv->sgmii_rx_clk_falling_edge=true;++break;+default:}}
@@ -1224,8 +1201,8 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,conststructphylink_link_state*state){structqca8k_priv*priv=ds->priv;-u32reg,val;-intret;+intcpu_port_index,ret;+u32reg,val,delay;switch(port){case0:/* 1st CPU port */
@@ -1237,6 +1214,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,return;reg=QCA8K_REG_PORT0_PAD_CTRL;+cpu_port_index=QCA8K_CPU_PORT0;break;case1:case2:
@@ -1255,6 +1233,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,return;reg=QCA8K_REG_PORT6_PAD_CTRL;+cpu_port_index=QCA8K_CPU_PORT6;break;default:dev_err(ds->dev,"%s: unsupported port: %i\n",__func__,port);
@@ -1269,23 +1248,40 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,switch(state->interface){casePHY_INTERFACE_MODE_RGMII:-/* RGMII mode means no delay so don't enable the delay */-qca8k_write(priv,reg,QCA8K_PORT_PAD_RGMII_EN);-break;casePHY_INTERFACE_MODE_RGMII_ID:casePHY_INTERFACE_MODE_RGMII_TXID:casePHY_INTERFACE_MODE_RGMII_RXID:-/* RGMII_ID needs internal delay. This is enabled through-*PORT5_PAD_CTRLforallports,ratherthanindividualport-*registers+val=QCA8K_PORT_PAD_RGMII_EN;++/* Delay can be declared in 3 different way.+*Modetorgmiiandinternal-delaystandardbindingdefined+*rgmii-idorrgmii-tx/rxphymodeset.+*Theparselogicsetadelaydifferentthan0onlywhenone+*ofthe3differentwayisused.Inallothercasedelayis+*notenabled.WithIDorTX/RXIDdelayisenabledandset+*tothedefaultandrecommendedvalue.+*/+if(priv->rgmii_tx_delay[cpu_port_index]){+delay=priv->rgmii_tx_delay[cpu_port_index];++val|=QCA8K_PORT_PAD_RGMII_TX_DELAY(delay)|+QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;+}++if(priv->rgmii_rx_delay[cpu_port_index]){+delay=priv->rgmii_rx_delay[cpu_port_index];++val|=QCA8K_PORT_PAD_RGMII_RX_DELAY(delay)|+QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;+}++/* Set RGMII delay based on the selected values */+qca8k_write(priv,reg,val);++/* QCA8337 requires to set rgmii rx delay for all ports.+*ThisisenabledthroughPORT5_PAD_CTRLforallports,+*ratherthanindividualportregisters.*/-qca8k_write(priv,reg,-QCA8K_PORT_PAD_RGMII_EN|-QCA8K_PORT_PAD_RGMII_TX_DELAY(priv->rgmii_tx_delay)|-QCA8K_PORT_PAD_RGMII_RX_DELAY(priv->rgmii_rx_delay)|-QCA8K_PORT_PAD_RGMII_TX_DELAY_EN|-QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);-/* QCA8337 requires to set rgmii rx delay */if(priv->switch_id==QCA8K_ID_QCA8337)qca8k_write(priv,QCA8K_REG_PORT5_PAD_CTRL,QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:21
Support enabling PLL on the SGMII CPU port. Some device require this
special configuration or no traffic is transmitted and the switch
doesn't work at all. A dedicated binding is added to the CPU node
port to apply the correct reg on mac config.
Fail to correctly configure sgmii with qca8327 switch and warn if pll is
used on qca8337 with a revision greater than 1.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 19 +++++++++++++++++--
drivers/net/dsa/qca8k.h | 1 +
2 files changed, 18 insertions(+), 2 deletions(-)
@@ -996,6 +996,18 @@ qca8k_parse_port_config(struct qca8k_priv *priv)if(of_property_read_bool(port_dn,"qca,sgmii-rxclk-falling-edge"))priv->sgmii_rx_clk_falling_edge=true;+if(of_property_read_bool(port_dn,"qca,sgmii-enable-pll")){+priv->sgmii_enable_pll=true;++if(priv->switch_id==QCA8K_ID_QCA8327){+dev_err(priv->dev,"SGMII PLL should NOT be enabled for qca8327. Aborting enabling");+priv->sgmii_enable_pll=false;+}++if(priv->switch_revision<2)+dev_warn(priv->dev,"SGMII PLL should NOT be enabled for qca8337 with revision 2 or more.");+}+break;default:}
@@ -1306,8 +1318,11 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,if(ret)return;-val|=QCA8K_SGMII_EN_PLL|QCA8K_SGMII_EN_RX|-QCA8K_SGMII_EN_TX|QCA8K_SGMII_EN_SD;+val|=QCA8K_SGMII_EN_SD;++if(priv->sgmii_enable_pll)+val|=QCA8K_SGMII_EN_PLL|QCA8K_SGMII_EN_RX|+QCA8K_SGMII_EN_TX;if(dsa_is_cpu_port(ds,port)){/* CPU port, we're talking to the CPU MAC, be a PHY */
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:21
Document new binding qca,ignore-power-on-sel used to ignore
power on strapping and use sw regs instead.
Document qca,led-open.drain to set led to open drain mode, the
qca,ignore-power-on-sel is mandatory with this enabled or an error will
be reported.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 11 +++++++++++
1 file changed, 11 insertions(+)
@@ -13,6 +13,17 @@ Required properties: Optional properties: - reset-gpios: GPIO to be used to reset the whole device+- qca,ignore-power-on-sel: Ignore power on pin strapping to configure led open+ drain or eeprom presence. This is needed for broken+ devices that have wrong configuration or when the oem+ decided to not use pin strapping and fallback to sw+ regs.+- qca,led-open-drain: Set leds to open-drain mode. This requires the+ qca,ignore-power-on-sel to be set or the driver will fail+ to probe. This is needed if the oem doesn't use pin+ strapping to set this mode and prefers to set it using sw+ regs. The pin strapping related to led open drain mode is+ the pin B68 for QCA832x and B49 for QCA833x Subnodes:
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:28
Some qca8327 switch require to force the ignore of power on sel
strapping. Some switch require to set the led open drain mode in regs
instead of using strapping. While most of the device implements this
using the correct way using pin strapping, there are still some broken
device that require to be set using sw regs.
Introduce a new binding and support these special configuration.
As led open drain require to ignore pin strapping to work, the probe
fails with EINVAL error with incorrect configuration.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 39 +++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/qca8k.h | 6 ++++++
2 files changed, 45 insertions(+)
@@ -931,6 +931,41 @@ static int qca8k_find_cpu_port(struct dsa_switch *ds)return-EINVAL;}+staticint+qca8k_setup_of_pws_reg(structqca8k_priv*priv)+{+structdevice_node*node=priv->dev->of_node;+u32val=0;+intret;++/* QCA8327 require to set to the correct mode.+*HisbiggerbrotherQCA8328havethe172pinlayout.+*Shouldbeappliedbydefaultbutwesetthisjusttomakesure.+*/+if(priv->switch_id==QCA8K_ID_QCA8327){+ret=qca8k_rmw(priv,QCA8K_REG_PWS,QCA8327_PWS_PACKAGE148_EN,+QCA8327_PWS_PACKAGE148_EN);+if(ret)+returnret;+}++if(of_property_read_bool(node,"qca,ignore-power-on-sel"))+val|=QCA8K_PWS_POWER_ON_SEL;++if(of_property_read_bool(node,"qca,led-open-drain")){+if(!(val&QCA8K_PWS_POWER_ON_SEL)){+dev_err(priv->dev,"qca,led-open-drain require qca,ignore-power-on-sel to be set.");+return-EINVAL;+}++val|=QCA8K_PWS_LED_OPEN_EN_CSR;+}++returnqca8k_rmw(priv,QCA8K_REG_PWS,+QCA8K_PWS_LED_OPEN_EN_CSR|QCA8K_PWS_POWER_ON_SEL,+val);+}+staticintqca8k_parse_port_config(structqca8k_priv*priv){
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:42
QCA8328 is the bigger brother of qca8327. Document the new compatible
binding and add some information to understand the various switch
compatible.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:48
QCA8328 switch is the bigger brother of the qca8327. Same regs different
chip. Change the function to set the correct pin layout and introduce a
new match_data to differentiate the 2 switch as they have the same ID
and their internal PHY have the same ID.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 19 ++++++++++++++++---
drivers/net/dsa/qca8k.h | 1 +
2 files changed, 17 insertions(+), 3 deletions(-)
@@ -943,8 +944,14 @@ qca8k_setup_of_pws_reg(struct qca8k_priv *priv)*Shouldbeappliedbydefaultbutwesetthisjusttomakesure.*/if(priv->switch_id==QCA8K_ID_QCA8327){+data=of_device_get_match_data(priv->dev);++/* Set the correct package of 148 pin for QCA8327 */+if(data->reduced_package)+val|=QCA8327_PWS_PACKAGE148_EN;+ret=qca8k_rmw(priv,QCA8K_REG_PWS,QCA8327_PWS_PACKAGE148_EN,-QCA8327_PWS_PACKAGE148_EN);+val);if(ret)returnret;}
@@ -2082,7 +2089,12 @@ static int qca8k_resume(struct device *dev)staticSIMPLE_DEV_PM_OPS(qca8k_pm_ops,qca8k_suspend,qca8k_resume);-staticconststructqca8k_match_dataqca832x={+staticconststructqca8k_match_dataqca8327={+.id=QCA8K_ID_QCA8327,+.reduced_package=true,+};++staticconststructqca8k_match_dataqca8328={.id=QCA8K_ID_QCA8327,};
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 01:31:52
QCA original code report port instability and sa that SGMII also require
to set internal delay. Generalize the rgmii delay function and apply the
advised value if they are not defined in DT.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 81 +++++++++++++++++++++++++++--------------
drivers/net/dsa/qca8k.h | 2 +
2 files changed, 55 insertions(+), 28 deletions(-)
@@ -1254,13 +1253,54 @@ qca8k_setup(struct dsa_switch *ds)return0;}+staticvoid+qca8k_mac_config_setup_internal_delay(structqca8k_priv*priv,intcpu_port_index,+u32reg)+{+u32delay,val=0;+intret;++/* Delay can be declared in 3 different way.+*Modetorgmiiandinternal-delaystandardbindingdefined+*rgmii-idorrgmii-tx/rxphymodeset.+*Theparselogicsetadelaydifferentthan0onlywhenone+*ofthe3differentwayisused.Inallothercasedelayis+*notenabled.WithIDorTX/RXIDdelayisenabledandset+*tothedefaultandrecommendedvalue.+*/+if(priv->rgmii_tx_delay[cpu_port_index]){+delay=priv->rgmii_tx_delay[cpu_port_index];++val|=QCA8K_PORT_PAD_RGMII_TX_DELAY(delay)|+QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;+}++if(priv->rgmii_rx_delay[cpu_port_index]){+delay=priv->rgmii_rx_delay[cpu_port_index];++val|=QCA8K_PORT_PAD_RGMII_RX_DELAY(delay)|+QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;+}++/* Set RGMII delay based on the selected values */+ret=qca8k_rmw(priv,reg,+QCA8K_PORT_PAD_RGMII_TX_DELAY_MASK|+QCA8K_PORT_PAD_RGMII_RX_DELAY_MASK|+QCA8K_PORT_PAD_RGMII_TX_DELAY_EN|+QCA8K_PORT_PAD_RGMII_RX_DELAY_EN,+val);+if(ret)+dev_err(priv->dev,"Failed to set internal delay for CPU port%d",+cpu_port_index==QCA8K_CPU_PORT0?0:6);+}+staticvoidqca8k_phylink_mac_config(structdsa_switch*ds,intport,unsignedintmode,conststructphylink_link_state*state){structqca8k_priv*priv=ds->priv;intcpu_port_index,ret;-u32reg,val,delay;+u32reg,val;switch(port){case0:/* 1st CPU port */
@@ -1309,32 +1349,10 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,casePHY_INTERFACE_MODE_RGMII_ID:casePHY_INTERFACE_MODE_RGMII_TXID:casePHY_INTERFACE_MODE_RGMII_RXID:-val=QCA8K_PORT_PAD_RGMII_EN;--/* Delay can be declared in 3 different way.-*Modetorgmiiandinternal-delaystandardbindingdefined-*rgmii-idorrgmii-tx/rxphymodeset.-*Theparselogicsetadelaydifferentthan0onlywhenone-*ofthe3differentwayisused.Inallothercasedelayis-*notenabled.WithIDorTX/RXIDdelayisenabledandset-*tothedefaultandrecommendedvalue.-*/-if(priv->rgmii_tx_delay[cpu_port_index]){-delay=priv->rgmii_tx_delay[cpu_port_index];--val|=QCA8K_PORT_PAD_RGMII_TX_DELAY(delay)|-QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;-}+qca8k_write(priv,reg,QCA8K_PORT_PAD_RGMII_EN);-if(priv->rgmii_rx_delay[cpu_port_index]){-delay=priv->rgmii_rx_delay[cpu_port_index];--val|=QCA8K_PORT_PAD_RGMII_RX_DELAY(delay)|-QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;-}--/* Set RGMII delay based on the selected values */-qca8k_write(priv,reg,val);+/* Configure rgmii delay */+qca8k_mac_config_setup_internal_delay(priv,cpu_port_index,reg);/* QCA8337 requires to set rgmii rx delay for all ports.*ThisisenabledthroughPORT5_PAD_CTRLforallports,
@@ -1405,6 +1423,13 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE|QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,val);++/* From original code is reported port instability as SGMII also+*requiredelayset.ApplyadvisedvalueshereortakethemfromDT.+*/+if(state->interface==PHY_INTERFACE_MODE_SGMII)+qca8k_mac_config_setup_internal_delay(priv,cpu_port_index,reg);+break;default:dev_err(ds->dev,"xMII mode %s not supported for port %d\n",
@@ -1029,20 +1029,20 @@ qca8k_parse_port_config(struct qca8k_priv *priv)delay=3;}-priv->rgmii_rx_delay[cpu_port_index]=delay;+priv->ports_config.rgmii_rx_delay[cpu_port_index]=delay;if(of_property_read_bool(port_dn,"qca,sgmii-txclk-falling-edge"))-priv->sgmii_tx_clk_falling_edge=true;+priv->ports_config.sgmii_tx_clk_falling_edge=true;if(of_property_read_bool(port_dn,"qca,sgmii-rxclk-falling-edge"))-priv->sgmii_rx_clk_falling_edge=true;+priv->ports_config.sgmii_rx_clk_falling_edge=true;if(of_property_read_bool(port_dn,"qca,sgmii-enable-pll")){-priv->sgmii_enable_pll=true;+priv->ports_config.sgmii_enable_pll=true;if(priv->switch_id==QCA8K_ID_QCA8327){dev_err(priv->dev,"SGMII PLL should NOT be enabled for qca8327. Aborting enabling");-priv->sgmii_enable_pll=false;+priv->ports_config.sgmii_enable_pll=false;}if(priv->switch_revision<2)
@@ -1268,15 +1268,15 @@ qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_inde*notenabled.WithIDorTX/RXIDdelayisenabledandset*tothedefaultandrecommendedvalue.*/-if(priv->rgmii_tx_delay[cpu_port_index]){-delay=priv->rgmii_tx_delay[cpu_port_index];+if(priv->ports_config.rgmii_tx_delay[cpu_port_index]){+delay=priv->ports_config.rgmii_tx_delay[cpu_port_index];val|=QCA8K_PORT_PAD_RGMII_TX_DELAY(delay)|QCA8K_PORT_PAD_RGMII_TX_DELAY_EN;}-if(priv->rgmii_rx_delay[cpu_port_index]){-delay=priv->rgmii_rx_delay[cpu_port_index];+if(priv->ports_config.rgmii_rx_delay[cpu_port_index]){+delay=priv->ports_config.rgmii_rx_delay[cpu_port_index];val|=QCA8K_PORT_PAD_RGMII_RX_DELAY(delay)|QCA8K_PORT_PAD_RGMII_RX_DELAY_EN;
@@ -1384,7 +1384,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,val|=QCA8K_SGMII_EN_SD;-if(priv->sgmii_enable_pll)+if(priv->ports_config.sgmii_enable_pll)val|=QCA8K_SGMII_EN_PLL|QCA8K_SGMII_EN_RX|QCA8K_SGMII_EN_TX;
@@ -1412,10 +1412,10 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,val=0;/* SGMII Clock phase configuration */-if(priv->sgmii_rx_clk_falling_edge)+if(priv->ports_config.sgmii_rx_clk_falling_edge)val|=QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;-if(priv->sgmii_tx_clk_falling_edge)+if(priv->ports_config.sgmii_tx_clk_falling_edge)val|=QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;if(val)
@@ -270,15 +270,19 @@ enum {QCA8K_CPU_PORT6,};-structqca8k_priv{-u8switch_id;-u8switch_revision;+structqca8k_ports_config{boolsgmii_rx_clk_falling_edge;boolsgmii_tx_clk_falling_edge;boolsgmii_enable_pll;u8rgmii_rx_delay[QCA8K_NUM_CPU_PORTS];/* 0: CPU port0, 1: CPU port6 */u8rgmii_tx_delay[QCA8K_NUM_CPU_PORTS];/* 0: CPU port0, 1: CPU port6 */+};++structqca8k_priv{+u8switch_id;+u8switch_revision;boollegacy_phy_port_mapping;+structqca8k_ports_configports_config;structregmap*regmap;structmii_bus*bus;structar8xxx_port_statusport_sts[QCA8K_NUM_PORTS];
Add missing mac power sel support needed for ipq8064/5 SoC that require
1.8v for the internal regulator port instead of the default 1.5v.
If other device needs this, consider adding a dedicated binding to
support this.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Add names and descriptions of additional PORT0_PAD_CTRL properties.
qca,sgmii-(rx|tx)clk-falling-edge are for setting the respective clock
phase to failling edge.
Signed-off-by: Matthew Hagan <redacted>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
This should presumably have Matthew as the Author, so we would see a
heading with:
From: Matthew Hagan <redacted>
--
Florian
Add support for this in the qca8k driver. Also add support for SGMII
rx/tx clock falling edge. This is only present for pad0, pad5 and
pad6 have these bit reserved from Documentation. Add a comment that this
is hardcoded to PAD0 as qca8327/28/34/37 have an unique sgmii line and
setting falling in port0 applies to both configuration with sgmii used
for port0 or port6.
Signed-off-by: Matthew Hagan <redacted>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 57 +++++++++++++++++++++++++++++++++++++++++
drivers/net/dsa/qca8k.h | 4 +++
2 files changed, 61 insertions(+)
@@ -977,6 +977,36 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)returnret;}+staticint+qca8k_parse_port_config(structqca8k_priv*priv)+{+structdevice_node*port_dn;+phy_interface_tmode;+structdsa_port*dp;+intport;++/* We have 2 CPU port. Check them */+for(port=0;port<QCA8K_NUM_PORTS;port++){+/* Skip every other port */+if(port!=0&&port!=6)+continue;++dp=dsa_to_port(priv->ds,port);+port_dn=dp->dn;
You should probably have an:
if (!of_device_is_available(port_dn))
continue
to skip over ports being disabled, which could presumably happen in a
sparsely populated switch for instance.
+
+ of_get_phy_mode(port_dn, &mode);
This function returns an error that you are not checking.
quoted hunk
+ if (mode == PHY_INTERFACE_MODE_SGMII) {
+ if (of_property_read_bool(port_dn, "qca,sgmii-txclk-falling-edge"))
+ priv->sgmii_tx_clk_falling_edge = true;
+
+ if (of_property_read_bool(port_dn, "qca,sgmii-rxclk-falling-edge"))
+ priv->sgmii_rx_clk_falling_edge = true;
+ }
+ }
+
+ return 0;
+}
+
static int
qca8k_setup(struct dsa_switch *ds)
{
@@ -990,6 +1020,11 @@ qca8k_setup(struct dsa_switch *ds) return -EINVAL; }+ /* Parse CPU port config to be later used in phy_link mac_config */+ ret = qca8k_parse_port_config(priv);+ if (ret)+ return ret;+ mutex_init(&priv->reg_mutex); /* Start by setting up the register mapping */
@@ -1274,6 +1309,28 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode, } qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);++ /* For qca8327/qca8328/qca8334/qca8338 sgmii is unique and+ * falling edge is set writing in the PORT0 PAD reg+ */+ if (priv->switch_id == QCA8K_ID_QCA8327 ||+ priv->switch_id == QCA8K_ID_QCA8337)+ reg = QCA8K_REG_PORT0_PAD_CTRL;++ val = 0;++ /* SGMII Clock phase configuration */+ if (priv->sgmii_rx_clk_falling_edge)+ val |= QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE;++ if (priv->sgmii_tx_clk_falling_edge)+ val |= QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE;++ if (val)+ ret = qca8k_rmw(priv, reg,+ QCA8K_PORT0_PAD_SGMII_RXCLK_FALLING_EDGE |+ QCA8K_PORT0_PAD_SGMII_TXCLK_FALLING_EDGE,+ val); break; default: dev_err(ds->dev, "xMII mode %s not supported for port %d\n",
The switch now support CPU port to be set 6 instead of be hardcoded to
0. Document support for it and describe logic selection.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -29,7 +29,11 @@ the mdio MASTER is used as communication. Don't use mixed external and internal mdio-bus configurations, as this is not supported by the hardware.-The CPU port of this switch is always port 0.+This switch support 2 CPU port.
Plural: ports.
Normally and advised configuration is with
+CPU port set to port 0. It is also possible to set the CPU port to port 6
+if the device requires it. The driver will configure the switch to the defined
+port. With both CPU port declared the first CPU port is selected as primary
+and the secondary CPU ignored.
Is this universally supported by all models that this binding covers? If
not, you might want to explain that?
--
Florian
QCA8328 is the bigger brother of qca8327. Document the new compatible
binding and add some information to understand the various switch
compatible.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
For consistency with other patch subjects, drop the "drivers: " prefix.
On 10/10/2021 6:30 PM, Ansuel Smith wrote:
Currently CPU port is always hardcoded to port 0. This switch have 2 CPU
port.
Plural: ports.
The original intention of this driver seems to be use the
quoted hunk
mac06_exchange bit to swap MAC0 with MAC6 in the strange configuration
where device have connected only the CPU port 6. To skip the
introduction of a new binding, rework the driver to address the
secondary CPU port as primary and drop any reference of hardcoded port.
With configuration of mac06 exchange, just skip the definition of port0
and define the CPU port as a secondary. The driver will autoconfigure
the switch to use that as the primary CPU port.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 50 +++++++++++++++++++++++++++++------------
drivers/net/dsa/qca8k.h | 2 --
2 files changed, 36 insertions(+), 16 deletions(-)
For new functions please avoid the cast from void * which is unnecessary.
With those comments addressed:
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
From: Ansuel Smith <ansuelsmth@gmail.com> Date: 2021-10-11 02:03:21
On Sun, Oct 10, 2021 at 06:50:39PM -0700, Florian Fainelli wrote:
On 10/10/2021 6:30 PM, Ansuel Smith wrote:
quoted
The switch now support CPU port to be set 6 instead of be hardcoded to
0. Document support for it and describe logic selection.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
Documentation/devicetree/bindings/net/dsa/qca8k.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
@@ -29,7 +29,11 @@ the mdio MASTER is used as communication. Don't use mixed external and internal mdio-bus configurations, as this is not supported by the hardware.-The CPU port of this switch is always port 0.+This switch support 2 CPU port.
Plural: ports.
quoted
Normally and advised configuration is with
+CPU port set to port 0. It is also possible to set the CPU port to port 6
+if the device requires it. The driver will configure the switch to the defined
+port. With both CPU port declared the first CPU port is selected as primary
+and the secondary CPU ignored.
Is this universally supported by all models that this binding covers? If
not, you might want to explain that?
--
Florian
Yes we tested this and both qca8327 and qca8337 work correctly with cpu
port6 set as primary port. (no cpu0 defined)
If you were referring to double cpu mode. That is the common
configuration with this switch but we currently doesn't support
multi-cpu in DSA.
--
Ansuel
and one valid
configuration is first CPU port set to sgmii and second CPU port set to
regmii-id.
rgmii-id
The current implementation detects delay only for CPU port
zero set to rgmii and doesn't count any delay set in a secondary CPU
port. Drop the current delay scan function and move it to the sgmii
parser function to generilize
generalize
and implicitly add support for secondary
CPU port set to rgmii-id. Introduce new logic where delay is enabled
also with internal delay binding declared and rgmii set as PHY mode.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Nit: please remove the "drivers: " prefix from your v6 and do that
across your entire patch series.
On 10/10/2021 6:30 PM, Ansuel Smith wrote:
QCA8328 switch is the bigger brother of the qca8327. Same regs different
chip. Change the function to set the correct pin layout and introduce a
new match_data to differentiate the 2 switch as they have the same ID
and their internal PHY have the same ID.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
QCA original code report port instability and sa that SGMII also require
to set internal delay. Generalize the rgmii delay function and apply the
advised value if they are not defined in DT.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 81 +++++++++++++++++++++++++++--------------
drivers/net/dsa/qca8k.h | 2 +
2 files changed, 55 insertions(+), 28 deletions(-)
This also makes the RGMII* ports parse the couple of sgmii properties
introduced earlier, but since these properties are only acted on for
PHY_INTERFACE_MODE_SGMII in the .mac_config, I suppose that is fine.
--
Florian
Future proof commit. This switch have 2 CPU port and one valid
configuration is first CPU port set to sgmii and second CPU port set to
regmii-id. The current implementation detects delay only for CPU port
zero set to rgmii and doesn't count any delay set in a secondary CPU
port. Drop the current delay scan function and move it to the sgmii
parser function to generilize and implicitly add support for secondary
CPU port set to rgmii-id. Introduce new logic where delay is enabled
also with internal delay binding declared and rgmii set as PHY mode.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
quoted hunk
/* We have 2 CPU port. Check them */
for (port = 0; port < QCA8K_NUM_PORTS; port++) {
Support enabling PLL on the SGMII CPU port. Some device require this
special configuration or no traffic is transmitted and the switch
doesn't work at all. A dedicated binding is added to the CPU node
port to apply the correct reg on mac config.
Fail to correctly configure sgmii with qca8327 switch and warn if pll is
used on qca8337 with a revision greater than 1.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Move ports related config to dedicated struct to keep things organized.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
I wonder if this should not be done ahead of patches 3 and 5 so you just
add the new members there directly, up to you really.
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
Some qca8327 switch require to force the ignore of power on sel
strapping. Some switch require to set the led open drain mode in regs
instead of using strapping. While most of the device implements this
using the correct way using pin strapping, there are still some broken
device that require to be set using sw regs.
Introduce a new binding and support these special configuration.
As led open drain require to ignore pin strapping to work, the probe
fails with EINVAL error with incorrect configuration.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
int ret, i;
u32 mask;
- /* Make sure that port 0 is the cpu port */
- if (!dsa_is_cpu_port(ds, 0)) {
- dev_err(priv->dev, "port 0 is not the CPU port");
- return -EINVAL;
+ cpu_port = qca8k_find_cpu_port(ds);
+ if (cpu_port < 0) {
+ dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
+ return cpu_port;
}