* [PATCH v3 net-next] net: advance skb_defer_disable_key check in napi_consume_skb
From: Jason Xing @ 2026-04-01 3:32 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms; +Cc: netdev, Jason Xing
From: Jason Xing <kernelxing@tencent.com>
When net.core.skb_defer_max is adjusted to zero, napi_consume_skb
shouldn't go into deeper in skb_attempt_defer_free because that function
adds a pair of local_bh_enable/disable() which can be found in
kfree_skb_napi_cache(). Advancing the check of the static key saves more
cycles and benefits the single flow/few flows workloads.
Signed-off-by: Jason Xing <kernelxing@tencent.com>
---
v3
Link: https://lore.kernel.org/all/20260327153347.98647-1-kerneljasonxing@gmail.com/
1. use a simpler approach to avoid adding a new sysctl.
V2
Link: https://lore.kernel.org/all/20260326144249.97213-1-kerneljasonxing@gmail.com/
1. reuse proc_do_static_key() (Eric)
2. add doc (Stan)
---
net/core/skbuff.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3d6978dd0aa8..c1562ba6903e 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1519,7 +1519,8 @@ void napi_consume_skb(struct sk_buff *skb, int budget)
DEBUG_NET_WARN_ON_ONCE(!in_softirq());
- if (skb->alloc_cpu != smp_processor_id() && !skb_shared(skb)) {
+ if (!static_branch_unlikely(&skb_defer_disable_key) &&
+ skb->alloc_cpu != smp_processor_id() && !skb_shared(skb)) {
skb_release_head_state(skb);
return skb_attempt_defer_free(skb);
}
--
2.41.3
^ permalink raw reply related
* Re: [PATCH net-next] net: vxlan: check ipv6_mod_enabled() on neigh_reduce()
From: patchwork-bot+netdevbpf @ 2026-04-01 3:20 UTC (permalink / raw)
To: Fernando Fernandez Mancera
Cc: netdev, sdf, petrm, idosch, razor, pabeni, kuba, edumazet, davem,
andrew+netdev
In-Reply-To: <20260330121033.4479-1-fmancera@suse.de>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 14:10:33 +0200 you wrote:
> IPv6 must be enabled or otherwise neigh_reduce() might cause a kernel
> panic. This was prevented by a check on in6_dev. Use ipv6_mod_enabled()
> instead as it is cleaner and also consistent with the code at
> route_shortcircuit().
>
> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
>
> [...]
Here is the summary with links:
- [net-next] net: vxlan: check ipv6_mod_enabled() on neigh_reduce()
https://git.kernel.org/netdev/net-next/c/58e416e28328
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next] net: mana: hardening: Validate adapter_mtu from MANA_QUERY_DEV_CONFIG
From: patchwork-bot+netdevbpf @ 2026-04-01 3:20 UTC (permalink / raw)
To: Erni Sri Satya Vennela
Cc: kys, haiyangz, wei.liu, decui, longli, andrew+netdev, davem,
edumazet, kuba, pabeni, ssengar, dipayanroy, gargaditya,
shirazsaleem, kees, linux-hyperv, netdev, linux-kernel
In-Reply-To: <20260326173101.2010514-1-ernis@linux.microsoft.com>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 26 Mar 2026 10:30:56 -0700 you wrote:
> As a part of MANA hardening for CVM, validate the adapter_mtu value
> returned from the MANA_QUERY_DEV_CONFIG HWC command.
>
> The adapter_mtu value is used to compute ndev->max_mtu via:
> gc->adapter_mtu - ETH_HLEN. If hardware returns a bogus adapter_mtu
> smaller than ETH_HLEN (e.g. 0), the unsigned subtraction wraps to a
> huge value, silently allowing oversized MTU settings.
>
> [...]
Here is the summary with links:
- [net-next] net: mana: hardening: Validate adapter_mtu from MANA_QUERY_DEV_CONFIG
https://git.kernel.org/netdev/net-next/c/d7709812e13d
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next] net/iucv: Add missing kernel-doc return value descriptions
From: patchwork-bot+netdevbpf @ 2026-04-01 3:20 UTC (permalink / raw)
To: Alexandra Winter
Cc: davem, kuba, pabeni, edumazet, andrew+netdev, twinkler, netdev,
linux-s390, aswin, hca, gor, agordeev, borntraeger, svens, horms,
nagamani
In-Reply-To: <20260330114436.2010108-1-wintera@linux.ibm.com>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 13:44:36 +0200 you wrote:
> From: Nagamani PV <nagamani@linux.ibm.com>
>
> Add missing return value descriptions for several functions in
> net/iucv/af_iucv.c and net/iucv/iucv.c to address kernel-doc warnings.
>
> Warnings detected with:
> scripts/kernel-doc -none -Wall net/iucv/*
> Warning: net/iucv/af_iucv.c:131 No description found for return value of 'iucv_msg_length'
> Warning: net/iucv/af_iucv.c:150 No description found for return value of 'iucv_sock_in_state'
> ...
>
> [...]
Here is the summary with links:
- [net-next] net/iucv: Add missing kernel-doc return value descriptions
https://git.kernel.org/netdev/net-next/c/f1359c240191
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v4] net: stmmac: skip VLAN restore when VLAN hash ops are missing
From: patchwork-bot+netdevbpf @ 2026-04-01 3:20 UTC (permalink / raw)
To: Michal Piekos
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, mcoquelin.stm32,
alexandre.torgue, ovidiu.panait.rb, netdev, linux-stm32,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260328-vlan-restore-error-v4-1-f88624c530dc@mmpsystems.pl>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Sat, 28 Mar 2026 09:55:51 +0100 you wrote:
> stmmac_vlan_restore() unconditionally calls stmmac_vlan_update() when
> NETIF_F_VLAN_FEATURES is set. On platforms where priv->hw->vlan (or
> ->update_vlan_hash) is not provided, stmmac_update_vlan_hash() returns
> -EINVAL via stmmac_do_void_callback(), resulting in a spurious
> "Failed to restore VLANs" error even when no VLAN filtering is in use.
>
> Remove not needed comment.
> Remove not used return value from stmmac_vlan_restore().
>
> [...]
Here is the summary with links:
- [v4] net: stmmac: skip VLAN restore when VLAN hash ops are missing
https://git.kernel.org/netdev/net/c/48b3cd69265f
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next 3/3] net: usb: smsc95xx: suspend PHY during USB suspend
From: Parthiban.Veerasooran @ 2026-04-01 3:18 UTC (permalink / raw)
To: oneukum
Cc: netdev, linux-usb, piergiorgio.beruto, andrew, hkallweit1, linux,
davem, edumazet, kuba, pabeni, steve.glendinning, UNGLinuxDriver
In-Reply-To: <1c660862-de30-428d-a772-8bee9b990a59@suse.com>
Hi Oliver
Thank you for reviewing the patch.
On 30/03/26 11:09 pm, Oliver Neukum wrote:
>> @@ -1550,6 +1550,12 @@ static int smsc95xx_suspend(struct
>> usb_interface *intf, pm_message_t message)
>>
>> pdata->pm_task = current;
>>
>> + if (pdata->phydev) {
>> + ret = phy_suspend(pdata->phydev);
>> + if (ret)
>> + return ret;
>> + }
>
> At this point you have suspended the phy.
> Hence the device can no longer transmit
>
>> +
>> ret = usbnet_suspend(intf, message);
>
> This wants to
>
> 1. drain the queue if you do runtime PM
> 2. can return -EBUSY
>
>> if (ret < 0) {
>> netdev_warn(dev->net, "usbnet_suspend error\n");
>
> And here it will return in the error case. With the phy
> already suspended.
Thank you for pointing it out. I agree with you. I didn’t note it
earlier since the issue did not occur during my testing. I will move the
phy_suspend() to the appropriate place.
>
> And, as a question of principle: Why do you suspend the phy
> in suspend(), but take no action in resume()?
In resume(), I did not call phy_resume() because the resume path already
invokes phy_init_hw(), which internally calls
phydev->drv->config_init(). This reinitializes and reconfigures the PHY.
This is the reason why I didn't call phy_resume(). If there is a
preference or expectation to use phy_resume() for symmetry or to better
align with the PHY framework’s suspend/resume semantics, I’m happy to
update the code accordingly.
Moreover I will revisit the implementation with internal review and then
post the next version. Thank you for your support.
Best regards,
Parthiban V
>
> Regards
> Oliver
>
>
^ permalink raw reply
* Re: [PATCH net-next 1/3] net: phy: phy-c45: add OATC10 Sleep/Wakeup support in 10BASE-T1S PHYs
From: Parthiban.Veerasooran @ 2026-04-01 3:12 UTC (permalink / raw)
To: andrew
Cc: piergiorgio.beruto, hkallweit1, linux, davem, edumazet, kuba,
pabeni, steve.glendinning, UNGLinuxDriver, netdev, linux-usb
In-Reply-To: <239a7455-5cb6-4cbb-b9d6-1d48a0cadbc8@lunn.ch>
Hi Andrew,
On 30/03/26 8:16 pm, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>> + /* Cache PLCA settings for later use. These values must be restored when
>> + * the PHY wakes up from the low-power sleep state, as all configured
>> + * settings are lost.
>> + */
>
> Does the standard define that this configuration is lost in low power
> mode? If the standard says this, then fine. But if not, it should be
> the PHY driver which saves its state during suspend, and restores it
> during resume.
Thank you for the review and pointing this out.
You are correct that the Open Alliance TC10 specification does not
explicitly state that PHY configuration is lost when entering the
low‑power state. My earlier assumption was based on the LAN8670/1/2 PHY
implementation, where the 'monitor and react to wake event' block
remains active while other power supplies are switched off, resulting in
configuration loss.
However, since this behavior is not mandated by the specification and
may vary across PHY implementations, it should not be handled within the
generic PHY framework.
Given this, I agree that state save and restore is PHY‑specific
behavior. I will move this logic into the lan867x PHY driver in the next
revision.
Moreover I will revisit the implementation with internal review and then
post the next version. Thank you for your support.
Best regards,
Parthiban V
>
> Andrew
^ permalink raw reply
* Re: [PATCH net-next v2 2/3] dpll: add frequency monitoring callback ops
From: Jakub Kicinski @ 2026-04-01 3:10 UTC (permalink / raw)
To: Ivan Vecera
Cc: netdev, Vadim Fedorenko, Arkadiusz Kubalewski, Jiri Pirko,
Jonathan Corbet, Shuah Khan, David S. Miller, Eric Dumazet,
Paolo Abeni, Simon Horman, Donald Hunter, Prathosh Satish,
Petr Oros, linux-doc, linux-kernel
In-Reply-To: <20260330105505.715099-3-ivecera@redhat.com>
On Mon, 30 Mar 2026 12:55:04 +0200 Ivan Vecera wrote:
> +dpll_msg_add_freq_monitor(struct sk_buff *msg, struct dpll_device *dpll,
> + if (ops->freq_monitor_set && ops->freq_monitor_get) {
> + ret = ops->freq_monitor_get(dpll, dpll_priv(dpll),
> + &state, extack);
> + if (ret)
> + return ret;
> + if (nla_put_u32(msg, DPLL_A_FREQUENCY_MONITOR, state))
> + return -EMSGSIZE;
> + }
> +
> + return 0;
> +}
> +
> static int
> dpll_msg_add_phase_offset_avg_factor(struct sk_buff *msg,
> struct dpll_device *dpll,
> @@ -400,6 +420,38 @@ static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
> ffo);
> }
>
> +static int dpll_msg_add_measured_freq(struct sk_buff *msg, struct dpll_pin *pin,
> + struct dpll_pin_ref *ref,
> + struct netlink_ext_ack *extack)
> +{
> + const struct dpll_device_ops *dev_ops = dpll_device_ops(ref->dpll);
> + const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
> + struct dpll_device *dpll = ref->dpll;
> + enum dpll_feature_state state;
> + u64 measured_freq;
> + int ret;
> +
> + if (!ops->measured_freq_get)
> + return 0;
> + if (dev_ops->freq_monitor_get) {
what are you trying to cater to by making freq_monitor_get optional
here? I thought maybe some devices would have it always enabled, but
then dpll_msg_add_freq_monitor() should presumably report enabled
if !freq_monitor_get && measured_freq_get ?
Maybe there's some precedent in surrounding code outside of the context
but the intention of the patch reads a bit off.
> + ret = dev_ops->freq_monitor_get(dpll, dpll_priv(dpll),
> + &state, extack);
> + if (ret)
> + return ret;
> + if (state == DPLL_FEATURE_STATE_DISABLE)
> + return 0;
> + }
> + ret = ops->measured_freq_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
> + dpll, dpll_priv(dpll), &measured_freq, extack);
^ permalink raw reply
* Re: [PATCH net-next v2 1/3] dpll: add frequency monitoring to netlink spec
From: Jakub Kicinski @ 2026-04-01 3:05 UTC (permalink / raw)
To: Ivan Vecera
Cc: netdev, Vadim Fedorenko, Arkadiusz Kubalewski, Jiri Pirko,
Jonathan Corbet, Shuah Khan, David S. Miller, Eric Dumazet,
Paolo Abeni, Simon Horman, Donald Hunter, Prathosh Satish,
Petr Oros, linux-doc, linux-kernel
In-Reply-To: <20260330105505.715099-2-ivecera@redhat.com>
On Mon, 30 Mar 2026 12:55:03 +0200 Ivan Vecera wrote:
> Add DPLL_A_FREQUENCY_MONITOR device attribute to allow control over
> the frequency monitor feature. The attribute uses the existing
> dpll_feature_state enum (enable/disable) and is present in both
> device-get reply and device-set request.
>
> Add DPLL_A_PIN_MEASURED_FREQUENCY pin attribute to expose the measured
> input frequency in Hz. The attribute is present in the pin-get reply.
> + -
> + name: frequency-monitor
> + type: u32
> + enum: feature-state
> + doc: Receive or request state of frequency monitor feature.
reads a bit clunkily - how about:
Current or desired state of the frequency monitor feature.
?
> + If enabled, dpll device shall measure all currently available
> + inputs for their actual input frequency.
> -
> name: pin
> enum-name: dpll_a_pin
> @@ -456,6 +463,13 @@ attribute-sets:
> Value is in PPT (parts per trillion, 10^-12).
> Note: This attribute provides higher resolution than the standard
> fractional-frequency-offset (which is in PPM).
> + -
> + name: measured-frequency
> + type: u64
> + doc: |
> + The measured frequency of the input pin in Hz.
> + This is the actual frequency being received on the pin,
> + as measured by the dpll device hardware.
If we make this a u64 should it be fixed point? Seems dubious that we'd
ever be able to measure >4Ghz frequencies, much more likely that we'd
want sub-1 precision ? So let's say this is fixed point 34.30 ?
^ permalink raw reply
* Re: [RESEND PATCH net v3 2/2] net: stmmac: Prevent indefinite RX stall on buffer exhaustion
From: Jakub Kicinski @ 2026-04-01 2:59 UTC (permalink / raw)
To: Sam Edwards
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Maxime Coquelin, Alexandre Torgue, Russell King (Oracle),
Maxime Chevallier, Ovidiu Panait, Vladimir Oltean, Baruch Siach,
Serge Semin, Giuseppe Cavallaro, netdev, linux-stm32,
linux-arm-kernel, linux-kernel, stable
In-Reply-To: <20260328192503.520689-3-CFSworks@gmail.com>
On Sat, 28 Mar 2026 12:25:03 -0700 Sam Edwards wrote:
> @@ -5870,6 +5871,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
> priv->xstats.rx_dropped += rx_dropped;
> priv->xstats.rx_errors += rx_errors;
>
> + /* If stmmac_rx_refill() failed, keep trying until it doesn't. */
> + if (unlikely(stmmac_rx_dirty(priv, queue) > 0))
> + return budget;
If the system is OOMing having ksoftirq busy looping indefinitely is
not going to be very helpful. 1) only react if the fill level is below
some critical threshold, 2) try to add some delay (timer)? before the
retry
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH net-next 4/4] net: macb: Remove dedicated IRQ handler for WoL
From: Jakub Kicinski @ 2026-04-01 2:55 UTC (permalink / raw)
To: Kevin Hao
Cc: Nicolas Ferre, Claudiu Beznea, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, netdev
In-Reply-To: <20260328-macb-irq-v1-4-7b3e622fb46c@gmail.com>
On Sat, 28 Mar 2026 18:17:48 +0800 Kevin Hao wrote:
> In the current implementation, the suspend/resume path frees the
> existing IRQ handler and sets up a dedicated WoL IRQ handler, then
> restores the original handler upon resume. This approach is not used
> by any other Ethernet driver and unnecessarily complicates the
> suspend/resume process. After adjusting the IRQ handler in the previous
> patches, we can now handle WoL interrupts without introducing any
> overhead in the TX/RX hot path. Therefore, the dedicated WoL IRQ
> handler is removed.
Couple of sentences on testing (platform + flows) would be great here.
^ permalink raw reply
* Re: [PATCH net-next 3/4] net: macb: Factor out the handling of non-hot IRQ events into a separate function
From: Jakub Kicinski @ 2026-04-01 2:54 UTC (permalink / raw)
To: Kevin Hao
Cc: Nicolas Ferre, Claudiu Beznea, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, netdev
In-Reply-To: <20260328-macb-irq-v1-3-7b3e622fb46c@gmail.com>
On Sat, 28 Mar 2026 18:17:47 +0800 Kevin Hao wrote:
> struct macb_queue *queue = dev_id;
> struct macb *bp = queue->bp;
> struct net_device *dev = bp->dev;
> - u32 status, ctrl;
> + u32 status;
> bool isr_clear;
nit: please try to keep the variable declaration lines sorted longest to
shortest
^ permalink raw reply
* Re: [PATCH net-next 2/4] net: macb: Consolidate MACB_CAPS_ISR_CLEAR_ON_WRITE checks in IRQ handler
From: Jakub Kicinski @ 2026-04-01 2:54 UTC (permalink / raw)
To: Kevin Hao
Cc: Nicolas Ferre, Claudiu Beznea, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, netdev
In-Reply-To: <20260328-macb-irq-v1-2-7b3e622fb46c@gmail.com>
On Sat, 28 Mar 2026 18:17:46 +0800 Kevin Hao wrote:
> Currently, the MACB_CAPS_ISR_CLEAR_ON_WRITE flag is checked in every
> branch of the IRQ handler. This repeated evaluation is unnecessary.
> By consolidating the flag check, we eliminate redundant loads of
> bp->caps when TX and RX events occur simultaneously, a common scenario
> under high network throughput. Additionally, this optimization reduces
> the function size from 0x2e8 to 0x2c4.
feels a bit subjective TBH. An alternative improvement would be to
factor out the conditional to a helper:
static void macb_queue_isr_clear(bp, queue, mask)
{
if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
queue_writel(queue, ISR, mask);
}
I'd like an ack one way or the other from someone before merging this
^ permalink raw reply
* [syzbot] [net?] WARNING: refcount bug in dev_deactivate_many
From: syzbot @ 2026-04-01 2:50 UTC (permalink / raw)
To: davem, edumazet, horms, jhs, jiri, kuba, linux-kernel, netdev,
pabeni, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: f242ac4a0944 Merge tag 'x86-urgent-2026-03-29' of git://gi..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=165f90f2580000
kernel config: https://syzkaller.appspot.com/x/.config?x=5a3e5e8c17cc174e
dashboard link: https://syzkaller.appspot.com/bug?extid=1bd67523d909320dd9e2
compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
Unfortunately, I don't have any reproducer for this issue yet.
Downloadable assets:
disk image: https://storage.googleapis.com/syzbot-assets/a3583806d09a/disk-f242ac4a.raw.xz
vmlinux: https://storage.googleapis.com/syzbot-assets/0718400bb1a9/vmlinux-f242ac4a.xz
kernel image: https://storage.googleapis.com/syzbot-assets/b22f3be2e373/bzImage-f242ac4a.xz
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+1bd67523d909320dd9e2@syzkaller.appspotmail.com
------------[ cut here ]------------
refcount_t: decrement hit 0; leaking memory.
WARNING: lib/refcount.c:31 at refcount_warn_saturate+0x7c/0x130 lib/refcount.c:31, CPU#0: kworker/u8:5/93
Modules linked in:
CPU: 0 UID: 0 PID: 93 Comm: kworker/u8:5 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2026
Workqueue: events_unbound linkwatch_event
RIP: 0010:refcount_warn_saturate+0x7c/0x130 lib/refcount.c:31
Code: c0 51 1a 8c e8 25 17 12 fd 83 fd 02 0f 84 a1 00 00 00 76 27 83 fd 03 74 7d 83 fd 04 75 3e e8 fb 1b 12 fd 48 8d 3d b4 57 ed 0b <67> 48 0f b9 3a e8 ea 1b 12 fd 5b 5d c3 cc cc cc cc 85 ed 74 3a e8
RSP: 0018:ffffc9000215f878 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff88802a98c664 RCX: ffffffff84f6dbcb
RDX: ffff88801e7924c0 RSI: ffffffff84f6dbe5 RDI: ffffffff90e433a0
RBP: 0000000000000004 R08: 0000000000000005 R09: 0000000000000004
R10: 0000000000000004 R11: 0000000000000000 R12: 1ffff9200042bf14
R13: ffff88802a98c664 R14: 0000000000000000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88812433c000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000001b2ff15ff8 CR3: 000000003954a000 CR4: 00000000003526f0
Call Trace:
<TASK>
__refcount_dec include/linux/refcount.h:461 [inline]
refcount_dec include/linux/refcount.h:476 [inline]
ref_tracker_free+0x5cd/0x6c0 lib/ref_tracker.c:303
netdev_tracker_free include/linux/netdevice.h:4456 [inline]
netdev_put include/linux/netdevice.h:4473 [inline]
netdev_put include/linux/netdevice.h:4469 [inline]
netdev_watchdog_down net/sched/sch_generic.c:575 [inline]
dev_deactivate_many+0x28f/0xfc0 net/sched/sch_generic.c:1337
dev_deactivate+0xf8/0x1c0 net/sched/sch_generic.c:1368
linkwatch_do_dev net/core/link_watch.c:184 [inline]
linkwatch_do_dev+0xce/0x110 net/core/link_watch.c:166
__linkwatch_run_queue+0x3a9/0x900 net/core/link_watch.c:240
linkwatch_event+0x8f/0xc0 net/core/link_watch.c:314
process_one_work+0xa23/0x19a0 kernel/workqueue.c:3276
process_scheduled_works kernel/workqueue.c:3359 [inline]
worker_thread+0x5ef/0xe50 kernel/workqueue.c:3440
kthread+0x370/0x450 kernel/kthread.c:436
ret_from_fork+0x754/0xd80 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
----------------
Code disassembly (best guess):
0: c0 51 1a 8c rclb $0x8c,0x1a(%rcx)
4: e8 25 17 12 fd call 0xfd12172e
9: 83 fd 02 cmp $0x2,%ebp
c: 0f 84 a1 00 00 00 je 0xb3
12: 76 27 jbe 0x3b
14: 83 fd 03 cmp $0x3,%ebp
17: 74 7d je 0x96
19: 83 fd 04 cmp $0x4,%ebp
1c: 75 3e jne 0x5c
1e: e8 fb 1b 12 fd call 0xfd121c1e
23: 48 8d 3d b4 57 ed 0b lea 0xbed57b4(%rip),%rdi # 0xbed57de
* 2a: 67 48 0f b9 3a ud1 (%edx),%rdi <-- trapping instruction
2f: e8 ea 1b 12 fd call 0xfd121c1e
34: 5b pop %rbx
35: 5d pop %rbp
36: c3 ret
37: cc int3
38: cc int3
39: cc int3
3a: cc int3
3b: 85 ed test %ebp,%ebp
3d: 74 3a je 0x79
3f: e8 .byte 0xe8
---
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: [PATCH net v2] net: ftgmac100: fix ring allocation unwind on open failure
From: patchwork-bot+netdevbpf @ 2026-04-01 2:50 UTC (permalink / raw)
To: Yufan Chen
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, netdev,
linux-kernel
In-Reply-To: <20260328163257.60836-1-yufan.chen@linux.dev>
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Sun, 29 Mar 2026 00:32:57 +0800 you wrote:
> ftgmac100_alloc_rings() allocates rx_skbs, tx_skbs, rxdes, txdes, and
> rx_scratch in stages. On intermediate failures it returned -ENOMEM
> directly, leaking resources allocated earlier in the function.
>
> Rework the failure path to use staged local unwind labels and free
> allocated resources in reverse order before returning -ENOMEM. This
> matches common netdev allocation cleanup style.
>
> [...]
Here is the summary with links:
- [net,v2] net: ftgmac100: fix ring allocation unwind on open failure
https://git.kernel.org/netdev/net/c/c0fd0fe745f5
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next] net: airoha: Fix typo in airoha_set_gdm2_loopback routine name
From: patchwork-bot+netdevbpf @ 2026-04-01 2:40 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-arm-kernel,
linux-mediatek, netdev
In-Reply-To: <20260330-airoha_set_gdm2_loopback-fix-typo-v1-1-a1320ff6b6cc@kernel.org>
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 00:03:49 +0200 you wrote:
> Rename airhoha_set_gdm2_loopback() in airoha_set_gdm2_loopback()
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> [...]
Here is the summary with links:
- [net-next] net: airoha: Fix typo in airoha_set_gdm2_loopback routine name
https://git.kernel.org/netdev/net-next/c/a94ddc191f19
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v2 0/2] declance: Improve DMA error reporting
From: patchwork-bot+netdevbpf @ 2026-04-01 2:40 UTC (permalink / raw)
To: Maciej W. Rozycki
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, netdev,
linux-kernel
In-Reply-To: <alpine.DEB.2.21.2603291835550.60268@angie.orcam.me.uk>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Sun, 29 Mar 2026 19:07:18 +0100 (BST) you wrote:
> Hi,
>
> D'oh, this v2 fixes a silly thinko in the commit description of 2/2.
>
> Inspired by a recent discussion[1] I have come up with this pair of
> small improvements to DMA error reporting with declance. Please apply.
>
> [...]
Here is the summary with links:
- [net-next,v2,1/2] declance: Rate-limit DMA errors
https://git.kernel.org/netdev/net-next/c/ee769323b1bf
- [net-next,v2,2/2] declance: Include the offending address with DMA errors
https://git.kernel.org/netdev/net-next/c/aae5efaeb8aa
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net-next v3 0/4] net: hsr: address functional and concurrency bugs
From: Jakub Kicinski @ 2026-04-01 2:37 UTC (permalink / raw)
To: luka.gejak
Cc: davem, edumazet, pabeni, netdev, horms, fmaurer, liuhangbin,
linux-kernel
In-Reply-To: <20260329112313.17164-1-luka.gejak@linux.dev>
On Sun, 29 Mar 2026 13:23:09 +0200 luka.gejak@linux.dev wrote:
> This series addresses four logic bugs in the HSR/PRP implementation
> identified during a protocol audit.
>
> The primary change resolves a race condition in the node merging path by
> implementing address-based lock ordering. This ensures that concurrent
> mutations of sequence blocks do not lead to state corruption or
> deadlocks.
>
> Additional fixes include correcting asymmetric VLAN error unwinding,
> enforcing strict supervision frame TLV validation, and improving Netlink
> error reporting for invalid interlink attributes.
I think that patches 1 and 2 need to go to net with a Fixes tag.
They look like run of the mill bug fixes. 3 and 4 are logical
fixes and change behavior so net-next makes sense.
FWIW AI has something to say about patch 3, I did not investigate:
https://sashiko.dev/#/patchset/20260329112313.17164-2-luka.gejak@linux.dev
--
pw-bot: cr
^ permalink raw reply
* Re: [PATCH 0/2] net: refactor USB endpoint lookups
From: patchwork-bot+netdevbpf @ 2026-04-01 2:30 UTC (permalink / raw)
To: Johan Hovold
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, linux-usb, netdev,
linux-kernel
In-Reply-To: <20260330102611.1671546-1-johan@kernel.org>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 12:26:09 +0200 you wrote:
> Use the common USB helpers for looking up bulk and interrupt endpoints
> instead of open coding.
>
> Johan
>
>
> Johan Hovold (2):
> net: hso: refactor endpoint lookup
> net: ipeth: refactor endpoint lookup
>
> [...]
Here is the summary with links:
- [1/2] net: hso: refactor endpoint lookup
https://git.kernel.org/netdev/net-next/c/da45a55748f2
- [2/2] net: ipeth: refactor endpoint lookup
https://git.kernel.org/netdev/net-next/c/abfca6b13bcf
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH 0/3] nfc: refactor USB endpoint lookups
From: patchwork-bot+netdevbpf @ 2026-04-01 2:30 UTC (permalink / raw)
To: Johan Hovold; +Cc: netdev, linux-kernel
In-Reply-To: <20260330103655.1672331-1-johan@kernel.org>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 30 Mar 2026 12:36:52 +0200 you wrote:
> Use the common USB helper for looking up bulk and interrupt endpoints
> instead of open coding.
>
> Johan
>
>
> Johan Hovold (3):
> nfc: nfcmrvl: refactor endpoint lookup
> nfc: pn533: refactor endpoint lookup
> nfc: port100: refactor endpoint lookup
>
> [...]
Here is the summary with links:
- [1/3] nfc: nfcmrvl: refactor endpoint lookup
https://git.kernel.org/netdev/net-next/c/dba69cba4a5d
- [2/3] nfc: pn533: refactor endpoint lookup
https://git.kernel.org/netdev/net-next/c/13f2e141b944
- [3/3] nfc: port100: refactor endpoint lookup
https://git.kernel.org/netdev/net-next/c/771a627ddd3b
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [PATCH v10 net-next 11/11] net/nebula-matrix: add common dev start/stop operation
From: illusion.wang @ 2026-04-01 2:23 UTC (permalink / raw)
To: dimon.zhao, illusion.wang, alvin.wang, sam.chen, netdev
Cc: andrew+netdev, corbet, kuba, linux-doc, lorenzo, pabeni, horms,
vadim.fedorenko, lukas.bulwahn, edumazet, enelsonmoore, skhan,
hkallweit1, jani.nikula, open list
In-Reply-To: <20260401022318.28550-1-illusion.wang@nebula-matrix.com>
start common dev: config msix map table, alloc and enable msix vectors,
register mailbox ISR and enable mailbox irq
Signed-off-by: illusion.wang <illusion.wang@nebula-matrix.com>
---
.../nebula-matrix/nbl/nbl_core/nbl_dev.c | 214 ++++++++++++++++++
.../net/ethernet/nebula-matrix/nbl/nbl_main.c | 30 ++-
2 files changed, 243 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c
index 4c97832a25a6..a3aa0fcd1443 100644
--- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c
@@ -6,6 +6,17 @@
#include <linux/pci.h>
#include "nbl_dev.h"
+static int nbl_dev_clean_mailbox_schedule(struct nbl_dev_mgt *dev_mgt);
+
+/* ---------- Interrupt config ---------- */
+static irqreturn_t nbl_dev_clean_mailbox(int __always_unused irq, void *data)
+{
+ struct nbl_dev_mgt *dev_mgt = (struct nbl_dev_mgt *)data;
+
+ nbl_dev_clean_mailbox_schedule(dev_mgt);
+ return IRQ_HANDLED;
+}
+
static void nbl_dev_init_msix_cnt(struct nbl_dev_mgt *dev_mgt)
{
struct nbl_dev_common *dev_common = dev_mgt->common_dev;
@@ -14,6 +25,170 @@ static void nbl_dev_init_msix_cnt(struct nbl_dev_mgt *dev_mgt)
msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].num = 1;
}
+static int nbl_dev_request_mailbox_irq(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dev_common *dev_common = dev_mgt->common_dev;
+ struct nbl_msix_info *msix_info = &dev_common->msix_info;
+ struct nbl_common_info *common = dev_mgt->common;
+ u16 local_vec_id;
+ u32 irq_num;
+ int err;
+
+ if (!msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].num)
+ return 0;
+
+ local_vec_id =
+ msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].base_vector_id;
+ irq_num = pci_irq_vector(common->pdev, local_vec_id);
+
+ snprintf(dev_common->mailbox_name, sizeof(dev_common->mailbox_name),
+ "nbl_mailbox@pci:%s", pci_name(common->pdev));
+ err = request_irq(irq_num, nbl_dev_clean_mailbox, 0,
+ dev_common->mailbox_name, dev_mgt);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static void nbl_dev_free_mailbox_irq(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dev_common *dev_common = dev_mgt->common_dev;
+ struct nbl_msix_info *msix_info = &dev_common->msix_info;
+ struct nbl_common_info *common = dev_mgt->common;
+ u16 local_vec_id;
+ u32 irq_num;
+
+ if (!msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].num)
+ return;
+
+ local_vec_id =
+ msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].base_vector_id;
+ irq_num = pci_irq_vector(common->pdev, local_vec_id);
+
+ free_irq(irq_num, dev_mgt);
+}
+
+static int nbl_dev_enable_mailbox_irq(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dispatch_ops *disp_ops = dev_mgt->disp_ops_tbl->ops;
+ struct nbl_channel_ops *chan_ops = dev_mgt->chan_ops_tbl->ops;
+ struct nbl_dev_common *dev_common = dev_mgt->common_dev;
+ struct nbl_msix_info *msix_info = &dev_common->msix_info;
+ u16 local_vec_id;
+
+ if (!msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].num)
+ return 0;
+
+ local_vec_id =
+ msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].base_vector_id;
+ chan_ops->set_queue_state(dev_mgt->chan_ops_tbl->priv,
+ NBL_CHAN_INTERRUPT_READY,
+ NBL_CHAN_TYPE_MAILBOX, true);
+
+ return disp_ops->enable_mailbox_irq(dev_mgt->disp_ops_tbl->priv,
+ local_vec_id, true);
+}
+
+static int nbl_dev_disable_mailbox_irq(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dispatch_ops *disp_ops = dev_mgt->disp_ops_tbl->ops;
+ struct nbl_channel_ops *chan_ops = dev_mgt->chan_ops_tbl->ops;
+ struct nbl_dev_common *dev_common = dev_mgt->common_dev;
+ struct nbl_msix_info *msix_info = &dev_common->msix_info;
+ u16 local_vec_id;
+
+ if (!msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].num)
+ return 0;
+
+ flush_work(&dev_common->clean_mbx_task);
+ local_vec_id =
+ msix_info->serv_info[NBL_MSIX_MAILBOX_TYPE].base_vector_id;
+ chan_ops->set_queue_state(dev_mgt->chan_ops_tbl->priv,
+ NBL_CHAN_INTERRUPT_READY,
+ NBL_CHAN_TYPE_MAILBOX, false);
+
+ return disp_ops->enable_mailbox_irq(dev_mgt->disp_ops_tbl->priv,
+ local_vec_id, false);
+}
+
+static int nbl_dev_configure_msix_map(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dispatch_ops *disp_ops = dev_mgt->disp_ops_tbl->ops;
+ struct nbl_dev_common *dev_common = dev_mgt->common_dev;
+ struct nbl_msix_info *msix_info = &dev_common->msix_info;
+ bool mask_en = msix_info->serv_info[NBL_MSIX_NET_TYPE].hw_self_mask_en;
+ u16 msix_net_num = msix_info->serv_info[NBL_MSIX_NET_TYPE].num;
+ u16 msix_not_net_num = 0;
+ int err, i;
+
+ for (i = NBL_MSIX_NET_TYPE; i < NBL_MSIX_TYPE_MAX; i++)
+ msix_info->serv_info[i].base_vector_id =
+ msix_info->serv_info[i - 1].base_vector_id +
+ msix_info->serv_info[i - 1].num;
+
+ for (i = NBL_MSIX_MAILBOX_TYPE; i < NBL_MSIX_TYPE_MAX; i++)
+ msix_not_net_num += msix_info->serv_info[i].num;
+
+ err = disp_ops->configure_msix_map(dev_mgt->disp_ops_tbl->priv,
+ msix_net_num, msix_not_net_num,
+ mask_en);
+
+ return err;
+}
+
+static int nbl_dev_destroy_msix_map(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dispatch_ops *disp_ops = dev_mgt->disp_ops_tbl->ops;
+
+ return disp_ops->destroy_msix_map(dev_mgt->disp_ops_tbl->priv);
+}
+
+static int nbl_dev_alloc_msix_intr(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dev_common *dev_common = dev_mgt->common_dev;
+ struct nbl_msix_info *msix_info = &dev_common->msix_info;
+ struct nbl_common_info *common = dev_mgt->common;
+ int needed = 0;
+ int err;
+ int i;
+
+ for (i = 0; i < NBL_MSIX_TYPE_MAX; i++)
+ needed += msix_info->serv_info[i].num;
+
+ err = pci_alloc_irq_vectors(common->pdev, needed, needed,
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
+ if (err < 0) {
+ pr_err("pci_alloc_irq_vectors failed, err = %d.\n", err);
+ goto enable_msix_failed;
+ }
+
+ return needed;
+
+enable_msix_failed:
+ return err;
+}
+
+static int nbl_dev_init_interrupt_scheme(struct nbl_dev_mgt *dev_mgt)
+{
+ int err;
+
+ err = nbl_dev_alloc_msix_intr(dev_mgt);
+ if (err < 0) {
+ dev_err(dev_mgt->common->dev,
+ "Failed to enable MSI-X vectors\n");
+ return err;
+ }
+ return 0;
+}
+
+static void nbl_dev_clear_interrupt_scheme(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_common_info *common = dev_mgt->common;
+
+ pci_free_irq_vectors(common->pdev);
+}
+
/* ---------- Channel config ---------- */
static int nbl_dev_setup_chan_qinfo(struct nbl_dev_mgt *dev_mgt, u8 chan_type)
{
@@ -79,6 +254,14 @@ static void nbl_dev_clean_mailbox_task(struct work_struct *work)
NBL_CHAN_TYPE_MAILBOX);
}
+static int nbl_dev_clean_mailbox_schedule(struct nbl_dev_mgt *dev_mgt)
+{
+ struct nbl_dev_common *common_dev = dev_mgt->common_dev;
+
+ nbl_common_queue_work(&common_dev->clean_mbx_task);
+ return 0;
+}
+
/* ---------- Dev init process ---------- */
static int nbl_dev_setup_common_dev(struct nbl_adapter *adapter)
{
@@ -217,9 +400,40 @@ void nbl_dev_remove(struct nbl_adapter *adapter)
/* ---------- Dev start process ---------- */
int nbl_dev_start(struct nbl_adapter *adapter)
{
+ struct nbl_dev_mgt *dev_mgt = adapter->core.dev_mgt;
+ int ret;
+
+ ret = nbl_dev_configure_msix_map(dev_mgt);
+ if (ret)
+ goto config_msix_map_err;
+
+ ret = nbl_dev_init_interrupt_scheme(dev_mgt);
+ if (ret)
+ goto init_interrupt_scheme_err;
+ ret = nbl_dev_request_mailbox_irq(dev_mgt);
+ if (ret)
+ goto mailbox_request_irq_err;
+ ret = nbl_dev_enable_mailbox_irq(dev_mgt);
+ if (ret)
+ goto enable_mailbox_irq_err;
return 0;
+enable_mailbox_irq_err:
+ nbl_dev_disable_mailbox_irq(dev_mgt);
+ nbl_dev_free_mailbox_irq(dev_mgt);
+mailbox_request_irq_err:
+ nbl_dev_clear_interrupt_scheme(dev_mgt);
+init_interrupt_scheme_err:
+ nbl_dev_destroy_msix_map(dev_mgt);
+config_msix_map_err:
+ return ret;
}
void nbl_dev_stop(struct nbl_adapter *adapter)
{
+ struct nbl_dev_mgt *dev_mgt = adapter->core.dev_mgt;
+
+ nbl_dev_disable_mailbox_irq(dev_mgt);
+ nbl_dev_free_mailbox_irq(dev_mgt);
+ nbl_dev_clear_interrupt_scheme(dev_mgt);
+ nbl_dev_destroy_msix_map(dev_mgt);
}
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
index db035136e09c..8f07d4fbdf04 100644
--- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
@@ -286,7 +286,35 @@ static struct pci_driver nbl_driver = {
.remove = nbl_remove,
};
-module_pci_driver(nbl_driver);
+static int __init nbl_module_init(void)
+{
+ int status;
+
+ status = nbl_common_create_wq();
+ if (status) {
+ pr_err("Failed to create wq, err = %d\n", status);
+ goto wq_create_failed;
+ }
+ status = pci_register_driver(&nbl_driver);
+ if (status) {
+ pr_err("Failed to register PCI driver, err = %d\n", status);
+ goto pci_register_driver_failed;
+ }
+ return 0;
+
+pci_register_driver_failed:
+ nbl_common_destroy_wq();
+wq_create_failed:
+ return status;
+}
+
+static void __exit nbl_module_exit(void)
+{
+ pci_unregister_driver(&nbl_driver);
+ nbl_common_destroy_wq();
+}
+module_init(nbl_module_init);
+module_exit(nbl_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Nebula Matrix Network Driver");
--
2.47.3
^ permalink raw reply related
* Re: [PATCH net-next v2 1/3] net: pse-pd: prevent regulator cleanup from disabling unclaimed PSE PIs
From: Jakub Kicinski @ 2026-04-01 2:28 UTC (permalink / raw)
To: Carlo Szelinsky
Cc: Kory Maincent, Oleksij Rempel, Andrew Lunn, Heiner Kallweit,
Russell King, David S . Miller, Eric Dumazet, Paolo Abeni,
Simon Horman, netdev, linux-kernel
In-Reply-To: <20260330132952.2950531-2-github@szelinsky.de>
On Mon, 30 Mar 2026 15:29:50 +0200 Carlo Szelinsky wrote:
> --- a/include/linux/pse-pd/pse.h
> +++ b/include/linux/pse-pd/pse.h
> @@ -260,6 +260,7 @@ struct pse_pi {
> struct device_node *np;
> struct regulator_dev *rdev;
> bool admin_state_enabled;
> + bool admin_state_synced;
> struct pse_power_domain *pw_d;
new field is missing from the kdoc:
Warning: include/linux/pse-pd/pse.h:267 struct member 'admin_state_synced' not described in 'pse_pi'
--
pw-bot: cr
^ permalink raw reply
* [PATCH v10 net-next 01/11] net/nebula-matrix: add minimum nbl build framework
From: illusion.wang @ 2026-04-01 2:23 UTC (permalink / raw)
To: dimon.zhao, illusion.wang, alvin.wang, sam.chen, netdev
Cc: andrew+netdev, corbet, kuba, linux-doc, lorenzo, pabeni, horms,
vadim.fedorenko, lukas.bulwahn, edumazet, enelsonmoore, skhan,
hkallweit1, jani.nikula, open list
In-Reply-To: <20260401022318.28550-1-illusion.wang@nebula-matrix.com>
1.Add nbl min build infrastructure for nbl driver.
2.Implemented the framework of pci device initialization.
Signed-off-by: illusion.wang <illusion.wang@nebula-matrix.com>
---
.../device_drivers/ethernet/index.rst | 1 +
.../ethernet/nebula-matrix/nbl.rst | 27 +++++
MAINTAINERS | 10 ++
drivers/net/ethernet/Kconfig | 1 +
drivers/net/ethernet/Makefile | 1 +
drivers/net/ethernet/nebula-matrix/Kconfig | 34 ++++++
drivers/net/ethernet/nebula-matrix/Makefile | 6 +
.../net/ethernet/nebula-matrix/nbl/Makefile | 6 +
.../net/ethernet/nebula-matrix/nbl/nbl_core.h | 16 +++
.../nbl/nbl_include/nbl_include.h | 21 ++++
.../net/ethernet/nebula-matrix/nbl/nbl_main.c | 113 ++++++++++++++++++
11 files changed, 236 insertions(+)
create mode 100644 Documentation/networking/device_drivers/ethernet/nebula-matrix/nbl.rst
create mode 100644 drivers/net/ethernet/nebula-matrix/Kconfig
create mode 100644 drivers/net/ethernet/nebula-matrix/Makefile
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/Makefile
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
diff --git a/Documentation/networking/device_drivers/ethernet/index.rst b/Documentation/networking/device_drivers/ethernet/index.rst
index 5f3f06111911..14868fabc1c6 100644
--- a/Documentation/networking/device_drivers/ethernet/index.rst
+++ b/Documentation/networking/device_drivers/ethernet/index.rst
@@ -48,6 +48,7 @@ Contents:
meta/fbnic
microsoft/netvsc
mucse/rnpgbe
+ nebula-matrix/nbl
netronome/nfp
pensando/ionic
pensando/ionic_rdma
diff --git a/Documentation/networking/device_drivers/ethernet/nebula-matrix/nbl.rst b/Documentation/networking/device_drivers/ethernet/nebula-matrix/nbl.rst
new file mode 100644
index 000000000000..262796717dc4
--- /dev/null
+++ b/Documentation/networking/device_drivers/ethernet/nebula-matrix/nbl.rst
@@ -0,0 +1,27 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================================================
+Linux Base Driver for Nebula-matrix M18000-NIC family
+=====================================================
+
+Overview:
+=========
+M18000-NIC is a series of network interface card for the Data Center Area.
+
+The driver supports link-speed 100GbE/25GE/10GE.
+
+M18000-NIC devices support MSI-X interrupt vector for each Tx/Rx queue and
+interrupt moderation.
+
+M18000-NIC devices support also various offload features such as checksum offload,
+Receive-Side Scaling(RSS).
+
+Support
+=======
+
+For more information about M18000-NIC, please visit the following URL:
+https://www.nebula-matrix.com/
+
+If an issue is identified with the released source code on the supported kernel
+with a supported adapter, email the specific information related to the issue to
+open@nebula-matrix.com.
diff --git a/MAINTAINERS b/MAINTAINERS
index 7a2ffd9d37d5..041ad29ad62e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18206,6 +18206,16 @@ F: Documentation/devicetree/bindings/hwmon/nuvoton,nct7363.yaml
F: Documentation/hwmon/nct7363.rst
F: drivers/hwmon/nct7363.c
+NEBULA-MATRIX ETHERNET DRIVER (nebula-matrix)
+M: Illusion Wang <illusion.wang@nebula-matrix.com>
+M: Dimon Zhao <dimon.zhao@nebula-matrix.com>
+M: Alvin Wang <alvin.wang@nebula-matrix.com>
+M: Sam Chen <sam.chen@nebula-matrix.com>
+L: netdev@vger.kernel.org
+S: Maintained
+F: Documentation/networking/device_drivers/ethernet/nebula-matrix/
+F: drivers/net/ethernet/nebula-matrix/
+
NETCONSOLE
M: Breno Leitao <leitao@debian.org>
S: Maintained
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index aa7103e7f47f..3aa005adb90e 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -131,6 +131,7 @@ config FEALNX
source "drivers/net/ethernet/ni/Kconfig"
source "drivers/net/ethernet/natsemi/Kconfig"
+source "drivers/net/ethernet/nebula-matrix/Kconfig"
source "drivers/net/ethernet/netronome/Kconfig"
source "drivers/net/ethernet/8390/Kconfig"
source "drivers/net/ethernet/nvidia/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index 6615a67a63d5..024a8e91abed 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_NET_VENDOR_MUCSE) += mucse/
obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/
+obj-$(CONFIG_NET_VENDOR_NEBULA_MATRIX) += nebula-matrix/
obj-$(CONFIG_NET_VENDOR_NETRONOME) += netronome/
obj-$(CONFIG_NET_VENDOR_NI) += ni/
obj-$(CONFIG_NET_VENDOR_NVIDIA) += nvidia/
diff --git a/drivers/net/ethernet/nebula-matrix/Kconfig b/drivers/net/ethernet/nebula-matrix/Kconfig
new file mode 100644
index 000000000000..28a05dc7a0b4
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/Kconfig
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Nebula-matrix network device configuration
+#
+
+config NET_VENDOR_NEBULA_MATRIX
+ bool "Nebula-matrix devices"
+ default y
+ help
+ If you have a network (Ethernet) card belonging to this class, say Y.
+ Note that the answer to this question doesn't directly affect the
+ kernel: saying N will just cause the configurator to skip all
+ the questions about Nebula-matrix cards. If you say Y, you will be asked
+ for your specific card in the following questions.
+
+if NET_VENDOR_NEBULA_MATRIX
+
+config NBL
+ tristate "Nebula-matrix Ethernet Controller m18100/m18000 support"
+ depends on 64BIT && PCI
+ help
+ This driver supports Nebula-matrix Ethernet Controller m18100/m18000
+ Family of devices. For more information about this product, go to
+ the product description with smart NIC:
+
+ <http://www.nebula-matrix.com>
+
+ More specific information on configuring the driver is in
+ <file:Documentation/networking/device_drivers/ethernet/nebula-matrix/nbl.rst>.
+
+ To compile this driver as a module, choose M here. The module
+ will be called nbl.
+
+endif # NET_VENDOR_NEBULA_MATRIX
diff --git a/drivers/net/ethernet/nebula-matrix/Makefile b/drivers/net/ethernet/nebula-matrix/Makefile
new file mode 100644
index 000000000000..42cdf2db8f0c
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Nebula-matrix network device drivers.
+#
+
+obj-$(CONFIG_NBL) += nbl/
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/Makefile b/drivers/net/ethernet/nebula-matrix/nbl/Makefile
new file mode 100644
index 000000000000..b90fba239401
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Nebula Matrix Limited.
+
+obj-$(CONFIG_NBL) := nbl.o
+
+nbl-objs += nbl_main.o
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h
new file mode 100644
index 000000000000..c525114297b4
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_CORE_H_
+#define _NBL_CORE_H_
+
+enum {
+ NBL_CAP_HAS_CTRL_BIT,
+ NBL_CAP_HAS_NET_BIT,
+ NBL_CAP_IS_NIC_BIT,
+ NBL_CAP_IS_LEONIS_BIT,
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h
new file mode 100644
index 000000000000..1046e6517b15
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_INCLUDE_H_
+#define _NBL_INCLUDE_H_
+
+#include <linux/types.h>
+
+/* ------ Basic definitions ------- */
+#define NBL_DRIVER_NAME "nbl"
+
+struct nbl_func_caps {
+ u32 has_ctrl:1;
+ u32 has_net:1;
+ u32 is_nic:1;
+ u32 rsv:29;
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
new file mode 100644
index 000000000000..10c3536b327b
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include "nbl_include/nbl_include.h"
+#include "nbl_core.h"
+
+static int nbl_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ return 0;
+}
+
+static void nbl_remove(struct pci_dev *pdev)
+{
+}
+
+/*
+ * PCI Device IDs for Leonis/NBL Network Controllers
+ *
+ * Vendor ID: 0x1F0F
+ * SNIC v3r1 product Device IDs range: 0x3403-0x3412
+ */
+#define NBL_VENDOR_ID 0x1F0F
+
+#define NBL_DEVICE_ID_M18110 0x3403
+#define NBL_DEVICE_ID_M18110_LX 0x3404
+#define NBL_DEVICE_ID_M18110_BASE_T 0x3405
+#define NBL_DEVICE_ID_M18110_LX_BASE_T 0x3406
+#define NBL_DEVICE_ID_M18110_OCP 0x3407
+#define NBL_DEVICE_ID_M18110_LX_OCP 0x3408
+#define NBL_DEVICE_ID_M18110_BASE_T_OCP 0x3409
+#define NBL_DEVICE_ID_M18110_LX_BASE_T_OCP 0x340a
+#define NBL_DEVICE_ID_M18000 0x340b
+#define NBL_DEVICE_ID_M18000_LX 0x340c
+#define NBL_DEVICE_ID_M18000_BASE_T 0x340d
+#define NBL_DEVICE_ID_M18000_LX_BASE_T 0x340e
+#define NBL_DEVICE_ID_M18000_OCP 0x340f
+#define NBL_DEVICE_ID_M18000_LX_OCP 0x3410
+#define NBL_DEVICE_ID_M18000_BASE_T_OCP 0x3411
+#define NBL_DEVICE_ID_M18000_LX_BASE_T_OCP 0x3412
+
+static const struct pci_device_id nbl_id_table[] = {
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_BASE_T),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX_BASE_T),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_BASE_T_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18110_LX_BASE_T_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_BASE_T),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX_BASE_T),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_BASE_T_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ { PCI_DEVICE(NBL_VENDOR_ID, NBL_DEVICE_ID_M18000_LX_BASE_T_OCP),
+ .driver_data = BIT(NBL_CAP_HAS_NET_BIT) | BIT(NBL_CAP_IS_NIC_BIT) |
+ BIT(NBL_CAP_IS_LEONIS_BIT) },
+ /* required as sentinel */
+ {
+ 0,
+ }
+};
+MODULE_DEVICE_TABLE(pci, nbl_id_table);
+
+static struct pci_driver nbl_driver = {
+ .name = NBL_DRIVER_NAME,
+ .id_table = nbl_id_table,
+ .probe = nbl_probe,
+ .remove = nbl_remove,
+};
+
+module_pci_driver(nbl_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Nebula Matrix Network Driver");
--
2.47.3
^ permalink raw reply related
* [PATCH net-next] MAINTAINERS: orphan PPP over Ethernet driver
From: Qingfang Deng @ 2026-04-01 2:28 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Kees Cook, Guillaume Nault, Eric Woudstra,
linux-kernel, netdev
Cc: Michal Ostrowski, Michal Ostrowski, Cyrill Gorcunov
We haven't seen activities from Michal Ostrowski for quite a long time.
The last commit from him is fb64bb560e18 ("PPPoE: Fix flush/close
races."), which was in 2009. Email to mostrows@earthlink.net also
bounces.
Signed-off-by: Qingfang Deng <dqfext@gmail.com>
---
MAINTAINERS | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7a2ffd9d37d5..3b7b7802ff95 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -21064,8 +21064,7 @@ F: include/uapi/linux/atmppp.h
F: net/atm/pppoatm.c
PPP OVER ETHERNET
-M: Michal Ostrowski <mostrows@earthlink.net>
-S: Maintained
+S: Orphan
F: drivers/net/ppp/pppoe.c
F: drivers/net/ppp/pppox.c
--
2.43.0
^ permalink raw reply related
* [PATCH v10 net-next 02/11] net/nebula-matrix: add our driver architecture
From: illusion.wang @ 2026-04-01 2:23 UTC (permalink / raw)
To: dimon.zhao, illusion.wang, alvin.wang, sam.chen, netdev
Cc: andrew+netdev, corbet, kuba, linux-doc, lorenzo, pabeni, horms,
vadim.fedorenko, lukas.bulwahn, edumazet, enelsonmoore, skhan,
hkallweit1, jani.nikula, open list
In-Reply-To: <20260401022318.28550-1-illusion.wang@nebula-matrix.com>
our driver architecture:
Hardware (HW), Channel, Resource, Dispatch, and Device Layer
Struct Initialization/Deinitialization, and Operation Set Registration/
Unregistration
Our driver architecture is relatively complex because the code is highly
reusable and designed to support multiple features. Additionally, the
codebase supports multiple chip variants, each with distinct
hardware-software interactions.
To ensure compatibility, our architecture is divided into the following
layers:
1. Dev Layer (Device Layer)
The top-level business logic layer where all operations are
device-centric. Every operation is performed relative to the device
context. The intergration of base functions encompasses:
management(ctrl only for leonis pf0), network(net_dev,this time not
contained),common.
2. Dispatch Layer
The distribution from services to specific data operations is mainly
divided into two types: direct pass-through and handling by the
management PF. It shields the upper layer from the differences in
specific underlying locations.
It describes the processing locations and paths of the services.
3. Resource Layer
Handles tasks dispatched from Dispatch Layer. These tasks fall into two
categories:
3.1 Hardware control
The Resource Layer further invokes the HW Layer when hardware access is
needed, as only the HW Layer has OS-level privileges.
3.2 Software resource management
Operations like packet statistics collection that don't require hardware
access.
4. HW Layer (Hardware Layer)
Serves the Resource Layer by interacting with different hardware
chipsets.Writes to hardware registers to drive the hardware based on
Resource Layer directives.
5. Channel Layer
Handle communication between PF0(has ctrl func) and other PF,and provide
basic interaction channels.
6. Common Layer
Provides fundamental services
Signed-off-by: illusion.wang <illusion.wang@nebula-matrix.com>
---
.../net/ethernet/nebula-matrix/nbl/Makefile | 7 +-
.../nbl/nbl_channel/nbl_channel.c | 82 ++++++++
.../nbl/nbl_channel/nbl_channel.h | 29 +++
.../net/ethernet/nebula-matrix/nbl/nbl_core.h | 43 +++++
.../nebula-matrix/nbl/nbl_core/nbl_dev.c | 56 ++++++
.../nebula-matrix/nbl/nbl_core/nbl_dev.h | 27 +++
.../nebula-matrix/nbl/nbl_core/nbl_dispatch.c | 75 ++++++++
.../nebula-matrix/nbl/nbl_core/nbl_dispatch.h | 25 +++
.../nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.c | 140 ++++++++++++++
.../nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.h | 14 ++
.../nbl_hw_leonis/nbl_resource_leonis.c | 83 ++++++++
.../nbl_hw_leonis/nbl_resource_leonis.h | 10 +
.../nebula-matrix/nbl/nbl_hw/nbl_hw_reg.h | 68 +++++++
.../nebula-matrix/nbl/nbl_hw/nbl_resource.h | 30 +++
.../nbl/nbl_include/nbl_def_channel.h | 26 +++
.../nbl/nbl_include/nbl_def_common.h | 35 ++++
.../nbl/nbl_include/nbl_def_dev.h | 16 ++
.../nbl/nbl_include/nbl_def_dispatch.h | 29 +++
.../nbl/nbl_include/nbl_def_hw.h | 22 +++
.../nbl/nbl_include/nbl_def_resource.h | 20 ++
.../nbl/nbl_include/nbl_include.h | 11 ++
.../nbl/nbl_include/nbl_product_base.h | 18 ++
.../net/ethernet/nebula-matrix/nbl/nbl_main.c | 179 ++++++++++++++++++
23 files changed, 1044 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.c
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.c
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_reg.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_resource.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_common.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dev.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_hw.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_resource.h
create mode 100644 drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_product_base.h
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/Makefile b/drivers/net/ethernet/nebula-matrix/nbl/Makefile
index b90fba239401..271605920396 100644
--- a/drivers/net/ethernet/nebula-matrix/nbl/Makefile
+++ b/drivers/net/ethernet/nebula-matrix/nbl/Makefile
@@ -3,4 +3,9 @@
obj-$(CONFIG_NBL) := nbl.o
-nbl-objs += nbl_main.o
+nbl-objs += nbl_channel/nbl_channel.o \
+ nbl_hw/nbl_hw_leonis/nbl_hw_leonis.o \
+ nbl_hw/nbl_hw_leonis/nbl_resource_leonis.o \
+ nbl_core/nbl_dispatch.o \
+ nbl_core/nbl_dev.o \
+ nbl_main.o
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c
new file mode 100644
index 000000000000..9f4603870cb4
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#include <linux/device.h>
+#include <linux/pci.h>
+#include "nbl_channel.h"
+
+static struct nbl_channel_ops chan_ops = {
+};
+
+static struct nbl_channel_mgt *
+nbl_chan_setup_chan_mgt(struct nbl_adapter *adapter)
+{
+ struct nbl_hw_ops_tbl *hw_ops_tbl = adapter->intf.hw_ops_tbl;
+ struct nbl_common_info *common = &adapter->common;
+ struct device *dev = &adapter->pdev->dev;
+ struct nbl_chan_info *mailbox;
+ struct nbl_channel_mgt *chan_mgt;
+
+ chan_mgt = devm_kzalloc(dev, sizeof(*chan_mgt), GFP_KERNEL);
+ if (!chan_mgt)
+ return ERR_PTR(-ENOMEM);
+
+ chan_mgt->common = common;
+ chan_mgt->hw_ops_tbl = hw_ops_tbl;
+
+ mailbox = devm_kzalloc(dev, sizeof(*mailbox), GFP_KERNEL);
+ if (!mailbox)
+ return ERR_PTR(-ENOMEM);
+ mailbox->chan_type = NBL_CHAN_TYPE_MAILBOX;
+ chan_mgt->chan_info[NBL_CHAN_TYPE_MAILBOX] = mailbox;
+
+ return chan_mgt;
+}
+
+static struct nbl_channel_ops_tbl *
+nbl_chan_setup_ops(struct device *dev, struct nbl_channel_mgt *chan_mgt)
+{
+ struct nbl_channel_ops_tbl *chan_ops_tbl;
+
+ chan_ops_tbl = devm_kzalloc(dev, sizeof(*chan_ops_tbl), GFP_KERNEL);
+ if (!chan_ops_tbl)
+ return ERR_PTR(-ENOMEM);
+
+ chan_ops_tbl->ops = &chan_ops;
+ chan_ops_tbl->priv = chan_mgt;
+
+ return chan_ops_tbl;
+}
+
+int nbl_chan_init_common(struct nbl_adapter *adap)
+{
+ struct nbl_channel_ops_tbl *chan_ops_tbl;
+ struct device *dev = &adap->pdev->dev;
+ struct nbl_channel_mgt *chan_mgt;
+ int ret;
+
+ chan_mgt = nbl_chan_setup_chan_mgt(adap);
+ if (IS_ERR(chan_mgt)) {
+ ret = PTR_ERR(chan_mgt);
+ goto setup_mgt_fail;
+ }
+ adap->core.chan_mgt = chan_mgt;
+
+ chan_ops_tbl = nbl_chan_setup_ops(dev, chan_mgt);
+ if (IS_ERR(chan_ops_tbl)) {
+ ret = PTR_ERR(chan_ops_tbl);
+ goto setup_ops_fail;
+ }
+ adap->intf.channel_ops_tbl = chan_ops_tbl;
+ return 0;
+
+setup_ops_fail:
+setup_mgt_fail:
+ return ret;
+}
+
+void nbl_chan_remove_common(struct nbl_adapter *adap)
+{
+}
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.h
new file mode 100644
index 000000000000..637912d1e806
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_channel/nbl_channel.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_CHANNEL_H_
+#define _NBL_CHANNEL_H_
+
+#include <linux/types.h>
+
+#include "../nbl_include/nbl_include.h"
+#include "../nbl_include/nbl_product_base.h"
+#include "../nbl_include/nbl_def_channel.h"
+#include "../nbl_include/nbl_def_hw.h"
+#include "../nbl_include/nbl_def_common.h"
+#include "../nbl_core.h"
+
+struct nbl_chan_info {
+ u8 chan_type;
+};
+
+struct nbl_channel_mgt {
+ struct nbl_common_info *common;
+ struct nbl_hw_ops_tbl *hw_ops_tbl;
+ struct nbl_chan_info *chan_info[NBL_CHAN_TYPE_MAX];
+ struct nbl_hash_tbl_mgt *handle_hash_tbl;
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h
index c525114297b4..aa4d24d04e2c 100644
--- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core.h
@@ -6,6 +6,20 @@
#ifndef _NBL_CORE_H_
#define _NBL_CORE_H_
+#include <linux/pci.h>
+#include "nbl_include/nbl_def_common.h"
+#include "nbl_include/nbl_include.h"
+
+struct nbl_hw_mgt;
+struct nbl_hw_ops_tbl;
+struct nbl_resource_mgt;
+struct nbl_resource_ops_tbl;
+struct nbl_dispatch_mgt;
+struct nbl_dispatch_ops_tbl;
+struct nbl_channel_ops_tbl;
+struct nbl_channel_mgt;
+struct nbl_dev_mgt;
+
enum {
NBL_CAP_HAS_CTRL_BIT,
NBL_CAP_HAS_NET_BIT,
@@ -13,4 +27,33 @@ enum {
NBL_CAP_IS_LEONIS_BIT,
};
+struct nbl_interface {
+ struct nbl_hw_ops_tbl *hw_ops_tbl;
+ struct nbl_resource_ops_tbl *resource_ops_tbl;
+ struct nbl_dispatch_ops_tbl *dispatch_ops_tbl;
+ struct nbl_channel_ops_tbl *channel_ops_tbl;
+};
+
+struct nbl_core {
+ struct nbl_hw_mgt *hw_mgt;
+ struct nbl_resource_mgt *res_mgt;
+ struct nbl_dispatch_mgt *disp_mgt;
+ struct nbl_dev_mgt *dev_mgt;
+ struct nbl_channel_mgt *chan_mgt;
+};
+
+struct nbl_adapter {
+ struct pci_dev *pdev;
+ struct nbl_core core;
+ struct nbl_interface intf;
+ struct nbl_common_info common;
+ struct nbl_product_base_ops *product_base_ops;
+};
+
+struct nbl_adapter *nbl_core_init(struct pci_dev *pdev,
+ struct nbl_init_param *param);
+void nbl_core_remove(struct nbl_adapter *adapter);
+int nbl_core_start(struct nbl_adapter *adapter);
+void nbl_core_stop(struct nbl_adapter *adapter);
+
#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c
new file mode 100644
index 000000000000..5deb21e35f8e
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+#include <linux/device.h>
+#include <linux/pci.h>
+#include "nbl_dev.h"
+
+static struct nbl_dev_mgt *nbl_dev_setup_dev_mgt(struct nbl_common_info *common)
+{
+ struct nbl_dev_mgt *dev_mgt;
+
+ dev_mgt = devm_kzalloc(common->dev, sizeof(*dev_mgt), GFP_KERNEL);
+ if (!dev_mgt)
+ return ERR_PTR(-ENOMEM);
+
+ dev_mgt->common = common;
+ return dev_mgt;
+}
+
+int nbl_dev_init(struct nbl_adapter *adapter)
+{
+ struct nbl_common_info *common = &adapter->common;
+ struct nbl_dispatch_ops_tbl *disp_ops_tbl =
+ adapter->intf.dispatch_ops_tbl;
+ struct nbl_channel_ops_tbl *chan_ops_tbl =
+ adapter->intf.channel_ops_tbl;
+ struct nbl_dev_mgt *dev_mgt;
+ int ret;
+
+ dev_mgt = nbl_dev_setup_dev_mgt(common);
+ if (IS_ERR(dev_mgt)) {
+ ret = PTR_ERR(dev_mgt);
+ return ret;
+ }
+
+ dev_mgt->disp_ops_tbl = disp_ops_tbl;
+ dev_mgt->chan_ops_tbl = chan_ops_tbl;
+ adapter->core.dev_mgt = dev_mgt;
+
+ return 0;
+}
+
+void nbl_dev_remove(struct nbl_adapter *adapter)
+{
+}
+
+/* ---------- Dev start process ---------- */
+int nbl_dev_start(struct nbl_adapter *adapter)
+{
+ return 0;
+}
+
+void nbl_dev_stop(struct nbl_adapter *adapter)
+{
+}
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.h
new file mode 100644
index 000000000000..9b71092b99a0
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dev.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEV_H_
+#define _NBL_DEV_H_
+
+#include <linux/types.h>
+
+#include "../nbl_include/nbl_include.h"
+#include "../nbl_include/nbl_product_base.h"
+#include "../nbl_include/nbl_def_channel.h"
+#include "../nbl_include/nbl_def_hw.h"
+#include "../nbl_include/nbl_def_resource.h"
+#include "../nbl_include/nbl_def_dispatch.h"
+#include "../nbl_include/nbl_def_dev.h"
+#include "../nbl_include/nbl_def_common.h"
+#include "../nbl_core.h"
+
+struct nbl_dev_mgt {
+ struct nbl_common_info *common;
+ struct nbl_dispatch_ops_tbl *disp_ops_tbl;
+ struct nbl_channel_ops_tbl *chan_ops_tbl;
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c
new file mode 100644
index 000000000000..8b031f6e963f
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+#include <linux/device.h>
+#include <linux/pci.h>
+#include "nbl_dispatch.h"
+
+static struct nbl_dispatch_mgt *
+nbl_disp_setup_disp_mgt(struct nbl_common_info *common)
+{
+ struct nbl_dispatch_mgt *disp_mgt;
+ struct device *dev = common->dev;
+
+ disp_mgt = devm_kzalloc(dev, sizeof(*disp_mgt), GFP_KERNEL);
+ if (!disp_mgt)
+ return ERR_PTR(-ENOMEM);
+
+ disp_mgt->common = common;
+ return disp_mgt;
+}
+
+static struct nbl_dispatch_ops_tbl *
+nbl_disp_setup_ops(struct device *dev, struct nbl_dispatch_mgt *disp_mgt)
+{
+ struct nbl_dispatch_ops_tbl *disp_ops_tbl;
+ struct nbl_dispatch_ops *disp_ops;
+
+ disp_ops_tbl = devm_kzalloc(dev, sizeof(*disp_ops_tbl), GFP_KERNEL);
+ if (!disp_ops_tbl)
+ return ERR_PTR(-ENOMEM);
+
+ disp_ops =
+ devm_kzalloc(dev, sizeof(*disp_ops), GFP_KERNEL);
+ if (!disp_ops)
+ return ERR_PTR(-ENOMEM);
+
+ disp_ops_tbl->ops = disp_ops;
+ disp_ops_tbl->priv = disp_mgt;
+
+ return disp_ops_tbl;
+}
+
+int nbl_disp_init(struct nbl_adapter *adapter)
+{
+ struct nbl_common_info *common = &adapter->common;
+ struct nbl_dispatch_ops_tbl *disp_ops_tbl;
+ struct nbl_resource_ops_tbl *res_ops_tbl =
+ adapter->intf.resource_ops_tbl;
+ struct nbl_channel_ops_tbl *chan_ops_tbl =
+ adapter->intf.channel_ops_tbl;
+ struct device *dev = &adapter->pdev->dev;
+ struct nbl_dispatch_mgt *disp_mgt;
+ int ret;
+
+ disp_mgt = nbl_disp_setup_disp_mgt(common);
+ if (IS_ERR(disp_mgt)) {
+ ret = PTR_ERR(disp_mgt);
+ return ret;
+ }
+
+ disp_ops_tbl = nbl_disp_setup_ops(dev, disp_mgt);
+ if (IS_ERR(disp_ops_tbl)) {
+ ret = PTR_ERR(disp_ops_tbl);
+ return ret;
+ }
+
+ disp_mgt->res_ops_tbl = res_ops_tbl;
+ disp_mgt->chan_ops_tbl = chan_ops_tbl;
+ disp_mgt->disp_ops_tbl = disp_ops_tbl;
+ adapter->core.disp_mgt = disp_mgt;
+ adapter->intf.dispatch_ops_tbl = disp_ops_tbl;
+
+ return 0;
+}
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h
new file mode 100644
index 000000000000..fa7f4597febe
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_core/nbl_dispatch.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DISPATCH_H_
+#define _NBL_DISPATCH_H_
+#include "../nbl_include/nbl_include.h"
+#include "../nbl_include/nbl_product_base.h"
+#include "../nbl_include/nbl_def_channel.h"
+#include "../nbl_include/nbl_def_hw.h"
+#include "../nbl_include/nbl_def_resource.h"
+#include "../nbl_include/nbl_def_dispatch.h"
+#include "../nbl_include/nbl_def_common.h"
+#include "../nbl_core.h"
+
+struct nbl_dispatch_mgt {
+ struct nbl_common_info *common;
+ struct nbl_resource_ops_tbl *res_ops_tbl;
+ struct nbl_channel_ops_tbl *chan_ops_tbl;
+ struct nbl_dispatch_ops_tbl *disp_ops_tbl;
+ DECLARE_BITMAP(ctrl_lvl, NBL_DISP_CTRL_LVL_MAX);
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.c
new file mode 100644
index 000000000000..6dd8d3a087dd
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/bits.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include "nbl_hw_leonis.h"
+
+static struct nbl_hw_ops hw_ops = {
+};
+
+/* Structure starts here, adding an op should not modify anything below */
+static struct nbl_hw_mgt *nbl_hw_setup_hw_mgt(struct nbl_common_info *common)
+{
+ struct device *dev = common->dev;
+ struct nbl_hw_mgt *hw_mgt;
+
+ hw_mgt = devm_kzalloc(dev, sizeof(*hw_mgt), GFP_KERNEL);
+ if (!hw_mgt)
+ return ERR_PTR(-ENOMEM);
+
+ hw_mgt->common = common;
+
+ return hw_mgt;
+}
+
+static struct nbl_hw_ops_tbl *nbl_hw_setup_ops(struct nbl_common_info *common,
+ struct nbl_hw_mgt *hw_mgt)
+{
+ struct nbl_hw_ops_tbl *hw_ops_tbl;
+ struct device *dev;
+
+ dev = common->dev;
+ hw_ops_tbl =
+ devm_kzalloc(dev, sizeof(*hw_ops_tbl), GFP_KERNEL);
+ if (!hw_ops_tbl)
+ return ERR_PTR(-ENOMEM);
+
+ hw_ops_tbl->ops = &hw_ops;
+ hw_ops_tbl->priv = hw_mgt;
+
+ return hw_ops_tbl;
+}
+
+int nbl_hw_init_leonis(struct nbl_adapter *adapter)
+{
+ struct nbl_common_info *common = &adapter->common;
+ struct pci_dev *pdev = common->pdev;
+ struct nbl_hw_ops_tbl *hw_ops_tbl;
+ struct nbl_hw_mgt *hw_mgt;
+ int bar_mask;
+ int ret;
+
+ hw_mgt = nbl_hw_setup_hw_mgt(common);
+ if (IS_ERR(hw_mgt)) {
+ ret = PTR_ERR(hw_mgt);
+ goto setup_mgt_fail;
+ }
+ bar_mask = BIT(NBL_MEMORY_BAR) | BIT(NBL_MAILBOX_BAR);
+ ret = pci_request_selected_regions(pdev, bar_mask, NBL_DRIVER_NAME);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "Request memory bar and mailbox bar failed, err = %d\n",
+ ret);
+ goto request_bar_region_fail;
+ }
+
+ if (common->has_ctrl) {
+ hw_mgt->hw_addr =
+ ioremap(pci_resource_start(pdev, NBL_MEMORY_BAR),
+ pci_resource_len(pdev, NBL_MEMORY_BAR) -
+ NBL_RDMA_NOTIFY_OFF);
+ if (!hw_mgt->hw_addr) {
+ dev_err(&pdev->dev, "Memory bar ioremap failed\n");
+ ret = -EIO;
+ goto ioremap_err;
+ }
+ hw_mgt->hw_size = pci_resource_len(pdev, NBL_MEMORY_BAR) -
+ NBL_RDMA_NOTIFY_OFF;
+ } else {
+ hw_mgt->hw_addr =
+ ioremap(pci_resource_start(pdev, NBL_MEMORY_BAR),
+ NBL_RDMA_NOTIFY_OFF);
+ if (!hw_mgt->hw_addr) {
+ dev_err(&pdev->dev, "Memory bar ioremap failed\n");
+ ret = -EIO;
+ goto ioremap_err;
+ }
+ hw_mgt->hw_size = NBL_RDMA_NOTIFY_OFF;
+ }
+
+ hw_mgt->notify_offset = 0;
+ hw_mgt->mailbox_bar_hw_addr = pci_ioremap_bar(pdev, NBL_MAILBOX_BAR);
+ if (!hw_mgt->mailbox_bar_hw_addr) {
+ dev_err(&pdev->dev, "Mailbox bar ioremap failed\n");
+ ret = -EIO;
+ goto mailbox_ioremap_err;
+ }
+
+ spin_lock_init(&hw_mgt->reg_lock);
+ adapter->core.hw_mgt = hw_mgt;
+
+ hw_ops_tbl = nbl_hw_setup_ops(common, hw_mgt);
+ if (IS_ERR(hw_ops_tbl)) {
+ ret = PTR_ERR(hw_ops_tbl);
+ goto setup_ops_fail;
+ }
+ adapter->intf.hw_ops_tbl = hw_ops_tbl;
+
+ return 0;
+
+setup_ops_fail:
+ iounmap(hw_mgt->mailbox_bar_hw_addr);
+mailbox_ioremap_err:
+ iounmap(hw_mgt->hw_addr);
+ioremap_err:
+ pci_release_selected_regions(pdev, bar_mask);
+request_bar_region_fail:
+setup_mgt_fail:
+ return ret;
+}
+
+void nbl_hw_remove_leonis(struct nbl_adapter *adapter)
+{
+ int bar_mask = BIT(NBL_MEMORY_BAR) | BIT(NBL_MAILBOX_BAR);
+ struct nbl_common_info *common = &adapter->common;
+ struct nbl_hw_mgt *hw_mgt = adapter->core.hw_mgt;
+ u8 __iomem *hw_addr = hw_mgt->hw_addr;
+ struct pci_dev *pdev = common->pdev;
+ u8 __iomem *mailbox_bar_hw_addr;
+
+ mailbox_bar_hw_addr = hw_mgt->mailbox_bar_hw_addr;
+
+ iounmap(mailbox_bar_hw_addr);
+ iounmap(hw_addr);
+ pci_release_selected_regions(pdev, bar_mask);
+}
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.h
new file mode 100644
index 000000000000..77c67b67ba31
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_hw_leonis.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_HW_LEONIS_H_
+#define _NBL_HW_LEONIS_H_
+
+#include <linux/types.h>
+
+#include "../../nbl_include/nbl_include.h"
+#include "../nbl_hw_reg.h"
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.c
new file mode 100644
index 000000000000..355f7ea66b88
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.c
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+#include <linux/device.h>
+#include <linux/pci.h>
+#include "nbl_resource_leonis.h"
+
+static struct nbl_resource_ops res_ops = {
+};
+
+static struct nbl_resource_mgt *
+nbl_res_setup_res_mgt(struct nbl_common_info *common)
+{
+ struct nbl_resource_info *resource_info;
+ struct nbl_resource_mgt *res_mgt;
+ struct device *dev = common->dev;
+
+ res_mgt = devm_kzalloc(dev, sizeof(*res_mgt), GFP_KERNEL);
+ if (!res_mgt)
+ return ERR_PTR(-ENOMEM);
+ res_mgt->common = common;
+
+ resource_info =
+ devm_kzalloc(dev, sizeof(*resource_info), GFP_KERNEL);
+ if (!resource_info)
+ return ERR_PTR(-ENOMEM);
+ res_mgt->resource_info = resource_info;
+
+ return res_mgt;
+}
+
+static struct nbl_resource_ops_tbl *
+nbl_res_setup_ops(struct device *dev, struct nbl_resource_mgt *res_mgt)
+{
+ struct nbl_resource_ops_tbl *res_ops_tbl;
+
+ res_ops_tbl = devm_kzalloc(dev, sizeof(*res_ops_tbl), GFP_KERNEL);
+ if (!res_ops_tbl)
+ return ERR_PTR(-ENOMEM);
+
+ res_ops_tbl->ops = &res_ops;
+ res_ops_tbl->priv = res_mgt;
+
+ return res_ops_tbl;
+}
+
+static int nbl_res_start(struct nbl_resource_mgt *res_mgt)
+{
+ return 0;
+}
+
+int nbl_res_init_leonis(struct nbl_adapter *adap)
+{
+ struct nbl_channel_ops_tbl *chan_ops_tbl = adap->intf.channel_ops_tbl;
+ struct nbl_hw_ops_tbl *hw_ops_tbl = adap->intf.hw_ops_tbl;
+ struct nbl_common_info *common = &adap->common;
+ struct nbl_resource_ops_tbl *res_ops_tbl;
+ struct device *dev = &adap->pdev->dev;
+ struct nbl_resource_mgt *res_mgt;
+ int ret;
+
+ res_mgt = nbl_res_setup_res_mgt(common);
+ if (IS_ERR(res_mgt)) {
+ ret = PTR_ERR(res_mgt);
+ return ret;
+ }
+ res_mgt->chan_ops_tbl = chan_ops_tbl;
+ res_mgt->hw_ops_tbl = hw_ops_tbl;
+
+ ret = nbl_res_start(res_mgt);
+ if (ret)
+ return ret;
+ adap->core.res_mgt = res_mgt;
+
+ res_ops_tbl = nbl_res_setup_ops(dev, res_mgt);
+ if (IS_ERR(res_ops_tbl)) {
+ ret = PTR_ERR(res_ops_tbl);
+ return ret;
+ }
+ adap->intf.resource_ops_tbl = res_ops_tbl;
+ return 0;
+}
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.h
new file mode 100644
index 000000000000..4e61a5c141e5
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_leonis/nbl_resource_leonis.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_RESOURCE_LEONIS_H_
+#define _NBL_RESOURCE_LEONIS_H_
+
+#include "../nbl_resource.h"
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_reg.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_reg.h
new file mode 100644
index 000000000000..46e58b4e73dc
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_hw_reg.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_HW_REG_H_
+#define _NBL_HW_REG_H_
+
+#include <linux/types.h>
+
+#include "../nbl_include/nbl_product_base.h"
+#include "../nbl_include/nbl_def_channel.h"
+#include "../nbl_include/nbl_def_hw.h"
+#include "../nbl_include/nbl_def_common.h"
+#include "../nbl_core.h"
+
+#define NBL_MEMORY_BAR 0
+#define NBL_MAILBOX_BAR 2
+#define NBL_RDMA_NOTIFY_OFF 8192
+#define NBL_HW_DUMMY_REG 0x1300904
+
+struct nbl_hw_mgt {
+ struct nbl_common_info *common;
+ u8 __iomem *hw_addr;
+ u8 __iomem *mailbox_bar_hw_addr;
+ u64 notify_offset;
+ u32 version;
+ u32 hw_size;
+ spinlock_t reg_lock; /* Protect reg access */
+};
+
+static inline u32 rd32(u8 __iomem *addr, u64 reg)
+{
+ return readl(addr + reg);
+}
+
+static inline void wr32(u8 __iomem *addr, u64 reg, u32 value)
+{
+ writel(value, addr + reg);
+}
+
+static inline void nbl_hw_wr32(struct nbl_hw_mgt *hw_mgt, u64 reg, u32 value)
+{
+ /* Used for emu, make sure that we won't write too frequently */
+ wr32(hw_mgt->hw_addr, reg, value);
+}
+
+static inline u32 nbl_hw_rd32(struct nbl_hw_mgt *hw_mgt, u64 reg)
+{
+ return rd32(hw_mgt->hw_addr, reg);
+}
+
+static inline void nbl_mbx_wr32(struct nbl_hw_mgt *hw_mgt, u64 reg, u32 value)
+{
+ writel(value, hw_mgt->mailbox_bar_hw_addr + reg);
+}
+
+static inline void nbl_flush_writes(struct nbl_hw_mgt *hw_mgt)
+{
+ nbl_hw_rd32(hw_mgt, NBL_HW_DUMMY_REG);
+}
+
+static inline u32 nbl_mbx_rd32(struct nbl_hw_mgt *hw_mgt, u64 reg)
+{
+ return readl(hw_mgt->mailbox_bar_hw_addr + reg);
+}
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_resource.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_resource.h
new file mode 100644
index 000000000000..e08b6237da32
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_hw/nbl_resource.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_RESOURCE_H_
+#define _NBL_RESOURCE_H_
+
+#include <linux/types.h>
+
+#include "../nbl_include/nbl_include.h"
+#include "../nbl_include/nbl_product_base.h"
+#include "../nbl_include/nbl_def_channel.h"
+#include "../nbl_include/nbl_def_hw.h"
+#include "../nbl_include/nbl_def_resource.h"
+#include "../nbl_include/nbl_def_common.h"
+#include "../nbl_core.h"
+
+struct nbl_resource_info {
+};
+
+struct nbl_resource_mgt {
+ struct nbl_common_info *common;
+ struct nbl_resource_info *resource_info;
+ struct nbl_channel_ops_tbl *chan_ops_tbl;
+ struct nbl_hw_ops_tbl *hw_ops_tbl;
+ struct nbl_interrupt_mgt *intr_mgt;
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h
new file mode 100644
index 000000000000..ff03a53b9f5d
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_channel.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_CHANNEL_H_
+#define _NBL_DEF_CHANNEL_H_
+
+struct nbl_channel_mgt;
+struct nbl_adapter;
+enum nbl_channel_type {
+ NBL_CHAN_TYPE_MAILBOX,
+ NBL_CHAN_TYPE_MAX
+};
+
+struct nbl_channel_ops {
+};
+
+struct nbl_channel_ops_tbl {
+ struct nbl_channel_ops *ops;
+ struct nbl_channel_mgt *priv;
+};
+
+int nbl_chan_init_common(struct nbl_adapter *adapter);
+void nbl_chan_remove_common(struct nbl_adapter *adapter);
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_common.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_common.h
new file mode 100644
index 000000000000..cc73d6a91f3c
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_common.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_COMMON_H_
+#define _NBL_DEF_COMMON_H_
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/device.h>
+#include "nbl_include.h"
+
+struct nbl_common_info {
+ struct pci_dev *pdev;
+ struct device *dev;
+ u32 msg_enable;
+ u16 vsi_id;
+ u8 eth_id;
+ u8 logic_eth_id;
+ u8 eth_mode;
+
+ u8 function;
+ u8 devid;
+ u8 bus;
+ u8 hw_bus;
+ u16 mgt_pf;
+
+ bool pci_using_dac;
+ enum nbl_product_type product_type;
+ u8 has_ctrl;
+ u8 has_net;
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dev.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dev.h
new file mode 100644
index 000000000000..32e6cce38d39
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dev.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_DEV_H_
+#define _NBL_DEF_DEV_H_
+
+struct nbl_adapter;
+
+int nbl_dev_init(struct nbl_adapter *adapter);
+void nbl_dev_remove(struct nbl_adapter *adapter);
+int nbl_dev_start(struct nbl_adapter *adapter);
+void nbl_dev_stop(struct nbl_adapter *adapter);
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h
new file mode 100644
index 000000000000..2230c728079e
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_dispatch.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_DISPATCH_H_
+#define _NBL_DEF_DISPATCH_H_
+
+struct nbl_dispatch_mgt;
+struct nbl_adapter;
+enum {
+ NBL_DISP_CTRL_LVL_NEVER = 0,
+ NBL_DISP_CTRL_LVL_MGT,
+ NBL_DISP_CTRL_LVL_NET,
+ NBL_DISP_CTRL_LVL_ALWAYS,
+ NBL_DISP_CTRL_LVL_MAX,
+};
+
+struct nbl_dispatch_ops {
+};
+
+struct nbl_dispatch_ops_tbl {
+ struct nbl_dispatch_ops *ops;
+ struct nbl_dispatch_mgt *priv;
+};
+
+int nbl_disp_init(struct nbl_adapter *adapter);
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_hw.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_hw.h
new file mode 100644
index 000000000000..168504b30973
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_hw.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_HW_H_
+#define _NBL_DEF_HW_H_
+
+struct nbl_hw_mgt;
+struct nbl_adapter;
+struct nbl_hw_ops {
+};
+
+struct nbl_hw_ops_tbl {
+ struct nbl_hw_ops *ops;
+ struct nbl_hw_mgt *priv;
+};
+
+int nbl_hw_init_leonis(struct nbl_adapter *adapter);
+void nbl_hw_remove_leonis(struct nbl_adapter *adapter);
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_resource.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_resource.h
new file mode 100644
index 000000000000..16add7e25eae
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_def_resource.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_RESOURCE_H_
+#define _NBL_DEF_RESOURCE_H_
+
+struct nbl_resource_mgt;
+struct nbl_adapter;
+struct nbl_resource_ops {
+};
+
+struct nbl_resource_ops_tbl {
+ struct nbl_resource_ops *ops;
+ struct nbl_resource_mgt *priv;
+};
+
+int nbl_res_init_leonis(struct nbl_adapter *adapter);
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h
index 1046e6517b15..50f30f756bf3 100644
--- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_include.h
@@ -11,6 +11,11 @@
/* ------ Basic definitions ------- */
#define NBL_DRIVER_NAME "nbl"
+enum nbl_product_type {
+ NBL_LEONIS_TYPE,
+ NBL_PRODUCT_MAX,
+};
+
struct nbl_func_caps {
u32 has_ctrl:1;
u32 has_net:1;
@@ -18,4 +23,10 @@ struct nbl_func_caps {
u32 rsv:29;
};
+struct nbl_init_param {
+ struct nbl_func_caps caps;
+ enum nbl_product_type product_type;
+ bool pci_using_dac;
+};
+
#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_product_base.h b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_product_base.h
new file mode 100644
index 000000000000..4368d4f57a03
--- /dev/null
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_include/nbl_product_base.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2025 Nebula Matrix Limited.
+ */
+
+#ifndef _NBL_DEF_PRODUCT_BASE_H_
+#define _NBL_DEF_PRODUCT_BASE_H_
+
+struct nbl_adapter;
+struct nbl_product_base_ops {
+ int (*hw_init)(struct nbl_adapter *p);
+ void (*hw_remove)(struct nbl_adapter *p);
+ int (*res_init)(struct nbl_adapter *p);
+ int (*chan_init)(struct nbl_adapter *p);
+ void (*chan_remove)(struct nbl_adapter *p);
+};
+
+#endif
diff --git a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
index 10c3536b327b..db035136e09c 100644
--- a/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
+++ b/drivers/net/ethernet/nebula-matrix/nbl/nbl_main.c
@@ -6,17 +6,196 @@
#include <linux/device.h>
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/bits.h>
#include "nbl_include/nbl_include.h"
+#include "nbl_include/nbl_product_base.h"
+#include "nbl_include/nbl_def_channel.h"
+#include "nbl_include/nbl_def_hw.h"
+#include "nbl_include/nbl_def_resource.h"
+#include "nbl_include/nbl_def_dispatch.h"
+#include "nbl_include/nbl_def_dev.h"
+#include "nbl_include/nbl_def_common.h"
#include "nbl_core.h"
+static struct nbl_product_base_ops nbl_product_base_ops[NBL_PRODUCT_MAX] = {
+ {
+ .hw_init = nbl_hw_init_leonis,
+ .hw_remove = nbl_hw_remove_leonis,
+ .res_init = nbl_res_init_leonis,
+ .chan_init = nbl_chan_init_common,
+ .chan_remove = nbl_chan_remove_common,
+ },
+};
+
+int nbl_core_start(struct nbl_adapter *adapter)
+{
+ return nbl_dev_start(adapter);
+}
+
+void nbl_core_stop(struct nbl_adapter *adapter)
+{
+ nbl_dev_stop(adapter);
+}
+
+static struct nbl_product_base_ops *
+nbl_core_setup_product_ops(struct nbl_adapter *adapter,
+ struct nbl_init_param *param)
+{
+ adapter->product_base_ops = &nbl_product_base_ops[param->product_type];
+ return adapter->product_base_ops;
+}
+
+struct nbl_adapter *nbl_core_init(struct pci_dev *pdev,
+ struct nbl_init_param *param)
+{
+ struct nbl_product_base_ops *product_base_ops;
+ struct nbl_common_info *common;
+ struct nbl_adapter *adapter;
+ int ret;
+
+ adapter = devm_kzalloc(&pdev->dev, sizeof(*adapter), GFP_KERNEL);
+ if (!adapter)
+ return NULL;
+
+ adapter->pdev = pdev;
+ common = &adapter->common;
+
+ common->pdev = pdev;
+ common->dev = &pdev->dev;
+ common->has_ctrl = param->caps.has_ctrl;
+ common->has_net = param->caps.has_net;
+ common->pci_using_dac = param->pci_using_dac;
+ common->function = PCI_FUNC(pdev->devfn);
+ common->devid = PCI_SLOT(pdev->devfn);
+ common->bus = pdev->bus->number;
+ common->product_type = param->product_type;
+
+ product_base_ops = nbl_core_setup_product_ops(adapter, param);
+
+ /*
+ *every product's hw/chan/res layer has a great difference,
+ *so call their own init ops
+ */
+ ret = product_base_ops->hw_init(adapter);
+ if (ret)
+ goto hw_init_fail;
+
+ ret = product_base_ops->chan_init(adapter);
+ if (ret)
+ goto chan_init_fail;
+
+ ret = product_base_ops->res_init(adapter);
+ if (ret)
+ goto res_init_fail;
+
+ ret = nbl_disp_init(adapter);
+ if (ret)
+ goto res_init_fail;
+
+ ret = nbl_dev_init(adapter);
+ if (ret)
+ goto res_init_fail;
+ return adapter;
+
+res_init_fail:
+ product_base_ops->chan_remove(adapter);
+chan_init_fail:
+ product_base_ops->hw_remove(adapter);
+hw_init_fail:
+ return NULL;
+}
+
+void nbl_core_remove(struct nbl_adapter *adapter)
+{
+ struct nbl_product_base_ops *product_base_ops;
+
+ product_base_ops = adapter->product_base_ops;
+ nbl_dev_remove(adapter);
+ product_base_ops->chan_remove(adapter);
+ product_base_ops->hw_remove(adapter);
+}
+
+static void nbl_get_func_param(struct pci_dev *pdev, kernel_ulong_t driver_data,
+ struct nbl_init_param *param)
+{
+ param->caps.has_ctrl = !!(driver_data & BIT(NBL_CAP_HAS_CTRL_BIT));
+ param->caps.has_net = !!(driver_data & BIT(NBL_CAP_HAS_NET_BIT));
+ param->caps.is_nic = !!(driver_data & BIT(NBL_CAP_IS_NIC_BIT));
+
+ if (!!(driver_data & BIT(NBL_CAP_IS_LEONIS_BIT)))
+ param->product_type = NBL_LEONIS_TYPE;
+
+ /*
+ * Leonis only PF0 has ctrl capability, but PF0's pcie device_id
+ * is same with other PF.So handle it special.
+ */
+ if (param->product_type == NBL_LEONIS_TYPE &&
+ (PCI_FUNC(pdev->devfn) == 0))
+ param->caps.has_ctrl = 1;
+}
+
static int nbl_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
+ struct nbl_init_param param = { { 0 } };
+ struct device *dev = &pdev->dev;
+ struct nbl_adapter *adapter;
+ int err;
+
+ if (pci_enable_device(pdev)) {
+ dev_err(&pdev->dev, "Failed to enable PCI device\n");
+ return -ENODEV;
+ }
+
+ param.pci_using_dac = true;
+ nbl_get_func_param(pdev, id->driver_data, ¶m);
+
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
+ if (err) {
+ dev_dbg(dev, "Configure DMA 64 bit mask failed, err = %d\n",
+ err);
+ param.pci_using_dac = false;
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+ if (err) {
+ dev_err(dev,
+ "Configure DMA 32 bit mask failed, err = %d\n",
+ err);
+ goto configure_dma_err;
+ }
+ }
+ pci_set_master(pdev);
+ pci_save_state(pdev);
+ adapter = nbl_core_init(pdev, ¶m);
+ if (!adapter) {
+ dev_err(dev, "Nbl adapter init fail\n");
+ err = -ENOMEM;
+ goto adapter_init_err;
+ }
+ pci_set_drvdata(pdev, adapter);
+ err = nbl_core_start(adapter);
+ if (err)
+ goto core_start_err;
return 0;
+core_start_err:
+ nbl_core_remove(adapter);
+adapter_init_err:
+ pci_clear_master(pdev);
+configure_dma_err:
+ pci_disable_device(pdev);
+ return err;
}
static void nbl_remove(struct pci_dev *pdev)
{
+ struct nbl_adapter *adapter = pci_get_drvdata(pdev);
+
+ pci_disable_sriov(pdev);
+
+ nbl_core_stop(adapter);
+ nbl_core_remove(adapter);
+
+ pci_clear_master(pdev);
+ pci_disable_device(pdev);
}
/*
--
2.47.3
^ permalink raw reply related
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