From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A7668367B90 for ; Tue, 2 Jun 2026 21:23:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780435391; cv=none; b=atO5+//8DySDtOJOl/1QkJZwqN1/5QpTbvg3r1Ptr1VMUQAxQo+A2bycqmc/RCBrM4eJv7ot35FODzcZnKDBD+RNFjCyoa/z5B/59WVoEl2vPDugy7M7po9heACjE3Nv3DCIh1XYnIlyORmIgFF6Q5rMVD+rglzsvwE9Wzsfd5k= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780435391; c=relaxed/simple; bh=z5Aqy8y8/gAablVII3KpXjyzawsafBBcYtKVS7GNpDk=; h=Message-ID:Date:MIME-Version:From:Subject:To:Cc:References: In-Reply-To:Content-Type; b=c8RNW/Ab82eQIwsQm1oDl2DCtD5kz9ctPY6zGbL9TNhECgCpoddbCJq/hKBh77dJLgrcZ2Bz2jpadzKSqYFQnCO9k3V3x8qraOiTYDUaGsc8LasKWJk/tCYrH0nGKQxp25nLEKXzESrElxiaHzLPDypZohgq4PFHtzJigZEs05A= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=WrZk/VIg; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WrZk/VIg" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-490b1bbcf3aso11333495e9.1 for ; Tue, 02 Jun 2026 14:23:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780435387; x=1781040187; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=F3dRFdE5udSr8rlKm+jlouII2mlA29PWptN2wl7njtk=; b=WrZk/VIgrLDz789wo4+Lzez4x7sqrEa8ITExAs+/o2b/g0je9wVPlf4f03cOVqdlts OANue8BqVRPZq3ZSdYT3+y6PgogbigdetfQGeU4uzHhXV1PJbl7t+Coy7oRGoNnG2RFP hmQUGkaENocWWm9qPLgcgZ2MyWCI9WaudSox4Ix/367Sk5DdoS5dqkDVw+Ll/YtYFPgr hVqDBBpZBxHW6Y2MgNSvWLbQIdo+MMkL6oPCR2UBoOijM3nNKfNBSGLso7bM6gaGbfB/ h0h/rV6O6IzOqDvEz8nlCNBmEiWUTwkivBp1rvIUK5OZV+2l2RgDrJfzFbi/Z6TIIxLL hPTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780435387; x=1781040187; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:subject:from:user-agent:mime-version:date:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=F3dRFdE5udSr8rlKm+jlouII2mlA29PWptN2wl7njtk=; b=H4OAy5XLAlmSj86wRbmKGFmEyb/IKRrSQVbQ8QvD6eCsB2zWRPbQoxLhd0yBSK24I+ hLWHCCX0tbRrszkqa2ducxqUiydpGvEwNm0IzijH/3ZlFTnY25/1MjyHm3qDU/3os8Lp qSBeKR2FUfXf3yRiBKm/GZOw1PfGG39UWtiIaAEjDJ5snyI2JyMfPJpfEdzt2xHApXgB jcE3hy4S8Lz7TtEeimabZZoA97isAcj3nt5ioSxuREi4qB9uVsFSYcES1xQL6zOJ5WUB +bJYX54OsdvcbQgXmdnWmFWv91/J1WlhjRMDZv0dYb+NPHZK2MKc8S+sqaBklwodGFqZ 7Vuw== X-Forwarded-Encrypted: i=1; AFNElJ+un+KE59E3mr3gyyPksO1LEaTLj1nAzzn1oOQy3gHhv7yGLkpxBeBeg1dC9hTnCJr3k1jxPGqjtsyC0zY=@vger.kernel.org X-Gm-Message-State: AOJu0Yx1jN7TxoDjnAWx0l2chDCceymMZkoHfz68YtK0RLSmefiDZjKy Lu+7sKzWoNyvwNscQN+lR7T2VDEBaqLHLOGZ4XetkFogSzyMvu2OvaCQ X-Gm-Gg: Acq92OEw0RnnXRg2nwof4MBdZ1pdNzM+bX5GBR9dT01w4A3N3sCFc9qi0DZq6kGbka0 IteFSL7S3Dxc4kM0XGb+Vdm5/0ZTC3Vt0OUuwIemOX/Gl7cLpcWoawd+3Rg4sJT4pccMJwYlJJw n/MUxu0ixDPhAePWLMld4HOsz1UmP4W5YyFALnHTx/p6AZBqIrwymBbLO2ZYqIvZy5YIREBrcql S5wpkCHBoKkF2XfE16teQUqXTVy0o4n49sKG6EkscpNwz9vRn6oU5GhIsW+QFzJPXfT+gsYMZDz Sd1NI3U7rOTnJL38DQvAwtGqGVJRYx+hDrJo5L4cXUayYZj0i7hHGJ46CktM6fbeeC/m9G+vdsF bF+XekKuTEW4peoQL3VYmZk1cPkpCcuX6SOfe0qcL5XWvBR8veuhoYnnoOW9yaCfJ5iSwNbXuE1 5DoVBRp/wygFFVMPSaVUpLbtHscD/4dLnYUoAQuviB0/QwswI9zUqT+ZJw4RZgvf3862cA2oEYJ k0/yNBouzK0Tv7KgBikfNPkuGRrmgIhSShTah67wOhBF5az5Apd0n5HIpWNBoUASgIDRYf4BhGR X-Received: by 2002:a05:600c:5288:b0:490:5191:6e26 with SMTP id 5b1f17b1804b1-490b5ecbd41mr8540765e9.18.1780435386797; Tue, 02 Jun 2026 14:23:06 -0700 (PDT) Received: from ?IPV6:2003:ea:8f35:a100:65ef:a45f:1f40:5f43? (p200300ea8f35a10065efa45f1f405f43.dip0.t-ipconnect.de. [2003:ea:8f35:a100:65ef:a45f:1f40:5f43]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-490b444f4fesm36906265e9.12.2026.06.02.14.23.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 02 Jun 2026 14:23:06 -0700 (PDT) Message-ID: Date: Tue, 2 Jun 2026 23:23:05 +0200 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Heiner Kallweit Subject: Re: [Patch net-next v6 3/7] r8169: add support for new interrupt mapping To: javen , nic_swsd@realtek.com, andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, horms@kernel.org Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org References: <20260526081117.173-1-javen_xu@realsil.com.cn> <20260526081117.173-4-javen_xu@realsil.com.cn> Content-Language: en-US In-Reply-To: <20260526081117.173-4-javen_xu@realsil.com.cn> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 26.05.2026 10:11, javen wrote: > From: Javen Xu > > To support RSS, the number of hardware interrupt bits should match the > interrupt of software. So we add support for new interrupt mapping here. > ISR_VER_MAP_REG is the hardware register to indicate interrupt status. > IMR_SET_VEC_MAP_REG is interrupt mask which is set to enable irq. > > Signed-off-by: Javen Xu > --- > Changes in v2: > - no changes > > Changes in v3: > - init index in napi_struct and get message_id from index > - move rtl8169_disable_hw_interrupt_msix directly before the call to > napi_schedule() > - change the condition in rtl8169_request_irq when RTL_VEC_MAP_ENABLE > enabled, use rtl8169_interrupt_msix > > Changes in v4: > - remove flag tp->feature, replace tp->features & RTL_VEC_MAP_ENABLE > with tp->irq_nvecs > 1, they are equivalent. > - follow reverse xmas tree, in rtl8169_interrupt_msix(), > rtl8169_poll_msix_rx(), rtl8169_poll_msix_tx(), > rtl8169_poll_msix_other() > - use napi->index in rtl8169_poll_msix_other() > - add a comment to describe RTL8127 MSI-X vector layout > - simplify r8169_init_napi() > > Changes in v5: > - replace magic number in rtl8169_poll_msix_tx() > > Changes in v6: > - when irq_nvecs <= 1, use register IntrMask_8125, else using vec map > - fix irq sequence in rtl8169_interrupt_msix(), disable interrupts > before clean it > - remove dead code in rtl8169_poll_msix_tx() > --- > drivers/net/ethernet/realtek/r8169_main.c | 166 +++++++++++++++++++--- > 1 file changed, 150 insertions(+), 16 deletions(-) > > diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c > index 62bf77aa1ec8..951d2046a81b 100644 > --- a/drivers/net/ethernet/realtek/r8169_main.c > +++ b/drivers/net/ethernet/realtek/r8169_main.c > @@ -79,6 +79,7 @@ > #define R8169_TX_START_THRS (2 * R8169_TX_STOP_THRS) > #define R8169_MAX_RX_QUEUES 8 > #define R8127_MAX_RX_QUEUES 8 > +#define R8127_MAX_TX_QUEUES 8 > #define R8169_DEFAULT_RX_QUEUES 1 > #define R8169_MAX_TX_QUEUES 1 > > @@ -449,8 +450,12 @@ enum rtl8125_registers { > RSS_CTRL_8125 = 0x4500, > Q_NUM_CTRL_8125 = 0x4800, > EEE_TXIDLE_TIMER_8125 = 0x6048, > + IMR_CLEAR_VEC_MAP_REG = 0x0d00, > + ISR_VEC_MAP_REG = 0x0d04, > + IMR_SET_VEC_MAP_REG = 0x0d0c, > }; > > +#define MSIX_ID_VEC_MAP_LINKCHG 29 > #define LEDSEL_MASK_8125 0x23f > > #define RX_VLAN_INNER_8125 BIT(22) > @@ -581,6 +586,9 @@ enum rtl_register_content { > > /* magic enable v2 */ > MagicPacket_v2 = (1 << 16), /* Wake up when receives a Magic Packet */ > +#define ISRIMR_LINKCHG BIT(29) > +#define ISRIMR_TOK_Q0 BIT(8) > +#define ISRIMR_ROK_Q0 BIT(0) > }; > > enum rtl_desc_bit { > @@ -1664,26 +1672,38 @@ static u32 rtl_get_events(struct rtl8169_private *tp) > > static void rtl_ack_events(struct rtl8169_private *tp, u32 bits) > { > - if (rtl_is_8125(tp)) > - RTL_W32(tp, IntrStatus_8125, bits); > - else > + if (rtl_is_8125(tp)) { > + if (tp->irq_nvecs > 1) > + RTL_W32(tp, ISR_VEC_MAP_REG, bits); > + else > + RTL_W32(tp, IntrStatus_8125, bits); > + } else { > RTL_W16(tp, IntrStatus, bits); > + } > } > > static void rtl_irq_disable(struct rtl8169_private *tp) > { > - if (rtl_is_8125(tp)) > - RTL_W32(tp, IntrMask_8125, 0); > - else > + if (rtl_is_8125(tp)) { > + if (tp->irq_nvecs > 1) > + RTL_W32(tp, IMR_CLEAR_VEC_MAP_REG, 0xffffffff); > + else > + RTL_W32(tp, IntrMask_8125, 0); > + } else { > RTL_W16(tp, IntrMask, 0); > + } > } > > static void rtl_irq_enable(struct rtl8169_private *tp) > { > - if (rtl_is_8125(tp)) > - RTL_W32(tp, IntrMask_8125, tp->irq_mask); > - else > + if (rtl_is_8125(tp)) { > + if (tp->irq_nvecs > 1) > + RTL_W32(tp, IMR_SET_VEC_MAP_REG, tp->irq_mask); > + else > + RTL_W32(tp, IntrMask_8125, tp->irq_mask); > + } else { > RTL_W16(tp, IntrMask, tp->irq_mask); > + } > } > > static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) > @@ -5062,6 +5082,45 @@ static void rtl8169_free_irq(struct rtl8169_private *tp) > } > } > > +static void rtl8169_disable_hw_interrupt_msix(struct rtl8169_private *tp, int message_id) > +{ > + RTL_W32(tp, IMR_CLEAR_VEC_MAP_REG, BIT(message_id)); > +} > + > +static void rtl8169_clear_hw_isr(struct rtl8169_private *tp, int message_id) > +{ > + RTL_W32(tp, ISR_VEC_MAP_REG, BIT(message_id)); > +} > + > +static void rtl8169_enable_hw_interrupt_msix(struct rtl8169_private *tp, int message_id) > +{ > + RTL_W32(tp, IMR_SET_VEC_MAP_REG, BIT(message_id)); > +} > + > +static irqreturn_t rtl8169_interrupt_msix(int irq, void *dev_instance) > +{ > + struct napi_struct *napi = dev_instance; > + struct net_device *dev = napi->dev; > + int message_id = napi->index; > + struct rtl8169_private *tp; > + > + tp = netdev_priv(dev); > + > + if (message_id == MSIX_ID_VEC_MAP_LINKCHG) { > + rtl8169_clear_hw_isr(tp, message_id); > + phy_mac_interrupt(tp->phydev); > + return IRQ_HANDLED; > + } > + > + rtl8169_disable_hw_interrupt_msix(tp, message_id); > + rtl8169_clear_hw_isr(tp, message_id); > + > + tp->recheck_desc_ownbit = true; > + napi_schedule(napi); > + > + return IRQ_HANDLED; > +} > + > static int rtl8169_request_irq(struct rtl8169_private *tp) > { > struct net_device *dev = tp->dev; > @@ -5070,8 +5129,12 @@ static int rtl8169_request_irq(struct rtl8169_private *tp) > > for (i = 0; i < tp->irq_nvecs; i++) { > napi = &tp->rtl8169_napi[i]; > - rc = pci_request_irq(tp->pci_dev, i, rtl8169_interrupt, > - NULL, napi, "%s-%d", dev->name, i); > + if (tp->irq_nvecs > 1) > + rc = pci_request_irq(tp->pci_dev, i, rtl8169_interrupt_msix, > + NULL, napi, "%s-%d", dev->name, i); > + else > + rc = pci_request_irq(tp->pci_dev, i, rtl8169_interrupt, > + NULL, napi, "%s-%d", dev->name, i); > if (rc) > goto free_irq; > } > @@ -5517,10 +5580,16 @@ static const struct net_device_ops rtl_netdev_ops = { > > static void rtl_set_irq_mask(struct rtl8169_private *tp) > { > - tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; > + if (tp->irq_nvecs > 1) { > + tp->irq_mask = ISRIMR_LINKCHG | ISRIMR_TOK_Q0; > + for (int i = 0; i < tp->num_rx_rings; i++) > + tp->irq_mask |= ISRIMR_ROK_Q0 << i; > + } else { > + tp->irq_mask = RxOK | RxErr | TxOK | TxErr | LinkChg; > > - if (tp->mac_version <= RTL_GIGA_MAC_VER_06) > - tp->irq_mask |= SYSErr | RxFIFOOver; > + if (tp->mac_version <= RTL_GIGA_MAC_VER_06) > + tp->irq_mask |= SYSErr | RxFIFOOver; > + } > } > > static int rtl_alloc_irq(struct rtl8169_private *tp) > @@ -5825,10 +5894,75 @@ static void r8169_del_napi_action(void *data) > netif_napi_del(&tp->rtl8169_napi[i]); > } > > +static int rtl8169_poll_msix_rx(struct napi_struct *napi, int budget) > +{ > + struct net_device *dev = napi->dev; > + const int message_id = napi->index; > + struct rtl8169_private *tp; > + int work_done = 0; > + > + tp = netdev_priv(dev); > + > + if (message_id < tp->num_rx_rings) > + work_done += rtl_rx(dev, tp, &tp->rx_ring[message_id], budget); > + > + if (work_done < budget && napi_complete_done(napi, work_done)) > + rtl8169_enable_hw_interrupt_msix(tp, message_id); > + > + return work_done; > +} > + > +static int rtl8169_poll_msix_tx(struct napi_struct *napi, int budget) > +{ > + struct net_device *dev = napi->dev; > + const int message_id = napi->index; > + struct rtl8169_private *tp; > + > + tp = netdev_priv(dev); > + > + rtl_tx(dev, tp, budget); > + > + if (napi_complete_done(napi, 0)) > + rtl8169_enable_hw_interrupt_msix(tp, message_id); > + > + return 0; > +} > + > +static int rtl8169_poll_msix_other(struct napi_struct *napi, int budget) > +{ > + struct net_device *dev = napi->dev; > + const int message_id = napi->index; This variable is used only once, I don't really see a benefit. > + struct rtl8169_private *tp; > + > + tp = netdev_priv(dev); > + > + if (napi_complete_done(napi, 0)) > + rtl8169_enable_hw_interrupt_msix(tp, message_id); > + > + return 0; > +} > + > +/* RTL8127 MSI-X vector layout: > + * Vectors 0 .. (RxQs - 1) : Rx Queues > + * Vectors RxQs .. (RxQs + TxQs - 1) : Tx Queues > + * Vector (RxQs + TxQs) and up : Other events (Link status(29), etc.) > + */ > static void r8169_init_napi(struct rtl8169_private *tp) > { > - for (int i = 0; i < tp->irq_nvecs; i++) > - netif_napi_add(tp->dev, &tp->rtl8169_napi[i], rtl8169_poll); > + for (int i = 0; i < tp->irq_nvecs; i++) { > + int (*poll_fn)(struct napi_struct *, int) = rtl8169_poll; > + > + if (tp->irq_nvecs > 1) { > + if (i < R8127_MAX_RX_QUEUES) > + poll_fn = rtl8169_poll_msix_rx; > + else if (i < R8127_MAX_RX_QUEUES + R8127_MAX_TX_QUEUES) > + poll_fn = rtl8169_poll_msix_tx; > + else > + poll_fn = rtl8169_poll_msix_other; > + } > + netif_napi_add(tp->dev, &tp->rtl8169_napi[i], poll_fn); > + tp->rtl8169_napi[i].index = i; > + } > devm_add_action_or_reset(&tp->pci_dev->dev, r8169_del_napi_action, tp); > } >