* RE: [PATCH v2 1/1] tipc: fix double-free in tipc_buf_append()
From: Tung Quang Nguyen @ 2026-04-22 8:47 UTC (permalink / raw)
To: Lee Jones
Cc: tipc-discussion@lists.sourceforge.net, Jon Maloy, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, Ying Xue,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260421124528.162996-1-lee@kernel.org>
>Subject: [PATCH v2 1/1] tipc: fix double-free in tipc_buf_append()
>
>tipc_msg_validate() can potentially reallocate the skb it is validating, freeing
>the old one. In tipc_buf_append(), it was being called with a pointer to a local
>variable which was a copy of the caller's skb pointer.
>
>If the skb was reallocated and validation subsequently failed, the error
>handling path would free the original skb pointer, which had already been
>freed, leading to double-free.
>
>Fix this by checking if head now points to a newly allocated reassembled skb.
>If it does, reassign *headbuf for later freeing operations.
>
>Fixes: d618d09a68e4 ("tipc: enforce valid ratio between skb truesize and
>contents")
>Suggested-by: Tung Nguyen <tung.quang.nguyen@est.tech>
>Signed-off-by: Lee Jones <lee@kernel.org>
>---
>1v => v2: Keep the passed pointer type the same, but reassign on-change
>
> net/tipc/msg.c | 14 +++++++++++++-
> 1 file changed, 13 insertions(+), 1 deletion(-)
>
>diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 76284fc538eb..b0bba0feef56
>100644
>--- a/net/tipc/msg.c
>+++ b/net/tipc/msg.c
>@@ -177,8 +177,20 @@ int tipc_buf_append(struct sk_buff **headbuf, struct
>sk_buff **buf)
>
> if (fragid == LAST_FRAGMENT) {
> TIPC_SKB_CB(head)->validated = 0;
>- if (unlikely(!tipc_msg_validate(&head)))
>+
>+ /* If the reassembled skb has been freed in
>+ * tipc_msg_validate() because of an invalid truesize,
>+ * then head will point to a newly allocated reassembled
>+ * skb, while *headbuf points to freed reassembled skb.
>+ * In such cases, correct *headbuf for freeing the newly
>+ * allocated reassembled skb later.
>+ */
>+ if (unlikely(!tipc_msg_validate(&head))) {
>+ if (head != *headbuf)
>+ *headbuf = head;
> goto err;
>+ }
>+
> *buf = head;
> TIPC_SKB_CB(head)->tail = NULL;
> *headbuf = NULL;
>--
>2.54.0.rc1.555.g9c883467ad-goog
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
^ permalink raw reply
* Re: [PATCH] net/stmmac: Fix typos: 'tx_undeflow_irq' -> 'tx_underflow_irq'
From: Jakub Raczynski @ 2026-04-22 8:42 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, linux-kernel, kuba, davem, andrew+netdev, kernel-janitors,
linux-arm-kernel, linux-stm32
In-Reply-To: <7eb9e4d4-909c-4203-833d-bd8b664fdfbc@lunn.ch>
[-- Attachment #1: Type: text/plain, Size: 963 bytes --]
On Tue, Apr 21, 2026 at 02:39:15PM +0200, Andrew Lunn wrote:
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
> > @@ -78,7 +78,7 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
> > STMMAC_STAT(rx_vlan),
> > STMMAC_STAT(rx_split_hdr_pkt_n),
> > /* Tx/Rx IRQ error info */
> > - STMMAC_STAT(tx_undeflow_irq),
> > + STMMAC_STAT(tx_underflow_irq),
>
> Please take another look at this one and think about it.
>
> Andrew
>
> ---
> pw-bot: cr
>
I don't see anything wrong with it?
- naming is correct, same as stmmac_extra_stats from common.h, as it
wouldn't compile otherwise
- string length is ok, as max name length is ETH_GSTRING_LEN=32 and it is
not close
- ethtool just polls data from driver and in my tests it is ok
- all instances of 'undeflow' are changed
- 'underflow' semantic is ok, 'undeflow' is just not correct
Please correct me if I am wrong, but imo no issues with this patch.
Regards
Jakub Raczynski
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: [PATCH iwl-net v2] igc: fix potential skb leak in igc_fpe_xmit_smd_frame()
From: Abdul Rahim, Faizal @ 2026-04-22 8:38 UTC (permalink / raw)
To: Kohei Enju, intel-wired-lan, netdev
Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, kohei.enju, stable
In-Reply-To: <20260415025226.114115-1-kohei@enjuk.jp>
On 15/4/2026 10:52 am, Kohei Enju wrote:
> When igc_fpe_init_tx_descriptor() fails, no one takes care of an
> allocated skb, leaking it. [1]
> Use dev_kfree_skb_any() on failure.
>
> Tested on an I226 adapter with the following command, while injecting
> faults in igc_fpe_init_tx_descriptor() to trigger the error path.
> # ethtool --set-mm $DEV verify-enabled on tx-enabled on pmac-enabled on
>
> [1]
> unreferenced object 0xffff888113c6cdc0 (size 224):
> ...
> backtrace (crc be3d3fda):
> kmem_cache_alloc_node_noprof+0x3b1/0x410
> __alloc_skb+0xde/0x830
> igc_fpe_xmit_smd_frame.isra.0+0xad/0x1b0
> igc_fpe_send_mpacket+0x37/0x90
> ethtool_mmsv_verify_timer+0x15e/0x300
>
> Cc: stable@vger.kernel.org
> Fixes: 5422570c0010 ("igc: add support for frame preemption verification")
> Signed-off-by: Kohei Enju <kohei@enjuk.jp>
> ---
> Changes:
> v2:
> - change to idiomatic style with goto (Simon)
> - add Cc to stable (Alex)
> - add reprodunction steps (Alex)
> v1: https://lore.kernel.org/all/20260329145122.126040-1-kohei@enjuk.jp/
> ---
> drivers/net/ethernet/intel/igc/igc_tsn.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/igc/igc_tsn.c b/drivers/net/ethernet/intel/igc/igc_tsn.c
> index 8a110145bfee..02dd9f0290a3 100644
> --- a/drivers/net/ethernet/intel/igc/igc_tsn.c
> +++ b/drivers/net/ethernet/intel/igc/igc_tsn.c
> @@ -109,10 +109,16 @@ static int igc_fpe_xmit_smd_frame(struct igc_adapter *adapter,
> __netif_tx_lock(nq, cpu);
>
> err = igc_fpe_init_tx_descriptor(ring, skb, type);
> - igc_flush_tx_descriptors(ring);
> + if (err)
> + goto err_free_skb_any;
>
> + igc_flush_tx_descriptors(ring);
> __netif_tx_unlock(nq);
> + return 0;
>
> +err_free_skb_any:
> + __netif_tx_unlock(nq);
> + dev_kfree_skb_any(skb);
> return err;
> }
>
Thanks for helping to fix this.
Reviewed-by: Faizal Rahim <faizal.abdul.rahim@linux.intel.com>
^ permalink raw reply
* [net-next v2 3/3] net: phy: motorcomm: Add YT8522 100M RMII PHY support
From: Minda Chen @ 2026-04-22 8:32 UTC (permalink / raw)
To: Frank, Andrew Lunn, Heiner Kallweit, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev
Cc: linux-kernel, Minda Chen
In-Reply-To: <20260422083255.29692-1-minda.chen@starfivetech.com>
Add YT8522 100M RMII ethernet PHY base driver support, including
PHY ID and base config init function.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
---
drivers/net/phy/motorcomm.c | 49 ++++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index ebc24f51e626..13d57aba5487 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
- * Motorcomm 8511/8521/8531/8531S/8821 PHY driver.
+ * Motorcomm 8511/8521/8522/8531/8531S/8821 PHY driver.
*
* Author: Peter Geis <pgwipeout@gmail.com>
* Author: Frank <Frank.Sae@motor-comm.com>
@@ -14,6 +14,7 @@
#define PHY_ID_YT8511 0x0000010a
#define PHY_ID_YT8521 0x0000011a
+#define PHY_ID_YT8522 0x4f51e928
#define PHY_ID_YT8531 0x4f51e91b
#define PHY_ID_YT8531S 0x4f51e91a
#define PHY_ID_YT8821 0x4f51ea19
@@ -227,6 +228,13 @@
#define YT8521_LED_100_ON_EN BIT(5)
#define YT8521_LED_10_ON_EN BIT(4)
+#define YT8522_EXTREG_SLEEP_CONTROL 0x2027
+#define YT8522_EN_SLEEP_SW 15
+
+#define YT8522_EXTENDED_COMBO_CTRL 0x4000
+#define YT8522_RXDV_SEL BIT(4)
+#define YT8522_RMII_EN BIT(1)
+
#define YTPHY_MISC_CONFIG_REG 0xA006
#define YTPHY_MCR_FIBER_SPEED_MASK BIT(0)
#define YTPHY_MCR_FIBER_1000BX (0x1 << 0)
@@ -1843,6 +1851,36 @@ static int yt8531_config_init(struct phy_device *phydev)
return 0;
}
+static int yt8522_config_init(struct phy_device *phydev)
+{
+ struct device_node *node = phydev->mdio.dev.of_node;
+ int ret, val;
+
+ val = ytphy_read_ext_with_lock(phydev, YT8522_EXTENDED_COMBO_CTRL);
+ if (val < 0)
+ return val;
+
+ if (val & YT8522_RMII_EN) {
+ val |= YT8522_RXDV_SEL;
+ ret = ytphy_write_ext_with_lock(phydev,
+ YT8522_EXTENDED_COMBO_CTRL,
+ val);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (of_property_read_bool(node, "motorcomm,auto-sleep-disabled")) {
+ /* disable auto sleep */
+ ret = ytphy_modify_ext_with_lock(phydev,
+ YT8522_EXTREG_SLEEP_CONTROL,
+ YT8522_EN_SLEEP_SW, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
/**
* yt8531_link_change_notify() - Adjust the tx clock direction according to
* the current speed and dts config.
@@ -3052,6 +3090,14 @@ static struct phy_driver motorcomm_phy_drvs[] = {
.led_hw_control_set = yt8521_led_hw_control_set,
.led_hw_control_get = yt8521_led_hw_control_get,
},
+ {
+ PHY_ID_MATCH_EXACT(PHY_ID_YT8522),
+ .name = "YT8522 100 Megabit Ethernet",
+ .config_aneg = genphy_config_aneg,
+ .config_init = yt8522_config_init,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ },
{
PHY_ID_MATCH_EXACT(PHY_ID_YT8531),
.name = "YT8531 Gigabit Ethernet",
@@ -3112,6 +3158,7 @@ MODULE_LICENSE("GPL");
static const struct mdio_device_id __maybe_unused motorcomm_tbl[] = {
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8511) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8521) },
+ { PHY_ID_MATCH_EXACT(PHY_ID_YT8522) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8531) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8531S) },
{ PHY_ID_MATCH_EXACT(PHY_ID_YT8821) },
--
2.17.1
^ permalink raw reply related
* [net-next v2 2/3] net: motorcomm: phy: set drive strength in 8531s RGMII case
From: Minda Chen @ 2026-04-22 8:32 UTC (permalink / raw)
To: Frank, Andrew Lunn, Heiner Kallweit, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev
Cc: linux-kernel, Minda Chen
In-Reply-To: <20260422083255.29692-1-minda.chen@starfivetech.com>
Set RXD and RX CLK pin drive strength while in 8531s RGMII
case.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
---
drivers/net/phy/motorcomm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index c66804537aa2..ebc24f51e626 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -1698,6 +1698,11 @@ static int yt8521_config_init(struct phy_device *phydev)
if (ret < 0)
goto err_restore_page;
}
+
+ if (phydev->drv->phy_id == PHY_ID_YT8531S &&
+ phy_interface_is_rgmii(phydev))
+ ret = yt8531_set_ds(phydev);
+
err_restore_page:
return phy_restore_page(phydev, old_page, ret);
}
--
2.17.1
^ permalink raw reply related
* [net-next v2 0/3] Add motorcomm 8531s set ds func and 8522 driver
From: Minda Chen @ 2026-04-22 8:32 UTC (permalink / raw)
To: Frank, Andrew Lunn, Heiner Kallweit, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev
Cc: linux-kernel, Minda Chen
This patch is for Starfive JHB100 EVB board. JHB100 contain
1 RGMII/RMII and 1 RMII synopsys GMAC cores. In the EVB board, RGMII
interface connect with YT8531s Ethernet PHY. RMII interface connect
with YT8522 ethernet PHY. So patch 1-2 is for RGMII interface
patch 3 is RMII is for RMII interface.
JHB100 is a Starfive new RISC-V SoC for datacenter BMC (BaseBoard
Managent Controller). Similar with Aspeed 27x0.
The JHB100 minimal system upstream is in progress:
https://patchwork.kernel.org/project/linux-riscv/cover/20260403054945.467700-1-changhuang.liang@starfivetech.com/
The patch base in V7.0-rc5
The change list:
v2:
1. patch1 move mdio lock out from yt8531_set_ds().
2. patch2 changed to phy_interface_is_rgmii().
Minda Chen (3):
net: phy: motorcomm: move mdio lock out from yt8531_set_ds()
net: motorcomm: phy: set drive strength in 8531s RGMII case
net: phy: motorcomm: Add YT8522 100M RMII PHY support
drivers/net/phy/motorcomm.c | 77 ++++++++++++++++++++++++++++++++-----
1 file changed, 67 insertions(+), 10 deletions(-)
base-commit: c369299895a591d96745d6492d4888259b004a9e
--
2.17.1
^ permalink raw reply
* [net-next v2 1/3] net: phy: motorcomm: move mdio lock out from yt8531_set_ds()
From: Minda Chen @ 2026-04-22 8:32 UTC (permalink / raw)
To: Frank, Andrew Lunn, Heiner Kallweit, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev
Cc: linux-kernel, Minda Chen
In-Reply-To: <20260422083255.29692-1-minda.chen@starfivetech.com>
yt8531_set_ds() default set register with mdio lock and only called
with YT8531 PHY. But new type YT8531s support RGMII and has the same
pin strength setting with YT8531, YT8531s need to call yt8531_set_ds()
setting pin drive strength. But YT8531s config init function
yt8521_config_init() already get the mdio lock with phy_select_page().
If calling yt8521_config_init() with mdio lock will cause dead lock.
Need to get the lock before calling yt8531_get_ds() and move mdio
lock out from it can solve this issue.
Signed-off-by: Minda Chen <minda.chen@starfivetech.com>
---
drivers/net/phy/motorcomm.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 4d62f7b36212..c66804537aa2 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -974,7 +974,8 @@ static u32 yt8531_get_ldo_vol(struct phy_device *phydev)
{
u32 val;
- val = ytphy_read_ext_with_lock(phydev, YT8521_CHIP_CONFIG_REG);
+ val = ytphy_read_ext(phydev, YT8521_CHIP_CONFIG_REG);
+
val = FIELD_GET(YT8531_RGMII_LDO_VOL_MASK, val);
return val <= YT8531_LDO_VOL_1V8 ? val : YT8531_LDO_VOL_1V8;
@@ -1010,10 +1011,11 @@ static int yt8531_set_ds(struct phy_device *phydev)
ds = YT8531_RGMII_RX_DS_DEFAULT;
}
- ret = ytphy_modify_ext_with_lock(phydev,
- YTPHY_PAD_DRIVE_STRENGTH_REG,
- YT8531_RGMII_RXC_DS_MASK,
- FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
+ ret = ytphy_modify_ext(phydev,
+ YTPHY_PAD_DRIVE_STRENGTH_REG,
+ YT8531_RGMII_RXC_DS_MASK,
+ FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds));
+
if (ret < 0)
return ret;
@@ -1033,10 +1035,11 @@ static int yt8531_set_ds(struct phy_device *phydev)
ds_field_low = FIELD_GET(GENMASK(1, 0), ds);
ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low);
- ret = ytphy_modify_ext_with_lock(phydev,
- YTPHY_PAD_DRIVE_STRENGTH_REG,
- YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
- ds_field_low | ds_field_hi);
+ ret = ytphy_modify_ext(phydev,
+ YTPHY_PAD_DRIVE_STRENGTH_REG,
+ YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK,
+ ds_field_low | ds_field_hi);
+
if (ret < 0)
return ret;
@@ -1826,7 +1829,9 @@ static int yt8531_config_init(struct phy_device *phydev)
return ret;
}
+ phy_lock_mdio_bus(phydev);
ret = yt8531_set_ds(phydev);
+ phy_unlock_mdio_bus(phydev);
if (ret < 0)
return ret;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] net/intel: Replace manual array size calculation with ARRAY_SIZE
From: Jakub Raczynski @ 2026-04-22 8:32 UTC (permalink / raw)
To: Dan Carpenter
Cc: netdev, kuba, przemyslaw.kitszel, anthony.l.nguyen,
kernel-janitors
In-Reply-To: <aeeFh1zQqhVysvxI@stanley.mountain>
[-- Attachment #1: Type: text/plain, Size: 898 bytes --]
On Tue, Apr 21, 2026 at 05:11:19PM +0300, Dan Carpenter wrote:
> On Tue, Apr 21, 2026 at 01:40:29PM +0200, Jakub Raczynski wrote:
> >
> > - if (!((u32)aq_rc < (sizeof(aq_to_posix) / sizeof((aq_to_posix)[0]))))
> > + if (!((u32)aq_rc < ARRAY_SIZE(aq_to_posix)))
>
> This still isn't beautiful. There are so many parens. The !(foo < size)
> formulation is weird. The cast is unnnecessary. Better to write it as:
>
> if (aq_rc >= ARRAY_SIZE(aq_to_posix))
> return -ERANGE;
>
> > return -ERANGE;
> >
> > return aq_to_posix[aq_rc];
>
> regards,
> dan carpenter
>
Alright, will beautify it and resend soon.
I can see potential original intention of not comparing unsigned from sizeof
with int, maybe that was original compiler configuration to include that
warning.
But at this variable range it is irrelevant and it is probably most disabled
warning ever.
regards
Jakub Raczynski
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: [PATCH net v3 1/1] net: hsr: limit node table growth
From: Felix Maurer @ 2026-04-22 8:31 UTC (permalink / raw)
To: Ren Wei
Cc: netdev, Sebastian Andrzej Siewior, davem, edumazet, kuba, pabeni,
horms, kees, kexinsun, luka.gejak, Arvid.Brodin, m-karicheri2,
yuantan098, yifanwucs, tomapufckgml, bird, xuyuqiabc, royenheart
In-Reply-To: <3bdbe54e81bd89c1443b05500368fb45bddc3191.1776754203.git.royenheart@gmail.com>
On Tue, Apr 21, 2026 at 10:50:01PM +0800, Ren Wei wrote:
> From: Haoze Xie <royenheart@gmail.com>
>
> The HSR/PRP node learning paths allocate one persistent entry per
> previously unseen source MAC. Since learned entries stay alive until the
> prune timer catches up, the node tables can otherwise grow without a
> bound under high churn of learned senders.
>
> Limit the number of learned entries in each node table and stop adding
> new ones once the configured limit is reached. This keeps node-table
> resource use bounded across the affected learning paths.
Hi,
thank you for giving this approach a try!
[snip]
> diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
> index d09875b33588..8a5a2a54a81f 100644
> --- a/net/hsr/hsr_framereg.c
> +++ b/net/hsr/hsr_framereg.c
> @@ -14,12 +14,18 @@
> #include <kunit/visibility.h>
> #include <linux/if_ether.h>
> #include <linux/etherdevice.h>
> +#include <linux/moduleparam.h>
> #include <linux/slab.h>
> #include <linux/rculist.h>
> #include "hsr_main.h"
> #include "hsr_framereg.h"
> #include "hsr_netlink.h"
>
> +static unsigned int hsr_node_table_size = 1024;
> +module_param_named(node_table_size, hsr_node_table_size, uint, 0644);
> +MODULE_PARM_DESC(node_table_size,
> + "Maximum number of learned entries in each HSR/PRP node table (0 = unlimited)");
> +
> bool hsr_addr_is_redbox(struct hsr_priv *hsr, unsigned char *addr)
> {
> if (!hsr->redbox || !is_valid_ether_addr(hsr->macaddress_redbox))
> @@ -189,6 +195,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
> enum hsr_port_type rx_port)
> {
> struct hsr_node *new_node, *node = NULL;
> + unsigned int node_count = 0;
> unsigned long now;
> size_t block_sz;
> int i;
> @@ -226,20 +233,31 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr,
> spin_lock_bh(&hsr->list_lock);
> list_for_each_entry_rcu(node, node_db, mac_list,
> lockdep_is_held(&hsr->list_lock)) {
> + node_count++;
I'm not sure if this on-the-fly node counting is the best solution here.
My concern is that it comes quite late in the process, i.e., after we
already allocated a bunch of memory, etc. As we are discussing a
scenario where a lot of entries are created, maybe we shouldn't even
allocate a new_node if the table is already full? For example by storing
the node_count in hsr_priv and checking it early in the function?
> if (ether_addr_equal(node->macaddress_A, addr))
> - goto out;
> + goto out_found;
> if (ether_addr_equal(node->macaddress_B, addr))
> - goto out;
> + goto out_found;
> }
> +
> + if (hsr_node_table_size && node_count >= hsr_node_table_size)
> + goto out_drop;
I think it would be good to somehow make this situation transparent to
the user, so they can react if this an undesired behavior (for example,
because they simply have a large network and need a large node table).
> list_add_tail_rcu(&new_node->mac_list, node_db);
> spin_unlock_bh(&hsr->list_lock);
> return new_node;
> -out:
> +out_found:
> spin_unlock_bh(&hsr->list_lock);
> + xa_destroy(&new_node->seq_blocks);
> kfree(new_node->block_buf);
> -free:
> kfree(new_node);
> return node;
> +out_drop:
> + spin_unlock_bh(&hsr->list_lock);
> + xa_destroy(&new_node->seq_blocks);
> + kfree(new_node->block_buf);
> +free:
> + kfree(new_node);
> + return NULL;
> }
The two cleanup paths are almost the same now. We usually attempt to
keep them unified to make sure that we do the correct cleanup steps in
all situations. So please keep them unified here as well.
Thanks,
Felix
^ permalink raw reply
* Re: [PATCH] wifi: mac80211: check ieee80211_rx_data_set_link return in pubsta MLO path
From: Benjamin Berg @ 2026-04-22 8:17 UTC (permalink / raw)
To: Johannes Berg, Michael Bommarito, linux-wireless
Cc: Felix Fietkau, netdev, linux-kernel, Ramasamy Kaliappan
In-Reply-To: <434407f50d6b7ee85ad14dd6db757f7d9f695a96.camel@sipsolutions.net>
On Wed, 2026-04-22 at 08:27 +0200, Johannes Berg wrote:
> On Tue, 2026-04-21 at 20:06 -0400, Michael Bommarito wrote:
>
> > Benjamin Berg's 2026-02 RFC v2 "wifi: mac80211: refactor RX
> > link_id and station handling"
> > (20260223133818.9f5550ab445f.I...@changeid) touches the same
> > code and may supersede or subsume this patch; happy to fold /
> > rebase / drop.
>
> Yeah, Benjamin, what's up with that :)
Hmm, good question. I was hoping for a userspace hostap implementation
to start using the new NO_STA flag as that part is otherwise untested.
Qualcomm was going to work on that, but I have not yet heard about it
again.
That said, it should be fine to merge patches 1-4 at least. So I am
happy to submit them separately.
Benjamin
>
> OTOH we perhaps wants this patch in wireless, and then yours in
> wireless-next.
>
> johannes
^ permalink raw reply
* Re: [PATCH] smb: smbdirect: move fs/smb/common/smbdirect/ to fs/smb/smbdirect/
From: Stefan Metzmacher @ 2026-04-22 8:16 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linux-cifs, linux-rdma, netdev, samba-technical, Tom Talpey,
Steve French, Linus Torvalds, Namjae Jeon
In-Reply-To: <aehrPuY60VMcYGU8@infradead.org>
Hi Christoph,
>> diff --git a/fs/smb/Makefile b/fs/smb/Makefile
>> index 9a1bf59a1a65..353b1c2eefc4 100644
>> --- a/fs/smb/Makefile
>> +++ b/fs/smb/Makefile
>> @@ -1,5 +1,6 @@
>> # SPDX-License-Identifier: GPL-2.0
>>
>> obj-$(CONFIG_SMBFS) += common/
>> +obj-$(CONFIG_SMBDIRECT) += smbdirect/
>
> Why is this not in net/smbdirect/ or driver/infiniband/ulp/smdirect?
Yes, I also thought about net/smbdirect.
As IPPROTO_SMBDIRECT or PF_SMBDIRECT will be the next step,
see the open discussion here:
https://lore.kernel.org/linux-cifs/cover.1775571957.git.metze@samba.org/
(I'll follow with that discussion soon)
I was just unsure about the consequences, e.g. would
the maintainer/pull request flow have to change in that case?
Or would Steve be able to take the changes via his trees?
Any I also didn't want to offend anybody, so I just took
what Linus proposed.
Using driver/infiniband/ulp/smdirect would also work,
if everybody prefer that.
> As far as I can tell there is zero file system logic in this code.
>
>> -#include "../common/smbdirect/smbdirect_public.h"
>> +#include "../smbdirect/public.h"
>
> And all these relative includes suggest you really want a
> include/linux/smdirect/ instead.
Yes, that's my also my goal in the next steps.
> While we're at it: __SMBDIRECT_EXPORT_SYMBOL__ is really odd.
> One thing is the __ pre- and postfix that make it look weird.
Yes, the __SMBDIRECT_EXPORT_SYMBOL__ was mainly a temporary
thing, now it's useless and I'll remove it.
> The other is that EXPORT_SYMBOL_FOR_MODULES is for very specific
> symbols that really should not exported. What this warrants instead
> is a normal EXPORT_SYMBOL_NS_GPL.
I want the exported functions be minimal, as most of
of should go via the socket layer instead.
If EXPORT_SYMBOL_NS_GPL(func, "smbdirect") is better than
EXPORT_SYMBOL_FOR_MODULES() I can change that.
It means cifs.ko and ksmbd.ko would need MODULE_IMPORT_NS("smbdirect"), correct?
Thanks!
metze
^ permalink raw reply
* Re: [PATCH iproute2] ss: fix vsock port filter
From: Stefano Garzarella @ 2026-04-22 8:03 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Luigi Leonardi, stefanha, netdev, Mathieu Schroeter, David Ahern
In-Reply-To: <20260421163757.31da8751@phoenix.local>
On Wed, 22 Apr 2026 at 01:38, Stephen Hemminger <stephen@networkplumber.org> wrote:
>
> On Tue, 21 Apr 2026 14:35:12 +0200
> Luigi Leonardi <leonardi@redhat.com> wrote:
>
> > parse_hostcond() uses get_u32() to parse the vsock port into the
> > aafilter.port field, which is a long. On 64-bit systems, get_u32()
> > only writes the lower 32 bits, leaving the upper 32 bits set from
> > the -1 initialization. This causes the port comparison
> > "a->port != s->rport" in run_ssfilter() to always fail, since the
> > corrupted long value never matches the int rport.
> >
> > Fix by using get_long() instead, consistent with how AF_PACKET and
> > AF_NETLINK handle the same field.
> >
> > Fixes: c759116a0b2b ("ss: add AF_VSOCK support")
> > Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
> > ---
> > misc/ss.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/misc/ss.c b/misc/ss.c
> > index 14e9f27a..6e3321ac 100644
> > --- a/misc/ss.c
> > +++ b/misc/ss.c
> > @@ -2323,7 +2323,7 @@ void *parse_hostcond(char *addr, bool is_port)
> > port = find_port(addr, is_port);
> >
> > if (port && strcmp(port, "*") &&
> > - get_u32((__u32 *)&a.port, port, 0))
> > + get_long(&a.port, port, 0))
> > return NULL;
>
> If you use get_long() then the code could get negative values.
> Actually have port in ss as signed value seems like a mistake in original design.
>
> The port in unix domain socket is inode number.
> Originally it was int, but got changed to long back in 6.6
>
> The port in ss cache is int.
Yeah, as I mentioned I think the issue was introduced by commit
012cb515 ("ss: change aafilter port from int to long (inode support)").
After teverting it, the filtering on AF_VSOCK works correctly.
IMO (I don't know the code at all), commit 012cb515 is incomplete and we
should also move from int to long lport and rport in `struct sockstat`.
>
> The ss code is one of those legacy dog piles that needs a major
> overhaul and refactoring.
>
yeah, I see...
Thanks,
Stefano
^ permalink raw reply
* [syzbot] [atm?] general protection fault in atmtcp_ioctl
From: syzbot @ 2026-04-22 7:51 UTC (permalink / raw)
To: 3chas3, linux-atm-general, linux-kernel, netdev, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 1f5ffc672165 Fix mismerge of the arm64 / timer-core interr..
git tree: net-next
console output: https://syzkaller.appspot.com/x/log.txt?x=14b72c36580000
kernel config: https://syzkaller.appspot.com/x/.config?x=95729ed00549063a
dashboard link: https://syzkaller.appspot.com/bug?extid=52bbaea57234493b6b17
compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
Unfortunately, I don't have any reproducer for this issue yet.
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/6b552538b97f/disk-1f5ffc67.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/724a3a1d69d7/vmlinux-1f5ffc67.xz
kernel image: https://storage.googleapis.com/syzbot-assets/ea684969e2c2/bzImage-1f5ffc67.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+52bbaea57234493b6b17@syzkaller.appspotmail.com
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 1 UID: 0 PID: 15453 Comm: syz.2.2407 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/18/2026
RIP: 0010:atmtcp_attach drivers/atm/atmtcp.c:408 [inline]
RIP: 0010:atmtcp_ioctl+0x860/0xdf0 drivers/atm/atmtcp.c:477
Code: ff e9 b4 fb ff ff 4c 8d 63 20 4c 89 e0 48 c1 e8 03 80 3c 28 00 74 08 4c 89 e7 e8 cb 21 0b fb 4d 8b 24 24 4c 89 e0 48 c1 e8 03 <80> 3c 28 00 74 08 4c 89 e7 e8 b2 21 0b fb 49 83 3c 24 00 0f 84 f0
RSP: 0018:ffffc9000f6b7c30 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff888037f2f000 RCX: ffffffff8bb4829e
RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffc9000f6b7b80
RBP: dffffc0000000000 R08: ffffc9000f6b7b87 R09: 1ffff92001ed6f70
R10: dffffc0000000000 R11: fffff52001ed6f71 R12: 0000000000000000
R13: 1ffff11006fe5e00 R14: ffff88808ac0d440 R15: ffff88803234e000
FS: 00007fd42b7c26c0(0000) GS:ffff888125345000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000001944 CR3: 00000000358e6000 CR4: 00000000003526f0
Call Trace:
<TASK>
do_vcc_ioctl+0x36d/0x9d0 net/atm/ioctl.c:159
sock_do_ioctl+0x101/0x320 net/socket.c:1313
sock_ioctl+0x5c6/0x7f0 net/socket.c:1434
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd42a99c819
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007fd42b7c2028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007fd42ac15fa0 RCX: 00007fd42a99c819
RDX: 0000000000000000 RSI: 0000000000006180 RDI: 0000000000000008
RBP: 00007fd42aa32c91 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fd42ac16038 R14: 00007fd42ac15fa0 R15: 00007ffe8b9d1618
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:atmtcp_attach drivers/atm/atmtcp.c:408 [inline]
RIP: 0010:atmtcp_ioctl+0x860/0xdf0 drivers/atm/atmtcp.c:477
Code: ff e9 b4 fb ff ff 4c 8d 63 20 4c 89 e0 48 c1 e8 03 80 3c 28 00 74 08 4c 89 e7 e8 cb 21 0b fb 4d 8b 24 24 4c 89 e0 48 c1 e8 03 <80> 3c 28 00 74 08 4c 89 e7 e8 b2 21 0b fb 49 83 3c 24 00 0f 84 f0
RSP: 0018:ffffc9000f6b7c30 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff888037f2f000 RCX: ffffffff8bb4829e
RDX: 0000000000000001 RSI: 0000000000000008 RDI: ffffc9000f6b7b80
RBP: dffffc0000000000 R08: ffffc9000f6b7b87 R09: 1ffff92001ed6f70
R10: dffffc0000000000 R11: fffff52001ed6f71 R12: 0000000000000000
R13: 1ffff11006fe5e00 R14: ffff88808ac0d440 R15: ffff88803234e000
FS: 00007fd42b7c26c0(0000) GS:ffff888125345000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000000110c3d9593 CR3: 00000000358e6000 CR4: 00000000003526f0
----------------
Code disassembly (best guess):
0: ff ljmp (bad)
1: e9 b4 fb ff ff jmp 0xfffffbba
6: 4c 8d 63 20 lea 0x20(%rbx),%r12
a: 4c 89 e0 mov %r12,%rax
d: 48 c1 e8 03 shr $0x3,%rax
11: 80 3c 28 00 cmpb $0x0,(%rax,%rbp,1)
15: 74 08 je 0x1f
17: 4c 89 e7 mov %r12,%rdi
1a: e8 cb 21 0b fb call 0xfb0b21ea
1f: 4d 8b 24 24 mov (%r12),%r12
23: 4c 89 e0 mov %r12,%rax
26: 48 c1 e8 03 shr $0x3,%rax
* 2a: 80 3c 28 00 cmpb $0x0,(%rax,%rbp,1) <-- trapping instruction
2e: 74 08 je 0x38
30: 4c 89 e7 mov %r12,%rdi
33: e8 b2 21 0b fb call 0xfb0b21ea
38: 49 83 3c 24 00 cmpq $0x0,(%r12)
3d: 0f .byte 0xf
3e: 84 f0 test %dh,%al
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
^ permalink raw reply
* RE: [RFC Patch net-next v1 9/9] r8169: add support for ethtool
From: Javen @ 2026-04-22 7:47 UTC (permalink / raw)
To: Andrew Lunn
Cc: hkallweit1@gmail.com, nic_swsd@realtek.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, horms@kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <c94f23f6-e353-4e88-af91-9e73d70d009d@lunn.ch>
>> +static int rtl8169_set_channels(struct net_device *dev,
>> + struct ethtool_channels *ch) {
>> + struct rtl8169_private *tp = netdev_priv(dev);
>> + bool if_running = netif_running(dev);
>> + int i;
>> +
>> + if (!tp->rss_support && (ch->rx_count > 1 || ch->tx_count > 1)) {
>> + netdev_warn(dev, "This chip does not support multiple
>channels/RSS.\n");
>> + return -EOPNOTSUPP;
>> + }
>> +
>> + if (ch->rx_count == 0 || ch->tx_count == 0)
>> + return -EINVAL;
>> + if (ch->rx_count > tp->HwSuppNumRxQueues ||
>> + ch->tx_count > tp->HwSuppNumTxQueues)
>> + return -EINVAL;
>> + if (ch->other_count || ch->combined_count)
>> + return -EINVAL;
>> +
>> + if (ch->rx_count == tp->num_rx_rings &&
>> + ch->tx_count == tp->num_tx_rings)
>> + return 0;
>> +
>> + if (if_running)
>> + rtl8169_close(dev);
>
>I assume this releases all the memory from the rings?
>
>> +
>> + tp->num_rx_rings = ch->rx_count;
>> + tp->num_tx_rings = ch->tx_count;
>> +
>> + tp->rss_enable = (tp->num_rx_rings > 1 && tp->rss_support);
>> +
>> + for (i = 0; i < tp->HwSuppIndirTblEntries; i++) {
>> + if (tp->rss_enable)
>> + tp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, tp-
>>num_rx_rings);
>> + else
>> + tp->rss_indir_tbl[i] = 0;
>> + }
>> +
>> + if (tp->rss_enable)
>> + tp->InitRxDescType = RX_DESC_RING_TYPE_RSS;
>> + else
>> + tp->InitRxDescType = RX_DESC_RING_TYPE_DEAFULT;
>> +
>> + if (if_running)
>> + return rtl_open(dev);
>
>And this tries to allocate the memory needed for the rings? And if the system
>is under memory pressure, it fails and your network is dead?
>
>Please modify the code so that is first allocated the new rings and then frees
>the old rings, so you can fail gracefully.
>
> Andrew
Thank you for your advice. I have updated the code accordingly. This patch is
based on RFC Patch net-next 9/9.
This patch fixes issues when using ethtool -L to change the number of RX rings.
Specifically, if allocating memory for the new RX rings fails, it now gracefully rolls
back to the original state.
Additionally, it fixes a bug where ping or iperf would fail after manually setting
8 RX rings (when the default suggested RSS queue number is only 1 or 2). This
was caused by a missing call to rtl_set_irq_mask, which is now added.
---
drivers/net/ethernet/realtek/r8169_main.c | 101 +++++++++++++++++++---
1 file changed, 90 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c
index 57087abe7d88..4b2abd3deee0 100644
--- a/drivers/net/ethernet/realtek/r8169_main.c
+++ b/drivers/net/ethernet/realtek/r8169_main.c
@@ -6116,6 +6116,8 @@ static void rtl8169_double_check_rss_support(struct rtl8169_private *tp)
if (tp->num_rx_rings >= 2) {
tp->rss_enable = 1;
tp->InitRxDescType = RX_DESC_RING_TYPE_RSS;
+ } else if (tp->num_rx_rings == 1 && tp->irq_nvecs > 1) {
+ tp->rss_enable = 0;
} else {
tp->rss_enable = 0;
if (tp->irq_nvecs > 1) {
@@ -6534,18 +6536,70 @@ static void rtl8169_get_channels(struct net_device *dev,
ch->combined_count = 0;
}
+static int rtl8169_realloc_rx(struct rtl8169_private *tp,
+ struct rtl8169_rx_ring *new_rx,
+ int new_count)
+{
+ int i, ret;
+
+ new_rx[0].rdsar_reg = RxDescAddrLow;
+ for (i = 1; i < new_count; i++)
+ new_rx[i].rdsar_reg = (u16)(RDSAR_Q1_LOW + (i - 1) * 8);
+
+ for (i = 0; i < new_count; i++)
+ new_rx[i].num_rx_desc = NUM_RX_DESC;
+
+ for (i = 0; i < new_count; i++) {
+ struct rtl8169_rx_ring *ring = &new_rx[i];
+
+ ring->RxDescAllocSize = (NUM_RX_DESC + 1) * sizeof(struct RxDesc);
+ ring->RxDescArray = dma_alloc_coherent(&tp->pci_dev->dev,
+ ring->RxDescAllocSize,
+ &ring->RxPhyAddr,
+ GFP_KERNEL);
+ if (!ring->RxDescArray) {
+ ret = -ENOMEM;
+ goto err_free;
+ }
+
+ memset(ring->Rx_databuff, 0, sizeof(ring->Rx_databuff));
+ ret = rtl8169_rx_fill(tp, ring);
+ if (ret) {
+ dma_free_coherent(&tp->pci_dev->dev, ring->RxDescAllocSize,
+ ring->RxDescArray, ring->RxPhyAddr);
+ goto err_free;
+ }
+ }
+ return 0;
+
+err_free:
+ while (--i >= 0) {
+ rtl8169_rx_clear(tp, &new_rx[i]);
+ dma_free_coherent(&tp->pci_dev->dev, new_rx[i].RxDescAllocSize,
+ new_rx[i].RxDescArray, new_rx[i].RxPhyAddr);
+ }
+ return ret;
+}
+
static int rtl8169_set_channels(struct net_device *dev,
struct ethtool_channels *ch)
{
struct rtl8169_private *tp = netdev_priv(dev);
bool if_running = netif_running(dev);
- int i;
+ struct rtl8169_rx_ring *new_rx;
+ u8 old_tx_desc_type = tp->InitRxDescType;
+ u8 new_desc_type;
+ bool new_rss_enable;
+ int i, ret;
if (!tp->rss_support && (ch->rx_count > 1 || ch->tx_count > 1)) {
netdev_warn(dev, "This chip does not support multiple channels/RSS.\n");
return -EOPNOTSUPP;
}
+ if (tp->features & RTL_FEATURE_MSI)
+ return -EINVAL;
+
if (ch->rx_count == 0 || ch->tx_count == 0)
return -EINVAL;
if (ch->rx_count > tp->HwSuppNumRxQueues ||
@@ -6558,13 +6612,39 @@ static int rtl8169_set_channels(struct net_device *dev,
ch->tx_count == tp->num_tx_rings)
return 0;
- if (if_running)
- rtl8169_close(dev);
+ new_rss_enable = (ch->rx_count > 1 && tp->rss_support);
+ new_desc_type = new_rss_enable ? RX_DESC_RING_TYPE_RSS : RX_DESC_RING_TYPE_DEAFULT;
+ tp->InitRxDescType = new_desc_type;
+
+ if (!if_running) {
+ tp->num_rx_rings = ch->rx_count;
+ tp->rss_enable = new_rss_enable;
+ return 0;
+ }
+
+ new_rx = kcalloc(R8169_MAX_RX_QUEUES, sizeof(*new_rx), GFP_KERNEL);
+ if (!new_rx)
+ return -ENOMEM;
+
+ ret = rtl8169_realloc_rx(tp, new_rx, ch->rx_count);
+ if (ret) {
+ kfree(new_rx);
+ tp->InitRxDescType = old_tx_desc_type;
+ return ret;
+ }
+
+ netif_stop_queue(dev);
+ rtl8169_down(tp);
+
+ for (i = 0; i < tp->num_rx_rings; i++)
+ rtl8169_rx_clear(tp, &tp->rx_ring[i]);
+ rtl8169_free_rx_desc(tp);
tp->num_rx_rings = ch->rx_count;
- tp->num_tx_rings = ch->tx_count;
+ tp->rss_enable = new_rss_enable;
- tp->rss_enable = (tp->num_rx_rings > 1 && tp->rss_support);
+ memset(tp->rx_ring, 0, sizeof(tp->rx_ring));
+ memcpy(tp->rx_ring, new_rx, sizeof(*new_rx) * ch->rx_count);
for (i = 0; i < tp->HwSuppIndirTblEntries; i++) {
if (tp->rss_enable)
@@ -6573,13 +6653,12 @@ static int rtl8169_set_channels(struct net_device *dev,
tp->rss_indir_tbl[i] = 0;
}
- if (tp->rss_enable)
- tp->InitRxDescType = RX_DESC_RING_TYPE_RSS;
- else
- tp->InitRxDescType = RX_DESC_RING_TYPE_DEAFULT;
+ rtl_set_irq_mask(tp);
+
+ rtl8169_up(tp);
+ netif_start_queue(dev);
- if (if_running)
- return rtl_open(dev);
+ kfree(new_rx);
return 0;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net 00/18] Remove a number of ISA and PCMCIA Ethernet drivers
From: Geert Uytterhoeven @ 2026-04-22 7:42 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan,
linux-kernel, netdev, linux-doc
In-Reply-To: <20260421-v7-0-0-net-next-driver-removal-v1-v1-0-69517c689d1f@lunn.ch>
Hi Andrew,
On Tue, 21 Apr 2026 at 21:31, Andrew Lunn <andrew@lunn.ch> wrote:
> These old drivers have not been much of a Maintenance burden until
> recently. Now there are more newbies using AI and fuzzers finding
> issues, resulting in more work for Maintainers. Fixing these old
> drivers make little sense, if it is not clear they have users.
Thanks for your series!
> These are all ISA and PCMCIA Ethernet devices, mostly from the last
Only the drivers that depend solely on ISA or PCMCIA are drivers
for ISA and PCMCIA devices.
These are not:
- depends on (PCI || EISA) && HAS_IOPORT_MAP
- depends on DIO
- depends on MVME147
- depends on ARM || (COMPILE_TEST && !PPC)
- depends on MAC
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH net] tcp: make probe0 timer handle expired user timeout
From: Eric Dumazet @ 2026-04-22 7:39 UTC (permalink / raw)
To: Altan Hacigumus
Cc: Neal Cardwell, Kuniyuki Iwashima, David S . Miller, David Ahern,
Jakub Kicinski, Paolo Abeni, Simon Horman, netdev, linux-kernel,
Enke Chen
In-Reply-To: <CALjTKDkJ9L-88hdODbt-8D=eEDe6r5egtTfk_RnwgVq_NF+q+g@mail.gmail.com>
On Tue, Apr 21, 2026 at 8:31 PM Altan Hacigumus <ahacigu.linux@gmail.com> wrote:
>
> On Mon, Apr 20, 2026 at 9:58 PM Eric Dumazet <edumazet@google.com> wrote:
> >
> > On Mon, Apr 13, 2026 at 6:36 PM Altan Hacigumus <ahacigu.linux@gmail.com> wrote:
> > >
> > > tcp_clamp_probe0_to_user_timeout() computes remaining time in jiffies
> > > using subtraction with an unsigned lvalue. If elapsed probing time
> > > already exceeds the configured TCP_USER_TIMEOUT, the subtraction
> > > underflows and yields a large value.
> > >
> > > Handle this expiration case similarly to tcp_clamp_rto_to_user_timeout().
> > >
> > > Fixes: 344db93ae3ee ("tcp: make TCP_USER_TIMEOUT accurate for zero window probes")
> > > Signed-off-by: Altan Hacigumus <ahacigu.linux@gmail.com>
> > > ---
> > > net/ipv4/tcp_timer.c | 5 ++++-
> > > 1 file changed, 4 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
> > > index 5a14a53a3c9e..4a43356a4e06 100644
> > > --- a/net/ipv4/tcp_timer.c
> > > +++ b/net/ipv4/tcp_timer.c
> > > @@ -50,7 +50,8 @@ static u32 tcp_clamp_rto_to_user_timeout(const struct sock *sk)
> > > u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when)
> > > {
> > > const struct inet_connection_sock *icsk = inet_csk(sk);
> > > - u32 remaining, user_timeout;
> > > + u32 user_timeout;
> > > + s32 remaining;
> > > s32 elapsed;
> > >
> > > user_timeout = READ_ONCE(icsk->icsk_user_timeout);
> > > @@ -61,6 +62,8 @@ u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when)
> > > if (unlikely(elapsed < 0))
> > > elapsed = 0;
> > > remaining = msecs_to_jiffies(user_timeout) - elapsed;
> > > + if (remaining <= 0)
> > > + return 1;
> >
> > I do not think this chunk is needed ?
> > If @remaining is signed, then perhaps change the following line to:
> >
> > remaining = max_t(int, remaining, TCP_TIMEOUT_MIN);
> >
>
> The if (remaining <= 0) return 1 handles the already-expired case and
> mirrors the logic in tcp_clamp_rto_to_user_timeout().
tcp_clamp_rto_to_user_timeout() has two conditionals.
if (remaining <= 0)
return 1;
return min_t(u32, icsk->icsk_rto, msecs_to_jiffies(remaining));
First one was to avoid to call msecs_to_jiffies() with a negative number.
tcp_clamp_probe0_to_user_timeout() has 3 tests already, you want to
add a fourth one...
I would prefer something less obscure.
We do not care if we return 1 or 2 (TCP_TIMEOUT_MIN) jiffies
>
> max_t(s32, remaining, TCP_TIMEOUT_MIN) with remaining changed to s32
> also fixes the underflow; I used the explicit early return for symmetry
> with the RTO helper, but I can switch that in v2 if you prefer.
>
> > Also, it would be great to have a new packetdrill test.
> >
>
> With packetdrill, AFAICS it would require a late ACK to be processed
> after TCP_USER_TIMEOUT has elapsed but before tcp_probe_timer() runs the
> abort check - i.e. a race between the RX softirq path and the timer.
> This is not purely an event/packet ordering problem, so it is not clear
> to me how a deterministic behavior can be simulated with packetdrill
> without tying it to exact probe timing.
I was trying to sense if the bug was serious or not, considering last
tcp_clamp_probe0_to_user_timeout()
statement is:
return min_t(u32, remaining, when);
Perhaps you should give more details in the changelog. What were the
symptoms of this bug, for TCP_USER_TIMEOUT users.
^ permalink raw reply
* [PATCH bpf v3] bpf: Fix NULL pointer dereference in bpf_sk_storage_clone and diag paths
From: Weiming Shi @ 2026-04-22 6:54 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Martin KaFai Lau, Alexei Starovoitov, Amery Hung,
Leon Hwang, Kees Cook, Fushuai Wang, Menglong Dong, netdev, bpf,
Xiang Mei, Weiming Shi
bpf_selem_unlink_nofail() sets SDATA(selem)->smap to NULL before
removing the selem from the storage hlist. A concurrent RCU reader in
bpf_sk_storage_clone() can observe the selem still on the list with
smap already NULL, causing a NULL pointer dereference.
general protection fault, probably for non-canonical address 0xdffffc000000000a:
KASAN: null-ptr-deref in range [0x0000000000000050-0x0000000000000057]
RIP: 0010:bpf_sk_storage_clone+0x1cd/0xaa0 net/core/bpf_sk_storage.c:174
Call Trace:
<IRQ>
sk_clone+0xfed/0x1980 net/core/sock.c:2591
inet_csk_clone_lock+0x30/0x760 net/ipv4/inet_connection_sock.c:1222
tcp_create_openreq_child+0x35/0x2680 net/ipv4/tcp_minisocks.c:571
tcp_v4_syn_recv_sock+0x123/0xf90 net/ipv4/tcp_ipv4.c:1729
tcp_check_req+0x8e1/0x2580 include/net/tcp.h:855
tcp_v4_rcv+0x1845/0x3b80 net/ipv4/tcp_ipv4.c:2347
Add a NULL check for smap in bpf_sk_storage_clone().
bpf_sk_storage_diag_put_all() and bpf_sk_storage_diag_put() have the
same unprotected dereference pattern, add NULL checks there as well and
pass the validated smap to diag_get() so it no longer performs its own
rcu_dereference.
Fixes: 5d800f87d0a5 ("bpf: Support lockless unlink when freeing map or local storage")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
---
v3:
pass smap to diag_get()
v2:
drop the NULL check in diag_get(); The caller already checks smap for
NULL.
net/core/bpf_sk_storage.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c
index f8338acebf077..1f9bd0005883b 100644
--- a/net/core/bpf_sk_storage.c
+++ b/net/core/bpf_sk_storage.c
@@ -172,7 +172,7 @@ int bpf_sk_storage_clone(const struct sock *sk, struct sock *newsk)
struct bpf_map *map;
smap = rcu_dereference(SDATA(selem)->smap);
- if (!(smap->map.map_flags & BPF_F_CLONE))
+ if (!smap || !(smap->map.map_flags & BPF_F_CLONE))
continue;
/* Note that for lockless listeners adding new element
@@ -534,10 +534,10 @@ bpf_sk_storage_diag_alloc(const struct nlattr *nla_stgs)
}
EXPORT_SYMBOL_GPL(bpf_sk_storage_diag_alloc);
-static int diag_get(struct bpf_local_storage_data *sdata, struct sk_buff *skb)
+static int diag_get(struct bpf_local_storage_map *smap,
+ struct bpf_local_storage_data *sdata, struct sk_buff *skb)
{
struct nlattr *nla_stg, *nla_value;
- struct bpf_local_storage_map *smap;
/* It cannot exceed max nlattr's payload */
BUILD_BUG_ON(U16_MAX - NLA_HDRLEN < BPF_LOCAL_STORAGE_MAX_VALUE_SIZE);
@@ -546,7 +546,6 @@ static int diag_get(struct bpf_local_storage_data *sdata, struct sk_buff *skb)
if (!nla_stg)
return -EMSGSIZE;
- smap = rcu_dereference(sdata->smap);
if (nla_put_u32(skb, SK_DIAG_BPF_STORAGE_MAP_ID, smap->map.id))
goto errout;
@@ -599,9 +598,11 @@ static int bpf_sk_storage_diag_put_all(struct sock *sk, struct sk_buff *skb,
saved_len = skb->len;
hlist_for_each_entry_rcu(selem, &sk_storage->list, snode) {
smap = rcu_dereference(SDATA(selem)->smap);
+ if (!smap)
+ continue;
diag_size += nla_value_size(smap->map.value_size);
- if (nla_stgs && diag_get(SDATA(selem), skb))
+ if (nla_stgs && diag_get(smap, SDATA(selem), skb))
/* Continue to learn diag_size */
err = -EMSGSIZE;
}
@@ -633,6 +634,7 @@ int bpf_sk_storage_diag_put(struct bpf_sk_storage_diag *diag,
unsigned int diag_size = nla_total_size(0);
struct bpf_local_storage *sk_storage;
struct bpf_local_storage_data *sdata;
+ struct bpf_local_storage_map *smap;
struct nlattr *nla_stgs;
unsigned int saved_len;
int err = 0;
@@ -668,7 +670,11 @@ int bpf_sk_storage_diag_put(struct bpf_sk_storage_diag *diag,
diag_size += nla_value_size(diag->maps[i]->value_size);
- if (nla_stgs && diag_get(sdata, skb))
+ smap = rcu_dereference(sdata->smap);
+ if (!smap)
+ continue;
+
+ if (nla_stgs && diag_get(smap, sdata, skb))
/* Continue to learn diag_size */
err = -EMSGSIZE;
}
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net 06/18] drivers: net: amd: Remove hplance and mvme147
From: Geert Uytterhoeven @ 2026-04-22 7:37 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan,
linux-kernel, netdev, linux-doc, linux-m68k
In-Reply-To: <20260421-v7-0-0-net-next-driver-removal-v1-v1-6-69517c689d1f@lunn.ch>
CC linux-m68k
On Tue, 21 Apr 2026 at 21:33, Andrew Lunn <andrew@lunn.ch> wrote:
> These drivers use the 7990 core with wrappers for the HP300 and
> Motorola MVME147 SBC circa 1998. It is unlikely they are used with a
> modern kernel.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> drivers/net/ethernet/amd/7990.c | 671 -------------------------------------
> drivers/net/ethernet/amd/7990.h | 251 --------------
> drivers/net/ethernet/amd/Kconfig | 18 -
> drivers/net/ethernet/amd/Makefile | 2 -
> drivers/net/ethernet/amd/hplance.c | 238 -------------
> drivers/net/ethernet/amd/hplance.h | 27 --
> drivers/net/ethernet/amd/mvme147.c | 198 -----------
> 7 files changed, 1405 deletions(-)
>
> diff --git a/drivers/net/ethernet/amd/7990.c b/drivers/net/ethernet/amd/7990.c
> deleted file mode 100644
> index 27792a52b6cf..000000000000
> --- a/drivers/net/ethernet/amd/7990.c
> +++ /dev/null
> @@ -1,671 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * 7990.c -- LANCE ethernet IC generic routines.
> - * This is an attempt to separate out the bits of various ethernet
> - * drivers that are common because they all use the AMD 7990 LANCE
> - * (Local Area Network Controller for Ethernet) chip.
> - *
> - * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
> - *
> - * Most of this stuff was obtained by looking at other LANCE drivers,
> - * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
> - * NB: this was made easy by the fact that Jes Sorensen had cleaned up
> - * most of a2025 and sunlance with the aim of merging them, so the
> - * common code was pretty obvious.
> - */
> -#include <linux/crc32.h>
> -#include <linux/delay.h>
> -#include <linux/errno.h>
> -#include <linux/netdevice.h>
> -#include <linux/etherdevice.h>
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -#include <linux/fcntl.h>
> -#include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -#include <linux/in.h>
> -#include <linux/route.h>
> -#include <linux/string.h>
> -#include <linux/skbuff.h>
> -#include <linux/pgtable.h>
> -#include <asm/irq.h>
> -/* Used for the temporal inet entries and routing */
> -#include <linux/socket.h>
> -#include <linux/bitops.h>
> -
> -#include <asm/io.h>
> -#include <asm/dma.h>
> -#ifdef CONFIG_HP300
> -#include <asm/blinken.h>
> -#endif
> -
> -#include "7990.h"
> -
> -#define WRITERAP(lp, x) out_be16(lp->base + LANCE_RAP, (x))
> -#define WRITERDP(lp, x) out_be16(lp->base + LANCE_RDP, (x))
> -#define READRDP(lp) in_be16(lp->base + LANCE_RDP)
> -
> -#if IS_ENABLED(CONFIG_HPLANCE)
> -#include "hplance.h"
> -
> -#undef WRITERAP
> -#undef WRITERDP
> -#undef READRDP
> -
> -#if IS_ENABLED(CONFIG_MVME147_NET)
> -
> -/* Lossage Factor Nine, Mr Sulu. */
> -#define WRITERAP(lp, x) (lp->writerap(lp, x))
> -#define WRITERDP(lp, x) (lp->writerdp(lp, x))
> -#define READRDP(lp) (lp->readrdp(lp))
> -
> -#else
> -
> -/* These inlines can be used if only CONFIG_HPLANCE is defined */
> -static inline void WRITERAP(struct lance_private *lp, __u16 value)
> -{
> - do {
> - out_be16(lp->base + HPLANCE_REGOFF + LANCE_RAP, value);
> - } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
> -}
> -
> -static inline void WRITERDP(struct lance_private *lp, __u16 value)
> -{
> - do {
> - out_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP, value);
> - } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
> -}
> -
> -static inline __u16 READRDP(struct lance_private *lp)
> -{
> - __u16 value;
> - do {
> - value = in_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP);
> - } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
> - return value;
> -}
> -
> -#endif
> -#endif /* IS_ENABLED(CONFIG_HPLANCE) */
> -
> -/* debugging output macros, various flavours */
> -/* #define TEST_HITS */
> -#ifdef UNDEF
> -#define PRINT_RINGS() \
> -do { \
> - int t; \
> - for (t = 0; t < RX_RING_SIZE; t++) { \
> - printk("R%d: @(%02X %04X) len %04X, mblen %04X, bits %02X\n", \
> - t, ib->brx_ring[t].rmd1_hadr, ib->brx_ring[t].rmd0, \
> - ib->brx_ring[t].length, \
> - ib->brx_ring[t].mblength, ib->brx_ring[t].rmd1_bits); \
> - } \
> - for (t = 0; t < TX_RING_SIZE; t++) { \
> - printk("T%d: @(%02X %04X) len %04X, misc %04X, bits %02X\n", \
> - t, ib->btx_ring[t].tmd1_hadr, ib->btx_ring[t].tmd0, \
> - ib->btx_ring[t].length, \
> - ib->btx_ring[t].misc, ib->btx_ring[t].tmd1_bits); \
> - } \
> -} while (0)
> -#else
> -#define PRINT_RINGS()
> -#endif
> -
> -/* Load the CSR registers. The LANCE has to be STOPped when we do this! */
> -static void load_csrs(struct lance_private *lp)
> -{
> - volatile struct lance_init_block *aib = lp->lance_init_block;
> - int leptr;
> -
> - leptr = LANCE_ADDR(aib);
> -
> - WRITERAP(lp, LE_CSR1); /* load address of init block */
> - WRITERDP(lp, leptr & 0xFFFF);
> - WRITERAP(lp, LE_CSR2);
> - WRITERDP(lp, leptr >> 16);
> - WRITERAP(lp, LE_CSR3);
> - WRITERDP(lp, lp->busmaster_regval); /* set byteswap/ALEctrl/byte ctrl */
> -
> - /* Point back to csr0 */
> - WRITERAP(lp, LE_CSR0);
> -}
> -
> -/* #define to 0 or 1 appropriately */
> -#define DEBUG_IRING 0
> -/* Set up the Lance Rx and Tx rings and the init block */
> -static void lance_init_ring(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - volatile struct lance_init_block *ib = lp->init_block;
> - volatile struct lance_init_block *aib; /* for LANCE_ADDR computations */
> - int leptr;
> - int i;
> -
> - aib = lp->lance_init_block;
> -
> - lp->rx_new = lp->tx_new = 0;
> - lp->rx_old = lp->tx_old = 0;
> -
> - ib->mode = LE_MO_PROM; /* normal, enable Tx & Rx */
> -
> - /* Copy the ethernet address to the lance init block
> - * Notice that we do a byteswap if we're big endian.
> - * [I think this is the right criterion; at least, sunlance,
> - * a2065 and atarilance do the byteswap and lance.c (PC) doesn't.
> - * However, the datasheet says that the BSWAP bit doesn't affect
> - * the init block, so surely it should be low byte first for
> - * everybody? Um.]
> - * We could define the ib->physaddr as three 16bit values and
> - * use (addr[1] << 8) | addr[0] & co, but this is more efficient.
> - */
> -#ifdef __BIG_ENDIAN
> - ib->phys_addr[0] = dev->dev_addr[1];
> - ib->phys_addr[1] = dev->dev_addr[0];
> - ib->phys_addr[2] = dev->dev_addr[3];
> - ib->phys_addr[3] = dev->dev_addr[2];
> - ib->phys_addr[4] = dev->dev_addr[5];
> - ib->phys_addr[5] = dev->dev_addr[4];
> -#else
> - for (i = 0; i < 6; i++)
> - ib->phys_addr[i] = dev->dev_addr[i];
> -#endif
> -
> - if (DEBUG_IRING)
> - printk("TX rings:\n");
> -
> - lp->tx_full = 0;
> - /* Setup the Tx ring entries */
> - for (i = 0; i < (1 << lp->lance_log_tx_bufs); i++) {
> - leptr = LANCE_ADDR(&aib->tx_buf[i][0]);
> - ib->btx_ring[i].tmd0 = leptr;
> - ib->btx_ring[i].tmd1_hadr = leptr >> 16;
> - ib->btx_ring[i].tmd1_bits = 0;
> - ib->btx_ring[i].length = 0xf000; /* The ones required by tmd2 */
> - ib->btx_ring[i].misc = 0;
> - if (DEBUG_IRING)
> - printk("%d: 0x%8.8x\n", i, leptr);
> - }
> -
> - /* Setup the Rx ring entries */
> - if (DEBUG_IRING)
> - printk("RX rings:\n");
> - for (i = 0; i < (1 << lp->lance_log_rx_bufs); i++) {
> - leptr = LANCE_ADDR(&aib->rx_buf[i][0]);
> -
> - ib->brx_ring[i].rmd0 = leptr;
> - ib->brx_ring[i].rmd1_hadr = leptr >> 16;
> - ib->brx_ring[i].rmd1_bits = LE_R1_OWN;
> - /* 0xf000 == bits that must be one (reserved, presumably) */
> - ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;
> - ib->brx_ring[i].mblength = 0;
> - if (DEBUG_IRING)
> - printk("%d: 0x%8.8x\n", i, leptr);
> - }
> -
> - /* Setup the initialization block */
> -
> - /* Setup rx descriptor pointer */
> - leptr = LANCE_ADDR(&aib->brx_ring);
> - ib->rx_len = (lp->lance_log_rx_bufs << 13) | (leptr >> 16);
> - ib->rx_ptr = leptr;
> - if (DEBUG_IRING)
> - printk("RX ptr: %8.8x\n", leptr);
> -
> - /* Setup tx descriptor pointer */
> - leptr = LANCE_ADDR(&aib->btx_ring);
> - ib->tx_len = (lp->lance_log_tx_bufs << 13) | (leptr >> 16);
> - ib->tx_ptr = leptr;
> - if (DEBUG_IRING)
> - printk("TX ptr: %8.8x\n", leptr);
> -
> - /* Clear the multicast filter */
> - ib->filter[0] = 0;
> - ib->filter[1] = 0;
> - PRINT_RINGS();
> -}
> -
> -/* LANCE must be STOPped before we do this, too... */
> -static int init_restart_lance(struct lance_private *lp)
> -{
> - int i;
> -
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_INIT);
> -
> - /* Need a hook here for sunlance ledma stuff */
> -
> - /* Wait for the lance to complete initialization */
> - for (i = 0; (i < 100) && !(READRDP(lp) & (LE_C0_ERR | LE_C0_IDON)); i++)
> - barrier();
> - if ((i == 100) || (READRDP(lp) & LE_C0_ERR)) {
> - printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, READRDP(lp));
> - return -1;
> - }
> -
> - /* Clear IDON by writing a "1", enable interrupts and start lance */
> - WRITERDP(lp, LE_C0_IDON);
> - WRITERDP(lp, LE_C0_INEA | LE_C0_STRT);
> -
> - return 0;
> -}
> -
> -static int lance_reset(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - int status;
> -
> - /* Stop the lance */
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_STOP);
> -
> - load_csrs(lp);
> - lance_init_ring(dev);
> - netif_trans_update(dev); /* prevent tx timeout */
> - status = init_restart_lance(lp);
> -#ifdef DEBUG_DRIVER
> - printk("Lance restart=%d\n", status);
> -#endif
> - return status;
> -}
> -
> -static int lance_rx(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - volatile struct lance_init_block *ib = lp->init_block;
> - volatile struct lance_rx_desc *rd;
> - unsigned char bits;
> -#ifdef TEST_HITS
> - int i;
> -#endif
> -
> -#ifdef TEST_HITS
> - printk("[");
> - for (i = 0; i < RX_RING_SIZE; i++) {
> - if (i == lp->rx_new)
> - printk("%s",
> - ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "_" : "X");
> - else
> - printk("%s",
> - ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "." : "1");
> - }
> - printk("]");
> -#endif
> -#ifdef CONFIG_HP300
> - blinken_leds(0x40, 0);
> -#endif
> - WRITERDP(lp, LE_C0_RINT | LE_C0_INEA); /* ack Rx int, reenable ints */
> - for (rd = &ib->brx_ring[lp->rx_new]; /* For each Rx ring we own... */
> - !((bits = rd->rmd1_bits) & LE_R1_OWN);
> - rd = &ib->brx_ring[lp->rx_new]) {
> -
> - /* We got an incomplete frame? */
> - if ((bits & LE_R1_POK) != LE_R1_POK) {
> - dev->stats.rx_over_errors++;
> - dev->stats.rx_errors++;
> - continue;
> - } else if (bits & LE_R1_ERR) {
> - /* Count only the end frame as a rx error,
> - * not the beginning
> - */
> - if (bits & LE_R1_BUF)
> - dev->stats.rx_fifo_errors++;
> - if (bits & LE_R1_CRC)
> - dev->stats.rx_crc_errors++;
> - if (bits & LE_R1_OFL)
> - dev->stats.rx_over_errors++;
> - if (bits & LE_R1_FRA)
> - dev->stats.rx_frame_errors++;
> - if (bits & LE_R1_EOP)
> - dev->stats.rx_errors++;
> - } else {
> - int len = (rd->mblength & 0xfff) - 4;
> - struct sk_buff *skb = netdev_alloc_skb(dev, len + 2);
> -
> - if (!skb) {
> - dev->stats.rx_dropped++;
> - rd->mblength = 0;
> - rd->rmd1_bits = LE_R1_OWN;
> - lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
> - return 0;
> - }
> -
> - skb_reserve(skb, 2); /* 16 byte align */
> - skb_put(skb, len); /* make room */
> - skb_copy_to_linear_data(skb,
> - (unsigned char *)&(ib->rx_buf[lp->rx_new][0]),
> - len);
> - skb->protocol = eth_type_trans(skb, dev);
> - netif_rx(skb);
> - dev->stats.rx_packets++;
> - dev->stats.rx_bytes += len;
> - }
> -
> - /* Return the packet to the pool */
> - rd->mblength = 0;
> - rd->rmd1_bits = LE_R1_OWN;
> - lp->rx_new = (lp->rx_new + 1) & lp->rx_ring_mod_mask;
> - }
> - return 0;
> -}
> -
> -static int lance_tx(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - volatile struct lance_init_block *ib = lp->init_block;
> - volatile struct lance_tx_desc *td;
> - int i, j;
> - int status;
> -
> -#ifdef CONFIG_HP300
> - blinken_leds(0x80, 0);
> -#endif
> - /* csr0 is 2f3 */
> - WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
> - /* csr0 is 73 */
> -
> - j = lp->tx_old;
> - for (i = j; i != lp->tx_new; i = j) {
> - td = &ib->btx_ring[i];
> -
> - /* If we hit a packet not owned by us, stop */
> - if (td->tmd1_bits & LE_T1_OWN)
> - break;
> -
> - if (td->tmd1_bits & LE_T1_ERR) {
> - status = td->misc;
> -
> - dev->stats.tx_errors++;
> - if (status & LE_T3_RTY)
> - dev->stats.tx_aborted_errors++;
> - if (status & LE_T3_LCOL)
> - dev->stats.tx_window_errors++;
> -
> - if (status & LE_T3_CLOS) {
> - dev->stats.tx_carrier_errors++;
> - if (lp->auto_select) {
> - lp->tpe = 1 - lp->tpe;
> - printk("%s: Carrier Lost, trying %s\n",
> - dev->name,
> - lp->tpe ? "TPE" : "AUI");
> - /* Stop the lance */
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_STOP);
> - lance_init_ring(dev);
> - load_csrs(lp);
> - init_restart_lance(lp);
> - return 0;
> - }
> - }
> -
> - /* buffer errors and underflows turn off the transmitter */
> - /* Restart the adapter */
> - if (status & (LE_T3_BUF|LE_T3_UFL)) {
> - dev->stats.tx_fifo_errors++;
> -
> - printk("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",
> - dev->name);
> - /* Stop the lance */
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_STOP);
> - lance_init_ring(dev);
> - load_csrs(lp);
> - init_restart_lance(lp);
> - return 0;
> - }
> - } else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {
> - /*
> - * So we don't count the packet more than once.
> - */
> - td->tmd1_bits &= ~(LE_T1_POK);
> -
> - /* One collision before packet was sent. */
> - if (td->tmd1_bits & LE_T1_EONE)
> - dev->stats.collisions++;
> -
> - /* More than one collision, be optimistic. */
> - if (td->tmd1_bits & LE_T1_EMORE)
> - dev->stats.collisions += 2;
> -
> - dev->stats.tx_packets++;
> - }
> -
> - j = (j + 1) & lp->tx_ring_mod_mask;
> - }
> - lp->tx_old = j;
> - WRITERDP(lp, LE_C0_TINT | LE_C0_INEA);
> - return 0;
> -}
> -
> -static irqreturn_t
> -lance_interrupt(int irq, void *dev_id)
> -{
> - struct net_device *dev = (struct net_device *)dev_id;
> - struct lance_private *lp = netdev_priv(dev);
> - int csr0;
> -
> - spin_lock(&lp->devlock);
> -
> - WRITERAP(lp, LE_CSR0); /* LANCE Controller Status */
> - csr0 = READRDP(lp);
> -
> - PRINT_RINGS();
> -
> - if (!(csr0 & LE_C0_INTR)) { /* Check if any interrupt has */
> - spin_unlock(&lp->devlock);
> - return IRQ_NONE; /* been generated by the Lance. */
> - }
> -
> - /* Acknowledge all the interrupt sources ASAP */
> - WRITERDP(lp, csr0 & ~(LE_C0_INEA|LE_C0_TDMD|LE_C0_STOP|LE_C0_STRT|LE_C0_INIT));
> -
> - if ((csr0 & LE_C0_ERR)) {
> - /* Clear the error condition */
> - WRITERDP(lp, LE_C0_BABL|LE_C0_ERR|LE_C0_MISS|LE_C0_INEA);
> - }
> -
> - if (csr0 & LE_C0_RINT)
> - lance_rx(dev);
> -
> - if (csr0 & LE_C0_TINT)
> - lance_tx(dev);
> -
> - /* Log misc errors. */
> - if (csr0 & LE_C0_BABL)
> - dev->stats.tx_errors++; /* Tx babble. */
> - if (csr0 & LE_C0_MISS)
> - dev->stats.rx_errors++; /* Missed a Rx frame. */
> - if (csr0 & LE_C0_MERR) {
> - printk("%s: Bus master arbitration failure, status %4.4x.\n",
> - dev->name, csr0);
> - /* Restart the chip. */
> - WRITERDP(lp, LE_C0_STRT);
> - }
> -
> - if (lp->tx_full && netif_queue_stopped(dev) && (TX_BUFFS_AVAIL >= 0)) {
> - lp->tx_full = 0;
> - netif_wake_queue(dev);
> - }
> -
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_BABL|LE_C0_CERR|LE_C0_MISS|LE_C0_MERR|LE_C0_IDON|LE_C0_INEA);
> -
> - spin_unlock(&lp->devlock);
> - return IRQ_HANDLED;
> -}
> -
> -int lance_open(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - int res;
> -
> - /* Install the Interrupt handler. Or we could shunt this out to specific drivers? */
> - if (request_irq(lp->irq, lance_interrupt, IRQF_SHARED, lp->name, dev))
> - return -EAGAIN;
> -
> - res = lance_reset(dev);
> - spin_lock_init(&lp->devlock);
> - netif_start_queue(dev);
> -
> - return res;
> -}
> -EXPORT_SYMBOL_GPL(lance_open);
> -
> -int lance_close(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> -
> - netif_stop_queue(dev);
> -
> - /* Stop the LANCE */
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_STOP);
> -
> - free_irq(lp->irq, dev);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL_GPL(lance_close);
> -
> -void lance_tx_timeout(struct net_device *dev, unsigned int txqueue)
> -{
> - printk("lance_tx_timeout\n");
> - lance_reset(dev);
> - netif_trans_update(dev); /* prevent tx timeout */
> - netif_wake_queue(dev);
> -}
> -EXPORT_SYMBOL_GPL(lance_tx_timeout);
> -
> -netdev_tx_t lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - volatile struct lance_init_block *ib = lp->init_block;
> - int entry, skblen, len;
> - static int outs;
> - unsigned long flags;
> -
> - netif_stop_queue(dev);
> -
> - if (!TX_BUFFS_AVAIL) {
> - dev_consume_skb_any(skb);
> - return NETDEV_TX_OK;
> - }
> -
> - skblen = skb->len;
> -
> -#ifdef DEBUG_DRIVER
> - /* dump the packet */
> - {
> - int i;
> -
> - for (i = 0; i < 64; i++) {
> - if ((i % 16) == 0)
> - printk("\n");
> - printk("%2.2x ", skb->data[i]);
> - }
> - }
> -#endif
> - len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;
> - entry = lp->tx_new & lp->tx_ring_mod_mask;
> - ib->btx_ring[entry].length = (-len) | 0xf000;
> - ib->btx_ring[entry].misc = 0;
> -
> - if (skb->len < ETH_ZLEN)
> - memset((void *)&ib->tx_buf[entry][0], 0, ETH_ZLEN);
> - skb_copy_from_linear_data(skb, (void *)&ib->tx_buf[entry][0], skblen);
> -
> - /* Now, give the packet to the lance */
> - ib->btx_ring[entry].tmd1_bits = (LE_T1_POK|LE_T1_OWN);
> - lp->tx_new = (lp->tx_new + 1) & lp->tx_ring_mod_mask;
> -
> - outs++;
> - /* Kick the lance: transmit now */
> - WRITERDP(lp, LE_C0_INEA | LE_C0_TDMD);
> - dev_consume_skb_any(skb);
> -
> - spin_lock_irqsave(&lp->devlock, flags);
> - if (TX_BUFFS_AVAIL)
> - netif_start_queue(dev);
> - else
> - lp->tx_full = 1;
> - spin_unlock_irqrestore(&lp->devlock, flags);
> -
> - return NETDEV_TX_OK;
> -}
> -EXPORT_SYMBOL_GPL(lance_start_xmit);
> -
> -/* taken from the depca driver via a2065.c */
> -static void lance_load_multicast(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - volatile struct lance_init_block *ib = lp->init_block;
> - volatile u16 *mcast_table = (u16 *)&ib->filter;
> - struct netdev_hw_addr *ha;
> - u32 crc;
> -
> - /* set all multicast bits */
> - if (dev->flags & IFF_ALLMULTI) {
> - ib->filter[0] = 0xffffffff;
> - ib->filter[1] = 0xffffffff;
> - return;
> - }
> - /* clear the multicast filter */
> - ib->filter[0] = 0;
> - ib->filter[1] = 0;
> -
> - /* Add addresses */
> - netdev_for_each_mc_addr(ha, dev) {
> - crc = ether_crc_le(6, ha->addr);
> - crc = crc >> 26;
> - mcast_table[crc >> 4] |= 1 << (crc & 0xf);
> - }
> -}
> -
> -
> -void lance_set_multicast(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> - volatile struct lance_init_block *ib = lp->init_block;
> - int stopped;
> -
> - stopped = netif_queue_stopped(dev);
> - if (!stopped)
> - netif_stop_queue(dev);
> -
> - while (lp->tx_old != lp->tx_new)
> - schedule();
> -
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_STOP);
> - lance_init_ring(dev);
> -
> - if (dev->flags & IFF_PROMISC) {
> - ib->mode |= LE_MO_PROM;
> - } else {
> - ib->mode &= ~LE_MO_PROM;
> - lance_load_multicast(dev);
> - }
> - load_csrs(lp);
> - init_restart_lance(lp);
> -
> - if (!stopped)
> - netif_start_queue(dev);
> -}
> -EXPORT_SYMBOL_GPL(lance_set_multicast);
> -
> -#ifdef CONFIG_NET_POLL_CONTROLLER
> -void lance_poll(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> -
> - spin_lock(&lp->devlock);
> - WRITERAP(lp, LE_CSR0);
> - WRITERDP(lp, LE_C0_STRT);
> - spin_unlock(&lp->devlock);
> - lance_interrupt(dev->irq, dev);
> -}
> -EXPORT_SYMBOL_GPL(lance_poll);
> -#endif
> -
> -MODULE_DESCRIPTION("LANCE Ethernet IC generic routines");
> -MODULE_LICENSE("GPL");
> diff --git a/drivers/net/ethernet/amd/7990.h b/drivers/net/ethernet/amd/7990.h
> deleted file mode 100644
> index e53551daeea1..000000000000
> --- a/drivers/net/ethernet/amd/7990.h
> +++ /dev/null
> @@ -1,251 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * 7990.h -- LANCE ethernet IC generic routines.
> - * This is an attempt to separate out the bits of various ethernet
> - * drivers that are common because they all use the AMD 7990 LANCE
> - * (Local Area Network Controller for Ethernet) chip.
> - *
> - * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
> - *
> - * Most of this stuff was obtained by looking at other LANCE drivers,
> - * in particular a2065.[ch]. The AMD C-LANCE datasheet was also helpful.
> - */
> -
> -#ifndef _7990_H
> -#define _7990_H
> -
> -/* The lance only has two register locations. We communicate mostly via memory. */
> -#define LANCE_RDP 0 /* Register Data Port */
> -#define LANCE_RAP 2 /* Register Address Port */
> -
> -/* Transmit/receive ring definitions.
> - * We allow the specific drivers to override these defaults if they want to.
> - * NB: according to lance.c, increasing the number of buffers is a waste
> - * of space and reduces the chance that an upper layer will be able to
> - * reorder queued Tx packets based on priority. [Clearly there is a minimum
> - * limit too: too small and we drop rx packets and can't tx at full speed.]
> - * 4+4 seems to be the usual setting; the atarilance driver uses 3 and 5.
> - */
> -
> -/* Blast! This won't work. The problem is that we can't specify a default
> - * setting because that would cause the lance_init_block struct to be
> - * too long (and overflow the RAM on shared-memory cards like the HP LANCE.
> - */
> -#ifndef LANCE_LOG_TX_BUFFERS
> -#define LANCE_LOG_TX_BUFFERS 1
> -#define LANCE_LOG_RX_BUFFERS 3
> -#endif
> -
> -#define TX_RING_SIZE (1 << LANCE_LOG_TX_BUFFERS)
> -#define RX_RING_SIZE (1 << LANCE_LOG_RX_BUFFERS)
> -#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
> -#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
> -#define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
> -#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
> -#define PKT_BUFF_SIZE (1544)
> -#define RX_BUFF_SIZE PKT_BUFF_SIZE
> -#define TX_BUFF_SIZE PKT_BUFF_SIZE
> -
> -/* Each receive buffer is described by a receive message descriptor (RMD) */
> -struct lance_rx_desc {
> - volatile unsigned short rmd0; /* low address of packet */
> - volatile unsigned char rmd1_bits; /* descriptor bits */
> - volatile unsigned char rmd1_hadr; /* high address of packet */
> - volatile short length; /* This length is 2s complement (negative)!
> - * Buffer length */
> - volatile unsigned short mblength; /* Actual number of bytes received */
> -};
> -
> -/* Ditto for TMD: */
> -struct lance_tx_desc {
> - volatile unsigned short tmd0; /* low address of packet */
> - volatile unsigned char tmd1_bits; /* descriptor bits */
> - volatile unsigned char tmd1_hadr; /* high address of packet */
> - volatile short length; /* Length is 2s complement (negative)! */
> - volatile unsigned short misc;
> -};
> -
> -/* There are three memory structures accessed by the LANCE:
> - * the initialization block, the receive and transmit descriptor rings,
> - * and the data buffers themselves. In fact we might as well put the
> - * init block,the Tx and Rx rings and the buffers together in memory:
> - */
> -struct lance_init_block {
> - volatile unsigned short mode; /* Pre-set mode (reg. 15) */
> - volatile unsigned char phys_addr[6]; /* Physical ethernet address */
> - volatile unsigned filter[2]; /* Multicast filter (64 bits) */
> -
> - /* Receive and transmit ring base, along with extra bits. */
> - volatile unsigned short rx_ptr; /* receive descriptor addr */
> - volatile unsigned short rx_len; /* receive len and high addr */
> - volatile unsigned short tx_ptr; /* transmit descriptor addr */
> - volatile unsigned short tx_len; /* transmit len and high addr */
> -
> - /* The Tx and Rx ring entries must be aligned on 8-byte boundaries.
> - * This will be true if this whole struct is 8-byte aligned.
> - */
> - volatile struct lance_tx_desc btx_ring[TX_RING_SIZE];
> - volatile struct lance_rx_desc brx_ring[RX_RING_SIZE];
> -
> - volatile char tx_buf[TX_RING_SIZE][TX_BUFF_SIZE];
> - volatile char rx_buf[RX_RING_SIZE][RX_BUFF_SIZE];
> - /* we use this just to make the struct big enough that we can move its startaddr
> - * in order to force alignment to an eight byte boundary.
> - */
> -};
> -
> -/* This is where we keep all the stuff the driver needs to know about.
> - * I'm definitely unhappy about the mechanism for allowing specific
> - * drivers to add things...
> - */
> -struct lance_private {
> - const char *name;
> - unsigned long base;
> - volatile struct lance_init_block *init_block; /* CPU address of RAM */
> - volatile struct lance_init_block *lance_init_block; /* LANCE address of RAM */
> -
> - int rx_new, tx_new;
> - int rx_old, tx_old;
> -
> - int lance_log_rx_bufs, lance_log_tx_bufs;
> - int rx_ring_mod_mask, tx_ring_mod_mask;
> -
> - int tpe; /* TPE is selected */
> - int auto_select; /* cable-selection is by carrier */
> - unsigned short busmaster_regval;
> -
> - unsigned int irq; /* IRQ to register */
> -
> - /* This is because the HP LANCE is disgusting and you have to check
> - * a DIO-specific register every time you read/write the LANCE regs :-<
> - * [could we get away with making these some sort of macro?]
> - */
> - void (*writerap)(void *, unsigned short);
> - void (*writerdp)(void *, unsigned short);
> - unsigned short (*readrdp)(void *);
> - spinlock_t devlock;
> - char tx_full;
> -};
> -
> -/*
> - * Am7990 Control and Status Registers
> - */
> -#define LE_CSR0 0x0000 /* LANCE Controller Status */
> -#define LE_CSR1 0x0001 /* IADR[15:0] (bit0==0 ie word aligned) */
> -#define LE_CSR2 0x0002 /* IADR[23:16] (high bits reserved) */
> -#define LE_CSR3 0x0003 /* Misc */
> -
> -/*
> - * Bit definitions for CSR0 (LANCE Controller Status)
> - */
> -#define LE_C0_ERR 0x8000 /* Error = BABL | CERR | MISS | MERR */
> -#define LE_C0_BABL 0x4000 /* Babble: Transmitted too many bits */
> -#define LE_C0_CERR 0x2000 /* No Heartbeat (10BASE-T) */
> -#define LE_C0_MISS 0x1000 /* Missed Frame (no rx buffer to put it in) */
> -#define LE_C0_MERR 0x0800 /* Memory Error */
> -#define LE_C0_RINT 0x0400 /* Receive Interrupt */
> -#define LE_C0_TINT 0x0200 /* Transmit Interrupt */
> -#define LE_C0_IDON 0x0100 /* Initialization Done */
> -#define LE_C0_INTR 0x0080 /* Interrupt Flag
> - = BABL | MISS | MERR | RINT | TINT | IDON */
> -#define LE_C0_INEA 0x0040 /* Interrupt Enable */
> -#define LE_C0_RXON 0x0020 /* Receive On */
> -#define LE_C0_TXON 0x0010 /* Transmit On */
> -#define LE_C0_TDMD 0x0008 /* Transmit Demand */
> -#define LE_C0_STOP 0x0004 /* Stop */
> -#define LE_C0_STRT 0x0002 /* Start */
> -#define LE_C0_INIT 0x0001 /* Initialize */
> -
> -
> -/*
> - * Bit definitions for CSR3
> - */
> -#define LE_C3_BSWP 0x0004 /* Byte Swap (on for big endian byte order) */
> -#define LE_C3_ACON 0x0002 /* ALE Control (on for active low ALE) */
> -#define LE_C3_BCON 0x0001 /* Byte Control */
> -
> -
> -/*
> - * Mode Flags
> - */
> -#define LE_MO_PROM 0x8000 /* Promiscuous Mode */
> -/* these next ones 0x4000 -- 0x0080 are not available on the LANCE 7990,
> - * but they are in NetBSD's am7990.h, presumably for backwards-compatible chips
> - */
> -#define LE_MO_DRCVBC 0x4000 /* disable receive broadcast */
> -#define LE_MO_DRCVPA 0x2000 /* disable physical address detection */
> -#define LE_MO_DLNKTST 0x1000 /* disable link status */
> -#define LE_MO_DAPC 0x0800 /* disable automatic polarity correction */
> -#define LE_MO_MENDECL 0x0400 /* MENDEC loopback mode */
> -#define LE_MO_LRTTSEL 0x0200 /* lower RX threshold / TX mode selection */
> -#define LE_MO_PSEL1 0x0100 /* port selection bit1 */
> -#define LE_MO_PSEL0 0x0080 /* port selection bit0 */
> -/* and this one is from the C-LANCE data sheet... */
> -#define LE_MO_EMBA 0x0080 /* Enable Modified Backoff Algorithm
> - (C-LANCE, not original LANCE) */
> -#define LE_MO_INTL 0x0040 /* Internal Loopback */
> -#define LE_MO_DRTY 0x0020 /* Disable Retry */
> -#define LE_MO_FCOLL 0x0010 /* Force Collision */
> -#define LE_MO_DXMTFCS 0x0008 /* Disable Transmit CRC */
> -#define LE_MO_LOOP 0x0004 /* Loopback Enable */
> -#define LE_MO_DTX 0x0002 /* Disable Transmitter */
> -#define LE_MO_DRX 0x0001 /* Disable Receiver */
> -
> -
> -/*
> - * Receive Flags
> - */
> -#define LE_R1_OWN 0x80 /* LANCE owns the descriptor */
> -#define LE_R1_ERR 0x40 /* Error */
> -#define LE_R1_FRA 0x20 /* Framing Error */
> -#define LE_R1_OFL 0x10 /* Overflow Error */
> -#define LE_R1_CRC 0x08 /* CRC Error */
> -#define LE_R1_BUF 0x04 /* Buffer Error */
> -#define LE_R1_SOP 0x02 /* Start of Packet */
> -#define LE_R1_EOP 0x01 /* End of Packet */
> -#define LE_R1_POK 0x03 /* Packet is complete: SOP + EOP */
> -
> -
> -/*
> - * Transmit Flags
> - */
> -#define LE_T1_OWN 0x80 /* LANCE owns the descriptor */
> -#define LE_T1_ERR 0x40 /* Error */
> -#define LE_T1_RES 0x20 /* Reserved, LANCE writes this with a zero */
> -#define LE_T1_EMORE 0x10 /* More than one retry needed */
> -#define LE_T1_EONE 0x08 /* One retry needed */
> -#define LE_T1_EDEF 0x04 /* Deferred */
> -#define LE_T1_SOP 0x02 /* Start of Packet */
> -#define LE_T1_EOP 0x01 /* End of Packet */
> -#define LE_T1_POK 0x03 /* Packet is complete: SOP + EOP */
> -
> -/*
> - * Error Flags
> - */
> -#define LE_T3_BUF 0x8000 /* Buffer Error */
> -#define LE_T3_UFL 0x4000 /* Underflow Error */
> -#define LE_T3_LCOL 0x1000 /* Late Collision */
> -#define LE_T3_CLOS 0x0800 /* Loss of Carrier */
> -#define LE_T3_RTY 0x0400 /* Retry Error */
> -#define LE_T3_TDR 0x03ff /* Time Domain Reflectometry */
> -
> -/* Miscellaneous useful macros */
> -
> -#define TX_BUFFS_AVAIL ((lp->tx_old <= lp->tx_new) ? \
> - lp->tx_old + lp->tx_ring_mod_mask - lp->tx_new : \
> - lp->tx_old - lp->tx_new - 1)
> -
> -/* The LANCE only uses 24 bit addresses. This does the obvious thing. */
> -#define LANCE_ADDR(x) ((int)(x) & ~0xff000000)
> -
> -/* Now the prototypes we export */
> -int lance_open(struct net_device *dev);
> -int lance_close(struct net_device *dev);
> -netdev_tx_t lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
> -void lance_set_multicast(struct net_device *dev);
> -void lance_tx_timeout(struct net_device *dev, unsigned int txqueue);
> -#ifdef CONFIG_NET_POLL_CONTROLLER
> -void lance_poll(struct net_device *dev);
> -#endif
> -
> -#endif /* ndef _7990_H */
> diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig
> index 45e8d698781c..9e83f3aa435a 100644
> --- a/drivers/net/ethernet/amd/Kconfig
> +++ b/drivers/net/ethernet/amd/Kconfig
> @@ -93,14 +93,6 @@ config DECLANCE
> DEC (now Compaq) based on the AMD LANCE chipset, including the
> DEPCA series. (This chipset is better known via the NE2100 cards.)
>
> -config HPLANCE
> - tristate "HP on-board LANCE support"
> - depends on DIO
> - select CRC32
> - help
> - If you want to use the builtin "LANCE" Ethernet controller on an
> - HP300 machine, say Y here.
> -
> config MIPS_AU1X00_ENET
> tristate "MIPS AU1000 Ethernet support"
> depends on MIPS_ALCHEMY
> @@ -110,16 +102,6 @@ config MIPS_AU1X00_ENET
> If you have an Alchemy Semi AU1X00 based system
> say Y. Otherwise, say N.
>
> -config MVME147_NET
> - tristate "MVME147 (LANCE) Ethernet support"
> - depends on MVME147
> - select CRC32
> - help
> - Support for the on-board Ethernet interface on the Motorola MVME147
> - single-board computer. Say Y here to include the
> - driver for this chip in your kernel.
> - To compile this driver as a module, choose M here.
> -
> config PCMCIA_NMCLAN
> tristate "New Media PCMCIA support"
> depends on PCMCIA && HAS_IOPORT
> diff --git a/drivers/net/ethernet/amd/Makefile b/drivers/net/ethernet/amd/Makefile
> index 2dcfb84731e1..387ec74e8e95 100644
> --- a/drivers/net/ethernet/amd/Makefile
> +++ b/drivers/net/ethernet/amd/Makefile
> @@ -8,10 +8,8 @@ obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
> obj-$(CONFIG_ARIADNE) += ariadne.o
> obj-$(CONFIG_ATARILANCE) += atarilance.o
> obj-$(CONFIG_DECLANCE) += declance.o
> -obj-$(CONFIG_HPLANCE) += hplance.o 7990.o
> obj-$(CONFIG_LANCE) += lance.o
> obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
> -obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o
> obj-$(CONFIG_PCMCIA_NMCLAN) += nmclan_cs.o
> obj-$(CONFIG_PCNET32) += pcnet32.o
> obj-$(CONFIG_SUN3LANCE) += sun3lance.o
> diff --git a/drivers/net/ethernet/amd/hplance.c b/drivers/net/ethernet/amd/hplance.c
> deleted file mode 100644
> index df42294530cb..000000000000
> --- a/drivers/net/ethernet/amd/hplance.c
> +++ /dev/null
> @@ -1,238 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/* hplance.c : the Linux/hp300/lance ethernet driver
> - *
> - * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
> - * Based on the Sun Lance driver and the NetBSD HP Lance driver
> - * Uses the generic 7990.c LANCE code.
> - */
> -
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -#include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -#include <linux/string.h>
> -#include <linux/delay.h>
> -#include <linux/init.h>
> -#include <linux/errno.h>
> -#include <linux/pgtable.h>
> -/* Used for the temporal inet entries and routing */
> -#include <linux/socket.h>
> -#include <linux/route.h>
> -#include <linux/dio.h>
> -#include <linux/netdevice.h>
> -#include <linux/etherdevice.h>
> -#include <linux/skbuff.h>
> -
> -#include <asm/io.h>
> -
> -#include "hplance.h"
> -
> -/* We have 16392 bytes of RAM for the init block and buffers. This places
> - * an upper limit on the number of buffers we can use. NetBSD uses 8 Rx
> - * buffers and 2 Tx buffers, it takes (8 + 2) * 1544 bytes.
> - */
> -#define LANCE_LOG_TX_BUFFERS 1
> -#define LANCE_LOG_RX_BUFFERS 3
> -
> -#include "7990.h" /* use generic LANCE code */
> -
> -/* Our private data structure */
> -struct hplance_private {
> - struct lance_private lance;
> -};
> -
> -/* function prototypes... This is easy because all the grot is in the
> - * generic LANCE support. All we have to support is probing for boards,
> - * plus board-specific init, open and close actions.
> - * Oh, and we need to tell the generic code how to read and write LANCE registers...
> - */
> -static int hplance_init_one(struct dio_dev *d, const struct dio_device_id *ent);
> -static void hplance_init(struct net_device *dev, struct dio_dev *d);
> -static void hplance_remove_one(struct dio_dev *d);
> -static void hplance_writerap(void *priv, unsigned short value);
> -static void hplance_writerdp(void *priv, unsigned short value);
> -static unsigned short hplance_readrdp(void *priv);
> -static int hplance_open(struct net_device *dev);
> -static int hplance_close(struct net_device *dev);
> -
> -static struct dio_device_id hplance_dio_tbl[] = {
> - { DIO_ID_LAN },
> - { 0 }
> -};
> -
> -static struct dio_driver hplance_driver = {
> - .name = "hplance",
> - .id_table = hplance_dio_tbl,
> - .probe = hplance_init_one,
> - .remove = hplance_remove_one,
> -};
> -
> -static const struct net_device_ops hplance_netdev_ops = {
> - .ndo_open = hplance_open,
> - .ndo_stop = hplance_close,
> - .ndo_start_xmit = lance_start_xmit,
> - .ndo_set_rx_mode = lance_set_multicast,
> - .ndo_validate_addr = eth_validate_addr,
> - .ndo_set_mac_address = eth_mac_addr,
> -#ifdef CONFIG_NET_POLL_CONTROLLER
> - .ndo_poll_controller = lance_poll,
> -#endif
> -};
> -
> -/* Find all the HP Lance boards and initialise them... */
> -static int hplance_init_one(struct dio_dev *d, const struct dio_device_id *ent)
> -{
> - struct net_device *dev;
> - int err = -ENOMEM;
> -
> - dev = alloc_etherdev(sizeof(struct hplance_private));
> - if (!dev)
> - goto out;
> -
> - err = -EBUSY;
> - if (!request_mem_region(dio_resource_start(d),
> - dio_resource_len(d), d->name))
> - goto out_free_netdev;
> -
> - hplance_init(dev, d);
> - err = register_netdev(dev);
> - if (err)
> - goto out_release_mem_region;
> -
> - dio_set_drvdata(d, dev);
> -
> - printk(KERN_INFO "%s: %s; select code %d, addr %pM, irq %d\n",
> - dev->name, d->name, d->scode, dev->dev_addr, d->ipl);
> -
> - return 0;
> -
> - out_release_mem_region:
> - release_mem_region(dio_resource_start(d), dio_resource_len(d));
> - out_free_netdev:
> - free_netdev(dev);
> - out:
> - return err;
> -}
> -
> -static void hplance_remove_one(struct dio_dev *d)
> -{
> - struct net_device *dev = dio_get_drvdata(d);
> -
> - unregister_netdev(dev);
> - release_mem_region(dio_resource_start(d), dio_resource_len(d));
> - free_netdev(dev);
> -}
> -
> -/* Initialise a single lance board at the given DIO device */
> -static void hplance_init(struct net_device *dev, struct dio_dev *d)
> -{
> - unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
> - struct hplance_private *lp;
> - u8 addr[ETH_ALEN];
> - int i;
> -
> - /* reset the board */
> - out_8(va + DIO_IDOFF, 0xff);
> - udelay(100); /* ariba! ariba! udelay! udelay! */
> -
> - /* Fill the dev fields */
> - dev->base_addr = va;
> - dev->netdev_ops = &hplance_netdev_ops;
> - dev->dma = 0;
> -
> - for (i = 0; i < 6; i++) {
> - /* The NVRAM holds our ethernet address, one nibble per byte,
> - * at bytes NVRAMOFF+1,3,5,7,9...
> - */
> - addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
> - | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
> - }
> - eth_hw_addr_set(dev, addr);
> -
> - lp = netdev_priv(dev);
> - lp->lance.name = d->name;
> - lp->lance.base = va;
> - lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */
> - lp->lance.lance_init_block = NULL; /* LANCE addr of same RAM */
> - lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */
> - lp->lance.irq = d->ipl;
> - lp->lance.writerap = hplance_writerap;
> - lp->lance.writerdp = hplance_writerdp;
> - lp->lance.readrdp = hplance_readrdp;
> - lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
> - lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
> - lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
> - lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
> -}
> -
> -/* This is disgusting. We have to check the DIO status register for ack every
> - * time we read or write the LANCE registers.
> - */
> -static void hplance_writerap(void *priv, unsigned short value)
> -{
> - struct lance_private *lp = (struct lance_private *)priv;
> -
> - do {
> - out_be16(lp->base + HPLANCE_REGOFF + LANCE_RAP, value);
> - } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
> -}
> -
> -static void hplance_writerdp(void *priv, unsigned short value)
> -{
> - struct lance_private *lp = (struct lance_private *)priv;
> -
> - do {
> - out_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP, value);
> - } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
> -}
> -
> -static unsigned short hplance_readrdp(void *priv)
> -{
> - struct lance_private *lp = (struct lance_private *)priv;
> - __u16 value;
> -
> - do {
> - value = in_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP);
> - } while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
> - return value;
> -}
> -
> -static int hplance_open(struct net_device *dev)
> -{
> - int status;
> - struct lance_private *lp = netdev_priv(dev);
> -
> - status = lance_open(dev); /* call generic lance open code */
> - if (status)
> - return status;
> - /* enable interrupts at board level. */
> - out_8(lp->base + HPLANCE_STATUS, LE_IE);
> -
> - return 0;
> -}
> -
> -static int hplance_close(struct net_device *dev)
> -{
> - struct lance_private *lp = netdev_priv(dev);
> -
> - out_8(lp->base + HPLANCE_STATUS, 0); /* disable interrupts at boardlevel */
> - lance_close(dev);
> - return 0;
> -}
> -
> -static int __init hplance_init_module(void)
> -{
> - return dio_register_driver(&hplance_driver);
> -}
> -
> -static void __exit hplance_cleanup_module(void)
> -{
> - dio_unregister_driver(&hplance_driver);
> -}
> -
> -module_init(hplance_init_module);
> -module_exit(hplance_cleanup_module);
> -
> -MODULE_DESCRIPTION("HP300 on-board LANCE Ethernet driver");
> -MODULE_LICENSE("GPL");
> diff --git a/drivers/net/ethernet/amd/hplance.h b/drivers/net/ethernet/amd/hplance.h
> deleted file mode 100644
> index bc845a2c60c1..000000000000
> --- a/drivers/net/ethernet/amd/hplance.h
> +++ /dev/null
> @@ -1,27 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/* Random defines and structures for the HP Lance driver.
> - * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
> - * Based on the Sun Lance driver and the NetBSD HP Lance driver
> - */
> -
> -/* Registers */
> -#define HPLANCE_ID 0x01 /* DIO register: ID byte */
> -#define HPLANCE_STATUS 0x03 /* DIO register: interrupt enable/status */
> -
> -/* Control and status bits for the status register */
> -#define LE_IE 0x80 /* interrupt enable */
> -#define LE_IR 0x40 /* interrupt requested */
> -#define LE_LOCK 0x08 /* lock status register */
> -#define LE_ACK 0x04 /* ack of lock */
> -#define LE_JAB 0x02 /* loss of tx clock (???) */
> -/* We can also extract the IPL from the status register with the standard
> - * DIO_IPL(hplance) macro, or using dio_scodetoipl()
> - */
> -
> -/* These are the offsets for the DIO regs (hplance_reg), lance_ioreg,
> - * memory and NVRAM:
> - */
> -#define HPLANCE_IDOFF 0 /* board baseaddr */
> -#define HPLANCE_REGOFF 0x4000 /* lance registers */
> -#define HPLANCE_MEMOFF 0x8000 /* struct lance_init_block */
> -#define HPLANCE_NVRAMOFF 0xC008 /* etheraddress as one *nibble* per byte */
> diff --git a/drivers/net/ethernet/amd/mvme147.c b/drivers/net/ethernet/amd/mvme147.c
> deleted file mode 100644
> index f19b04b92fa9..000000000000
> --- a/drivers/net/ethernet/amd/mvme147.c
> +++ /dev/null
> @@ -1,198 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/* mvme147.c : the Linux/mvme147/lance ethernet driver
> - *
> - * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
> - * Based on the Sun Lance driver and the NetBSD HP Lance driver
> - * Uses the generic 7990.c LANCE code.
> - */
> -
> -#include <linux/module.h>
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -#include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -#include <linux/string.h>
> -#include <linux/delay.h>
> -#include <linux/init.h>
> -#include <linux/errno.h>
> -#include <linux/gfp.h>
> -#include <linux/pgtable.h>
> -/* Used for the temporal inet entries and routing */
> -#include <linux/socket.h>
> -#include <linux/route.h>
> -#include <linux/netdevice.h>
> -#include <linux/etherdevice.h>
> -#include <linux/skbuff.h>
> -
> -#include <asm/io.h>
> -#include <asm/mvme147hw.h>
> -
> -/* We have 32K of RAM for the init block and buffers. This places
> - * an upper limit on the number of buffers we can use. NetBSD uses 8 Rx
> - * buffers and 2 Tx buffers, it takes (8 + 2) * 1544 bytes.
> - */
> -#define LANCE_LOG_TX_BUFFERS 1
> -#define LANCE_LOG_RX_BUFFERS 3
> -
> -#include "7990.h" /* use generic LANCE code */
> -
> -/* Our private data structure */
> -struct m147lance_private {
> - struct lance_private lance;
> - unsigned long ram;
> -};
> -
> -/* function prototypes... This is easy because all the grot is in the
> - * generic LANCE support. All we have to support is probing for boards,
> - * plus board-specific init, open and close actions.
> - * Oh, and we need to tell the generic code how to read and write LANCE registers...
> - */
> -static int m147lance_open(struct net_device *dev);
> -static int m147lance_close(struct net_device *dev);
> -static void m147lance_writerap(struct lance_private *lp, unsigned short value);
> -static void m147lance_writerdp(struct lance_private *lp, unsigned short value);
> -static unsigned short m147lance_readrdp(struct lance_private *lp);
> -
> -typedef void (*writerap_t)(void *, unsigned short);
> -typedef void (*writerdp_t)(void *, unsigned short);
> -typedef unsigned short (*readrdp_t)(void *);
> -
> -static const struct net_device_ops lance_netdev_ops = {
> - .ndo_open = m147lance_open,
> - .ndo_stop = m147lance_close,
> - .ndo_start_xmit = lance_start_xmit,
> - .ndo_set_rx_mode = lance_set_multicast,
> - .ndo_tx_timeout = lance_tx_timeout,
> - .ndo_validate_addr = eth_validate_addr,
> - .ndo_set_mac_address = eth_mac_addr,
> -};
> -
> -/* Initialise the one and only on-board 7990 */
> -static struct net_device * __init mvme147lance_probe(void)
> -{
> - struct net_device *dev;
> - static int called;
> - static const char name[] = "MVME147 LANCE";
> - struct m147lance_private *lp;
> - u8 macaddr[ETH_ALEN];
> - u_long *addr;
> - u_long address;
> - int err;
> -
> - if (!MACH_IS_MVME147 || called)
> - return ERR_PTR(-ENODEV);
> - called++;
> -
> - dev = alloc_etherdev(sizeof(struct m147lance_private));
> - if (!dev)
> - return ERR_PTR(-ENOMEM);
> -
> - /* Fill the dev fields */
> - dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
> - dev->netdev_ops = &lance_netdev_ops;
> - dev->dma = 0;
> -
> - addr = (u_long *)ETHERNET_ADDRESS;
> - address = *addr;
> - macaddr[0] = 0x08;
> - macaddr[1] = 0x00;
> - macaddr[2] = 0x3e;
> - address = address >> 8;
> - macaddr[5] = address&0xff;
> - address = address >> 8;
> - macaddr[4] = address&0xff;
> - address = address >> 8;
> - macaddr[3] = address&0xff;
> - eth_hw_addr_set(dev, macaddr);
> -
> - lp = netdev_priv(dev);
> - lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */
> - if (!lp->ram) {
> - printk("%s: No memory for LANCE buffers\n", dev->name);
> - free_netdev(dev);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> - lp->lance.name = name;
> - lp->lance.base = dev->base_addr;
> - lp->lance.init_block = (struct lance_init_block *)(lp->ram); /* CPU addr */
> - lp->lance.lance_init_block = (struct lance_init_block *)(lp->ram); /* LANCE addr of same RAM */
> - lp->lance.busmaster_regval = LE_C3_BSWP; /* we're bigendian */
> - lp->lance.irq = MVME147_LANCE_IRQ;
> - lp->lance.writerap = (writerap_t)m147lance_writerap;
> - lp->lance.writerdp = (writerdp_t)m147lance_writerdp;
> - lp->lance.readrdp = (readrdp_t)m147lance_readrdp;
> - lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
> - lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
> - lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
> - lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
> -
> - err = register_netdev(dev);
> - if (err) {
> - free_pages(lp->ram, 3);
> - free_netdev(dev);
> - return ERR_PTR(err);
> - }
> -
> - netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
> - dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr);
> -
> - return dev;
> -}
> -
> -static void m147lance_writerap(struct lance_private *lp, unsigned short value)
> -{
> - out_be16(lp->base + LANCE_RAP, value);
> -}
> -
> -static void m147lance_writerdp(struct lance_private *lp, unsigned short value)
> -{
> - out_be16(lp->base + LANCE_RDP, value);
> -}
> -
> -static unsigned short m147lance_readrdp(struct lance_private *lp)
> -{
> - return in_be16(lp->base + LANCE_RDP);
> -}
> -
> -static int m147lance_open(struct net_device *dev)
> -{
> - int status;
> -
> - status = lance_open(dev); /* call generic lance open code */
> - if (status)
> - return status;
> - /* enable interrupts at board level. */
> - m147_pcc->lan_cntrl = 0; /* clear the interrupts (if any) */
> - m147_pcc->lan_cntrl = 0x08 | 0x04; /* Enable irq 4 */
> -
> - return 0;
> -}
> -
> -static int m147lance_close(struct net_device *dev)
> -{
> - /* disable interrupts at boardlevel */
> - m147_pcc->lan_cntrl = 0x0; /* disable interrupts */
> - lance_close(dev);
> - return 0;
> -}
> -
> -MODULE_DESCRIPTION("MVME147 LANCE Ethernet driver");
> -MODULE_LICENSE("GPL");
> -
> -static struct net_device *dev_mvme147_lance;
> -static int __init m147lance_init(void)
> -{
> - dev_mvme147_lance = mvme147lance_probe();
> - return PTR_ERR_OR_ZERO(dev_mvme147_lance);
> -}
> -module_init(m147lance_init);
> -
> -static void __exit m147lance_exit(void)
> -{
> - struct m147lance_private *lp = netdev_priv(dev_mvme147_lance);
> - unregister_netdev(dev_mvme147_lance);
> - free_pages(lp->ram, 3);
> - free_netdev(dev_mvme147_lance);
> -}
> -module_exit(m147lance_exit);
>
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH net 12/18] drivers: net: cirrus: mac89x0: Remove this driver
From: Geert Uytterhoeven @ 2026-04-22 7:36 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan,
linux-kernel, netdev, linux-doc, linux-m68k
In-Reply-To: <20260421-v7-0-0-net-next-driver-removal-v1-v1-12-69517c689d1f@lunn.ch>
CC linux-m68k
On Wed, 22 Apr 2026 at 02:48, Andrew Lunn <andrew@lunn.ch> wrote:
>
> The mac89x0 was written by Russell Nelson in 1996. It is an MAC
> device, so unlikely to be used with modern kernels.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
> drivers/net/ethernet/cirrus/Kconfig | 10 -
> drivers/net/ethernet/cirrus/Makefile | 1 -
> drivers/net/ethernet/cirrus/cs89x0.h | 461 ---------------------------
> drivers/net/ethernet/cirrus/mac89x0.c | 577 ----------------------------------
> 4 files changed, 1049 deletions(-)
>
> diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig
> index 1a0c7b3bfcd6..786d379e79fe 100644
> --- a/drivers/net/ethernet/cirrus/Kconfig
> +++ b/drivers/net/ethernet/cirrus/Kconfig
> @@ -25,14 +25,4 @@ config EP93XX_ETH
> This is a driver for the ethernet hardware included in EP93xx CPUs.
> Say Y if you are building a kernel for EP93xx based devices.
>
> -config MAC89x0
> - tristate "Macintosh CS89x0 based ethernet cards"
> - depends on MAC
> - help
> - Support for CS89x0 chipset based Ethernet cards. If you have a
> - Nubus or LC-PDS network (Ethernet) card of this type, say Y here.
> -
> - To compile this driver as a module, choose M here. This module will
> - be called mac89x0.
> -
> endif # NET_VENDOR_CIRRUS
> diff --git a/drivers/net/ethernet/cirrus/Makefile b/drivers/net/ethernet/cirrus/Makefile
> index cb740939d976..03800af0f0e1 100644
> --- a/drivers/net/ethernet/cirrus/Makefile
> +++ b/drivers/net/ethernet/cirrus/Makefile
> @@ -4,4 +4,3 @@
> #
>
> obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o
> -obj-$(CONFIG_MAC89x0) += mac89x0.o
> diff --git a/drivers/net/ethernet/cirrus/cs89x0.h b/drivers/net/ethernet/cirrus/cs89x0.h
> deleted file mode 100644
> index 210f9ec9af4b..000000000000
> --- a/drivers/net/ethernet/cirrus/cs89x0.h
> +++ /dev/null
> @@ -1,461 +0,0 @@
> -/* Copyright, 1988-1992, Russell Nelson, Crynwr Software
> -
> - This program is free software; you can redistribute it and/or modify
> - it under the terms of the GNU General Public License as published by
> - the Free Software Foundation, version 1.
> -
> - This program is distributed in the hope that it will be useful,
> - but WITHOUT ANY WARRANTY; without even the implied warranty of
> - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - GNU General Public License for more details.
> -
> - You should have received a copy of the GNU General Public License
> - along with this program; if not, write to the Free Software
> - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> - */
> -
> -
> -#define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */
> - /* offset 2h -> Model/Product Number */
> - /* offset 3h -> Chip Revision Number */
> -
> -#define PP_ISAIOB 0x0020 /* IO base address */
> -#define PP_CS8900_ISAINT 0x0022 /* ISA interrupt select */
> -#define PP_CS8920_ISAINT 0x0370 /* ISA interrupt select */
> -#define PP_CS8900_ISADMA 0x0024 /* ISA Rec DMA channel */
> -#define PP_CS8920_ISADMA 0x0374 /* ISA Rec DMA channel */
> -#define PP_ISASOF 0x0026 /* ISA DMA offset */
> -#define PP_DmaFrameCnt 0x0028 /* ISA DMA Frame count */
> -#define PP_DmaByteCnt 0x002A /* ISA DMA Byte count */
> -#define PP_CS8900_ISAMemB 0x002C /* Memory base */
> -#define PP_CS8920_ISAMemB 0x0348 /* */
> -
> -#define PP_ISABootBase 0x0030 /* Boot Prom base */
> -#define PP_ISABootMask 0x0034 /* Boot Prom Mask */
> -
> -/* EEPROM data and command registers */
> -#define PP_EECMD 0x0040 /* NVR Interface Command register */
> -#define PP_EEData 0x0042 /* NVR Interface Data Register */
> -#define PP_DebugReg 0x0044 /* Debug Register */
> -
> -#define PP_RxCFG 0x0102 /* Rx Bus config */
> -#define PP_RxCTL 0x0104 /* Receive Control Register */
> -#define PP_TxCFG 0x0106 /* Transmit Config Register */
> -#define PP_TxCMD 0x0108 /* Transmit Command Register */
> -#define PP_BufCFG 0x010A /* Bus configuration Register */
> -#define PP_LineCTL 0x0112 /* Line Config Register */
> -#define PP_SelfCTL 0x0114 /* Self Command Register */
> -#define PP_BusCTL 0x0116 /* ISA bus control Register */
> -#define PP_TestCTL 0x0118 /* Test Register */
> -#define PP_AutoNegCTL 0x011C /* Auto Negotiation Ctrl */
> -
> -#define PP_ISQ 0x0120 /* Interrupt Status */
> -#define PP_RxEvent 0x0124 /* Rx Event Register */
> -#define PP_TxEvent 0x0128 /* Tx Event Register */
> -#define PP_BufEvent 0x012C /* Bus Event Register */
> -#define PP_RxMiss 0x0130 /* Receive Miss Count */
> -#define PP_TxCol 0x0132 /* Transmit Collision Count */
> -#define PP_LineST 0x0134 /* Line State Register */
> -#define PP_SelfST 0x0136 /* Self State register */
> -#define PP_BusST 0x0138 /* Bus Status */
> -#define PP_TDR 0x013C /* Time Domain Reflectometry */
> -#define PP_AutoNegST 0x013E /* Auto Neg Status */
> -#define PP_TxCommand 0x0144 /* Tx Command */
> -#define PP_TxLength 0x0146 /* Tx Length */
> -#define PP_LAF 0x0150 /* Hash Table */
> -#define PP_IA 0x0158 /* Physical Address Register */
> -
> -#define PP_RxStatus 0x0400 /* Receive start of frame */
> -#define PP_RxLength 0x0402 /* Receive Length of frame */
> -#define PP_RxFrame 0x0404 /* Receive frame pointer */
> -#define PP_TxFrame 0x0A00 /* Transmit frame pointer */
> -
> -/* Primary I/O Base Address. If no I/O base is supplied by the user, then this */
> -/* can be used as the default I/O base to access the PacketPage Area. */
> -#define DEFAULTIOBASE 0x0300
> -#define FIRST_IO 0x020C /* First I/O port to check */
> -#define LAST_IO 0x037C /* Last I/O port to check (+10h) */
> -#define ADD_MASK 0x3000 /* Mask it use of the ADD_PORT register */
> -#define ADD_SIG 0x3000 /* Expected ID signature */
> -
> -/* On Macs, we only need use the ISA I/O stuff until we do MEMORY_ON */
> -#ifdef CONFIG_MAC
> -#define LCSLOTBASE 0xfee00000
> -#define MMIOBASE 0x40000
> -#endif
> -
> -#define CHIP_EISA_ID_SIG 0x630E /* Product ID Code for Crystal Chip (CS8900 spec 4.3) */
> -#define CHIP_EISA_ID_SIG_STR "0x630E"
> -
> -#ifdef IBMEIPKT
> -#define EISA_ID_SIG 0x4D24 /* IBM */
> -#define PART_NO_SIG 0x1010 /* IBM */
> -#define MONGOOSE_BIT 0x0000 /* IBM */
> -#else
> -#define EISA_ID_SIG 0x630E /* PnP Vendor ID (same as chip id for Crystal board) */
> -#define PART_NO_SIG 0x4000 /* ID code CS8920 board (PnP Vendor Product code) */
> -#define MONGOOSE_BIT 0x2000 /* PART_NO_SIG + MONGOOSE_BUT => ID of mongoose */
> -#endif
> -
> -#define PRODUCT_ID_ADD 0x0002 /* Address of product ID */
> -
> -/* Mask to find out the types of registers */
> -#define REG_TYPE_MASK 0x001F
> -
> -/* Eeprom Commands */
> -#define ERSE_WR_ENBL 0x00F0
> -#define ERSE_WR_DISABLE 0x0000
> -
> -/* Defines Control/Config register quintuplet numbers */
> -#define RX_BUF_CFG 0x0003
> -#define RX_CONTROL 0x0005
> -#define TX_CFG 0x0007
> -#define TX_COMMAND 0x0009
> -#define BUF_CFG 0x000B
> -#define LINE_CONTROL 0x0013
> -#define SELF_CONTROL 0x0015
> -#define BUS_CONTROL 0x0017
> -#define TEST_CONTROL 0x0019
> -
> -/* Defines Status/Count registers quintuplet numbers */
> -#define RX_EVENT 0x0004
> -#define TX_EVENT 0x0008
> -#define BUF_EVENT 0x000C
> -#define RX_MISS_COUNT 0x0010
> -#define TX_COL_COUNT 0x0012
> -#define LINE_STATUS 0x0014
> -#define SELF_STATUS 0x0016
> -#define BUS_STATUS 0x0018
> -#define TDR 0x001C
> -
> -/* PP_RxCFG - Receive Configuration and Interrupt Mask bit definition - Read/write */
> -#define SKIP_1 0x0040
> -#define RX_STREAM_ENBL 0x0080
> -#define RX_OK_ENBL 0x0100
> -#define RX_DMA_ONLY 0x0200
> -#define AUTO_RX_DMA 0x0400
> -#define BUFFER_CRC 0x0800
> -#define RX_CRC_ERROR_ENBL 0x1000
> -#define RX_RUNT_ENBL 0x2000
> -#define RX_EXTRA_DATA_ENBL 0x4000
> -
> -/* PP_RxCTL - Receive Control bit definition - Read/write */
> -#define RX_IA_HASH_ACCEPT 0x0040
> -#define RX_PROM_ACCEPT 0x0080
> -#define RX_OK_ACCEPT 0x0100
> -#define RX_MULTCAST_ACCEPT 0x0200
> -#define RX_IA_ACCEPT 0x0400
> -#define RX_BROADCAST_ACCEPT 0x0800
> -#define RX_BAD_CRC_ACCEPT 0x1000
> -#define RX_RUNT_ACCEPT 0x2000
> -#define RX_EXTRA_DATA_ACCEPT 0x4000
> -#define RX_ALL_ACCEPT (RX_PROM_ACCEPT|RX_BAD_CRC_ACCEPT|RX_RUNT_ACCEPT|RX_EXTRA_DATA_ACCEPT)
> -/* Default receive mode - individually addressed, broadcast, and error free */
> -#define DEF_RX_ACCEPT (RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | RX_OK_ACCEPT)
> -
> -/* PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write */
> -#define TX_LOST_CRS_ENBL 0x0040
> -#define TX_SQE_ERROR_ENBL 0x0080
> -#define TX_OK_ENBL 0x0100
> -#define TX_LATE_COL_ENBL 0x0200
> -#define TX_JBR_ENBL 0x0400
> -#define TX_ANY_COL_ENBL 0x0800
> -#define TX_16_COL_ENBL 0x8000
> -
> -/* PP_TxCMD - Transmit Command bit definition - Read-only */
> -#define TX_START_4_BYTES 0x0000
> -#define TX_START_64_BYTES 0x0040
> -#define TX_START_128_BYTES 0x0080
> -#define TX_START_ALL_BYTES 0x00C0
> -#define TX_FORCE 0x0100
> -#define TX_ONE_COL 0x0200
> -#define TX_TWO_PART_DEFF_DISABLE 0x0400
> -#define TX_NO_CRC 0x1000
> -#define TX_RUNT 0x2000
> -
> -/* PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write */
> -#define GENERATE_SW_INTERRUPT 0x0040
> -#define RX_DMA_ENBL 0x0080
> -#define READY_FOR_TX_ENBL 0x0100
> -#define TX_UNDERRUN_ENBL 0x0200
> -#define RX_MISS_ENBL 0x0400
> -#define RX_128_BYTE_ENBL 0x0800
> -#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000
> -#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000
> -#define RX_DEST_MATCH_ENBL 0x8000
> -
> -/* PP_LineCTL - Line Control bit definition - Read/write */
> -#define SERIAL_RX_ON 0x0040
> -#define SERIAL_TX_ON 0x0080
> -#define AUI_ONLY 0x0100
> -#define AUTO_AUI_10BASET 0x0200
> -#define MODIFIED_BACKOFF 0x0800
> -#define NO_AUTO_POLARITY 0x1000
> -#define TWO_PART_DEFDIS 0x2000
> -#define LOW_RX_SQUELCH 0x4000
> -
> -/* PP_SelfCTL - Software Self Control bit definition - Read/write */
> -#define POWER_ON_RESET 0x0040
> -#define SW_STOP 0x0100
> -#define SLEEP_ON 0x0200
> -#define AUTO_WAKEUP 0x0400
> -#define HCB0_ENBL 0x1000
> -#define HCB1_ENBL 0x2000
> -#define HCB0 0x4000
> -#define HCB1 0x8000
> -
> -/* PP_BusCTL - ISA Bus Control bit definition - Read/write */
> -#define RESET_RX_DMA 0x0040
> -#define MEMORY_ON 0x0400
> -#define DMA_BURST_MODE 0x0800
> -#define IO_CHANNEL_READY_ON 0x1000
> -#define RX_DMA_SIZE_64K 0x2000
> -#define ENABLE_IRQ 0x8000
> -
> -/* PP_TestCTL - Test Control bit definition - Read/write */
> -#define LINK_OFF 0x0080
> -#define ENDEC_LOOPBACK 0x0200
> -#define AUI_LOOPBACK 0x0400
> -#define BACKOFF_OFF 0x0800
> -#define FDX_8900 0x4000
> -#define FAST_TEST 0x8000
> -
> -/* PP_RxEvent - Receive Event Bit definition - Read-only */
> -#define RX_IA_HASHED 0x0040
> -#define RX_DRIBBLE 0x0080
> -#define RX_OK 0x0100
> -#define RX_HASHED 0x0200
> -#define RX_IA 0x0400
> -#define RX_BROADCAST 0x0800
> -#define RX_CRC_ERROR 0x1000
> -#define RX_RUNT 0x2000
> -#define RX_EXTRA_DATA 0x4000
> -
> -#define HASH_INDEX_MASK 0x0FC00
> -
> -/* PP_TxEvent - Transmit Event Bit definition - Read-only */
> -#define TX_LOST_CRS 0x0040
> -#define TX_SQE_ERROR 0x0080
> -#define TX_OK 0x0100
> -#define TX_LATE_COL 0x0200
> -#define TX_JBR 0x0400
> -#define TX_16_COL 0x8000
> -#define TX_SEND_OK_BITS (TX_OK|TX_LOST_CRS)
> -#define TX_COL_COUNT_MASK 0x7800
> -
> -/* PP_BufEvent - Buffer Event Bit definition - Read-only */
> -#define SW_INTERRUPT 0x0040
> -#define RX_DMA 0x0080
> -#define READY_FOR_TX 0x0100
> -#define TX_UNDERRUN 0x0200
> -#define RX_MISS 0x0400
> -#define RX_128_BYTE 0x0800
> -#define TX_COL_OVRFLW 0x1000
> -#define RX_MISS_OVRFLW 0x2000
> -#define RX_DEST_MATCH 0x8000
> -
> -/* PP_LineST - Ethernet Line Status bit definition - Read-only */
> -#define LINK_OK 0x0080
> -#define AUI_ON 0x0100
> -#define TENBASET_ON 0x0200
> -#define POLARITY_OK 0x1000
> -#define CRS_OK 0x4000
> -
> -/* PP_SelfST - Chip Software Status bit definition */
> -#define ACTIVE_33V 0x0040
> -#define INIT_DONE 0x0080
> -#define SI_BUSY 0x0100
> -#define EEPROM_PRESENT 0x0200
> -#define EEPROM_OK 0x0400
> -#define EL_PRESENT 0x0800
> -#define EE_SIZE_64 0x1000
> -
> -/* PP_BusST - ISA Bus Status bit definition */
> -#define TX_BID_ERROR 0x0080
> -#define READY_FOR_TX_NOW 0x0100
> -
> -/* PP_AutoNegCTL - Auto Negotiation Control bit definition */
> -#define RE_NEG_NOW 0x0040
> -#define ALLOW_FDX 0x0080
> -#define AUTO_NEG_ENABLE 0x0100
> -#define NLP_ENABLE 0x0200
> -#define FORCE_FDX 0x8000
> -#define AUTO_NEG_BITS (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE)
> -#define AUTO_NEG_MASK (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE|ALLOW_FDX|RE_NEG_NOW)
> -
> -/* PP_AutoNegST - Auto Negotiation Status bit definition */
> -#define AUTO_NEG_BUSY 0x0080
> -#define FLP_LINK 0x0100
> -#define FLP_LINK_GOOD 0x0800
> -#define LINK_FAULT 0x1000
> -#define HDX_ACTIVE 0x4000
> -#define FDX_ACTIVE 0x8000
> -
> -/* The following block defines the ISQ event types */
> -#define ISQ_RECEIVER_EVENT 0x04
> -#define ISQ_TRANSMITTER_EVENT 0x08
> -#define ISQ_BUFFER_EVENT 0x0c
> -#define ISQ_RX_MISS_EVENT 0x10
> -#define ISQ_TX_COL_EVENT 0x12
> -
> -#define ISQ_EVENT_MASK 0x003F /* ISQ mask to find out type of event */
> -#define ISQ_HIST 16 /* small history buffer */
> -#define AUTOINCREMENT 0x8000 /* Bit mask to set bit-15 for autoincrement */
> -
> -#define TXRXBUFSIZE 0x0600
> -#define RXDMABUFSIZE 0x8000
> -#define RXDMASIZE 0x4000
> -#define TXRX_LENGTH_MASK 0x07FF
> -
> -/* rx options bits */
> -#define RCV_WITH_RXON 1 /* Set SerRx ON */
> -#define RCV_COUNTS 2 /* Use Framecnt1 */
> -#define RCV_PONG 4 /* Pong respondent */
> -#define RCV_DONG 8 /* Dong operation */
> -#define RCV_POLLING 0x10 /* Poll RxEvent */
> -#define RCV_ISQ 0x20 /* Use ISQ, int */
> -#define RCV_AUTO_DMA 0x100 /* Set AutoRxDMAE */
> -#define RCV_DMA 0x200 /* Set RxDMA only */
> -#define RCV_DMA_ALL 0x400 /* Copy all DMA'ed */
> -#define RCV_FIXED_DATA 0x800 /* Every frame same */
> -#define RCV_IO 0x1000 /* Use ISA IO only */
> -#define RCV_MEMORY 0x2000 /* Use ISA Memory */
> -
> -#define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */
> -#define PKT_START PP_TxFrame /* Start of packet RAM */
> -
> -#define RX_FRAME_PORT 0x0000
> -#define TX_FRAME_PORT RX_FRAME_PORT
> -#define TX_CMD_PORT 0x0004
> -#define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */
> -#define TX_AFTER_381 0x0040 /* Tx packet after 381 bytes copied */
> -#define TX_AFTER_ALL 0x00c0 /* Tx packet after all bytes copied */
> -#define TX_LEN_PORT 0x0006
> -#define ISQ_PORT 0x0008
> -#define ADD_PORT 0x000A
> -#define DATA_PORT 0x000C
> -
> -#define EEPROM_WRITE_EN 0x00F0
> -#define EEPROM_WRITE_DIS 0x0000
> -#define EEPROM_WRITE_CMD 0x0100
> -#define EEPROM_READ_CMD 0x0200
> -
> -/* Receive Header */
> -/* Description of header of each packet in receive area of memory */
> -#define RBUF_EVENT_LOW 0 /* Low byte of RxEvent - status of received frame */
> -#define RBUF_EVENT_HIGH 1 /* High byte of RxEvent - status of received frame */
> -#define RBUF_LEN_LOW 2 /* Length of received data - low byte */
> -#define RBUF_LEN_HI 3 /* Length of received data - high byte */
> -#define RBUF_HEAD_LEN 4 /* Length of this header */
> -
> -#define CHIP_READ 0x1 /* Used to mark state of the repins code (chip or dma) */
> -#define DMA_READ 0x2 /* Used to mark state of the repins code (chip or dma) */
> -
> -/* for bios scan */
> -/* */
> -#ifdef CSDEBUG
> -/* use these values for debugging bios scan */
> -#define BIOS_START_SEG 0x00000
> -#define BIOS_OFFSET_INC 0x0010
> -#else
> -#define BIOS_START_SEG 0x0c000
> -#define BIOS_OFFSET_INC 0x0200
> -#endif
> -
> -#define BIOS_LAST_OFFSET 0x0fc00
> -
> -/* Byte offsets into the EEPROM configuration buffer */
> -#define ISA_CNF_OFFSET 0x6
> -#define TX_CTL_OFFSET (ISA_CNF_OFFSET + 8) /* 8900 eeprom */
> -#define AUTO_NEG_CNF_OFFSET (ISA_CNF_OFFSET + 8) /* 8920 eeprom */
> -
> - /* the assumption here is that the bits in the eeprom are generally */
> - /* in the same position as those in the autonegctl register. */
> - /* Of course the IMM bit is not in that register so it must be */
> - /* masked out */
> -#define EE_FORCE_FDX 0x8000
> -#define EE_NLP_ENABLE 0x0200
> -#define EE_AUTO_NEG_ENABLE 0x0100
> -#define EE_ALLOW_FDX 0x0080
> -#define EE_AUTO_NEG_CNF_MASK (EE_FORCE_FDX|EE_NLP_ENABLE|EE_AUTO_NEG_ENABLE|EE_ALLOW_FDX)
> -
> -#define IMM_BIT 0x0040 /* ignore missing media */
> -
> -#define ADAPTER_CNF_OFFSET (AUTO_NEG_CNF_OFFSET + 2)
> -#define A_CNF_10B_T 0x0001
> -#define A_CNF_AUI 0x0002
> -#define A_CNF_10B_2 0x0004
> -#define A_CNF_MEDIA_TYPE 0x0070
> -#define A_CNF_MEDIA_AUTO 0x0070
> -#define A_CNF_MEDIA_10B_T 0x0020
> -#define A_CNF_MEDIA_AUI 0x0040
> -#define A_CNF_MEDIA_10B_2 0x0010
> -#define A_CNF_DC_DC_POLARITY 0x0080
> -#define A_CNF_NO_AUTO_POLARITY 0x2000
> -#define A_CNF_LOW_RX_SQUELCH 0x4000
> -#define A_CNF_EXTND_10B_2 0x8000
> -
> -#define PACKET_PAGE_OFFSET 0x8
> -
> -/* Bit definitions for the ISA configuration word from the EEPROM */
> -#define INT_NO_MASK 0x000F
> -#define DMA_NO_MASK 0x0070
> -#define ISA_DMA_SIZE 0x0200
> -#define ISA_AUTO_RxDMA 0x0400
> -#define ISA_RxDMA 0x0800
> -#define DMA_BURST 0x1000
> -#define STREAM_TRANSFER 0x2000
> -#define ANY_ISA_DMA (ISA_AUTO_RxDMA | ISA_RxDMA)
> -
> -/* DMA controller registers */
> -#define DMA_BASE 0x00 /* DMA controller base */
> -#define DMA_BASE_2 0x0C0 /* DMA controller base */
> -
> -#define DMA_STAT 0x0D0 /* DMA controller status register */
> -#define DMA_MASK 0x0D4 /* DMA controller mask register */
> -#define DMA_MODE 0x0D6 /* DMA controller mode register */
> -#define DMA_RESETFF 0x0D8 /* DMA controller first/last flip flop */
> -
> -/* DMA data */
> -#define DMA_DISABLE 0x04 /* Disable channel n */
> -#define DMA_ENABLE 0x00 /* Enable channel n */
> -/* Demand transfers, incr. address, auto init, writes, ch. n */
> -#define DMA_RX_MODE 0x14
> -/* Demand transfers, incr. address, auto init, reads, ch. n */
> -#define DMA_TX_MODE 0x18
> -
> -#define DMA_SIZE (16*1024) /* Size of dma buffer - 16k */
> -
> -#define CS8900 0x0000
> -#define CS8920 0x4000
> -#define CS8920M 0x6000
> -#define REVISON_BITS 0x1F00
> -#define EEVER_NUMBER 0x12
> -#define CHKSUM_LEN 0x14
> -#define CHKSUM_VAL 0x0000
> -#define START_EEPROM_DATA 0x001c /* Offset into eeprom for start of data */
> -#define IRQ_MAP_EEPROM_DATA 0x0046 /* Offset into eeprom for the IRQ map */
> -#define IRQ_MAP_LEN 0x0004 /* No of bytes to read for the IRQ map */
> -#define PNP_IRQ_FRMT 0x0022 /* PNP small item IRQ format */
> -#define CS8900_IRQ_MAP 0x1c20 /* This IRQ map is fixed */
> -
> -#define CS8920_NO_INTS 0x0F /* Max CS8920 interrupt select # */
> -
> -#define PNP_ADD_PORT 0x0279
> -#define PNP_WRITE_PORT 0x0A79
> -
> -#define GET_PNP_ISA_STRUCT 0x40
> -#define PNP_ISA_STRUCT_LEN 0x06
> -#define PNP_CSN_CNT_OFF 0x01
> -#define PNP_RD_PORT_OFF 0x02
> -#define PNP_FUNCTION_OK 0x00
> -#define PNP_WAKE 0x03
> -#define PNP_RSRC_DATA 0x04
> -#define PNP_RSRC_READY 0x01
> -#define PNP_STATUS 0x05
> -#define PNP_ACTIVATE 0x30
> -#define PNP_CNF_IO_H 0x60
> -#define PNP_CNF_IO_L 0x61
> -#define PNP_CNF_INT 0x70
> -#define PNP_CNF_DMA 0x74
> -#define PNP_CNF_MEM 0x48
> diff --git a/drivers/net/ethernet/cirrus/mac89x0.c b/drivers/net/ethernet/cirrus/mac89x0.c
> deleted file mode 100644
> index 6723df9b65d9..000000000000
> --- a/drivers/net/ethernet/cirrus/mac89x0.c
> +++ /dev/null
> @@ -1,577 +0,0 @@
> -/* mac89x0.c: A Crystal Semiconductor CS89[02]0 driver for linux. */
> -/*
> - Written 1996 by Russell Nelson, with reference to skeleton.c
> - written 1993-1994 by Donald Becker.
> -
> - This software may be used and distributed according to the terms
> - of the GNU General Public License, incorporated herein by reference.
> -
> - The author may be reached at nelson@crynwr.com, Crynwr
> - Software, 11 Grant St., Potsdam, NY 13676
> -
> - Changelog:
> -
> - Mike Cruse : mcruse@cti-ltd.com
> - : Changes for Linux 2.0 compatibility.
> - : Added dev_id parameter in net_interrupt(),
> - : request_irq() and free_irq(). Just NULL for now.
> -
> - Mike Cruse : Added MOD_INC_USE_COUNT and MOD_DEC_USE_COUNT macros
> - : in net_open() and net_close() so kerneld would know
> - : that the module is in use and wouldn't eject the
> - : driver prematurely.
> -
> - Mike Cruse : Rewrote init_module() and cleanup_module using 8390.c
> - : as an example. Disabled autoprobing in init_module(),
> - : not a good thing to do to other devices while Linux
> - : is running from all accounts.
> -
> - Alan Cox : Removed 1.2 support, added 2.1 extra counters.
> -
> - David Huggins-Daines <dhd@debian.org>
> -
> - Split this off into mac89x0.c, and gutted it of all parts which are
> - not relevant to the existing CS8900 cards on the Macintosh
> - (i.e. basically the Daynaport CS and LC cards). To be precise:
> -
> - * Removed all the media-detection stuff, because these cards are
> - TP-only.
> -
> - * Lobotomized the ISA interrupt bogosity, because these cards use
> - a hardwired NuBus interrupt and a magic ISAIRQ value in the card.
> -
> - * Basically eliminated everything not relevant to getting the
> - cards minimally functioning on the Macintosh.
> -
> - I might add that these cards are badly designed even from the Mac
> - standpoint, in that Dayna, in their infinite wisdom, used NuBus slot
> - I/O space and NuBus interrupts for these cards, but neglected to
> - provide anything even remotely resembling a NuBus ROM. Therefore we
> - have to probe for them in a brain-damaged ISA-like fashion.
> -
> - Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 11/01/2001
> - check kmalloc and release the allocated memory on failure in
> - mac89x0_probe and in init_module
> - use local_irq_{save,restore}(flags) in net_get_stat, not just
> - local_irq_{dis,en}able()
> -*/
> -
> -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> -
> -static const char version[] =
> -"cs89x0.c:v1.02 11/26/96 Russell Nelson <nelson@crynwr.com>\n";
> -
> -#include <linux/module.h>
> -
> -/*
> - Sources:
> -
> - Crynwr packet driver epktisa.
> -
> - Crystal Semiconductor data sheets.
> -
> -*/
> -
> -#include <linux/kernel.h>
> -#include <linux/types.h>
> -#include <linux/fcntl.h>
> -#include <linux/interrupt.h>
> -#include <linux/ioport.h>
> -#include <linux/in.h>
> -#include <linux/string.h>
> -#include <linux/nubus.h>
> -#include <linux/errno.h>
> -#include <linux/init.h>
> -#include <linux/netdevice.h>
> -#include <linux/platform_device.h>
> -#include <linux/etherdevice.h>
> -#include <linux/skbuff.h>
> -#include <linux/delay.h>
> -#include <linux/bitops.h>
> -#include <linux/gfp.h>
> -
> -#include <asm/io.h>
> -#include <asm/hwtest.h>
> -#include <asm/macints.h>
> -
> -#include "cs89x0.h"
> -
> -static int debug = -1;
> -module_param(debug, int, 0);
> -MODULE_PARM_DESC(debug, "debug message level");
> -
> -/* Information that need to be kept for each board. */
> -struct net_local {
> - int msg_enable;
> - int chip_type; /* one of: CS8900, CS8920, CS8920M */
> - char chip_revision; /* revision letter of the chip ('A'...) */
> - int send_cmd; /* the propercommand used to send a packet. */
> - int rx_mode;
> - int curr_rx_cfg;
> - int send_underrun; /* keep track of how many underruns in a row we get */
> -};
> -
> -/* Index to functions, as function prototypes. */
> -static int net_open(struct net_device *dev);
> -static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
> -static irqreturn_t net_interrupt(int irq, void *dev_id);
> -static void set_multicast_list(struct net_device *dev);
> -static void net_rx(struct net_device *dev);
> -static int net_close(struct net_device *dev);
> -static struct net_device_stats *net_get_stats(struct net_device *dev);
> -static int set_mac_address(struct net_device *dev, void *addr);
> -
> -/* For reading/writing registers ISA-style */
> -static inline int
> -readreg_io(struct net_device *dev, int portno)
> -{
> - nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
> - return swab16(nubus_readw(dev->base_addr + DATA_PORT));
> -}
> -
> -static inline void
> -writereg_io(struct net_device *dev, int portno, int value)
> -{
> - nubus_writew(swab16(portno), dev->base_addr + ADD_PORT);
> - nubus_writew(swab16(value), dev->base_addr + DATA_PORT);
> -}
> -
> -/* These are for reading/writing registers in shared memory */
> -static inline int
> -readreg(struct net_device *dev, int portno)
> -{
> - return swab16(nubus_readw(dev->mem_start + portno));
> -}
> -
> -static inline void
> -writereg(struct net_device *dev, int portno, int value)
> -{
> - nubus_writew(swab16(value), dev->mem_start + portno);
> -}
> -
> -static const struct net_device_ops mac89x0_netdev_ops = {
> - .ndo_open = net_open,
> - .ndo_stop = net_close,
> - .ndo_start_xmit = net_send_packet,
> - .ndo_get_stats = net_get_stats,
> - .ndo_set_rx_mode = set_multicast_list,
> - .ndo_set_mac_address = set_mac_address,
> - .ndo_validate_addr = eth_validate_addr,
> -};
> -
> -/* Probe for the CS8900 card in slot E. We won't bother looking
> - anywhere else until we have a really good reason to do so. */
> -static int mac89x0_device_probe(struct platform_device *pdev)
> -{
> - struct net_device *dev;
> - struct net_local *lp;
> - int i, slot;
> - unsigned rev_type = 0;
> - unsigned long ioaddr;
> - unsigned short sig;
> - int err = -ENODEV;
> - struct nubus_rsrc *fres;
> -
> - dev = alloc_etherdev(sizeof(struct net_local));
> - if (!dev)
> - return -ENOMEM;
> -
> - /* We might have to parameterize this later */
> - slot = 0xE;
> - /* Get out now if there's a real NuBus card in slot E */
> - for_each_func_rsrc(fres)
> - if (fres->board->slot == slot)
> - goto out;
> -
> - /* The pseudo-ISA bits always live at offset 0x300 (gee,
> - wonder why...) */
> - ioaddr = (unsigned long)
> - nubus_slot_addr(slot) | (((slot&0xf) << 20) + DEFAULTIOBASE);
> - {
> - int card_present;
> -
> - card_present = (hwreg_present((void *)ioaddr + 4) &&
> - hwreg_present((void *)ioaddr + DATA_PORT));
> - if (!card_present)
> - goto out;
> - }
> -
> - nubus_writew(0, ioaddr + ADD_PORT);
> - sig = nubus_readw(ioaddr + DATA_PORT);
> - if (sig != swab16(CHIP_EISA_ID_SIG))
> - goto out;
> -
> - SET_NETDEV_DEV(dev, &pdev->dev);
> -
> - /* Initialize the net_device structure. */
> - lp = netdev_priv(dev);
> -
> - lp->msg_enable = netif_msg_init(debug, 0);
> -
> - /* Fill in the 'dev' fields. */
> - dev->base_addr = ioaddr;
> - dev->mem_start = (unsigned long)
> - nubus_slot_addr(slot) | (((slot&0xf) << 20) + MMIOBASE);
> - dev->mem_end = dev->mem_start + 0x1000;
> -
> - /* Turn on shared memory */
> - writereg_io(dev, PP_BusCTL, MEMORY_ON);
> -
> - /* get the chip type */
> - rev_type = readreg(dev, PRODUCT_ID_ADD);
> - lp->chip_type = rev_type &~ REVISON_BITS;
> - lp->chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
> -
> - /* Check the chip type and revision in order to set the correct send command
> - CS8920 revision C and CS8900 revision F can use the faster send. */
> - lp->send_cmd = TX_AFTER_381;
> - if (lp->chip_type == CS8900 && lp->chip_revision >= 'F')
> - lp->send_cmd = TX_NOW;
> - if (lp->chip_type != CS8900 && lp->chip_revision >= 'C')
> - lp->send_cmd = TX_NOW;
> -
> - netif_dbg(lp, drv, dev, "%s", version);
> -
> - pr_info("cs89%c0%s rev %c found at %#8lx\n",
> - lp->chip_type == CS8900 ? '0' : '2',
> - lp->chip_type == CS8920M ? "M" : "",
> - lp->chip_revision, dev->base_addr);
> -
> - /* Try to read the MAC address */
> - if ((readreg(dev, PP_SelfST) & (EEPROM_PRESENT | EEPROM_OK)) == 0) {
> - pr_info("No EEPROM, giving up now.\n");
> - goto out1;
> - } else {
> - u8 addr[ETH_ALEN];
> -
> - for (i = 0; i < ETH_ALEN; i += 2) {
> - /* Big-endian (why??!) */
> - unsigned short s = readreg(dev, PP_IA + i);
> - addr[i] = s >> 8;
> - addr[i+1] = s & 0xff;
> - }
> - eth_hw_addr_set(dev, addr);
> - }
> -
> - dev->irq = SLOT2IRQ(slot);
> -
> - /* print the IRQ and ethernet address. */
> -
> - pr_info("MAC %pM, IRQ %d\n", dev->dev_addr, dev->irq);
> -
> - dev->netdev_ops = &mac89x0_netdev_ops;
> -
> - err = register_netdev(dev);
> - if (err)
> - goto out1;
> -
> - platform_set_drvdata(pdev, dev);
> - return 0;
> -out1:
> - nubus_writew(0, dev->base_addr + ADD_PORT);
> -out:
> - free_netdev(dev);
> - return err;
> -}
> -
> -/* Open/initialize the board. This is called (in the current kernel)
> - sometime after booting when the 'ifconfig' program is run.
> -
> - This routine should set everything up anew at each open, even
> - registers that "should" only need to be set once at boot, so that
> - there is non-reboot way to recover if something goes wrong.
> - */
> -static int
> -net_open(struct net_device *dev)
> -{
> - struct net_local *lp = netdev_priv(dev);
> - int i;
> -
> - /* Disable the interrupt for now */
> - writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) & ~ENABLE_IRQ);
> -
> - /* Grab the interrupt */
> - if (request_irq(dev->irq, net_interrupt, 0, "cs89x0", dev))
> - return -EAGAIN;
> -
> - /* Set up the IRQ - Apparently magic */
> - if (lp->chip_type == CS8900)
> - writereg(dev, PP_CS8900_ISAINT, 0);
> - else
> - writereg(dev, PP_CS8920_ISAINT, 0);
> -
> - /* set the Ethernet address */
> - for (i=0; i < ETH_ALEN/2; i++)
> - writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
> -
> - /* Turn on both receive and transmit operations */
> - writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
> -
> - /* Receive only error free packets addressed to this card */
> - lp->rx_mode = 0;
> - writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
> -
> - lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
> -
> - writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
> -
> - writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
> - TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
> -
> - writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
> - TX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
> -
> - /* now that we've got our act together, enable everything */
> - writereg(dev, PP_BusCTL, readreg(dev, PP_BusCTL) | ENABLE_IRQ);
> - netif_start_queue(dev);
> - return 0;
> -}
> -
> -static netdev_tx_t
> -net_send_packet(struct sk_buff *skb, struct net_device *dev)
> -{
> - struct net_local *lp = netdev_priv(dev);
> - unsigned long flags;
> -
> - netif_dbg(lp, tx_queued, dev, "sent %d byte packet of type %x\n",
> - skb->len, skb->data[ETH_ALEN + ETH_ALEN] << 8 |
> - skb->data[ETH_ALEN + ETH_ALEN + 1]);
> -
> - /* keep the upload from being interrupted, since we
> - ask the chip to start transmitting before the
> - whole packet has been completely uploaded. */
> - local_irq_save(flags);
> - netif_stop_queue(dev);
> -
> - /* initiate a transmit sequence */
> - writereg(dev, PP_TxCMD, lp->send_cmd);
> - writereg(dev, PP_TxLength, skb->len);
> -
> - /* Test to see if the chip has allocated memory for the packet */
> - if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) {
> - /* Gasp! It hasn't. But that shouldn't happen since
> - we're waiting for TxOk, so return 1 and requeue this packet. */
> - local_irq_restore(flags);
> - return NETDEV_TX_BUSY;
> - }
> -
> - /* Write the contents of the packet */
> - skb_copy_from_linear_data(skb, (void *)(dev->mem_start + PP_TxFrame),
> - skb->len+1);
> -
> - local_irq_restore(flags);
> - dev_kfree_skb (skb);
> -
> - return NETDEV_TX_OK;
> -}
> -
> -/* The typical workload of the driver:
> - Handle the network interface interrupts. */
> -static irqreturn_t net_interrupt(int irq, void *dev_id)
> -{
> - struct net_device *dev = dev_id;
> - struct net_local *lp;
> - int ioaddr, status;
> -
> - ioaddr = dev->base_addr;
> - lp = netdev_priv(dev);
> -
> - /* we MUST read all the events out of the ISQ, otherwise we'll never
> - get interrupted again. As a consequence, we can't have any limit
> - on the number of times we loop in the interrupt handler. The
> - hardware guarantees that eventually we'll run out of events. Of
> - course, if you're on a slow machine, and packets are arriving
> - faster than you can read them off, you're screwed. Hasta la
> - vista, baby! */
> - while ((status = swab16(nubus_readw(dev->base_addr + ISQ_PORT)))) {
> - netif_dbg(lp, intr, dev, "status=%04x\n", status);
> - switch(status & ISQ_EVENT_MASK) {
> - case ISQ_RECEIVER_EVENT:
> - /* Got a packet(s). */
> - net_rx(dev);
> - break;
> - case ISQ_TRANSMITTER_EVENT:
> - dev->stats.tx_packets++;
> - netif_wake_queue(dev);
> - if ((status & TX_OK) == 0)
> - dev->stats.tx_errors++;
> - if (status & TX_LOST_CRS)
> - dev->stats.tx_carrier_errors++;
> - if (status & TX_SQE_ERROR)
> - dev->stats.tx_heartbeat_errors++;
> - if (status & TX_LATE_COL)
> - dev->stats.tx_window_errors++;
> - if (status & TX_16_COL)
> - dev->stats.tx_aborted_errors++;
> - break;
> - case ISQ_BUFFER_EVENT:
> - if (status & READY_FOR_TX) {
> - /* we tried to transmit a packet earlier,
> - but inexplicably ran out of buffers.
> - That shouldn't happen since we only ever
> - load one packet. Shrug. Do the right
> - thing anyway. */
> - netif_wake_queue(dev);
> - }
> - if (status & TX_UNDERRUN) {
> - netif_dbg(lp, tx_err, dev, "transmit underrun\n");
> - lp->send_underrun++;
> - if (lp->send_underrun == 3) lp->send_cmd = TX_AFTER_381;
> - else if (lp->send_underrun == 6) lp->send_cmd = TX_AFTER_ALL;
> - }
> - break;
> - case ISQ_RX_MISS_EVENT:
> - dev->stats.rx_missed_errors += (status >> 6);
> - break;
> - case ISQ_TX_COL_EVENT:
> - dev->stats.collisions += (status >> 6);
> - break;
> - }
> - }
> - return IRQ_HANDLED;
> -}
> -
> -/* We have a good packet(s), get it/them out of the buffers. */
> -static void
> -net_rx(struct net_device *dev)
> -{
> - struct net_local *lp = netdev_priv(dev);
> - struct sk_buff *skb;
> - int status, length;
> -
> - status = readreg(dev, PP_RxStatus);
> - if ((status & RX_OK) == 0) {
> - dev->stats.rx_errors++;
> - if (status & RX_RUNT)
> - dev->stats.rx_length_errors++;
> - if (status & RX_EXTRA_DATA)
> - dev->stats.rx_length_errors++;
> - if ((status & RX_CRC_ERROR) &&
> - !(status & (RX_EXTRA_DATA|RX_RUNT)))
> - /* per str 172 */
> - dev->stats.rx_crc_errors++;
> - if (status & RX_DRIBBLE)
> - dev->stats.rx_frame_errors++;
> - return;
> - }
> -
> - length = readreg(dev, PP_RxLength);
> - /* Malloc up new buffer. */
> - skb = alloc_skb(length, GFP_ATOMIC);
> - if (skb == NULL) {
> - dev->stats.rx_dropped++;
> - return;
> - }
> - skb_put(skb, length);
> -
> - skb_copy_to_linear_data(skb, (void *)(dev->mem_start + PP_RxFrame),
> - length);
> -
> - netif_dbg(lp, rx_status, dev, "received %d byte packet of type %x\n",
> - length, skb->data[ETH_ALEN + ETH_ALEN] << 8 |
> - skb->data[ETH_ALEN + ETH_ALEN + 1]);
> -
> - skb->protocol=eth_type_trans(skb,dev);
> - netif_rx(skb);
> - dev->stats.rx_packets++;
> - dev->stats.rx_bytes += length;
> -}
> -
> -/* The inverse routine to net_open(). */
> -static int
> -net_close(struct net_device *dev)
> -{
> -
> - writereg(dev, PP_RxCFG, 0);
> - writereg(dev, PP_TxCFG, 0);
> - writereg(dev, PP_BufCFG, 0);
> - writereg(dev, PP_BusCTL, 0);
> -
> - netif_stop_queue(dev);
> -
> - free_irq(dev->irq, dev);
> -
> - /* Update the statistics here. */
> -
> - return 0;
> -
> -}
> -
> -/* Get the current statistics. This may be called with the card open or
> - closed. */
> -static struct net_device_stats *
> -net_get_stats(struct net_device *dev)
> -{
> - unsigned long flags;
> -
> - local_irq_save(flags);
> - /* Update the statistics from the device registers. */
> - dev->stats.rx_missed_errors += (readreg(dev, PP_RxMiss) >> 6);
> - dev->stats.collisions += (readreg(dev, PP_TxCol) >> 6);
> - local_irq_restore(flags);
> -
> - return &dev->stats;
> -}
> -
> -static void set_multicast_list(struct net_device *dev)
> -{
> - struct net_local *lp = netdev_priv(dev);
> -
> - if(dev->flags&IFF_PROMISC)
> - {
> - lp->rx_mode = RX_ALL_ACCEPT;
> - } else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev)) {
> - /* The multicast-accept list is initialized to accept-all, and we
> - rely on higher-level filtering for now. */
> - lp->rx_mode = RX_MULTCAST_ACCEPT;
> - }
> - else
> - lp->rx_mode = 0;
> -
> - writereg(dev, PP_RxCTL, DEF_RX_ACCEPT | lp->rx_mode);
> -
> - /* in promiscuous mode, we accept errored packets, so we have to enable interrupts on them also */
> - writereg(dev, PP_RxCFG, lp->curr_rx_cfg |
> - (lp->rx_mode == RX_ALL_ACCEPT? (RX_CRC_ERROR_ENBL|RX_RUNT_ENBL|RX_EXTRA_DATA_ENBL) : 0));
> -}
> -
> -
> -static int set_mac_address(struct net_device *dev, void *addr)
> -{
> - struct sockaddr *saddr = addr;
> - int i;
> -
> - if (!is_valid_ether_addr(saddr->sa_data))
> - return -EADDRNOTAVAIL;
> -
> - eth_hw_addr_set(dev, saddr->sa_data);
> - netdev_info(dev, "Setting MAC address to %pM\n", dev->dev_addr);
> -
> - /* set the Ethernet address */
> - for (i=0; i < ETH_ALEN/2; i++)
> - writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
> -
> - return 0;
> -}
> -
> -MODULE_DESCRIPTION("Macintosh CS89x0-based Ethernet driver");
> -MODULE_LICENSE("GPL");
> -
> -static void mac89x0_device_remove(struct platform_device *pdev)
> -{
> - struct net_device *dev = platform_get_drvdata(pdev);
> -
> - unregister_netdev(dev);
> - nubus_writew(0, dev->base_addr + ADD_PORT);
> - free_netdev(dev);
> -}
> -
> -static struct platform_driver mac89x0_platform_driver = {
> - .probe = mac89x0_device_probe,
> - .remove = mac89x0_device_remove,
> - .driver = {
> - .name = "mac89x0",
> - },
> -};
> -
> -module_platform_driver(mac89x0_platform_driver);
^ permalink raw reply
* Re: [PATCH net 11/18] drivers: net: cirrus: cs89x0: Remove this driver
From: Geert Uytterhoeven @ 2026-04-22 7:31 UTC (permalink / raw)
To: Andrew Lunn
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman, Jonathan Corbet, Shuah Khan,
linux-kernel, netdev, linux-doc
In-Reply-To: <20260421-v7-0-0-net-next-driver-removal-v1-v1-11-69517c689d1f@lunn.ch>
Hi Andrew,
On Wed, 22 Apr 2026 at 03:04, Andrew Lunn <andrew@lunn.ch> wrote:
> The cs89x0 was written by Bonald Becker 1993 to 1994. It is an ISA
> device, so unlikely to be used with modern kernels.
>
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Thanks for your patch!
> --- a/drivers/net/ethernet/cirrus/Kconfig
> +++ b/drivers/net/ethernet/cirrus/Kconfig
> @@ -17,36 +17,6 @@ config NET_VENDOR_CIRRUS
>
> if NET_VENDOR_CIRRUS
>
> -config CS89x0
> - tristate
> -
> -config CS89x0_ISA
> - tristate "CS89x0 ISA driver support"
> - depends on HAS_IOPORT_MAP
> - depends on ISA
> - depends on !PPC32
> - depends on CS89x0_PLATFORM=n
> - select NETDEV_LEGACY_INIT
> - select CS89x0
> - help
> - Support for CS89x0 chipset based Ethernet cards. If you have a
> - network (Ethernet) card of this type, say Y and read the file
> - <file:Documentation/networking/device_drivers/ethernet/cirrus/cs89x0.rst>.
> -
> - To compile this driver as a module, choose M here. The module
> - will be called cs89x0.
This is the driver for the old twentieth-century ISA device...
> -
> -config CS89x0_PLATFORM
> - tristate "CS89x0 platform driver support"
> - depends on ARM || (COMPILE_TEST && !PPC)
> - select CS89x0
> - help
> - Say Y to compile the cs89x0 platform driver. This makes this driver
> - suitable for use on certain evaluation boards such as the iMX21ADS.
> -
> - To compile this driver as a module, choose M here. The module
> - will be called cs89x0.
This is the more modern DT-based part...
> --- a/drivers/net/ethernet/cirrus/cs89x0.c
> +++ /dev/null
> -#if IS_ENABLED(CONFIG_CS89x0_PLATFORM)
[...]
> -static const struct of_device_id __maybe_unused cs89x0_match[] = {
> - { .compatible = "cirrus,cs8900", },
> - { .compatible = "cirrus,cs8920", },
> - { },
> -};
> -MODULE_DEVICE_TABLE(of, cs89x0_match);
[...]
> -#endif /* CONFIG_CS89x0_PLATFORM */
However, no users of these compatible values ever appeared upstream.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH net v8 03/15] net: cache snapshot entries for ndo_set_rx_mode_async
From: Paolo Abeni @ 2026-04-22 7:27 UTC (permalink / raw)
To: Stanislav Fomichev; +Cc: netdev, davem, edumazet, kuba
In-Reply-To: <aef3wzOywP8_LhCh@devvm17672.vll0.facebook.com>
On 4/22/26 12:19 AM, Stanislav Fomichev wrote:
> On 04/21, Paolo Abeni wrote:
>> On 4/21/26 11:52 AM, Paolo Abeni wrote:
>>> On 4/16/26 8:57 PM, Stanislav Fomichev wrote:
>>>> Add a per-device netdev_hw_addr_list cache (rx_mode_addr_cache) that
>>>> allows __hw_addr_list_snapshot() and __hw_addr_list_reconcile() to
>>>> reuse previously allocated entries instead of hitting GFP_ATOMIC on
>>>> every snapshot cycle.
>>>>
>>>> snapshot pops entries from the cache when available, falling back to
>>>> __hw_addr_create(). reconcile splices both snapshot lists back into
>>>> the cache via __hw_addr_splice(). The cache is flushed in
>>>> free_netdev().
>>>>
>>>> Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
>>>> (cherry picked from commit ba3ab1832a511f660fdc6231245b14bf610c05bd)
>>>
>>> Are you backporting from 7.2 via time machine??? :-P
>>>
>>>> @@ -611,8 +633,8 @@ void __hw_addr_list_reconcile(struct netdev_hw_addr_list *real_list,
>>>> }
>>>> }
>>>>
>>>> - __hw_addr_flush(work);
>>>> - __hw_addr_flush(ref);
>>>> + __hw_addr_splice(cache, work);
>>>> + __hw_addr_splice(cache, ref);
>>>
>>> I think here sashiko has a point, with the cache size being unbounded. I
>>> guess syzkaller or the like will find a way to make it grow too much.
>>>
>>> What about hard-limit it to some reasonable value?!?
>>
>> There are a few more remarks from sashiko at the driver level, but
>> AFAICS are all pre-existing issues.
>>
>> I think even the above one it's better handled as a follow-up, so I'm
>> applying the series as-is (I'll just drop the cherry-pick statement above).
>
> I have a follow-up series to add retries here, but not sure it's the
> right direction. I can send it once net-next opens just to opinions.
I'm not sure how you are going to use retries with cache access?!?
Likely some code could clarify.
I was wondering about a dumb limit for such cache, possibly netns-wide,
possibly with a paired sysctl.
/P
^ permalink raw reply
* [PATCH net] net: txgbe: fix firmware version check
From: Jiawen Wu @ 2026-04-22 7:18 UTC (permalink / raw)
To: netdev
Cc: Mengyuan Lou, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jacob Keller,
Jiawen Wu, stable
For the device SP, the firmware version is a 32-bit value where the
lower 20 bits represent the base version number. And the customized
firmware version populates the upper 12 bits with a specific
identification number.
For other devices AML 25G and 40G, the upper 12 bits of the firmware
version is always non-zero, and they have other naming conventions.
Only SP devices need to check this to tell if XPCS will work properly.
So the judgement of MAC type is added here.
And the original logic compared the entire 32-bit value against 0x20010,
which caused the outdated base firmwares bypass the version check
without a warning. Apply a mask 0xfffff to isolate the lower 20 bits for
an accurate base version comparison.
Fixes: ab928c24e6cd ("net: txgbe: add FW version warning")
Cc: stable@vger.kernel.org
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
index ec32a5f422f2..8b7c3753bb6a 100644
--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
@@ -864,7 +864,8 @@ static int txgbe_probe(struct pci_dev *pdev,
"0x%08x", etrack_id);
}
- if (etrack_id < 0x20010)
+ if (wx->mac.type == wx_mac_sp &&
+ ((etrack_id & 0xfffff) < 0x20010))
dev_warn(&pdev->dev, "Please upgrade the firmware to 0x20010 or above.\n");
err = txgbe_test_hostif(wx);
--
2.51.0
^ permalink raw reply related
* Re: [PATCH net v4 2/2] selftests/bpf: check epoll readiness during reuseport migration
From: Zhenzhong Wu @ 2026-04-22 7:14 UTC (permalink / raw)
To: Kuniyuki Iwashima
Cc: Tamir Duberstein, netdev, edumazet, ncardwell, davem, dsahern,
kuba, pabeni, horms, shuah, linux-kernel, linux-kselftest
In-Reply-To: <CAAVpQUAKCDVPHhFjWch2-zpKp2rHEPzvwE4R1UrDTMd_6Y2HYA@mail.gmail.com>
Thanks both. Keeping the goto for consistency with the rest of the test.
On Wed, Apr 22, 2026 at 2:40 PM Kuniyuki Iwashima <kuniyu@google.com> wrote:
>
> On Tue, Apr 21, 2026 at 11:34 PM Zhenzhong Wu <jt26wzz@gmail.com> wrote:
> >
> > Thanks Tamir, I will fold this into v5 - there's already a precedent
> > in socket_helpers.h, so I will just include it from there.
>
> The test does not use cleanup in other places,
> no need to mix them up.
>
>
> >
> > On Wed, Apr 22, 2026 at 11:04 AM Tamir Duberstein <tamird@kernel.org> wrote:
> > >
> > > On Tue, Apr 21, 2026 at 7:46 PM Zhenzhong Wu <jt26wzz@gmail.com> wrote:
> > > >
> > > > Inside migrate_dance(), add epoll checks around shutdown() to
> > > > verify that the target listener is not ready before shutdown()
> > > > and becomes ready immediately after shutdown() triggers migration.
> > > >
> > > > Cover TCP_ESTABLISHED and TCP_SYN_RECV. Exclude TCP_NEW_SYN_RECV
> > > > as it depends on later handshake completion.
> > > >
> > > > Suggested-by: Kuniyuki Iwashima <kuniyu@google.com>
> > > > Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
> > > > Signed-off-by: Zhenzhong Wu <jt26wzz@gmail.com>
> > > > ---
> > > > .../bpf/prog_tests/migrate_reuseport.c | 49 ++++++++++++++++---
> > > > 1 file changed, 42 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c b/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c
> > > > index 653b0a20f..c62907732 100644
> > > > --- a/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c
> > > > +++ b/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c
> > > > @@ -7,24 +7,29 @@
> > > > * 3. call listen() for 1 server socket. (migration target)
> > > > * 4. update a map to migrate all child sockets
> > > > * to the last server socket (migrate_map[cookie] = 4)
> > > > - * 5. call shutdown() for first 4 server sockets
> > > > + * 5. for TCP_ESTABLISHED and TCP_SYN_RECV cases, verify via epoll
> > > > + * that the last server socket is not ready before migration.
> > > > + * 6. call shutdown() for first 4 server sockets
> > > > * and migrate the requests in the accept queue
> > > > * to the last server socket.
> > > > - * 6. call listen() for the second server socket.
> > > > - * 7. call shutdown() for the last server
> > > > + * 7. for TCP_ESTABLISHED and TCP_SYN_RECV cases, verify via epoll
> > > > + * that the last server socket is ready after migration.
> > > > + * 8. call listen() for the second server socket.
> > > > + * 9. call shutdown() for the last server
> > > > * and migrate the requests in the accept queue
> > > > * to the second server socket.
> > > > - * 8. call listen() for the last server.
> > > > - * 9. call shutdown() for the second server
> > > > + * 10. call listen() for the last server.
> > > > + * 11. call shutdown() for the second server
> > > > * and migrate the requests in the accept queue
> > > > * to the last server socket.
> > > > - * 10. call accept() for the last server socket.
> > > > + * 12. call accept() for the last server socket.
> > > > *
> > > > * Author: Kuniyuki Iwashima <kuniyu@amazon.co.jp>
> > > > */
> > > >
> > > > #include <bpf/bpf.h>
> > > > #include <bpf/libbpf.h>
> > > > +#include <sys/epoll.h>
> > > >
> > > > #include "test_progs.h"
> > > > #include "test_migrate_reuseport.skel.h"
> > > > @@ -350,21 +355,51 @@ static int update_maps(struct migrate_reuseport_test_case *test_case,
> > > >
> > > > static int migrate_dance(struct migrate_reuseport_test_case *test_case)
> > > > {
> > > > + struct epoll_event ev = {
> > > > + .events = EPOLLIN,
> > > > + };
> > > > + int epoll = -1, nfds;
> > > > int i, err;
> > > >
> > > > + if (test_case->state != BPF_TCP_NEW_SYN_RECV) {
> > > > + epoll = epoll_create1(0);
> > > > + if (!ASSERT_NEQ(epoll, -1, "epoll_create1"))
> > > > + return -1;
> > > > +
> > > > + ev.data.fd = test_case->servers[MIGRATED_TO];
> > > > + if (!ASSERT_OK(epoll_ctl(epoll, EPOLL_CTL_ADD,
> > > > + test_case->servers[MIGRATED_TO], &ev),
> > > > + "epoll_ctl"))
> > > > + goto close_epoll;
> > > > +
> > > > + nfds = epoll_wait(epoll, &ev, 1, 0);
> > > > + if (!ASSERT_EQ(nfds, 0, "epoll_wait 1"))
> > > > + goto close_epoll;
> > > > + }
> > > > +
> > > > /* Migrate TCP_ESTABLISHED and TCP_SYN_RECV requests
> > > > * to the last listener based on eBPF.
> > > > */
> > > > for (i = 0; i < MIGRATED_TO; i++) {
> > > > err = shutdown(test_case->servers[i], SHUT_RDWR);
> > > > if (!ASSERT_OK(err, "shutdown"))
> > > > - return -1;
> > > > + goto close_epoll;
> > > > }
> > > >
> > > > /* No dance for TCP_NEW_SYN_RECV to migrate based on eBPF */
> > > > if (test_case->state == BPF_TCP_NEW_SYN_RECV)
> > > > return 0;
> > > >
> > > > + nfds = epoll_wait(epoll, &ev, 1, 0);
> > > > + if (!ASSERT_EQ(nfds, 1, "epoll_wait 2")) {
> > > > +close_epoll:
> > > > + if (epoll >= 0)
> > > > + close(epoll);
> > > > + return -1;
> > > > + }
> > >
> > > I think you can avoid this goto using `__attribute__((cleanup(...))`:
> > >
> > > static void close_fd(int *fd)
> > > {
> > > if (*fd >= 0)
> > > close(*fd);
> > > }
> > >
> > > #define __close_fd __attribute__((cleanup(close_fd)))
> > >
> > > then in the test:
> > >
> > > __close_fd int epoll = -1;
> > >
> > > there's an example of this in
> > > tools/testing/selftests/bpf/prog_tests/socket_helpers.h.
^ permalink raw reply
* Re: [PATCH net-deletions v2] net: remove unused ATM protocols and legacy ATM device drivers
From: Andy Shevchenko @ 2026-04-22 7:08 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, corbet,
skhan, linux, tsbogend, maddy, mpe, npiggin, chleroy, 3chas3,
razor, idosch, jani.nikula, mchehab+huawei, tytso, herbert, geert,
ebiggers, johannes.berg, jonathan.cameron, kees, kuniyu,
fourier.thomas, rdunlap, akpm, linux-doc, linux-mips,
linuxppc-dev, bridge, dwmw2
In-Reply-To: <20260422041846.2035118-1-kuba@kernel.org>
On Tue, Apr 21, 2026 at 09:18:44PM -0700, Jakub Kicinski wrote:
> Remove the ATM protocol modules and PCI/SBUS ATM device drivers
> that are no longer in active use.
>
> The ATM core protocol stack, PPPoATM, BR2684, and USB DSL modem
> drivers (drivers/usb/atm/) are retained in-tree to maintain PPP
> over ATM (PPPoA) and PPPoE-over-BR2684 support for DSL connections.
>
> Removed ATM protocol modules:
> - net/atm/clip.c - Classical IP over ATM (RFC 2225)
> - net/atm/lec.c - LAN Emulation Client (LANE)
> - net/atm/mpc.c, mpoa_caches.c, mpoa_proc.c - Multi-Protocol Over ATM
>
> Removed PCI/SBUS ATM device drivers (drivers/atm/):
> - adummy, atmtcp - software/testing ATM devices
> - eni - Efficient Networks ENI155P (OC-3, ~1995)
> - fore200e - FORE Systems 200E PCI/SBUS (OC-3, ~1999)
> - he - ForeRunner HE (OC-3/OC-12, ~2000)
> - idt77105 - IDT 77105 25 Mbps ATM PHY
> - idt77252 - IDT 77252 NICStAR II (OC-3, ~2000)
> - iphase - Interphase ATM PCI (OC-3/DS3/E3)
> - lanai - Efficient Networks Speedstream 3010
> - nicstar - IDT 77201 NICStAR (155/25 Mbps, ~1999)
> - solos-pci - Traverse Technologies ADSL2+ PCI
> - suni - PMC S/UNI SONET PHY library
>
> Also clean up references in:
> - net/bridge/ - remove ATM LANE hook (br_fdb_test_addr_hook,
> br_fdb_test_addr)
> - net/core/dev.c - remove br_fdb_test_addr_hook export
> - defconfig files - remove ATM driver config options
>
> The removed code is moved to an out-of-tree module package (mod-orphan).
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> ---
> v2:
> - keep BR2684
> - correct the claim that Traverse Technologies is defunct,
> I'm still deleting the solos driver, chances are nobody uses it.
> Easy enough to revert back in since core is still around.
> The guiding principle is to keep USB modems and delete
> the rest as USB ADSL2+ CPEs were most popular historically.
> v1: https://lore.kernel.org/20260421021943.1295109-1-kuba@kernel.org
>
> CC: corbet@lwn.net
> CC: skhan@linuxfoundation.org
> CC: linux@armlinux.org.uk
> CC: tsbogend@alpha.franken.de
> CC: maddy@linux.ibm.com
> CC: mpe@ellerman.id.au
> CC: npiggin@gmail.com
> CC: chleroy@kernel.org
> CC: 3chas3@gmail.com
> CC: razor@blackwall.org
> CC: idosch@nvidia.com
> CC: jani.nikula@intel.com
> CC: mchehab+huawei@kernel.org
> CC: tytso@mit.edu
> CC: herbert@gondor.apana.org.au
> CC: geert@linux-m68k.org
> CC: ebiggers@kernel.org
> CC: johannes.berg@intel.com
> CC: jonathan.cameron@huawei.com
> CC: kees@kernel.org
> CC: kuniyu@google.com
> CC: fourier.thomas@gmail.com
> CC: andriy.shevchenko@intel.com
> CC: rdunlap@infradead.org
> CC: akpm@linux-foundation.org
> CC: linux-doc@vger.kernel.org
> CC: linux-mips@vger.kernel.org
> CC: linuxppc-dev@lists.ozlabs.org
> CC: bridge@lists.linux.dev
> CC: dwmw2@infradead.org
> CC: herbert@gondor.apana.org.au
Acked-by: Andy Shevchenko <andriy.shevchenko@intel.com>
P.S.
Since it's almost removal and it will go via netdev tree (same tree you are
maintaining, I suppose) the -D would have a big help to review the changes
(and not see removals at all, as 32k lines of one email is too much).
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [net-next PATCH 08/10] net: dsa: realtek: rtl8365mb: add FDB support
From: Luiz Angelo Daros de Luca @ 2026-04-22 6:56 UTC (permalink / raw)
To: Linus Walleij
Cc: Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Alvin Šipraga,
Yury Norov, Rasmus Villemoes, Russell King, netdev, linux-kernel
In-Reply-To: <CAD++jLnbZ6q+Noe9abWWRNrvYVjCU-X3w4jpzKKYQDUcKNcKew@mail.gmail.com>
> I actually at one point started to implement FDB accessors to the RTL8366RB
> before I got sidetracked (for the same reasons of being able to do hardware
> offloading), here is how far I got before I got distracted:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/patch/?id=9941b129f91e92423803d6e2869022ffa66e9654
>
> You can see that it also has an L2 table albeit with 4 entries rather than 6,
> and an additional "CAM" (content adressable memory...) table that I don't quite
> understand.
I will look into the CAM table info in rtl8367c family.
> On Wed, Apr 1, 2026 at 1:01 AM Luiz Angelo Daros de Luca
> <luizluca@gmail.com> wrote:
>
> > +int rtl8365mb_l2_del_mc(struct realtek_priv *priv, u16 port,
> > + const unsigned char mac_addr[static ETH_ALEN],
> > + u16 vid)
> > +int rtl8365mb_l2_get_next_uc(struct realtek_priv *priv, u16 *addr, u16 port,
> > + struct rtl8365mb_l2_uc *uc);
> > +int rtl8365mb_l2_add_uc(struct realtek_priv *priv, u16 port,
> > + const unsigned char addr[static ETH_ALEN],
> > + u16 efid, u16 vid);
> > +int rtl8365mb_l2_del_uc(struct realtek_priv *priv, u16 port,
> > + const unsigned char addr[static ETH_ALEN],
> > + u16 efid, u16 vid);
> > +int rtl8365mb_l2_flush(struct realtek_priv *priv, int port, u16 vid);
> > +
> > +int rtl8365mb_l2_add_mc(struct realtek_priv *priv, u16 port,
> > + const unsigned char mac_addr[static ETH_ALEN],
> > + u16 vid);
> > +int rtl8365mb_l2_del_mc(struct realtek_priv *priv, u16 port,
> > + const unsigned char mac_addr[static ETH_ALEN],
> > + u16 vid);
>
> I think it would make sense to add these to struct realtek_ops and
> make them available for all RTL8366 variants.
Agreed. I will add these to struct realtek_ops. I'll need to create a
generic replacement for struct rtl8365mb_l2_uc, but the rest of the
migration should be straightforward. For now, the efid argument can
simply be ignored by the RTL8366 implementation.
> Possibly it would even make sense to move rtl8365mb_table_query()
> to struct realtek_ops under the name .table_query and all of
> these helpers to rtl8366-core.c as rtl8366_l2_del_mc() etc
> just calling the per-chip table query variant. I'm not sure
> but you can perhaps see what makes most sense?
I suspect rtl8365mb_table_query() might be too complex to abstract
effectively without first seeing how the RTL8366 handles table
lookups, as hardware-specific behaviors can vary significantly here. I
suggest we implement it for the RTL8366 first; once we have a
reference point, we can discuss the best way to consolidate the logic.
> > + struct mutex l2_lock;
>
> Move to struct realtek_priv, every chip will need an l2 lock.
Sure.
> > +static void rtl8365mb_port_fast_age(struct dsa_switch *ds, int port)
> > +static int rtl8365mb_port_fdb_add(struct dsa_switch *ds, int port,
> > + const unsigned char *addr, u16 vid,
> > + struct dsa_db db)
> > +static int rtl8365mb_port_fdb_del(struct dsa_switch *ds, int port,
> > + const unsigned char *addr, u16 vid,
> > + struct dsa_db db)
> > +static int rtl8365mb_port_fdb_dump(struct dsa_switch *ds, int port,
> > + dsa_fdb_dump_cb_t *cb, void *data)
> > +static int rtl8365mb_port_mdb_add(struct dsa_switch *ds, int port,
> > + const struct switchdev_obj_port_mdb *mdb,
> > + struct dsa_db db)
> > +static int rtl8365mb_port_mdb_del(struct dsa_switch *ds, int port,
> > + const struct switchdev_obj_port_mdb *mdb,
> > + struct dsa_db db)
>
> I think you should rename all of these rtl8366_port_* and move them
> to rtl8366-core.c. They are generic.
Yes. Once rtl8365mb_l2_* is moved to realtek_ops, these functions
become generic wrappers and fit perfectly in rtl83xx.c.
> > @@ -2498,6 +2687,12 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops = {
> > .port_bridge_join = rtl8365mb_port_bridge_join,
> > .port_bridge_leave = rtl8365mb_port_bridge_leave,
> > .port_stp_state_set = rtl8365mb_port_stp_state_set,
> > + .port_fast_age = rtl8365mb_port_fast_age,
>
> .port_fast_age = rtl8366_port_fast_age,
I will update the ops to use the new generics.
Regards,
Luiz
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox