Both RTL930x and RTL931x were missing the code to support enabling and
disabling MAC address learning and unknown unicast flooding on a per-port
basis.
* rtl93*x_enable_learning() allows toggling of dynamic MAC learning on
individual ports by modifying the L2 learning constraint control
register.
* rtl93*x_enable_flood() provides the ability to control unknown unicast
flooding behavior, disabling forwarding when set. If it is enabled, it
will just forward it. If it is disabled, packets will simply be dropped.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19581
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Each MBR ctrl block has 64 bits to store the 56 possible ports. The offsets
between the groups is therefore also 64 bit.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19574
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The comment incorrectly stated that RTL931X doesn't have smi_poll_ctrl. But
there is actually a register for using it.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19574
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Some of the parameters added to RTL9300_FAMILY_ID are missing for
RTL9310_FAMILY_ID. Simply add the missing ones to keep sharing code between
the two SoCs.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19574
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
* In RTL931x, bit 31 of the (4th column) of 802_1Q_VLAN_QINQ table
indicates the validity of l2 tunnel. Before bit 63 (3rd column)
was being checked for validity of l2 tunnel.
* The untagged_ports requires 64 bits to represent 56 ports. Do not
store u64 in u32 variable
* First 24 ports are represented in the 2nd register not just first 20
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19576
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The workqueue items don't need to be processed directly when they are
scheduled. It can happen that they are simply processed at a much later
time. It is therefore necessary to ensure that all workqueue items of a
driver are no longer being processed before the driver (or structures of
this driver) are destroyed.
When skipping this step, the driver driver can cause a kernel Oops on
reboot.
Unfortunately, it is not recommended [1] to flush items out of the system
workqueue - simply because this can cause deadlocks. The driver itself must
have a private workqueue which is then flushed.
[1] https://lkml.kernel.org/r/49925af7-78a8-a3dd-bce6-cfc02e1a9236@I-love.SAKURA.ne.jp
Signed-off-by: Issam Hamdi <ih@simonwunderlich.de>
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19570
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Just like rtl930x, rtl931x also requires two reads to fetch current link
status.
While at it, rename the function to a proper naming scheme.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Co-developed-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Co-developed-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19578
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Link status needs to be read twice, and a single register value is
enough for determining link status for all the ports
It is not necessary to go through each potential port separately and later
actually identify for which ports the interrupt actually was. The helper
for_each_set_bit() directly iterate through all set bits.
While at it, rename the function to a proper naming scheme.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Co-developed-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19578
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Currently the SerDes driven SFP ports give strange ethtool readings
on RTL93xx devices. Especially duplex and speed are shown even if
no link is up and running. That leads to confusion because the MAC
reports arbitrary values.
Enhance the readout by refactoring the pcs_get_state() function.
Calculate speed/duplex/pause only if link is detected.
Suggested-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19575
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The media_sts register only shows type of link, fiber/copper,
and has nothing to do with the link status
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19575
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
We are slowly getting to the point where the mdio driver will be
carved out from the ethernet driver. Since the beginning it had
the feature to hand out SFP serdes as phys. So one can access
them from the phy driver. This will be kept during the final
migration and it even will provide a consistent interface for the
phy/serdes registers.
With this being done we need to identify how to handle the affected
ports in a generic way for all targets. Doing first things first,
this starts with a consistent DTS. Currently we have:
for RTL838x + Zyxel XGS1210:
phy-mode = "1000base-x"
managed = "in-band-status"
phy-handle = ...
for all other RTL93x devices:
phy-mode = "10gbase-r"
managed = "in-band-status"
pseudo-phy-handle = ...
Looking at the phylink kernel code one can see a nifty detail.
There is dynamic phy bringup depending on the mode.
int phylink_fwnode_phy_connect(struct phylink *pl,
const struct fwnode_handle *fwnode,
u32 flags)
{
struct fwnode_handle *phy_fwnode;
struct phy_device *phy_dev;
int ret;
/* Fixed links and 802.3z are handled without needing a PHY */
if (pl->cfg_link_an_mode == MLO_AN_FIXED ||
(pl->cfg_link_an_mode == MLO_AN_INBAND &&
phy_interface_mode_is_8023z(pl->link_interface)))
return 0;
...
}
Where 802.3z means 1000base-x or 2500base-x. Aligning this with
IEEE specs it means essentially:
- 10gbase-r defined ports with phy-handle must statically bring up
a phylink from the beginning that immediately depends on a
phy read_status() implementation.
- 1000base-x/2500base-x defined ports will dynamically bringup a
phylink during link detection regardless of a phy-handle. So
it usually runs at the moment when a SFP has been plugged in.
We currently still rely on a phy-handle but do not want to bring
up the phy immediately. Commit 4457c1eee4 ("realtek: rtl93xx:
support SFPs with phys") tried to fix exactly that error for
10gbase-r definied ports. Kernel shows "sfp sfp-p8: sfp_add_phy
failed: -EBUSY" in that case.
But it did it in the wrong way. It implemented a workaround by
introducing a DTS property "pseudo-phy-handle". Instead it
should have simply converted the DTS nodes to 1000base-x.
Revert the commit and fix the DTS with wrong definitions. From
now on we have a consistent SFP definition throughout all DTS
and targets.
Aside from the positive effect this setting has it is more or
less an arbitrary speed definition. When plugging in the SFP the
real speed will be choosen dynamically.
Fixes: 4457c1eee4 ("realtek: rtl93xx: support SFPs with phys")
Tested-By: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19648
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Move the definitions to mach-rtl83xx.h, so they can be used during init
to read more detailed SoC information. Also rename the RTL931X register,
as it has the same address on all RTL93xx.
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/19653
Signed-off-by: Robert Marko <robimarko@gmail.com>
The migration of the RTL930x mdio/serdes access functions over to the
mdio bus is a little more complicated than for RTL83xx. There are several
places where the serdes is accessed directly. So do it in two steps. With
this first step:
- use the rtmdio prefix for the serdes reader/writer functions
- move the functions over to the bus (inside the ethernet driver)
- Adapt all callers.
This is not only a copy/paste but the serdes access will be hardened too.
For this:
- put a mutex around the read/write functions because we have only
indirect register access through a mdio style bus.
- Verify input values to avoid data mess.
Tested-by: Bjørn Mork <bjorn@mork.no>
Tested-by: Jan Hoffmann <jan@3e8.eu>
Tested-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19662
Signed-off-by: Robert Marko <robimarko@gmail.com>
The RTL839x mdio functions are scattered around the code. Relocate
them to the bus (still inside the ethernet driver).
Additionally provide a consistent SerDes register access through the
mdio bus. Until now when a SerDes directly drives a SFP module there
is no clear rule of how to handle its register set that consists of
two parts:
- c22 phy registers 0-15 live in the fiber page (2) of the SerDes
- other SerDes specific registers exist in pages before and after
The mdio bus and other SerDes functions are a wild mix of directly
looking into page 2 or just using self defined methods to access
data.
Adapt the bus to the new consistent phy interface that mixes the
SerDes register set like classic Realtek phys do it.
- Use register 31 as page select (already in the bus)
- Always keep the common registers 0-15 in place and read fiber page
- Map the SerDes internal registers into the upper vendor specific
registers 16-23 according to the page select register (31).
That gives a register mapping as follows:
+-----------------------+-----------------------+---------------+-------------+
| reg 0x00-0x0f | reg 0x10-0x17 | reg 0x18-0x1e | reg 0x1f |
+-----------------------+-----------------------+---------------+-------------+
| SerDes fiber page (3) | real SerDes registers | zero | SerDes page |
| registers 0 - 15 | in packages of 8 | | select reg |
+-----------------------+-----------------------+---------------+-------------+
Example to make it as clear as possible.
SerDes registers on a RTL839x show
Page / Reg | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B ...
-------------+----------------------------------------------------------------
0 - SDS | 0C03 0F00 7060 7106 074D 0EBF 0F0F 0359 5248 0000 0F80 0000 ...
1 - SDS_EXT | 0000 0000 85FA 8C6D 5CCC 0000 20D8 0003 79AA 8C64 00C3 1482 ...
2 - FIB | 1140 6189 001C CA40 01A0 0000 0000 0004 0000 0000 0000 0000 ...
3 - FIB_EXT | 1140 6109 001C CA40 01A0 0000 0000 0004 0000 0000 0000 0000 ...
This translates to this phy layout
| SerDes fiber registers normal SerDes registers zero p.sel
Page / Reg | 0x00 0x01 0x02 0x03 ... 0x10 0x11 0x12 0x13 ... 0x18 ... 0x1f
-------------+---------------------------------------------------------------
0 | 1140 6189 001C CA40 ... 0C03 0F00 7060 7106 ... 0000 ... 0000
1 | 1140 6189 001C CA40 ... 5248 0000 0F80 0000 ... 0000 ... 0001
...
4 | 1140 6189 001C CA40 ... 0000 0000 85FA 8C6D ... 0000 ... 0004
...
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19634
Signed-off-by: Robert Marko <robimarko@gmail.com>
When a SerDes directly drives a SFP module there is no clear rule of
how to handle its register set that consists of two parts:
- c22 phy registers 0-15 live in the fiber page (2) of the SerDes
- other SerDes specific registers exist in pages before and after
The mdio bus and other SerDes functions are a wild mix of directly
looking into page 2 or just using self defined methods to access
data.
Provide a consistent phy interface that mixes the SerDes register
set like classic Realtek phys do it.
- Use register 31 as page select (already in the bus)
- Always keep the common registers 0-15 in place and read fiber page
- Map the SerDes internal registers into the upper vendor specific
registers 16-23 according to the page select register (31).
That gives a register mapping as follows:
+-----------------------+-----------------------+---------------+-------------+
| reg 0x00-0x0f | reg 0x10-0x17 | reg 0x18-0x1e | reg 0x1f |
+-----------------------+-----------------------+---------------+-------------+
| SerDes fiber page (3) | real SerDes registers | zero | SerDes page |
| registers 0 - 15 | in packages of 8 | | select reg |
+-----------------------+-----------------------+---------------+-------------+
Example to make it as clear as possible.
SerDes registers on a RTL838x show
Page / Reg | 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B ...
-------------+----------------------------------------------------------------
0 - SDS | 0C03 0F00 7060 7106 074D 0EBF 0F0F 0359 5248 0000 0F80 0000 ...
1 - SDS_EXT | 0000 0000 85FA 8C6D 5CCC 0000 20D8 0003 79AA 8C64 00C3 1482 ...
2 - FIB | 1140 6189 001C CA40 01A0 0000 0000 0004 0000 0000 0000 0000 ...
3 - FIB_EXT | 1140 6109 001C CA40 01A0 0000 0000 0004 0000 0000 0000 0000 ...
This translates to this phy layout
| SerDes fiber registers normal SerDes registers zero p.sel
Page / Reg | 0x00 0x01 0x02 0x03 ... 0x10 0x11 0x12 0x13 ... 0x18 ... 0x1f
-------------+---------------------------------------------------------------
0 | 1140 6189 001C CA40 ... 0C03 0F00 7060 7106 ... 0000 ... 0000
1 | 1140 6189 001C CA40 ... 5248 0000 0F80 0000 ... 0000 ... 0001
...
4 | 1140 6189 001C CA40 ... 0000 0000 85FA 8C6D ... 0000 ... 0004
For now just do it for RTL838x devices.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19604
Signed-off-by: Robert Marko <robimarko@gmail.com>
The DSA has a link to the MDIO bus and already uses the read/write functions
that are provided. In parallel the dsa_switch_ops structure provides an
interface for phy_read and phy_write. These are still open-coded and sadly
circumvent the bus. Simplify the implementation and avoid inconsistencies by
reusing the existing bus infrastructure.
Additionally, remove two unused MMD header definitions as a quick win.
Reported-by: Jan Hoffmann <jan@3e8.eu>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19548
Signed-off-by: Robert Marko <robimarko@gmail.com>
The function rtl93xx_setup() is called by both RTL930x and RTL931x. But
only the RTL930x specific function to print port matrix was called.
Unfortuntaly, RTL931x needs a different function to access the correct
registers to retrieve the port matrix information.
It is therefore necessary differentiate in rtl93xx_setup between the
SoC families before calling the appropriate function.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19572
Signed-off-by: Robert Marko <robimarko@gmail.com>
The RTL931x has 56 (0-55) non-CPU ports. To receive updates about the port
state, it is therefore necessary to enable the interrupts for all these
ports.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19572
Signed-off-by: Robert Marko <robimarko@gmail.com>
* traffic isolation tables are different between rtl930x and rtl931x
* traffic_enable/disable/get/set functions span multiple columns in the
rtl931x as a result, previous implementation would only enable traffic
in some ports.
traffic_enable/disable and traffic_set/get should now work on all ports and
not just the initial 32
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19572
Signed-off-by: Robert Marko <robimarko@gmail.com>
During PHY matching, the SMI polling must be disabled to avoid conflicts
during the complex detection routine. Only after this finished, SMI polling
is allowed again.
This was implemented for all realtek families besides RTL931x.
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19603
Signed-off-by: Robert Marko <robimarko@gmail.com>
A RTL930x function to read the value from an SDS register must not used on
an RTL931x SoC. Doing it with rtl930x_read_sds_phy() would corrupt the
written results when only parts of the bits are written.
Fixes: 7026084066 ("realtek: Add SDS configuration routines for the RTL93XX platforms")
Signed-off-by: Harshal Gohel <hg@simonwunderlich.de>
Signed-off-by: Sharadanand Karanjkar <sk@simonwunderlich.de>
Link: https://github.com/openwrt/openwrt/pull/19603
Signed-off-by: Robert Marko <robimarko@gmail.com>
Maintain 64 bit counters by polling the hardware counters and adding up
the differences. Polling needs to happen just often enough to catch
every single overflow.
As we now have non-overflowing counters now, we can safely calculate
composite counters without getting weird results on overflow. Use this
to follow RFC 3635 more accurately by mapping the hardware counters to
the proper counters, while taking into account hardware quirks as best
as possible.
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/18415
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
By default, the network interface stats are based on software counters,
which only consider traffic from and to the CPU. Implementing the
get_stats64 method allows to report the full hardware counters instead.
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/18415
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The kernel offers several alternatives to get_ethtool_stats which allow
to report some stats in a more structured way. Use them where possible.
Ideally, we should follow RFC 3635 to translate the hardware counters to
the supported frame and octet counters. However, this is not feasible,
as some of the counters are 32-bit only (so it would produce incorrect
results as soon as one of them overflows).
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/18415
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The MIB registers contain different stats depending on the SoC, and for
RTL930x some stats are in an additional register.
Create separate MIB descs for each SoC to implement this. Also make
reading 64-bit counters more robust, by protecting against an overflow
of the lower 32 bits during the read.
RTL931x remains unsupported, because it uses a table and thus requires
a separate implementation.
While we are at it, rename structs/functions to use the rtldsa prefix.
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/18415
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The mdio bus functions are still split between ethernet and dsa driver.
Before moving everthing out to a separate mdio driver we decided to
collect everything in the ethernet driver with the rtmdio prefix.
Take over the remaining RTL838x functions.
Remark: This is more or less a copy/paste with function renaming. As
there are still some consumers in the DSA driver the definitions and
inclusions must be flipped.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19484
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Currently the SerDes driven SFP ports give strange ethtool readings
on RTL83xx devices. Especially duplex and speed are shown even if
no link is up and running. That leads to confusion because the MAC
reports arbitrary values.
Enhance the readout by refactoring the pcs_get_state() function.
Calculate speed/duplex/pause only if link is detected. Additionally
add reporting of 10G for SFP+ on RTL839x.
ethtool for empty SFP cage before/after
root@OpenWrt:~# ethtool lan9
Settings for lan9:
Supported ports: [ MII ]
Supported link modes: 1000baseT/Full
1000baseKX/Full
1000baseX/Full
1000baseT1/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 1000baseT/Full
1000baseKX/Full
1000baseX/Full
1000baseT1/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: 10Mb/s
Duplex: Half
Port: MII
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Link detected: no
root@OpenWrt:~# ethtool lan9
Settings for lan9:
Supported ports: [ MII ]
Supported link modes: 1000baseT/Full
1000baseKX/Full
1000baseX/Full
1000baseT1/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 1000baseT/Full
1000baseKX/Full
1000baseX/Full
1000baseT1/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: Unknown!
Duplex: Unknown! (255)
Port: MII
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Link detected: no
ethtool with inserted but NOT connected 1G module before/after
root@OpenWrt:~# ethtool lan9
Settings for lan9:
Supported ports: [ FIBRE ]
Supported link modes: 1000baseX/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 1000baseX/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: 1000Mb/s
Duplex: Full
Port: FIBRE
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Link detected: no
root@OpenWrt:~# ethtool lan9
Settings for lan9:
Supported ports: [ FIBRE ]
Supported link modes: 1000baseX/Full
Supported pause frame use: Symmetric Receive-only
Supports auto-negotiation: Yes
Supported FEC modes: Not reported
Advertised link modes: 1000baseX/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Advertised FEC modes: Not reported
Speed: Unknown!
Duplex: Unknown! (255)
Port: FIBRE
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: d
Wake-on: d
Link detected: no
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19524
Signed-off-by: Robert Marko <robimarko@gmail.com>
The SerDes setup function needs to be called to make 2500Base-X work.
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Link: https://github.com/openwrt/openwrt/pull/19517
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
On some devices (like ZyXEL GS1920) the phys are not initialized and patched
by the bootloader. This is done through the vendor SDK when the software
starts. To make these devices usable too, provide the most basic setup
sequence for the RTL8218B.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19491
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The driver currently uses two checks to verify the capabilities. These
are ..._phylink_get_caps() and ..._pcs_validate(). For RTL930x these
must allow 2.5G modes. Enhance that as follows:
Add 2500BASEX to phylink_get_caps(). Sort the interfaces alphabetically
and rename the function to the new prefix. IMPORTANT REMARK! Until now
this function allowed the XGMII mode (10G only parallel interface) that
was somehow mixed with the Realtek proprietary mode XSGMII (10G SGMII).
Remove it to avoid further confusion.
Looking upstream pcs_validate() is used less and less. There are only
2 consumers left in 6.16 and the calling location reads:
/* Validate the link parameters with the PCS */
if (pcs->ops->pcs_validate) {
ret = pcs->ops->pcs_validate(pcs, supported, state);
if (ret < 0 || phylink_is_empty_linkmode(supported))
return -EINVAL;
/* Ensure the advertising mask is a subset of the
* supported mask.
*/
linkmode_and(state->advertising, state->advertising,
supported);
}
There is no need for this additional check. Drop the functions.
Tested-by: Jan Hoffmann <jan@3e8.eu>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19429
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
RTL83xx devices have two types of receive interrupts for each of its
8 rings. One for packet received and another for ring overflow. When
the switch is flooded with incoming packets the receive handler will
disable the packet receive notification but still keeps the overflow
notification enabled. While the receive path "slowly" processes the
received packets each new packet triggers the overflow IRQ again. The
device becomes unresponsive and eventually produces messages like:
[18441.709764] rcu: Stack dump where RCU GP kthread last ran:
[18441.727892] Sending NMI from CPU 1 to CPUs 0:
[18441.742300] NMI backtrace for cpu 0 skipped: idling at 0x8080e994
[18415.251700] rcu: INFO: rcu_sched detected stalls on CPUs/tasks:
[18415.271350] rcu: 0-...!: (0 ticks this GP) idle=d740/0/0x0 ...
[18415.303046] rcu: (detected by 1, t=6004 jiffies, g=230925, ...
[18415.326095] Sending NMI from CPU 1 to CPUs 0:
[18415.340540] NMI backtrace for cpu 0
Fix this issue by always disabling receive and overflow interrupts at
the same time.
Test with hping3 --udp -p 5021 -d 1400 --flood 192.168.2.72
Before (3sec run):
[183260.324846] rtl838x-eth 1b00a300.ethernet eth0: RX buffer overrun: status 0x101, mask: 0x7ffeff
[183260.340524] rtl838x-eth 1b00a300.ethernet eth0: RX buffer overrun: status 0x1, mask: 0x7ffeff
[183260.345799] net_ratelimit: 489997 callbacks suppressed
After (3 sec run):
[ 373.981479] rtl838x-eth 1b00a300.ethernet eth0: rx ring overrun: status 0x101, mask: 0x7fffff
[ 374.031118] rtl838x-eth 1b00a300.ethernet eth0: rx ring overrun: status 0x101, mask: 0x7fffff
[ 377.919996] net_ratelimit: 34 callbacks suppressed
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19365
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The current implementation has several issues:
- it uses the hacky phy_port* macros
- it uses SoC dependent raw pages
- it disables/enables SoC dependent polling
Get rid of these dependencies and access the mdio bus the normal way.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19372
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
In rtl931x_led_init, the number of leds per port is not properly set. It
currently uses a hardcoded value of 1 which seems to be taken initially
from a specific device. This hardcoded value assumes any port always has
exactly two leds.
The RTL930x variant - rtl930x_led_init - does a better job at this. So
take it and use it for RTL931x too with the corresponding register.
While at it, rename the function to a proper naming scheme.
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/19241
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The operating mode of a SerDes must be aligned with the attached PHY or
SFP module. That does not only require to change the protocol (e.g. SGMII,
10Gbase-R, ...) but also the speed (e.g. 1.25G). For this the SerDes must
be re-initialized properly.
- It must be taken into power down
- The PLL speed must be set
- Maybe the CMU (clock management unit) must be resetted
- The new mode must be set
- The state machine must be resetted
- The power must be reactivated
Until now this sequence is bugged. First the driver relies on a clean
setup from U-Boot (rtk network on) and second trying to to change mode
and PLL speeds does not work at all. And not to forget: Currently two
adjacent SerDes cannot drive SGMII/HSGMII at the same time. Fix this by
taking care about the right SerDes/PLL/CMU command init order.
P.S. This code is inspired by the work of Jan Hofmann, who tried to
enable parallel SGMII/HSGMII mode. The only missing bit was a proper CMU
reset sequence.
Signed-off-by: Jan Hoffmann <jan@3e8.eu>
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19220
Signed-off-by: Robert Marko <robimarko@gmail.com>
During setup the mdio driver decides the polling mode of the 4 smi
busses depending on the DTS phy settings. This works as follows:
- set polling to c45 if at least one phy is ethernet-phy-ieee802.3-c45
- set polling to c22 if all phys are ethernet-phy-ieee802.3-c22
On RTL930x it is not possible to switch to c22 if uboot has set c45
before. Fix this by overwriting the bitfield properly. While we are
here:
- Sort variables according to kernel style (inverse christmas tree)
- Initialize fields properly with = { 0 }
- Use GENMASK() for better readability
- Make use of RTMDIO_MAX_SMI_BUS
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/19161
Signed-off-by: Robert Marko <robimarko@gmail.com>
Three different code paths for the same phy model. Now the bus
is prepared to handle c45 (mmd) read/writes correctly. Remove
the custom implementations and let generic kernel functions do
their best. To achieve this
- disable the PHY-mode EEE in rtl821x_config_init() as upstream does
- provide mmd read/write functions that avoid EEE via c45 over c22
While chaning the phy_driver functions sort them alphabetically.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
rtl8214fc_media_is_fibre() will need to be run when bus lock is held.
Split the function into two versions.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
As the mdio bus has been hardened and can now handle c45 requests
the DSA driver must honor that as well. For this
- add proper upstreamed bus read_c45 and write_c45 functions
- take over the disabled port mask from upstream bus
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
With the follow up EEE patches the mdio bus will run c22 and c45
accesses during initial scan. Especially when accessing addresses
beyond the CPU port phy requests might fail in a way that cannot
be handled gratefully. Do two things
- do not allow access to addresses starting from cpu port
- set the scan disable bitmask to ports starting from cpu port
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
If mmd and normal phy ops are issued the bus is lost because
of wrong park page settings. Force it to 0x1f as in GPL.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
The new kernel has relocated the definition of struct platform_device.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
The DSA driver uses set_mac_eee() for the outside API while
the interal helper is called port_eee_set(). Align that.
Additionally do not call the internal helpers directly by
the function names but use the register assignments.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
Upstream will get rid of the get_mac_eee() function in the DSA
driver and replace it by a boolean alternative. While we fill a
lot of data here (because of EEE bugs in the Realtek phy layer)
other DSA drivers only return if EEE is available or not for a
port. To make the next kernel upgrade easier follow that design.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
The validate function no longer exists in phylink_mac_ops. Remove
it for the internal ethernet interface. Instead provide some
meaningful mac capabilities.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
Not only the link but also the mac capabilities are needed here.
Additionally do some alphabetical sorting.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
The old upstream notation has been changed to something not so racist.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
EEE functions are now called with ethtool_keee instead of
ethtool_eee. Replace all occurrences. This will fix function
signature checks but still produces compilation errors due
to structure changes.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>
Automatically generated commit.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Link: https://github.com/openwrt/openwrt/pull/18935
Signed-off-by: Robert Marko <robimarko@gmail.com>