From nobody Sat Oct 4 22:20:25 2025 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4E9C026CE3F; Tue, 12 Aug 2025 12:33:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755002035; cv=none; b=jhQ8sxRwyeuh1WU3W9XN7bpriG68jgVrTeyKRT8fgmHCNEe0MbcDPEQd6YtHVtzrdS47x2MIWsdzdgwIPkAYSMknAIBUkPmtyemS2UIlCOGZAQnuJMTuOPE0XZI+CkZAY4rE1qWYQ3jiH8yi2XEvZsSt+siOQFtvKul1SFE+8aE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755002035; c=relaxed/simple; bh=hNULJ87ZxtX6Iu4BqQ00wfoBZmqcZio6prsPuynj+08=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nqS/ixvfLfyi+fpDgyTIbGFLxU/9bI/P4eJFG5lVjN3ZaSSu9Jkr+IG1tewHoJNtsnDbMtUR0JxkoHfBtGqgOhHlq7I7BpOrQ/l5LCOZsZzYxeZUDQ7HD2Xdvpuk3+tWutKRQqb1QHM7RpE/O/BQWFuC+45lkrdMg/fmgo2S5j0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.48]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4c1W5H3xtDz14M79; Tue, 12 Aug 2025 20:28:51 +0800 (CST) Received: from kwepemf100013.china.huawei.com (unknown [7.202.181.12]) by mail.maildlp.com (Postfix) with ESMTPS id 857AB18007F; Tue, 12 Aug 2025 20:33:50 +0800 (CST) Received: from DESKTOP-F6Q6J7K.china.huawei.com (10.174.175.220) by kwepemf100013.china.huawei.com (7.202.181.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Tue, 12 Aug 2025 20:33:49 +0800 From: Fan Gong To: Fan Gong , Zhu Yikai CC: , , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Andrew Lunn , , Jonathan Corbet , Bjorn Helgaas , luosifu , Xin Guo , Shen Chenyang , Zhou Shuai , Wu Like , Shi Jing , Fu Guiming , Meny Yossefi , Gur Stavi , Lee Trager , Michael Ellerman , Vadim Fedorenko , Suman Ghosh , Przemek Kitszel , Joe Damato , Christophe JAILLET Subject: [PATCH net-next v12 8/8] hinic3: Interrupt request configuration Date: Tue, 12 Aug 2025 20:33:26 +0800 Message-ID: X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200001.china.huawei.com (7.221.188.67) To kwepemf100013.china.huawei.com (7.202.181.12) Content-Type: text/plain; charset="utf-8" Configure interrupt request initialization. It allows driver to receive packets and management information from HW. Co-developed-by: Xin Guo Signed-off-by: Xin Guo Co-developed-by: Zhu Yikai Signed-off-by: Zhu Yikai Signed-off-by: Fan Gong --- .../ethernet/huawei/hinic3/hinic3_hw_comm.c | 31 ++++ .../ethernet/huawei/hinic3/hinic3_hw_comm.h | 13 ++ .../net/ethernet/huawei/hinic3/hinic3_irq.c | 136 +++++++++++++++++- .../ethernet/huawei/hinic3/hinic3_nic_dev.h | 4 - 4 files changed, 178 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c b/drivers/= net/ethernet/huawei/hinic3/hinic3_hw_comm.c index 434696ce7dc2..7adcdd569c7b 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.c @@ -8,6 +8,37 @@ #include "hinic3_hwif.h" #include "hinic3_mbox.h" =20 +int hinic3_set_interrupt_cfg_direct(struct hinic3_hwdev *hwdev, + const struct hinic3_interrupt_info *info) +{ + struct comm_cmd_cfg_msix_ctrl_reg msix_cfg =3D {}; + struct mgmt_msg_params msg_params =3D {}; + int err; + + msix_cfg.func_id =3D hinic3_global_func_id(hwdev); + msix_cfg.msix_index =3D info->msix_index; + msix_cfg.opcode =3D MGMT_MSG_CMD_OP_SET; + + msix_cfg.lli_credit_cnt =3D info->lli_credit_limit; + msix_cfg.lli_timer_cnt =3D info->lli_timer_cfg; + msix_cfg.pending_cnt =3D info->pending_limit; + msix_cfg.coalesce_timer_cnt =3D info->coalesc_timer_cfg; + msix_cfg.resend_timer_cnt =3D info->resend_timer_cfg; + + mgmt_msg_params_init_default(&msg_params, &msix_cfg, sizeof(msix_cfg)); + + err =3D hinic3_send_mbox_to_mgmt(hwdev, MGMT_MOD_COMM, + COMM_CMD_CFG_MSIX_CTRL_REG, &msg_params); + if (err || msix_cfg.head.status) { + dev_err(hwdev->dev, + "Failed to set interrupt config, err: %d, status: 0x%x\n", + err, msix_cfg.head.status); + return -EINVAL; + } + + return 0; +} + int hinic3_func_reset(struct hinic3_hwdev *hwdev, u16 func_id, u64 reset_f= lag) { struct comm_cmd_func_reset func_reset =3D {}; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.h b/drivers/= net/ethernet/huawei/hinic3/hinic3_hw_comm.h index c33a1c77da9c..2270987b126f 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_comm.h @@ -8,6 +8,19 @@ =20 struct hinic3_hwdev; =20 +struct hinic3_interrupt_info { + u32 lli_set; + u32 interrupt_coalesc_set; + u16 msix_index; + u8 lli_credit_limit; + u8 lli_timer_cfg; + u8 pending_limit; + u8 coalesc_timer_cfg; + u8 resend_timer_cfg; +}; + +int hinic3_set_interrupt_cfg_direct(struct hinic3_hwdev *hwdev, + const struct hinic3_interrupt_info *info); int hinic3_func_reset(struct hinic3_hwdev *hwdev, u16 func_id, u64 reset_f= lag); =20 #endif diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c b/drivers/net/= ethernet/huawei/hinic3/hinic3_irq.c index 8b92eed25edf..33eb9080739d 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_irq.c @@ -38,7 +38,7 @@ static int hinic3_poll(struct napi_struct *napi, int budg= et) return work_done; } =20 -void qp_add_napi(struct hinic3_irq_cfg *irq_cfg) +static void qp_add_napi(struct hinic3_irq_cfg *irq_cfg) { struct hinic3_nic_dev *nic_dev =3D netdev_priv(irq_cfg->netdev); =20 @@ -50,7 +50,7 @@ void qp_add_napi(struct hinic3_irq_cfg *irq_cfg) napi_enable(&irq_cfg->napi); } =20 -void qp_del_napi(struct hinic3_irq_cfg *irq_cfg) +static void qp_del_napi(struct hinic3_irq_cfg *irq_cfg) { napi_disable(&irq_cfg->napi); netif_queue_set_napi(irq_cfg->netdev, irq_cfg->irq_id, @@ -60,3 +60,135 @@ void qp_del_napi(struct hinic3_irq_cfg *irq_cfg) netif_stop_subqueue(irq_cfg->netdev, irq_cfg->irq_id); netif_napi_del(&irq_cfg->napi); } + +static irqreturn_t qp_irq(int irq, void *data) +{ + struct hinic3_irq_cfg *irq_cfg =3D data; + struct hinic3_nic_dev *nic_dev; + + nic_dev =3D netdev_priv(irq_cfg->netdev); + hinic3_msix_intr_clear_resend_bit(nic_dev->hwdev, + irq_cfg->msix_entry_idx, 1); + + napi_schedule(&irq_cfg->napi); + + return IRQ_HANDLED; +} + +static int hinic3_request_irq(struct hinic3_irq_cfg *irq_cfg, u16 q_id) +{ + struct hinic3_interrupt_info info =3D {}; + struct hinic3_nic_dev *nic_dev; + struct net_device *netdev; + int err; + + netdev =3D irq_cfg->netdev; + nic_dev =3D netdev_priv(netdev); + qp_add_napi(irq_cfg); + + info.msix_index =3D irq_cfg->msix_entry_idx; + info.interrupt_coalesc_set =3D 1; + info.pending_limit =3D nic_dev->intr_coalesce[q_id].pending_limit; + info.coalesc_timer_cfg =3D + nic_dev->intr_coalesce[q_id].coalesce_timer_cfg; + info.resend_timer_cfg =3D nic_dev->intr_coalesce[q_id].resend_timer_cfg; + err =3D hinic3_set_interrupt_cfg_direct(nic_dev->hwdev, &info); + if (err) { + netdev_err(netdev, "Failed to set RX interrupt coalescing attribute.\n"); + qp_del_napi(irq_cfg); + return err; + } + + err =3D request_irq(irq_cfg->irq_id, qp_irq, 0, irq_cfg->irq_name, + irq_cfg); + if (err) { + qp_del_napi(irq_cfg); + return err; + } + + irq_set_affinity_hint(irq_cfg->irq_id, &irq_cfg->affinity_mask); + + return 0; +} + +static void hinic3_release_irq(struct hinic3_irq_cfg *irq_cfg) +{ + irq_set_affinity_hint(irq_cfg->irq_id, NULL); + free_irq(irq_cfg->irq_id, irq_cfg); +} + +int hinic3_qps_irq_init(struct net_device *netdev) +{ + struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); + struct pci_dev *pdev =3D nic_dev->pdev; + struct hinic3_irq_cfg *irq_cfg; + struct msix_entry *msix_entry; + u32 local_cpu; + u16 q_id; + int err; + + for (q_id =3D 0; q_id < nic_dev->q_params.num_qps; q_id++) { + msix_entry =3D &nic_dev->qps_msix_entries[q_id]; + irq_cfg =3D &nic_dev->q_params.irq_cfg[q_id]; + + irq_cfg->irq_id =3D msix_entry->vector; + irq_cfg->msix_entry_idx =3D msix_entry->entry; + irq_cfg->netdev =3D netdev; + irq_cfg->txq =3D &nic_dev->txqs[q_id]; + irq_cfg->rxq =3D &nic_dev->rxqs[q_id]; + nic_dev->rxqs[q_id].irq_cfg =3D irq_cfg; + + local_cpu =3D cpumask_local_spread(q_id, dev_to_node(&pdev->dev)); + cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask); + + snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name), + "%s_qp%u", netdev->name, q_id); + + err =3D hinic3_request_irq(irq_cfg, q_id); + if (err) { + netdev_err(netdev, "Failed to request Rx irq\n"); + goto err_release_irqs; + } + + hinic3_set_msix_auto_mask_state(nic_dev->hwdev, + irq_cfg->msix_entry_idx, + HINIC3_SET_MSIX_AUTO_MASK); + hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, + HINIC3_MSIX_ENABLE); + } + + return 0; + +err_release_irqs: + while (q_id > 0) { + q_id--; + irq_cfg =3D &nic_dev->q_params.irq_cfg[q_id]; + qp_del_napi(irq_cfg); + hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, + HINIC3_MSIX_DISABLE); + hinic3_set_msix_auto_mask_state(nic_dev->hwdev, + irq_cfg->msix_entry_idx, + HINIC3_CLR_MSIX_AUTO_MASK); + hinic3_release_irq(irq_cfg); + } + + return err; +} + +void hinic3_qps_irq_uninit(struct net_device *netdev) +{ + struct hinic3_nic_dev *nic_dev =3D netdev_priv(netdev); + struct hinic3_irq_cfg *irq_cfg; + u16 q_id; + + for (q_id =3D 0; q_id < nic_dev->q_params.num_qps; q_id++) { + irq_cfg =3D &nic_dev->q_params.irq_cfg[q_id]; + qp_del_napi(irq_cfg); + hinic3_set_msix_state(nic_dev->hwdev, irq_cfg->msix_entry_idx, + HINIC3_MSIX_DISABLE); + hinic3_set_msix_auto_mask_state(nic_dev->hwdev, + irq_cfg->msix_entry_idx, + HINIC3_CLR_MSIX_AUTO_MASK); + hinic3_release_irq(irq_cfg); + } +} diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h b/drivers/= net/ethernet/huawei/hinic3/hinic3_nic_dev.h index 9577cc673257..9fad834f9e92 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_dev.h @@ -85,8 +85,4 @@ void hinic3_set_netdev_ops(struct net_device *netdev); int hinic3_qps_irq_init(struct net_device *netdev); void hinic3_qps_irq_uninit(struct net_device *netdev); =20 -/* Temporary prototypes. Functions become static in later submission. */ -void qp_add_napi(struct hinic3_irq_cfg *irq_cfg); -void qp_del_napi(struct hinic3_irq_cfg *irq_cfg); - #endif --=20 2.43.0