Huawei HiNIC Ethernet Driver
Subsystems (4)
v2 cover Huawei HiNIC Ethernet Driver
The patch-set contains the support of the HiNIC Ethernet driver for hinic family of PCIE Network Interface Cards.
The Huawei's PCIE HiNIC card is a new Ethernet card and hence there was a need of a new driver.
The current driver is meant to be used for the Physical Function and there would soon be a support for Virtual Function and more features once the basic PF driver has been accepted.
Changes v1 -> v2:
1. remove driver version - Andrew Lunn comment
https://lkml.org/lkml/2017/7/12/372 2. replace kzalloc by devm_kzalloc for short clean - Andrew Lunn comment https://lkml.org/lkml/2017/7/12/372 3. replace pr_ functions by dev_ functions - Andrew Lunn comment https://lkml.org/lkml/2017/7/12/375 4. seperate last patch by moving ops to a new patch - Andrew Lunn comment https://lkml.org/lkml/2017/7/12/377
Aviad Krawczyk (21):
net-next/hinic: Initialize hw interface net-next/hinic: Initialize hw device components net-next/hinic: Initialize api cmd resources net-next/hinic: Initialize api cmd hw net-next/hinic: Add management messages net-next/hinic: Add api cmd commands net-next/hinic: Add aeqs
net-next/hinic: Add port management commands net-next/hinic: Add Rx mode and link event handler net-next/hinic: Add logical Txq and Rxq net-next/hinic: Add wq
net-next/hinic: Add qp resources net-next/hinic: Set qp context net-next/hinic: Initialize cmdq net-next/hinic: Add ceqs
net-next/hinic: Add cmdq commands net-next/hinic: Add cmdq completion handler net-next/hinic: Add Rx handler net-next/hinic: Add Tx operation net-next/hinic: Add ethtool and stats net-next/hinic: Add select_queue and netpoll
Documentation/networking/hinic.txt | 125 +++ MAINTAINERS | 7 + drivers/net/ethernet/Kconfig | 1 + drivers/net/ethernet/Makefile | 1 + drivers/net/ethernet/huawei/Kconfig | 19 + drivers/net/ethernet/huawei/Makefile | 5 + drivers/net/ethernet/huawei/hinic/Kconfig | 13 + drivers/net/ethernet/huawei/hinic/Makefile | 6 + drivers/net/ethernet/huawei/hinic/hinic_common.c | 80 ++ drivers/net/ethernet/huawei/hinic/hinic_common.h | 38 + drivers/net/ethernet/huawei/hinic/hinic_dev.h | 64 ++ .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c | 978 +++++++++++++++++ .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 208 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 940 ++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 302 ++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 149 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 1058 ++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 239 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c | 877 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 265 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 353 ++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 272 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 537 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 97 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 599 ++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 153 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 864 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 394 +++++++ .../net/ethernet/huawei/hinic/hinic_hw_qp_ctxt.h | 214 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 885 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 113 ++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 1142 ++++++++++++++++++++ .../net/ethernet/huawei/hinic/hinic_pci_id_tbl.h | 27 + drivers/net/ethernet/huawei/hinic/hinic_port.c | 403 +++++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 198 ++++ drivers/net/ethernet/huawei/hinic/hinic_rx.c | 518 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_rx.h | 55 + drivers/net/ethernet/huawei/hinic/hinic_tx.c | 516 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 62 ++ 39 files changed, 12777 insertions(+) create mode 100644 Documentation/networking/hinic.txt create mode 100644 drivers/net/ethernet/huawei/Kconfig create mode 100644 drivers/net/ethernet/huawei/Makefile create mode 100644 drivers/net/ethernet/huawei/hinic/Kconfig create mode 100644 drivers/net/ethernet/huawei/hinic/Makefile create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_common.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_common.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_dev.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_if.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_if.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_io.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_io.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_qp_ctxt.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_main.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_port.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_port.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_rx.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_rx.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_tx.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_tx.h
Signature · 1 line
1.9.1
PATCH v2 1/21 net-next/hinic: Initialize hw interface
Initialize hw interface as part of the nic initialization for accessing hw.
--- Documentation/networking/hinic.txt | 125 ++++++++++++ drivers/net/ethernet/Kconfig | 1 + drivers/net/ethernet/Makefile | 1 + drivers/net/ethernet/huawei/Kconfig | 19 ++ drivers/net/ethernet/huawei/Makefile | 5 + drivers/net/ethernet/huawei/hinic/Kconfig | 13 ++ drivers/net/ethernet/huawei/hinic/Makefile | 3 + drivers/net/ethernet/huawei/hinic/hinic_dev.h | 33 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 36 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 208 ++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 42 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 208 ++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 160 ++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 209 +++++++++++++++++++++ .../net/ethernet/huawei/hinic/hinic_pci_id_tbl.h | 27 +++ 15 files changed, 1090 insertions(+) create mode 100644 Documentation/networking/hinic.txt create mode 100644 drivers/net/ethernet/huawei/Kconfig create mode 100644 drivers/net/ethernet/huawei/Makefile create mode 100644 drivers/net/ethernet/huawei/hinic/Kconfig create mode 100644 drivers/net/ethernet/huawei/hinic/Makefile create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_dev.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_if.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_if.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_main.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h
Documentation/networking/hinic.txt new file +125 -0
@@ -0,0 +1,125 @@ +Linux Kernel Driver for Huawei Intelligent NIC(HiNIC) family +============================================================ + +Overview: +========= +HiNIC is a network interface card for the Data Center Area. + +The driver supports a range of link-speed devices (10GbE, 25GbE, 40GbE, etc.). +The driver supports also a negotiated and extendable feature set. + +Some HiNIC devices support SR-IOV. This driver is used for Physical Function +(PF). + +HiNIC devices support MSI-X interrupt vector for each Tx/Rx queue and +adaptive interrupt moderation. + +HiNIC devices support also various offload features such as checksum offload, +TCP Transmit Segmentation Offload(TSO), Receive-Side Scaling(RSS) and +LRO(Large Receive Offload). + + +Supported PCI vendor ID/device IDs: +=================================== + +19e5:1822 - HiNIC PF + + +Driver Architecture and Source Code: +==================================== + +hinic_dev - Implement a Logical Network device that is independent from +specific HW details about HW data structure formats. + +hinic_hwdev - Implement the HW details of the device and include the components +for accessing the PCI NIC. + +hinic_hwdev contains the following components: +=============================================== + +HW Interface: +============= + +The interface for accessing the pci device (DMA memory and PCI BARs). +(hinic_hw_if.c, hinic_hw_if.h) + +Configuration Status Registers Area that describes the HW Registers on the +configuration and status BAR0. (hinic_hw_csr.h) + +MGMT components: +================ + +Asynchronous Event Queues(AEQs) - The event queues for receiving messages from +the MGMT modules on the cards. (hinic_hw_eqs.c, hinic_hw_eqs.h) + +Application Programmable Interface commands(API CMD) - Interface for sending +MGMT commands to the card. (hinic_hw_api_cmd.c, hinic_hw_api_cmd.h) + +Management (MGMT) - the PF to MGMT channel that uses API CMD for sending MGMT +commands to the card and receives notifications from the MGMT modules on the +card by AEQs. Also set the addresses of the IO CMDQs in HW. +(hinic_hw_mgmt.c, hinic_hw_mgmt.h) + +IO components: +============== + +Completion Event Queues(CEQs) - The completion Event Queues that describe IO +tasks that are finished. (hinic_hw_eqs.c, hinic_hw_eqs.h) + +Work Queues(WQ) - Contain the memory and operations for use by CMD queues and +the Queue Pairs. The WQ is a Memory Block in a Page. The Block contains +pointers to Memory Areas that are the Memory for the Work Queue Elements(WQEs). +(hinic_hw_wq.c, hinic_hw_wq.h) + +Command Queues(CMDQ) - The queues for sending commands for IO management and is +used to set the QPs addresses in HW. The commands completion events are +accumulated on the CEQ that is configured to receive the CMDQ completion events. +(hinic_hw_cmdq.c, hinic_hw_cmdq.h) + +Queue Pairs(QPs) - The HW Receive and Send queues for Receiving and Transmitting +Data. (hinic_hw_qp.c, hinic_hw_qp.h, hinic_hw_qp_ctxt.h) + +IO - de/constructs all the IO components. (hinic_hw_io.c, hinic_hw_io.h) + +HW device: +========== + +HW device - de/constructs the HW Interface, the MGMT components on the +initialization of the driver and the IO components on the case of Interface +UP/DOWN Events. (hinic_hw_dev.c, hinic_hw_dev.h) + + +hinic_dev contains the following components: +=============================================== + +PCI ID table - Contains the supported PCI Vendor/Device IDs. +(hinic_pci_tbl.h) + +Port Commands - Send commands to the HW device for port management +(MAC, Vlan, MTU, ...). (hinic_port.c, hinic_port.h) + +Tx Queues - Logical Tx Queues that use the HW Send Queues for transmit. +The Logical Tx queue is not dependent on the format of the HW Send Queue. +(hinic_tx.c, hinic_tx.h) + +Rx Queues - Logical Rx Queues that use the HW Receive Queues for receive. +The Logical Rx queue is not dependent on the format of the HW Receive Queue. +(hinic_rx.c, hinic_rx.h) + +hinic_dev - de/constructs the Logical Tx and Rx Queues. +(hinic_main.c, hinic_dev.h) + + +Miscellaneous: +============= + +Common functions that are used by HW and Logical Device. +(hinic_common.c, hinic_common.h) + + +Support +======= + +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 [email protected].
drivers/net/ethernet/Kconfig +1 -0
@@ -78,6 +78,7 @@ source "drivers/net/ethernet/freescale/Kconfig" source "drivers/net/ethernet/fujitsu/Kconfig" source "drivers/net/ethernet/hisilicon/Kconfig" source "drivers/net/ethernet/hp/Kconfig" +source "drivers/net/ethernet/huawei/Kconfig" source "drivers/net/ethernet/ibm/Kconfig" source "drivers/net/ethernet/intel/Kconfig" source "drivers/net/ethernet/i825xx/Kconfig"
drivers/net/ethernet/Makefile +1 -0
@@ -41,6 +41,7 @@ obj-$(CONFIG_NET_VENDOR_FREESCALE) += freescale/ obj-$(CONFIG_NET_VENDOR_FUJITSU) += fujitsu/ obj-$(CONFIG_NET_VENDOR_HISILICON) += hisilicon/ obj-$(CONFIG_NET_VENDOR_HP) += hp/ +obj-$(CONFIG_NET_VENDOR_HUAWEI) += huawei/ obj-$(CONFIG_NET_VENDOR_IBM) += ibm/ obj-$(CONFIG_NET_VENDOR_INTEL) += intel/ obj-$(CONFIG_NET_VENDOR_I825XX) += i825xx/
drivers/net/ethernet/huawei/Kconfig new file +19 -0
@@ -0,0 +1,19 @@ +# +# Huawei driver configuration +# + +config NET_VENDOR_HUAWEI + bool "Huawei 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 Huawei cards. If you say Y, you will be asked + for your specific card in the following questions. + +if NET_VENDOR_HUAWEI + +source "drivers/net/ethernet/huawei/hinic/Kconfig" + +endif # NET_VENDOR_HUAWEI
drivers/net/ethernet/huawei/Makefile new file +5 -0
@@ -0,0 +1,5 @@ +# +# Makefile for the Huawei device drivers. +# + +obj-$(CONFIG_HINIC) += hinic/
drivers/net/ethernet/huawei/hinic/Kconfig new file +13 -0
@@ -0,0 +1,13 @@ +# +# Huawei driver configuration +# + +config HINIC + tristate "Huawei Intelligent PCIE Network Interface Card" + depends on (PCI_MSI && X86) + default m + ---help--- + This driver supports HiNIC PCIE Ethernet cards. + To compile this driver as part of the kernel, choose Y here. + If unsure, choose N. + The default is compiled as module.
drivers/net/ethernet/huawei/hinic/Makefile new file +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_HINIC) += hinic.o + +hinic-y := hinic_main.o hinic_hw_dev.o hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_dev.h new file +33 -0
@@ -0,0 +1,33 @@ +/* +* Huawei HiNIC PCI Express Linux driver +* Copyright(c) 2017 Huawei Technologies Co., Ltd +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +* +*/ + +#ifndef HINIC_DEV_H +#define HINIC_DEV_H + +#include <linux/netdevice.h> +#include <linux/types.h> + +#include "hinic_hw_dev.h" + +#define HINIC_DRV_NAME "HiNIC" + +struct hinic_dev { +struct net_device *netdev; +struct hinic_hwdev *hwdev; + +u32 msg_enable; +}; + +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h new file +36 -0
@@ -0,0 +1,36 @@ +/* +* Huawei HiNIC PCI Express Linux driver +* Copyright(c) 2017 Huawei Technologies Co., Ltd +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +* +*/ + +#ifndef HINIC_HW_CSR_H +#define HINIC_HW_CSR_H + +/* HW interface registers */ +#define HINIC_CSR_FUNC_ATTR0_ADDR 0x0 +#define HINIC_CSR_FUNC_ATTR1_ADDR 0x4 + +#define HINIC_DMA_ATTR_BASE 0xC80 +#define HINIC_ELECTION_BASE 0x4200 + +#define HINIC_DMA_ATTR_STRIDE 0x4 +#define HINIC_CSR_DMA_ATTR_ADDR (idx) \ + (HINIC_DMA_ATTR_BASE + (idx) * HINIC_DMA_ATTR_STRIDE) + +#define HINIC_PPF_ELECTION_STRIDE 0x4 +#define HINIC_CSR_MAX_PORTS 4 + +#define HINIC_CSR_PPF_ELECTION_ADDR (idx) \ + (HINIC_ELECTION_BASE + (idx) * HINIC_PPF_ELECTION_STRIDE) + +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +208 -0
208 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h new file +42 -0
42 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.c new file +208 -0
208 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h new file +160 -0
160 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +209 -0
209 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +27 -0
@@ -0,0 +1,27 @@ +/* +* Huawei HiNIC PCI Express Linux driver +* Copyright(c) 2017 Huawei Technologies Co., Ltd +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +* +*/ + +#ifndef HINIC_PCI_ID_TBL_H +#define HINIC_PCI_ID_TBL_H + +#ifndef PCI_VENDOR_ID_HUAWEI +#define PCI_VENDOR_ID_HUAWEI 0x19e5 +#endif + +#ifndef PCI_DEVICE_ID_HI1822_PF +#define PCI_DEVICE_ID_HI1822_PF 0x1822 +#endif + +#endif
Signature · 1 line
1.9.1
Re: [PATCH V2 net-next 01/21] net-next/hinic: Initialize hw interface
Aviad Krawczyk <[email protected]> :
[...]
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +0
-0
[...]
Quoted 9 lines
+/**
+ *hinic_init_hwdev- Initialize the NIC HW
+ * @hwdev: the NIC HW device that is returned from the initialization
+ * @pdev: the NIC pci device
+ *
+ * Return 0 - Success, negative - Failure
+ *
+ * Initialize the NIC HW device and return a pointer to it in the first arg
+ **/
Return a pointer and use ERR_PTR / IS_ERR ?
Quoted 16 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +16
-0+int hinic_init_hwdev (struct hinic_hwdev **hwdev,struct pci_dev *pdev) +{ +struct hinic_pfhwdev *pfhwdev; +struct hinic_hwif *hwif; +int err; + + hwif =devm_kzalloc (&pdev->dev,sizeof (*hwif),GFP_KERNEL ); +if (!hwif) +return -ENOMEM ; + + err =hinic_init_hwif (hwif, pdev); +if (err) { +dev_err (&pdev->dev,"Failed to init HW interface\n" ); +return err; + } +
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c line 134
Quoted 10 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +10
-0+if (!HINIC_IS_PF (hwif) && !HINIC_IS_PPF (hwif)) { +dev_err (&pdev->dev,"Unsupported PCI Function type\n" ); + err = -EFAULT ; + goto func_type_err; + } + + pfhwdev =devm_kzalloc (&pdev->dev,sizeof (*pfhwdev),GFP_KERNEL ); +if (!pfhwdev) { + err = -ENOMEM ; + goto pfhwdev_alloc_err;
Intel, Mellanox, Broadcom, Amazon and friends use "err_xyz" labels.
Please consider using the same style.
[...]
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c line 177
Quoted 10 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +10
-0+void hinic_free_hwdev (struct hinic_hwdev *hwdev) +{ +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_pfhwdev *pfhwdev; + +if (!HINIC_IS_PF (hwif) && !HINIC_IS_PPF (hwif)) { +dev_err (&pdev->dev,"unsupported PCI Function type\n" ); +return ; + }
If it succeeded in hinic_init_hwdev, how could it fail here ?
If it failed in hinic_init_hwdev, hinic_free_hwdev should not even be called.
-> remove ?
[...]
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +0
-0
[...]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 167
Quoted 7 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +7
-0+static void hinic_remove (struct pci_dev *pdev) +{ +struct net_device *netdev =pci_get_drvdata (pdev); +struct hinic_dev *nic_dev; + +if (!netdev) +return ;
Your driver is flawed if this test can ever succeed.
[...]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 206
Quoted 9 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +9
-0+static int __init hinic_init (void ) +{ +return pci_register_driver (&hinic_driver); +} + +static void __exit hinic_exit(void) +{ +pci_unregister_driver (&hinic_driver); +}
Use module_pci_driver(hinic_driver).
Remove hinic_init() and hinic_exit().
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +0
-0
[...]
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h line 21
Quoted 6 lines
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +6
-0+#ifndef HINIC_PCI_ID_TBL_H +#define HINIC_PCI_ID_TBL_H + +#ifndef PCI_VENDOR_ID_HUAWEI +#define PCI_VENDOR_ID_HUAWEI 0x19e5 +#endif
Useless: it duplicates include/linux/pci_ids.h
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h line 25
Quoted 4 lines
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +4
-0+ +#ifndef PCI_DEVICE_ID_HI1822_PF +#define PCI_DEVICE_ID_HI1822_PF 0x1822 +#endif
Please move it to the .c file where it is actually used.
Extra:
grep -E 'void\ \*' drivers/net/ethernet/huawei/hinic/* makes me nervous.
At some point one function will be fed with a wrong pointer and the compiler won't notice it.
For instance hinic_sq_read_wqe is only called with &skb. There's no reason to declare it using a 'void **' argument.
Signature · 1 line
Ueimor
Re: [PATCH V2 net-next 01/21] net-next/hinic: Initialize hw interface
Hi Francois,
ERR_PTR / IS ERR - we will change it
err_xyz labels - we will change it according to other companies style.
hinic_free_hwdev - It is there to mark us changes for VF code. We will remove it, it can't be failed.
hinic_remove - If insmod failed and someone calls rmmod, we will get a crash because the resource are already free. Therefore we test if the device exists, please tell me if you meant to something different
pci_id_tbl - will be moved to the .c file.
void* - usually void * is something to avoid.
The priv data is in type void * because the
caller can use any struct that it wants, like the priv data in Linux (netdev, irq, tasklet, work..) -
we can change it but if we will pass different struct
in the future, we will have to change the prototype of the functions.
According to the other void *:
The wq struct is used for cmdq, sq and rq. Therefore the wqe is in type void *. There are 4 operations get_wqe, write_wqe, read_wqe and put_wqe - there is no option that one function will be fed with a wrong pointer because the caller should use what it got in get_wqe function.
When something is used as multiple types, it can be used as void * or union. Usually, I would prefer union. But, in this case if we will use union, maybe there is a chance of using the wrong wqe type in the wrong work queue type.
Another option is to use a wrapper for each wq type operations, so only the basic wq ops will use void *.
Then, there will be cmdq, rq, sq operations with the correct wqe type and wq operations that will use void *.
I will be glad to hear your opinion about the preferred style and about hinic_remove issue you mentioned above.
Thanks for your time and review,
Aviad
Quoted 135 lines · Francois Romieu
Aviad Krawczyk <[email protected]> :
[...]Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +0
-0[...]
Quoted 9 lines
+/**
+ *hinic_init_hwdev- Initialize the NIC HW
+ * @hwdev: the NIC HW device that is returned from the initialization
+ * @pdev: the NIC pci device
+ *
+ * Return 0 - Success, negative - Failure
+ *
+ * Initialize the NIC HW device and return a pointer to it in the first arg
+ **/Return a pointer and use
ERR_PTR/IS_ERR?Quoted 16 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +16
-0+int hinic_init_hwdev (struct hinic_hwdev **hwdev,struct pci_dev *pdev) +{ +struct hinic_pfhwdev *pfhwdev; +struct hinic_hwif *hwif; +int err; + + hwif =devm_kzalloc (&pdev->dev,sizeof (*hwif),GFP_KERNEL ); +if (!hwif) +return -ENOMEM ; + + err =hinic_init_hwif (hwif, pdev); +if (err) { +dev_err (&pdev->dev,"Failed to init HW interface\n" ); +return err; + } +drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c line 134
Quoted 10 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +10
-0+if (!HINIC_IS_PF (hwif) && !HINIC_IS_PPF (hwif)) { +dev_err (&pdev->dev,"Unsupported PCI Function type\n" ); + err = -EFAULT ; + goto func_type_err; + } + + pfhwdev =devm_kzalloc (&pdev->dev,sizeof (*pfhwdev),GFP_KERNEL ); +if (!pfhwdev) { + err = -ENOMEM ; + goto pfhwdev_alloc_err;Intel, Mellanox, Broadcom, Amazon and friends use "
err_xyz" labels.Please consider using the same style.
[...]
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c line 177
Quoted 10 lines
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c new file +10
-0+void hinic_free_hwdev (struct hinic_hwdev *hwdev) +{ +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_pfhwdev *pfhwdev; + +if (!HINIC_IS_PF (hwif) && !HINIC_IS_PPF (hwif)) { +dev_err (&pdev->dev,"unsupported PCI Function type\n" ); +return ; + }If it succeeded in
hinic_init_hwdev, how could it fail here ?If it failed in
hinic_init_hwdev,hinic_free_hwdevshould not even be called.-> remove ?
[...]
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +0
-0[...]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 167
Quoted 7 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +7
-0+static void hinic_remove (struct pci_dev *pdev) +{ +struct net_device *netdev =pci_get_drvdata (pdev); +struct hinic_dev *nic_dev; + +if (!netdev) +return ;Your driver is flawed if this test can ever succeed.
[...]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 206
Quoted 9 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c new file +9
-0+static int __init hinic_init (void ) +{ +return pci_register_driver (&hinic_driver); +} + +static void __exit hinic_exit(void) +{ +pci_unregister_driver (&hinic_driver); +}Use
module_pci_driver(hinic_driver).Remove
hinic_init()andhinic_exit().Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +0
-0[...]
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h line 21
Quoted 6 lines
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +6
-0+#ifndef HINIC_PCI_ID_TBL_H +#define HINIC_PCI_ID_TBL_H + +#ifndef PCI_VENDOR_ID_HUAWEI +#define PCI_VENDOR_ID_HUAWEI 0x19e5 +#endif Useless: it duplicates
include/linux/pci_ids.hdrivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h line 25
Quoted 4 lines
drivers/net/ethernet/huawei/hinic/hinic_pci_id_tbl.h new file +4
-0+ +#ifndef PCI_DEVICE_ID_HI1822_PF +#define PCI_DEVICE_ID_HI1822_PF 0x1822 +#endif Please move it to the .c file where it is actually used.
Extra:
grep -E 'void\ \*'
drivers/net/ethernet/huawei/hinic/*makes me nervous.At some point one function will be fed with a wrong pointer and the compiler won't notice it.
For instance
hinic_sq_read_wqeis only called with &skb. There's no reason to declare it using a 'void **' argument.
Re: [PATCH V2 net-next 01/21] net-next/hinic: Initialize hw interface
Aviad Krawczyk <[email protected]> :
[...]
Quoted 3 lines
hinic_remove- If insmod failed and someone calls rmmod, we will get a crash because the resource are already free. Therefore we test if the device exists, please tell me if you meant to something different
The module won't even proceed through the pci_driver remove method if the probe method failed. See drivers/pci/bus.c::pci_bus_add_device and track 'dev->is_added'. You don't need to believe me: try it.
I have no idea where your crash comes from but something does not look quite right.
(use module_pci_driver() to save some boilerplate code btw)
[...]
Quoted 3 lines
The priv data is in type void * because the
caller can use any struct that it wants, like the priv data in Linux (netdev, irq, tasklet, work..) -
I disagree. A driver is a piece of glue between hardware and software. It fills a kernel's contract. It is not supposed to introduce opaque data (even if it's hard to resist).
Quoted 2 lines
we can change it but if we will pass different struct
in the future, we will have to change the prototype of the functions.
It's fine. If I do something wrong - and at some point I will - I'd rather have it detected at compile time. Nobody wants to waste precious hardware lab testing time because of excess void *.
Quoted 9 lines
According to the other void *:
The wq struct is used for cmdq, sq and rq. Therefore the wqe is in type void *. There are 4 operationsget_wqe,write_wqe,read_wqeandput_wqe- there is no option that one function will be fed with a wrong pointer because the caller should use what it got inget_wqefunction.When something is used as multiple types, it can be used as void * or union. Usually, I would prefer union. But, in this case if we will use union, maybe there is a chance of using the wrong wqe type in the wrong work queue type.
union * will at least catch being fed a wrong type. void * won't notice.
Let's take a practical example: hinic_sq_get_sges.
void hinic_sq_get_sges(void *wqe, struct hinic_sge *sges, int nr_sges)
^^^^^^^^^
{
struct hinic_sq_wqe *sq_wqe = (struct hinic_sq_wqe *)wqe;static void free_all_tx_skbs(struct hinic_txq *txq)
{
struct hinic_dev *nic_dev = netdev_priv(txq->netdev);
struct hinic_sq *sq = txq->sq;
struct hinic_sq_wqe *wqe;
[...]
hinic_sq_get_sges(wqe, txq->free_sges, nr_sges);static int free_tx_poll(struct napi_struct *napi, int budget) {
[...]
struct hinic_sq_wqe *wqe;
[...]
hinic_sq_get_sges(wqe, txq->free_sges, nr_sges);Why is it:
void hinic_sq_get_sges(void *wqe, ...
instead of:
void hinic_sq_get_sges(struct hinic_sq_wqe *wqe, ...
Because of a future change ?
Signature · 1 line
Ueimor
Re: [PATCH V2 net-next 01/21] net-next/hinic: Initialize hw interface
Hi,
hinic_remove - you are right, it is over safe code. We can remove it without any crash. This case has never happened.
void * - I meant the problem is not in rq or sq, it can be in wq. But you confirmed that it is ok to use union instead of the void* in wq. So, we will use union in wq.c and in rq - rq_wqe and in sq - sq_wqe.
module_pci_driver - is not used in other drivers in the same segments, it is necessary?
Thanks,
Aviad
Quoted 78 lines · Francois Romieu
Aviad Krawczyk <[email protected]> :
[...]Quoted 3 lines
hinic_remove- If insmod failed and someone calls rmmod, we will get a crash because the resource are already free. Therefore we test if the device exists, please tell me if you meant to something differentThe module won't even proceed through the
pci_driverremove method if the probe method failed. See drivers/pci/bus.c::pci_bus_add_device and track 'dev->is_added'. You don't need to believe me: try it.I have no idea where your crash comes from but something does not look quite right.
(use
module_pci_driver()to save some boilerplate code btw)[...]
Quoted 3 lines
The priv data is in type void * because the
caller can use any struct that it wants, like the priv data in Linux (netdev, irq, tasklet, work..) -I disagree. A driver is a piece of glue between hardware and software. It fills a kernel's contract. It is not supposed to introduce opaque data (even if it's hard to resist).
Quoted 2 lines
we can change it but if we will pass different struct
in the future, we will have to change the prototype of the functions.It's fine. If I do something wrong - and at some point I will - I'd rather have it detected at compile time. Nobody wants to waste precious hardware lab testing time because of excess void *.
Quoted 9 lines
According to the other void *:
The wq struct is used for cmdq, sq and rq. Therefore the wqe is in type void *. There are 4 operationsget_wqe,write_wqe,read_wqeandput_wqe- there is no option that one function will be fed with a wrong pointer because the caller should use what it got inget_wqefunction.When something is used as multiple types, it can be used as void * or union. Usually, I would prefer union. But, in this case if we will use union, maybe there is a chance of using the wrong wqe type in the wrong work queue type.
union * will at least catch being fed a wrong type. void * won't notice.
Let's take a practical example:
hinic_sq_get_sges.void
hinic_sq_get_sges(void *wqe, struct hinic_sge *sges, int nr_sges)^^^^^^^^^ { struct hinic_sq_wqe *sq_wqe = (struct hinic_sq_wqe *)wqe;static void
free_all_tx_skbs(struct hinic_txq *txq){ struct hinic_dev *nic_dev = netdev_priv(txq->netdev); struct hinic_sq *sq = txq->sq; struct hinic_sq_wqe *wqe; [...] hinic_sq_get_sges(wqe, txq->free_sges, nr_sges);static int
free_tx_poll(struct napi_struct *napi, int budget){
[...]struct hinic_sq_wqe *wqe; [...] hinic_sq_get_sges(wqe, txq->free_sges, nr_sges);Why is it:
void hinic_sq_get_sges(void *wqe, ...
instead of:
void hinic_sq_get_sges(struct
hinic_sq_wqe*wqe, ...Because of a future change ?
Re: [PATCH V2 net-next 01/21] net-next/hinic: Initialize hw interface
Aviad Krawczyk <[email protected]> :
[...]
Quoted 2 lines
module_pci_driver- is not used in other drivers in the same segments, it is necessary ?
/me checks... Ok, there seems to be some overenthusiastic copy'paste.
See drivers/net/ethernet/intel/ixgb/ixgb_main.c:
[...]
/**
* ixgb_init_module - Driver Registration Routine
*
* ixgb_init_module is the first routine called when the driver is
* loaded. All it does is register with the PCI subsystem. **/
static int __initixgb_init_module(void)
{
pr_info("%s - version %s\n", ixgb_driver_string, ixgb_driver_version);
pr_info("%s\n", ixgb_copyright);
return pci_register_driver(&ixgb_driver);
}module_init(ixgb_init_module);
/**
* ixgb_exit_module - Driver Exit Cleanup Routine
*
* ixgb_exit_module is called just before the driver is removed
* from memory.
**/
static void __exitixgb_exit_module(void)
{
pci_unregister_driver(&ixgb_driver);
}module_exit(ixgb_exit_module);
Driver version ought to be fed through ethtool, if ever. Copyright message mildly contributes to a better world. So the whole stuff above could be:
module_pci_driver(ixgb_driver);
Signature · 1 line
Ueimor
Re: [PATCH V2 net-next 01/21] net-next/hinic: Initialize hw interface
OK, we will use module_pci_driver although it is not very common in the same segment.
Quoted 47 lines · Francois Romieu
Aviad Krawczyk <[email protected]> :
[...]Quoted 2 lines
module_pci_driver- is not used in other drivers in the same segments, it is necessary ?/me checks... Ok, there seems to be some overenthusiastic copy'paste.
See
drivers/net/ethernet/intel/ixgb/ixgb_main.c:
[...]
/**
*ixgb_init_module- Driver Registration Routine
*
*ixgb_init_moduleis the first routine called when the driver is
* loaded. All it does is register with the PCI subsystem. **/static int
__initixgb_init_module(void){ pr_info("%s - version %s\n", ixgb_driver_string, ixgb_driver_version); pr_info("%s\n", ixgb_copyright); return pci_register_driver(&ixgb_driver); }
module_init(ixgb_init_module);/**
*ixgb_exit_module- Driver Exit Cleanup Routine
*
*ixgb_exit_moduleis called just before the driver is removed
* from memory.
**/static void
__exitixgb_exit_module(void){ pci_unregister_driver(&ixgb_driver); }
module_exit(ixgb_exit_module);Driver version ought to be fed through ethtool, if ever. Copyright message mildly contributes to a better world. So the whole stuff above could be:
module_pci_driver(ixgb_driver);
PATCH v2 2/21 net-next/hinic: Initialize hw device components
In reply to Aviad KrawczykInitialize hw device by calling the initialization functions of aeqs and management channel.
--- drivers/net/ethernet/huawei/hinic/Makefile | 3 +- drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 176 ++++++++++++++++++++-- drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 14 +- drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c | 149 ++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 107 +++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 8 + drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 93 ++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 45 ++++++ 8 files changed, 580 insertions(+), 15 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h
drivers/net/ethernet/huawei/hinic/Makefile +2 -1
@@ -1,3 +1,4 @@ obj-$(CONFIG_HINIC) += hinic.o -hinic-y := hinic_main.o hinic_hw_dev.o hinic_hw_if.o +hinic-y := hinic_main.o hinic_hw_dev.o hinic_hw_mgmt.o hinic_hw_eqs.o \ + hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +163 -13
231 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +13 -1
@@ -17,20 +17,32 @@#define HINIC_HW_DEV_H #include <linux/pci.h> +#include <linux/types.h> #include "hinic_hw_if.h" +#include "hinic_hw_eqs.h" +#include "hinic_hw_mgmt.h" #define HINIC_MAX_QPS 32 +struct hinic_cap { +u16 max_qps; +u16 num_qps; +}; +struct hinic_hwdev {struct hinic_hwif *hwif;struct msix_entry *msix_entries; + +struct hinic_aeqs aeqs; + +struct hinic_cap nic_cap; };struct hinic_pfhwdev {struct hinic_hwdev hwdev; -/* PF Extended components should be here */ +struct hinic_pf_to_mgmt pf_to_mgmt; };int hinic_init_hwdev (struct hinic_hwdev **hwdev,struct pci_dev *pdev);
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c new file +149 -0
149 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h new file +107 -0
107 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +8 -0
@@ -119,6 +119,14 @@ enum hinic_func_type { HINIC_PPF = 2, }; +enum hinic_mod_type { +HINIC_MOD_COMM =0 ,/* HW communication module */ +HINIC_MOD_L2NIC =1 ,/* L2NIC module */ +HINIC_MOD_CFGM =7 ,/* Configuration module */ + +HINIC_MOD_MAX =15 +}; +struct hinic_func_attr {u16 func_global_idx;u8 pf_idx;
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c new file +93 -0
93 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h new file +45 -0
45 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 3/21 net-next/hinic: Initialize api cmd resources
In reply to Aviad KrawczykInitialize api cmd resources as part of management initialization.
--- drivers/net/ethernet/huawei/hinic/Makefile | 4 +- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c | 445 +++++++++++++++++++++ .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 102 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 10 + drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 3 + 5 files changed, 562 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h
drivers/net/ethernet/huawei/hinic/Makefile +2 -2
@@ -1,4 +1,4 @@ obj-$(CONFIG_HINIC) += hinic.o -hinic-y := hinic_main.o hinic_hw_dev.o hinic_hw_mgmt.o hinic_hw_eqs.o \ - hinic_hw_if.o +hinic-y := hinic_main.o hinic_hw_dev.o hinic_hw_mgmt.o hinic_hw_api_cmd.o \ + hinic_hw_eqs.o hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c new file +445 -0
445 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h new file +102 -0
102 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +10 -0
@@ -19,6 +19,7 @@#include "hinic_hw_if.h" #include "hinic_hw_eqs.h" +#include "hinic_hw_api_cmd.h" #include "hinic_hw_mgmt.h" #include "hinic_hw_dev.h"
@@ -70,9 +71,17 @@ int hinic_pf_to_mgmt_init(struct hinic_pf_to_mgmt *pf_to_mgmt, {struct hinic_pfhwdev *pfhwdev =mgmt_to_pfhwdev (pf_to_mgmt);struct hinic_hwdev *hwdev = &pfhwdev->hwdev; +struct pci_dev *pdev = hwif->pdev; +int err; pf_to_mgmt->hwif = hwif; + err =hinic_api_cmd_init (hwif, pf_to_mgmt->cmd_chain); +if (err) { +dev_err (&pdev->dev,"Failed to initialize cmd chains\n" ); +return err; + } +hinic_aeq_register_hw_cb (&hwdev->aeqs,HINIC_MSG_FROM_MGMT_CPU , pf_to_mgmt, mgmt_msg_aeqe_handler);
@@ -90,4 +99,5 @@ void hinic_pf_to_mgmt_free(struct hinic_pf_to_mgmt *pf_to_mgmt)struct hinic_hwdev *hwdev = &pfhwdev->hwdev;hinic_aeq_unregister_hw_cb (&hwdev->aeqs,HINIC_MSG_FROM_MGMT_CPU ); +hinic_api_cmd_free (pf_to_mgmt->cmd_chain); }
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +3 -0
@@ -19,6 +19,7 @@#include <linux/types.h> #include "hinic_hw_if.h" +#include "hinic_hw_api_cmd.h" enum hinic_mgmt_msg_type {HINIC_MGMT_MSG_SYNC =1 ,
@@ -30,6 +31,8 @@ enum hinic_cfg_cmd {struct hinic_pf_to_mgmt {struct hinic_hwif *hwif; + +struct hinic_api_cmd_chain *cmd_chain[HINIC_API_CMD_MAX ]; }; int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt,
Signature · 1 line
1.9.1
PATCH v2 4/21 net-next/hinic: Initialize api cmd hw
In reply to Aviad KrawczykUpdate the hardware about api cmd resources and initialize it.
--- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c | 173 ++++++++++++++++++++- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 38 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 25 +++ 3 files changed, 235 insertions(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +172 -1
@@ -13,6 +13,7 @@* */ +#include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/pci.h>
@@ -20,8 +21,12 @@#include <linux/slab.h> #include <linux/dma-mapping.h> #include <linux/bitops.h> +#include <linux/jiffies.h> +#include <linux/delay.h> +#include <linux/log2.h> #include <asm/byteorder.h> +#include "hinic_hw_csr.h" #include "hinic_hw_if.h" #include "hinic_hw_api_cmd.h"
@@ -34,8 +39,157 @@ (((cell_size) >=API_CMD_CELL_SIZE_MIN ) ? \ (1 << (fls(cell_size - 1))) : API_CMD_CELL_SIZE_MIN) +#define API_CMD_CELL_SIZE_VAL (size) \ + ilog2((size) >> API_CMD_CELL_SIZE_SHIFT) +#define API_CMD_BUF_SIZE 2048 +#define API_CMD_TIMEOUT 1000 + +enum api_cmd_xor_chk_level { +XOR_CHK_DIS =0 , + +XOR_CHK_ALL =3 , +}; + +/** +* api_cmd_hw_restart - restart the chain in the HW +* @chain: the API CMD specific chain to restart +* +* Return 0 - Success, negative - Failure +**/ +static int api_cmd_hw_restart (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +unsigned long end; +u32 reg_addr, val; +int err = -ETIMEDOUT ; + +/* Read Modify Write */ + reg_addr =HINIC_CSR_API_CMD_CHAIN_REQ_ADDR (chain->chain_type); + val =hinic_hwif_read_reg (hwif, reg_addr); + + val =HINIC_API_CMD_CHAIN_REQ_CLEAR (val,RESTART ); + val |=HINIC_API_CMD_CHAIN_REQ_SET (1 ,RESTART ); + +hinic_hwif_write_reg (hwif, reg_addr, val); + + end = jiffies +msecs_to_jiffies (API_CMD_TIMEOUT ); +do { + val =hinic_hwif_read_reg (hwif, reg_addr); + +if (!HINIC_API_CMD_CHAIN_REQ_GET (val,RESTART )) { + err =0 ; +break ; + } + +msleep (20 ); + }while (time_before (jiffies, end)); + +return err; +} + +/** +* api_cmd_ctrl_init - set the control register of a chain +* @chain: the API CMD specific chain to set control register for +**/ +static void api_cmd_ctrl_init (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +u32 reg_addr, ctrl; +u16 cell_size; + +/* Read Modify Write */ + reg_addr =HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR (chain->chain_type); + + cell_size =API_CMD_CELL_SIZE_VAL (chain->cell_size); + + ctrl =hinic_hwif_read_reg (hwif, reg_addr); + + ctrl =HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,RESTART_WB_STAT ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,XOR_ERR ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,AEQE_EN ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,XOR_CHK_EN ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,CELL_SIZE ); + + ctrl |=HINIC_API_CMD_CHAIN_CTRL_SET (1 ,XOR_ERR ) | +HINIC_API_CMD_CHAIN_CTRL_SET (XOR_CHK_ALL ,XOR_CHK_EN ) | +HINIC_API_CMD_CHAIN_CTRL_SET (cell_size,CELL_SIZE ); + +hinic_hwif_write_reg (hwif, reg_addr, ctrl); +} + +/** +* api_cmd_set_status_addr - set the status address of a chain in the HW +* @chain: the API CMD specific chain to set in HW status address for +**/ +static void api_cmd_set_status_addr (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +u32 addr, val; + + addr =HINIC_CSR_API_CMD_STATUS_HI_ADDR (chain->chain_type); + val =upper_32_bits (chain->wb_status_paddr); +hinic_hwif_write_reg (hwif, addr, val); + + addr =HINIC_CSR_API_CMD_STATUS_LO_ADDR (chain->chain_type); + val =lower_32_bits (chain->wb_status_paddr); +hinic_hwif_write_reg (hwif, addr, val); +} + +/** +* api_cmd_set_num_cells - set the number cells of a chain in the HW +* @chain: the API CMD specific chain to set in HW the number of cells for +**/ +static void api_cmd_set_num_cells (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +u32 addr, val; + + addr =HINIC_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR (chain->chain_type); + val = chain->num_cells; +hinic_hwif_write_reg (hwif, addr, val); +} + +/** +* api_cmd_head_init - set the head of a chain in the HW +* @chain: the API CMD specific chain to set in HW the head for +**/ +static void api_cmd_head_init (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +u32 addr, val; + + addr =HINIC_CSR_API_CMD_CHAIN_HEAD_HI_ADDR (chain->chain_type); + val =upper_32_bits (chain->head_cell_paddr); +hinic_hwif_write_reg (hwif, addr, val); + + addr =HINIC_CSR_API_CMD_CHAIN_HEAD_LO_ADDR (chain->chain_type); + val =lower_32_bits (chain->head_cell_paddr); +hinic_hwif_write_reg (hwif, addr, val); +} + +/** +* api_cmd_chain_hw_clean - clean the HW +* @chain: the API CMD specific chain +**/ +static void api_cmd_chain_hw_clean (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +u32 addr, ctrl; + + addr =HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR (chain->chain_type); + + ctrl =hinic_hwif_read_reg (hwif, addr); + ctrl =HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,RESTART_WB_STAT ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,XOR_ERR ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,AEQE_EN ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,XOR_CHK_EN ) & +HINIC_API_CMD_CHAIN_CTRL_CLEAR (ctrl,CELL_SIZE ); + +hinic_hwif_write_reg (hwif, addr, ctrl); +} +/** * api_cmd_chain_hw_init - initialize the chain in the HW * @chain: the API CMD specific chain to initialize in HW
@@ -44,7 +198,23 @@**/ static int api_cmd_chain_hw_init (struct hinic_api_cmd_chain *chain) { -/* should be implemented */ +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; +int err; + +api_cmd_chain_hw_clean (chain); + +api_cmd_set_status_addr (chain); + + err =api_cmd_hw_restart (chain); +if (err) { +dev_err (&pdev->dev,"Failed to restart API CMD HW\n" ); +return err; + } + +api_cmd_ctrl_init (chain); +api_cmd_set_num_cells (chain); +api_cmd_head_init (chain);return 0 ; }
@@ -374,6 +544,7 @@ static int api_cmd_create_chain(struct hinic_api_cmd_chain **cmd_chain,**/ static void api_cmd_destroy_chain (struct hinic_api_cmd_chain *chain) { +api_cmd_chain_hw_clean (chain);api_cmd_destroy_cells (chain, chain->num_cells);api_chain_free (chain); }
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h +38 -0
@@ -20,6 +20,44 @@#include "hinic_hw_if.h" +#define HINIC_API_CMD_CHAIN_REQ_RESTART_SHIFT 1 + +#define HINIC_API_CMD_CHAIN_REQ_RESTART_MASK 0x1 + +#define HINIC_API_CMD_CHAIN_REQ_SET (val, member) \ + (((u32)(val) & HINIC_API_CMD_CHAIN_REQ_##member##_MASK) << \ + HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT) + +#define HINIC_API_CMD_CHAIN_REQ_GET (val, member) \ + (((val) >> HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT) & \ + HINIC_API_CMD_CHAIN_REQ_##member##_MASK) + +#define HINIC_API_CMD_CHAIN_REQ_CLEAR (val, member) \ + ((val) & (~(HINIC_API_CMD_CHAIN_REQ_##member##_MASK \ + << HINIC_API_CMD_CHAIN_REQ_##member##_SHIFT))) + +#define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_SHIFT 1 +#define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_SHIFT 2 +#define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_SHIFT 4 +#define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_SHIFT 8 +#define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_SHIFT 28 +#define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_SHIFT 30 + +#define HINIC_API_CMD_CHAIN_CTRL_RESTART_WB_STAT_MASK 0x1 +#define HINIC_API_CMD_CHAIN_CTRL_XOR_ERR_MASK 0x1 +#define HINIC_API_CMD_CHAIN_CTRL_AEQE_EN_MASK 0x1 +#define HINIC_API_CMD_CHAIN_CTRL_AEQ_ID_MASK 0x3 +#define HINIC_API_CMD_CHAIN_CTRL_XOR_CHK_EN_MASK 0x3 +#define HINIC_API_CMD_CHAIN_CTRL_CELL_SIZE_MASK 0x3 + +#define HINIC_API_CMD_CHAIN_CTRL_SET (val, member) \ + (((u32)(val) & HINIC_API_CMD_CHAIN_CTRL_##member##_MASK) << \ + HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT) + +#define HINIC_API_CMD_CHAIN_CTRL_CLEAR (val, member) \ + ((val) & (~(HINIC_API_CMD_CHAIN_CTRL_##member##_MASK \ + << HINIC_API_CMD_CHAIN_CTRL_##member##_SHIFT))) +enum hinic_api_cmd_chain_type {HINIC_API_CMD_WRITE_TO_MGMT_CPU =2 ,
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h +25 -0
@@ -33,4 +33,29 @@#define HINIC_CSR_PPF_ELECTION_ADDR (idx) \ (HINIC_ELECTION_BASE + (idx) * HINIC_PPF_ELECTION_STRIDE) +/* API CMD registers */ +#define HINIC_CSR_API_CMD_BASE 0xF000 + +#define HINIC_CSR_API_CMD_STRIDE 0x100 + +#define HINIC_CSR_API_CMD_CHAIN_HEAD_HI_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x0 + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_CHAIN_HEAD_LO_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x4 + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_STATUS_HI_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x8 + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_STATUS_LO_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0xC + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_CHAIN_NUM_CELLS_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x10 + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x14 + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_CHAIN_REQ_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x20 + (idx) * HINIC_CSR_API_CMD_STRIDE)#endif
Signature · 1 line
1.9.1
PATCH v2 5/21 net-next/hinic: Add management messages
In reply to Aviad KrawczykAdd the management messages for sending to api cmd and the asynchronous event handler for the completion of the messages.
--- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c | 35 ++ .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 3 + drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 5 + drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 441 ++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 59 +++ 5 files changed, 540 insertions(+), 3 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +35 -0
@@ -53,6 +53,41 @@ enum api_cmd_xor_chk_level { };/** +* api_cmd - API CMD command +* @chain: chain for the command +* @dest: destination node on the card that will receive the command +* @cmd: command data +* @size: the command size +* +* Return 0 - Success, negative - Failure +**/ +static int api_cmd (struct hinic_api_cmd_chain *chain, +enum hinic_node_id dest,void *cmd,u16 cmd_size) +{ +/* should be implemented */ +return -EINVAL ; +} + +/** +* hinic_api_cmd_write - Write API CMD command +* @chain: chain for write command +* @dest: destination node on the card that will receive the command +* @cmd: command data +* @size: the command size +* +* Return 0 - Success, negative - Failure +**/ +int hinic_api_cmd_write (struct hinic_api_cmd_chain *chain, +enum hinic_node_id dest,void *cmd,u16 size) +{ +/* Verify the chain type */ +if (chain->chain_type ==HINIC_API_CMD_WRITE_TO_MGMT_CPU ) +return api_cmd (chain, dest, cmd, size); + +return -EINVAL ; +} + +/** * api_cmd_hw_restart - restart the chain in the HW * @chain: the API CMD specific chain to restart *
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h +3 -0
@@ -132,6 +132,9 @@ struct hinic_api_cmd_chain {struct hinic_api_cmd_cell *curr_node; }; +int hinic_api_cmd_write (struct hinic_api_cmd_chain *chain, +enum hinic_node_id dest,void *cmd,u16 size); +int hinic_api_cmd_init (struct hinic_hwif *hwif,struct hinic_api_cmd_chain **chain);
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +5 -0
@@ -93,6 +93,7 @@#define HINIC_HWIF_NUM_IRQS (hwif) ((hwif)->attr.num_irqs)#define HINIC_HWIF_GLOB_IDX (hwif) ((hwif)->attr.func_global_idx)#define HINIC_HWIF_PCI_INTF (hwif) ((hwif)->attr.pci_intf_idx) +#define HINIC_HWIF_PF_IDX (hwif) ((hwif)->attr.pf_idx)#define HINIC_FUNC_TYPE (hwif) ((hwif)->attr.func_type)#define HINIC_IS_PF (hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF)
@@ -127,6 +128,10 @@ enum hinic_mod_type {HINIC_MOD_MAX =15 }; +enum hinic_node_id { +HINIC_NODE_ID_MGMT =21 , +}; +struct hinic_func_attr {u16 func_global_idx;u8 pf_idx;
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +438 -3
474 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +59 -0
78 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 6/21 net-next/hinic: Add api cmd commands
In reply to Aviad KrawczykAdd the api cmd commands for sending management messages to the nic.
--- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.c | 331 ++++++++++++++++++++- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 65 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 7 + 3 files changed, 401 insertions(+), 2 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +329 -2
@@ -24,7 +24,9 @@#include <linux/jiffies.h> #include <linux/delay.h> #include <linux/log2.h> +#include <linux/semaphore.h> #include <asm/byteorder.h> +#include <asm/barrier.h> #include "hinic_hw_csr.h" #include "hinic_hw_if.h"
@@ -44,14 +46,314 @@#define API_CMD_BUF_SIZE 2048 +/* Sizes of the members in hinic_api_cmd_cell */ +#define API_CMD_CELL_DESC_SIZE 8 +#define API_CMD_CELL_DATA_ADDR_SIZE 8 + +#define API_CMD_CELL_ALIGNMENT 8 +#define API_CMD_TIMEOUT 1000 +#define MASKED_IDX (chain, idx) ((idx) & ((chain)->num_cells - 1)) + +#define SIZE_8BYTES (size) (ALIGN((size), 8) >> 3) +#define SIZE_4BYTES (size) (ALIGN((size), 4) >> 2) + +#define RD_DMA_ATTR_DEFAULT 0 +#define WR_DMA_ATTR_DEFAULT 0 + +enum api_cmd_data_format { +SGE_DATA =1 ,/* cell data is passed by hw address */ +}; + +enum api_cmd_type { +API_CMD_WRITE =0 , +}; + +enum api_cmd_bypass { +NO_BYPASS =0 , +BYPASS =1 , +}; +enum api_cmd_xor_chk_level {XOR_CHK_DIS =0 ,XOR_CHK_ALL =3 , }; +static u8 xor_chksum_set (void *data) +{ +int idx; +u8 *val, checksum =0 ; + + val = data; + +for (idx =0 ; idx <7 ; idx++) + checksum ^= val[idx]; + +return checksum; +} + +static void set_prod_idx (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +enum hinic_api_cmd_chain_type chain_type = chain->chain_type; +u32 hw_prod_idx_addr =HINIC_CSR_API_CMD_CHAIN_PI_ADDR (chain_type); +u32 prod_idx; + + prod_idx =hinic_hwif_read_reg (hwif, hw_prod_idx_addr); + + prod_idx =HINIC_API_CMD_PI_CLEAR (prod_idx,IDX ); + + prod_idx |=HINIC_API_CMD_PI_SET (chain->prod_idx,IDX ); + +hinic_hwif_write_reg (hwif, hw_prod_idx_addr, prod_idx); +} + +static u32 get_hw_cons_idx (struct hinic_api_cmd_chain *chain) +{ +u32 addr, val; + + addr =HINIC_CSR_API_CMD_STATUS_ADDR (chain->chain_type); + val =hinic_hwif_read_reg (chain->hwif, addr); + +return HINIC_API_CMD_STATUS_GET (val,CONS_IDX ); +} + +/** +* chain_busy - check if the chain is still processing last requests +* @chain: chain to check +* +* Return 0 - Success, negative - Failure +**/ +static int chain_busy (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; +u32 prod_idx; + +switch (chain->chain_type) { +case HINIC_API_CMD_WRITE_TO_MGMT_CPU : + chain->cons_idx =get_hw_cons_idx (chain); + prod_idx = chain->prod_idx; + +/* check for a space for a new command */ +if (chain->cons_idx ==MASKED_IDX (chain, prod_idx +1 )) { +dev_err (&pdev->dev,"API CMD chain %d is busy\n" , + chain->chain_type); +return -EBUSY ; + } +break ; + +default : +dev_err (&pdev->dev,"Unknown API CMD Chain type\n" ); +break ; + } + +return 0 ; +} + +/** +* get_cell_data_size - get the data size of a specific cell type +* @type: chain type +* +* Return the data(Desc + Address) size in the cell +**/ +static u8 get_cell_data_size (enum hinic_api_cmd_chain_type type) +{ +u8 cell_data_size =0 ; + +switch (type) { +case HINIC_API_CMD_WRITE_TO_MGMT_CPU : + cell_data_size =ALIGN (API_CMD_CELL_DESC_SIZE + +API_CMD_CELL_DATA_ADDR_SIZE , +API_CMD_CELL_ALIGNMENT ); +break ; +default : +break ; + } + +return cell_data_size; +} + +/** +* prepare_cell_ctrl - prepare the ctrl of the cell for the command +* @cell_ctrl: the control of the cell to set the control value into it +* @data_size: the size of the data in the cell +**/ +static void prepare_cell_ctrl (u64 *cell_ctrl,u16 data_size) +{ +u64 ctrl; +u8 chksum; + + ctrl =HINIC_API_CMD_CELL_CTRL_SET (SIZE_8BYTES (data_size),DATA_SZ ) | +HINIC_API_CMD_CELL_CTRL_SET (RD_DMA_ATTR_DEFAULT ,RD_DMA_ATTR ) | +HINIC_API_CMD_CELL_CTRL_SET (WR_DMA_ATTR_DEFAULT ,WR_DMA_ATTR ); + + chksum =xor_chksum_set (&ctrl); + + ctrl |=HINIC_API_CMD_CELL_CTRL_SET (chksum,XOR_CHKSUM ); + +/* The data in the HW should be in Big Endian Format */ + *cell_ctrl =cpu_to_be64 (ctrl); +} + +/** +* prepare_api_cmd - prepare API CMD command +* @chain: chain for the command +* @cell: the cell of the command +* @dest: destination node on the card that will receive the command +* @cmd: command data +* @cmd_size: the command size +**/ +static void prepare_api_cmd (struct hinic_api_cmd_chain *chain, +struct hinic_api_cmd_cell *cell, +enum hinic_node_id dest, +void *cmd,u16 cmd_size) +{ +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_api_cmd_cell_ctxt *cell_ctxt; + + cell_ctxt = &chain->cell_ctxt[chain->prod_idx]; + +switch (chain->chain_type) { +case HINIC_API_CMD_WRITE_TO_MGMT_CPU : + cell->desc =HINIC_API_CMD_DESC_SET (SGE_DATA ,API_TYPE ) | +HINIC_API_CMD_DESC_SET (API_CMD_WRITE ,RD_WR ) | +HINIC_API_CMD_DESC_SET (NO_BYPASS ,MGMT_BYPASS ); +break ; + +default : +dev_err (&pdev->dev,"unknown Chain type\n" ); +return ; + } + + cell->desc |=HINIC_API_CMD_DESC_SET (dest,DEST ) | +HINIC_API_CMD_DESC_SET (SIZE_4BYTES (cmd_size),SIZE ); + + cell->desc |=HINIC_API_CMD_DESC_SET (xor_chksum_set (&cell->desc), +XOR_CHKSUM ); + +/* The data in the HW should be in Big Endian Format */ + cell->desc =cpu_to_be64 (cell->desc); + +memcpy (cell_ctxt->api_cmd_vaddr, cmd, cmd_size); +} + +/** +* prepare_cell - prepare cell ctrl and cmd in the current cell +* @chain: chain for the command +* @dest: destination node on the card that will receive the command +* @cmd: command data +* @cmd_size: the command size +* +* Return 0 - Success, negative - Failure +**/ +static void prepare_cell (struct hinic_api_cmd_chain *chain, +enum hinic_node_id dest, +void *cmd,u16 cmd_size) +{ +struct hinic_api_cmd_cell *curr_node = chain->curr_node; +u16 data_size =get_cell_data_size (chain->chain_type); + +prepare_cell_ctrl (&curr_node->ctrl, data_size); +prepare_api_cmd (chain, curr_node, dest, cmd, cmd_size); +} + +static inline void cmd_chain_prod_idx_inc (struct hinic_api_cmd_chain *chain) +{ + chain->prod_idx =MASKED_IDX (chain, chain->prod_idx +1 ); +} + +/** +* api_cmd_status_update - update the status in the chain struct +* @chain: chain to update +**/ +static void api_cmd_status_update (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_api_cmd_status *wb_status; +enum hinic_api_cmd_chain_type chain_type; +u64 status_header; +u32 status; + + wb_status = chain->wb_status; + status_header =be64_to_cpu (wb_status->header); + + status =be32_to_cpu (wb_status->status); +if (HINIC_API_CMD_STATUS_GET (status,CHKSUM_ERR )) { +dev_err (&pdev->dev,"API CMD status: Xor check error\n" ); +return ; + } + + chain_type =HINIC_API_CMD_STATUS_HEADER_GET (status_header,CHAIN_ID ); +if (chain_type >=HINIC_API_CMD_MAX ) { +dev_err (&pdev->dev,"unknown API CMD Chain %d\n" , chain_type); +return ; + } + + chain->cons_idx =HINIC_API_CMD_STATUS_GET (status,CONS_IDX ); +} + +/** +* wait_for_status_poll - wait for write to api cmd command to complete +* @chain: the chain of the command +* +* Return 0 - Success, negative - Failure +**/ +static int wait_for_status_poll (struct hinic_api_cmd_chain *chain) +{ +unsigned long end; +int err = -ETIMEDOUT ; + + end = jiffies +msecs_to_jiffies (API_CMD_TIMEOUT ); +do { +api_cmd_status_update (chain); + +/* wait for CI to be updated - sign for completion */ +if (chain->cons_idx == chain->prod_idx) { + err =0 ; +break ; + } + +msleep (20 ); + }while (time_before (jiffies, end)); + +return err; +} + +/** +* wait_for_api_cmd_completion - wait for command to complete +* @chain: chain for the command +* +* Return 0 - Success, negative - Failure +**/ +static int wait_for_api_cmd_completion (struct hinic_api_cmd_chain *chain) +{ +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; +int err; + +switch (chain->chain_type) { +case HINIC_API_CMD_WRITE_TO_MGMT_CPU : + err =wait_for_status_poll (chain); +if (err) { +dev_err (&pdev->dev,"API CMD Poll status timeout\n" ); +break ; + } +break ; + +default : +dev_err (&pdev->dev,"unknown API CMD Chain type\n" ); + err = -EINVAL ; +break ; + } + +return err; +} +/** * api_cmd - API CMD command * @chain: chain for the command
@@ -64,8 +366,31 @@ enum api_cmd_xor_chk_level {static int api_cmd (struct hinic_api_cmd_chain *chain,enum hinic_node_id dest,void *cmd,u16 cmd_size) { -/* should be implemented */ -return -EINVAL ; +struct hinic_api_cmd_cell_ctxt *ctxt; +int err; + +down (&chain->sem); +if (chain_busy (chain)) { +up (&chain->sem); +return -EBUSY ; + } + +prepare_cell (chain, dest, cmd, cmd_size); +cmd_chain_prod_idx_inc (chain); + +wmb ();/* inc pi before issue the command */ + +set_prod_idx (chain);/* issue the command */ + + ctxt = &chain->cell_ctxt[chain->prod_idx]; + + chain->curr_node = ctxt->cell_vaddr; + + err =wait_for_api_cmd_completion (chain); + +up (&chain->sem); + +return err; }/**
@@ -490,6 +815,8 @@ static int api_chain_init(struct hinic_api_cmd_chain *chain, chain->prod_idx =0 ; chain->cons_idx =0 ; +sema_init (&chain->sem,1 ); + cell_ctxt_size = chain->num_cells *sizeof (*chain->cell_ctxt); chain->cell_ctxt =devm_kzalloc (&pdev->dev, cell_ctxt_size,GFP_KERNEL );if (!chain->cell_ctxt)
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.h +65 -0
86 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h +7 -0
@@ -56,6 +56,13 @@#define HINIC_CSR_API_CMD_CHAIN_CTRL_ADDR (idx) \ (HINIC_CSR_API_CMD_BASE + 0x14 + (idx) * HINIC_CSR_API_CMD_STRIDE) +#define HINIC_CSR_API_CMD_CHAIN_PI_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x1C + (idx) * HINIC_CSR_API_CMD_STRIDE) +#define HINIC_CSR_API_CMD_CHAIN_REQ_ADDR (idx) \ (HINIC_CSR_API_CMD_BASE + 0x20 + (idx) * HINIC_CSR_API_CMD_STRIDE) + +#define HINIC_CSR_API_CMD_STATUS_ADDR (idx) \ + (HINIC_CSR_API_CMD_BASE + 0x30 + (idx) * HINIC_CSR_API_CMD_STRIDE) +#endif
Signature · 1 line
1.9.1
PATCH v2 7/21 net-next/hinic: Add aeqs
In reply to Aviad KrawczykHandle aeq elements that are accumulated on the aeq by calling the registered handler for the specific event.
--- drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 49 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c | 454 ++++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 81 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 92 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 58 ++- 5 files changed, 726 insertions(+), 8 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h +49 -0
@@ -65,4 +65,53 @@#define HINIC_CSR_API_CMD_STATUS_ADDR (idx) \ (HINIC_CSR_API_CMD_BASE + 0x30 + (idx) * HINIC_CSR_API_CMD_STRIDE) +/* MSI-X registers */ +#define HINIC_CSR_MSIX_CTRL_BASE 0x2000 +#define HINIC_CSR_MSIX_CNT_BASE 0x2004 + +#define HINIC_CSR_MSIX_STRIDE 0x8 + +#define HINIC_CSR_MSIX_CTRL_ADDR (idx) \ + (HINIC_CSR_MSIX_CTRL_BASE + (idx) * HINIC_CSR_MSIX_STRIDE) + +#define HINIC_CSR_MSIX_CNT_ADDR (idx) \ + (HINIC_CSR_MSIX_CNT_BASE + (idx) * HINIC_CSR_MSIX_STRIDE) + +/* EQ registers */ +#define HINIC_AEQ_MTT_OFF_BASE_ADDR 0x200 + +#define HINIC_EQ_MTT_OFF_STRIDE 0x40 + +#define HINIC_CSR_AEQ_MTT_OFF (id) \ + (HINIC_AEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE) + +#define HINIC_CSR_EQ_PAGE_OFF_STRIDE 8 + +#define HINIC_CSR_AEQ_HI_PHYS_ADDR_REG (q_id, pg_num) \ + (HINIC_CSR_AEQ_MTT_OFF(q_id) + \ + (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE) + +#define HINIC_CSR_AEQ_LO_PHYS_ADDR_REG (q_id, pg_num) \ + (HINIC_CSR_AEQ_MTT_OFF(q_id) + \ + (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE + 4) + +#define HINIC_AEQ_CTRL_0_ADDR_BASE 0xE00 +#define HINIC_AEQ_CTRL_1_ADDR_BASE 0xE04 +#define HINIC_AEQ_CONS_IDX_ADDR_BASE 0xE08 +#define HINIC_AEQ_PROD_IDX_ADDR_BASE 0xE0C + +#define HINIC_EQ_OFF_STRIDE 0x80 + +#define HINIC_CSR_AEQ_CTRL_0_ADDR (idx) \ + (HINIC_AEQ_CTRL_0_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) + +#define HINIC_CSR_AEQ_CTRL_1_ADDR (idx) \ + (HINIC_AEQ_CTRL_1_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) + +#define HINIC_CSR_AEQ_CONS_IDX_ADDR (idx) \ + (HINIC_AEQ_CONS_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) + +#define HINIC_CSR_AEQ_PROD_IDX_ADDR (idx) \ + (HINIC_AEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c +452 -2
490 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h +81 -0
95 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.c +92 -0
98 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +52 -6
83 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 8/21 net-next/hinic: Add port management commands
In reply to Aviad KrawczykAdd the port management commands that are sent as management messages. The port management commands are used for netdev operations.
--- drivers/net/ethernet/huawei/hinic/Makefile | 4 +- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 4 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 30 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 29 +++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 201 ++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_port.c | 241 +++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 68 +++++++ 7 files changed, 574 insertions(+), 3 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_port.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_port.h
drivers/net/ethernet/huawei/hinic/Makefile +2 -2
@@ -1,4 +1,4 @@ obj-$(CONFIG_HINIC) += hinic.o -hinic-y := hinic_main.o hinic_hw_dev.o hinic_hw_mgmt.o hinic_hw_api_cmd.o \ - hinic_hw_eqs.o hinic_hw_if.o +hinic-y := hinic_main.o hinic_port.o hinic_hw_dev.o hinic_hw_mgmt.o \ + hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_dev.h +4 -0
@@ -18,6 +18,7 @@#include <linux/netdevice.h> #include <linux/types.h> +#include <linux/semaphore.h> #include "hinic_hw_dev.h"
@@ -28,6 +29,9 @@ struct hinic_dev {struct hinic_hwdev *hwdev;u32 msg_enable; + +struct semaphore mgmt_lock; + unsigned long *vlan_bitmap; };#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +30 -0
@@ -202,6 +202,36 @@ static void disable_msix(struct hinic_hwdev *hwdev) }/** +* hinic_port_msg_cmd - send port msg to mgmt +* @hwdev: the NIC HW device +* @cmd: the port command +* @buf_in: input buffer +* @in_size: input size +* @buf_out: output buffer +* @out_size: returned output size +* +* Return 0 - Success, negative - Failure +**/ +int hinic_port_msg_cmd (struct hinic_hwdev *hwdev,enum hinic_port_cmd cmd, +void *buf_in,u16 in_size,void *buf_out,u16 *out_size) +{ +struct hinic_pfhwdev *pfhwdev; +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; + +if (!HINIC_IS_PF (hwif) && !HINIC_IS_PPF (hwif)) { +dev_err (&pdev->dev,"unsupported PCI Function type\n" ); +return -EINVAL ; + } + + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); + +return hinic_msg_to_mgmt (&pfhwdev->pf_to_mgmt,HINIC_MOD_L2NIC , cmd, + buf_in, in_size, buf_out, out_size, +HINIC_MGMT_MSG_SYNC ); +} + +/** * init_pfhwdev - Initialize the extended components of PF * @pfhwdev: the HW device for PF *
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +29 -0
@@ -30,6 +30,31 @@ struct hinic_cap {u16 num_qps; }; +enum hinic_port_cmd { +HINIC_PORT_CMD_CHANGE_MTU =2 , + +HINIC_PORT_CMD_ADD_VLAN =3 , +HINIC_PORT_CMD_DEL_VLAN =4 , + +HINIC_PORT_CMD_SET_MAC =9 , +HINIC_PORT_CMD_GET_MAC =10 , +HINIC_PORT_CMD_DEL_MAC =11 , + +HINIC_PORT_CMD_SET_RX_MODE =12 , + +HINIC_PORT_CMD_GET_LINK_STATE =24 , + +HINIC_PORT_CMD_SET_PORT_STATE =41 , + +HINIC_PORT_CMD_FWCTXT_INIT =69 , + +HINIC_PORT_CMD_SET_FUNC_STATE =93 , + +HINIC_PORT_CMD_GET_GLOBAL_QPN =102 , + +HINIC_PORT_CMD_GET_CAP =170 , +}; +struct hinic_hwdev {struct hinic_hwif *hwif;struct msix_entry *msix_entries;
@@ -45,6 +70,10 @@ struct hinic_pfhwdev {struct hinic_pf_to_mgmt pf_to_mgmt; }; +int hinic_port_msg_cmd (struct hinic_hwdev *hwdev,enum hinic_port_cmd cmd, +void *buf_in,u16 in_size,void *buf_out, +u16 *out_size); +int hinic_init_hwdev (struct hinic_hwdev **hwdev,struct pci_dev *pdev);void hinic_free_hwdev (struct hinic_hwdev *hwdev);
drivers/net/ethernet/huawei/hinic/hinic_main.c +200 -1
240 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.c new file +241 -0
241 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.h new file +68 -0
68 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 9/21 net-next/hinic: Add Rx mode and link event handler
In reply to Aviad KrawczykAdd port management message for setting Rx mode in the card, used for rx_mode netdev operation. The link event handler is used for getting a notification about the link state.
--- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 17 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 2 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 120 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 63 ++++- drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 17 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 17 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 69 +++++- drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 28 +++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 285 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_port.c | 101 ++++++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 66 +++++ 11 files changed, 767 insertions(+), 18 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_dev.h +17 -0
@@ -19,19 +19,36 @@#include <linux/netdevice.h> #include <linux/types.h> #include <linux/semaphore.h> +#include <linux/workqueue.h> +#include <linux/bitops.h> #include "hinic_hw_dev.h" #define HINIC_DRV_NAME "HiNIC" +enum hinic_flags { +HINIC_LINK_UP =BIT (0 ), +HINIC_INTF_UP =BIT (1 ), +}; + +struct hinic_rx_mode_work { +struct work_struct work; +u32 rx_mode; +}; +struct hinic_dev {struct net_device *netdev;struct hinic_hwdev *hwdev;u32 msg_enable; +unsigned int flags; +struct semaphore mgmt_lock;unsigned long *vlan_bitmap; + +struct hinic_rx_mode_work rx_mode_work; +struct workqueue_struct *workq; };#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h +2 -0
@@ -20,6 +20,8 @@#define HINIC_CSR_FUNC_ATTR0_ADDR 0x0#define HINIC_CSR_FUNC_ATTR1_ADDR 0x4 +#define HINIC_CSR_FUNC_ATTR5_ADDR 0x14 +#define HINIC_DMA_ATTR_BASE 0xC80#define HINIC_ELECTION_BASE 0x4200
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +120 -0
138 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +50 -13
102 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.c +17 -0
@@ -118,6 +118,23 @@ int hinic_msix_attr_cnt_clear(struct hinic_hwif *hwif, u16 msix_index) }/** +* hinic_set_pf_action - set action on pf channel +* @hwif: the HW interface of a pci function device +* @action: action on pf channel +* +* Return 0 - Success, negative - Failure +**/ +void hinic_set_pf_action (struct hinic_hwif *hwif,enum hinic_pf_action action) +{ +u32 attr5 =hinic_hwif_read_reg (hwif,HINIC_CSR_FUNC_ATTR5_ADDR ); + + attr5 =HINIC_FA5_CLEAR (attr5,PF_ACTION ); + attr5 |=HINIC_FA5_SET (action,PF_ACTION ); + +hinic_hwif_write_reg (hwif,HINIC_CSR_FUNC_ATTR5_ADDR , attr5); +} + +/** * hwif_ready - test if the HW is ready for use * @hwif: the HW interface of a pci function device *
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +17 -0
@@ -73,6 +73,15 @@#define HINIC_FA1_GET (val, member) \ (((val) >> HINIC_FA1_##member##_SHIFT) & HINIC_FA1_##member##_MASK) +#define HINIC_FA5_PF_ACTION_SHIFT 0 +#define HINIC_FA5_PF_ACTION_MASK 0xFFFF + +#define HINIC_FA5_SET (val, member) \ + (((u32)(val) & HINIC_FA5_##member##_MASK) << HINIC_FA5_##member##_SHIFT) + +#define HINIC_FA5_CLEAR (val, member) \ + ((val) & (~(HINIC_FA5_##member##_MASK << HINIC_FA5_##member##_SHIFT))) +#define HINIC_PPF_ELECTION_IDX_SHIFT 0#define HINIC_PPF_ELECTION_IDX_MASK 0x1F
@@ -166,6 +175,12 @@ enum hinic_node_id { HINIC_NODE_ID_MGMT = 21, }; +enum hinic_pf_action { +HINIC_PF_MGMT_INIT =0x0 , + +HINIC_PF_MGMT_ACTIVE =0x11 , +}; +struct hinic_func_attr {u16 func_global_idx;u8 pf_idx;
@@ -212,6 +227,8 @@ int hinic_msix_attr_get(struct hinic_hwif *hwif, u16 msix_index,int hinic_msix_attr_cnt_clear (struct hinic_hwif *hwif,u16 msix_index); +void hinic_set_pf_action (struct hinic_hwif *hwif,enum hinic_pf_action action); +int hinic_init_hwif (struct hinic_hwif *hwif,struct pci_dev *pdev);void hinic_free_hwif (struct hinic_hwif *hwif);
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +65 -4
90 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +28 -0
@@ -19,6 +19,7 @@#include <linux/types.h> #include <linux/semaphore.h> #include <linux/completion.h> +#include <linux/bitops.h> #include "hinic_hw_if.h" #include "hinic_hw_api_cmd.h"
@@ -67,6 +68,11 @@ enum hinic_cfg_cmd { HINIC_CFG_NIC_CAP = 0, }; +enum hinic_mgmt_cb_state { +HINIC_MGMT_CB_ENABLED =BIT (0 ), +HINIC_MGMT_CB_RUNNING =BIT (1 ), +}; +struct hinic_recv_msg {void *msg;void *buf_out;
@@ -81,6 +87,15 @@ struct hinic_recv_msg {u16 msg_id; }; +struct hinic_mgmt_cb { +void (*cb)(void *handle,u8 cmd, +void *buf_in,u16 in_size, +void *buf_out,u16 *out_size); + +void *handle; +unsigned long state; +}; +struct hinic_pf_to_mgmt {struct hinic_hwif *hwif;
@@ -92,8 +107,21 @@ struct hinic_pf_to_mgmt {struct hinic_recv_msg recv_msg_from_mgmt;struct hinic_api_cmd_chain *cmd_chain[HINIC_API_CMD_MAX ]; + +struct hinic_mgmt_cb mgmt_cb[HINIC_MOD_MAX ]; }; +void hinic_register_mgmt_msg_cb (struct hinic_pf_to_mgmt *pf_to_mgmt, +enum hinic_mod_type mod, +void *handle, +void (*callback)(void *handle, +u8 cmd,void *buf_in, +u16 in_size,void *buf_out, +u16 *out_size)); + +void hinic_unregister_mgmt_msg_cb (struct hinic_pf_to_mgmt *pf_to_mgmt, +enum hinic_mod_type mod); + int hinic_msg_to_mgmt(struct hinic_pf_to_mgmt *pf_to_mgmt, enum hinic_mod_type mod, u8 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size,
drivers/net/ethernet/huawei/hinic/hinic_main.c +284 -1
384 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.c +101 -0
104 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.h +66 -0
85 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 10/21 net-next/hinic: Add logical Txq and Rxq
In reply to Aviad KrawczykCreate the logical queues of the nic.
--- drivers/net/ethernet/huawei/hinic/Makefile | 5 +- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 5 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 133 ++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 20 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 144 +++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 46 ++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 32 +++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 172 ++++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 72 ++++++++++ drivers/net/ethernet/huawei/hinic/hinic_rx.h | 46 ++++++ drivers/net/ethernet/huawei/hinic/hinic_tx.c | 75 ++++++++++ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 49 +++++++ 12 files changed, 795 insertions(+), 4 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_io.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_io.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_rx.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_rx.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_tx.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_tx.h
drivers/net/ethernet/huawei/hinic/Makefile +3 -2
@@ -1,4 +1,5 @@ obj-$(CONFIG_HINIC) += hinic.o -hinic-y := hinic_main.o hinic_port.o hinic_hw_dev.o hinic_hw_mgmt.o \ - hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o +hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ + hinic_hw_io.o hinic_hw_mgmt.o hinic_hw_api_cmd.o hinic_hw_eqs.o \ + hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_dev.h +5 -0
@@ -23,6 +23,8 @@#include <linux/bitops.h> #include "hinic_hw_dev.h" +#include "hinic_tx.h" +#include "hinic_rx.h" #define HINIC_DRV_NAME "HiNIC"
@@ -49,6 +51,9 @@ struct hinic_dev {struct hinic_rx_mode_work rx_mode_work;struct workqueue_struct *workq; + +struct hinic_txq *txqs; + struct hinic_rxq *rxqs; };#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +133 -0
148 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +20 -0
@@ -23,6 +23,8 @@#include "hinic_hw_if.h" #include "hinic_hw_eqs.h" #include "hinic_hw_mgmt.h" +#include "hinic_hw_qp.h" +#include "hinic_hw_io.h" #define HINIC_MAX_QPS 32
@@ -72,11 +74,21 @@ enum hinic_cb_state { HINIC_CB_RUNNING = BIT(1), }; +struct hinic_cmd_base_qpn { +u8 status; +u8 version; +u8 rsvd0[6 ]; + +u16 func_idx; +u16 qpn; +}; +struct hinic_hwdev {struct hinic_hwif *hwif;struct msix_entry *msix_entries;struct hinic_aeqs aeqs; +struct hinic_func_to_io func_to_io;struct hinic_cap nic_cap; };
@@ -111,10 +123,18 @@ int hinic_port_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_port_cmd cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size); +int hinic_hwdev_ifup (struct hinic_hwdev *hwdev); + +void hinic_hwdev_ifdown (struct hinic_hwdev *hwdev); +int hinic_init_hwdev (struct hinic_hwdev **hwdev,struct pci_dev *pdev);void hinic_free_hwdev (struct hinic_hwdev *hwdev);int hinic_hwdev_num_qps (struct hinic_hwdev *hwdev); +struct hinic_sq *hinic_hwdev_get_sq (struct hinic_hwdev *hwdev,int i); + +struct hinic_rq *hinic_hwdev_get_rq (struct hinic_hwdev *hwdev,int i); +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c new file +144 -0
144 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h new file +46 -0
46 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h new file +32 -0
@@ -0,0 +1,32 @@ +/* +* Huawei HiNIC PCI Express Linux driver +* Copyright(c) 2017 Huawei Technologies Co., Ltd +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +* +*/ + +#ifndef HINIC_HW_QP_H +#define HINIC_HW_QP_H + +struct hinic_sq { +/* should be implemented */ +}; + +struct hinic_rq { +/* should be implemented */ +}; + +struct hinic_qp { +struct hinic_sq sq; +struct hinic_rq rq; +}; + +#endif
drivers/net/ethernet/huawei/hinic/hinic_main.c +170 -2
218 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_rx.c new file +72 -0
72 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_rx.h new file +46 -0
46 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_tx.c new file +75 -0
75 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_tx.h new file +49 -0
49 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 11/21 net-next/hinic: Add wq
In reply to Aviad KrawczykCreate work queues for being used by the queue pairs.
--- drivers/net/ethernet/huawei/hinic/Makefile | 4 +- drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 68 ++- drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 6 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 17 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 523 ++++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 86 ++++ 6 files changed, 699 insertions(+), 5 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h
drivers/net/ethernet/huawei/hinic/Makefile +2 -2
@@ -1,5 +1,5 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ - hinic_hw_io.o hinic_hw_mgmt.o hinic_hw_api_cmd.o hinic_hw_eqs.o \ - hinic_hw_if.o + hinic_hw_io.o hinic_hw_wq.o hinic_hw_mgmt.o hinic_hw_api_cmd.o \ + hinic_hw_eqs.o hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c +65 -3
125 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +6 -0
@@ -20,11 +20,17 @@#include <linux/pci.h> #include "hinic_hw_if.h" +#include "hinic_hw_wq.h" #include "hinic_hw_qp.h" struct hinic_func_to_io {struct hinic_hwif *hwif; +struct hinic_wqs wqs; + +struct hinic_wq *sq_wq; +struct hinic_wq *rq_wq; +struct hinic_qp *qps;u16 max_qps; };
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +17 -0
@@ -16,6 +16,21 @@#ifndef HINIC_HW_QP_H #define HINIC_HW_QP_H +#include <linux/types.h> +#include <linux/sizes.h> + +#define HINIC_SQ_WQEBB_SIZE 64 +#define HINIC_RQ_WQEBB_SIZE 32 + +#define HINIC_SQ_PAGE_SIZE SZ_4K +#define HINIC_RQ_PAGE_SIZE SZ_4K + +#define HINIC_SQ_DEPTH SZ_4K +#define HINIC_RQ_DEPTH SZ_4K + +#define HINIC_SQ_WQE_MAX_SIZE 320 +#define HINIC_RQ_WQE_SIZE 32 +struct hinic_sq {/* should be implemented */ };
@@ -27,6 +42,8 @@ struct hinic_rq {struct hinic_qp {struct hinic_sq sq;struct hinic_rq rq; + +u16 q_id; };#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c new file +523 -0
523 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h new file +86 -0
86 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v2 12/21 net-next/hinic: Add qp resources
In reply to Aviad KrawczykCreate the resources for queue pair operations: doorbell area, consumer index address and producer index address.
--- drivers/net/ethernet/huawei/hinic/Makefile | 4 +- drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 167 ++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 27 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 264 ++++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 60 +++++- 6 files changed, 518 insertions(+), 5 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c
drivers/net/ethernet/huawei/hinic/Makefile +2 -2
@@ -1,5 +1,5 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ - hinic_hw_io.o hinic_hw_wq.o hinic_hw_mgmt.o hinic_hw_api_cmd.o \ - hinic_hw_eqs.o hinic_hw_if.o + hinic_hw_io.o hinic_hw_qp.o hinic_hw_wq.o hinic_hw_mgmt.o \ + hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +1 -0
@@ -137,6 +137,7 @@#define HINIC_IS_PPF (hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PPF)#define HINIC_PCI_CFG_REGS_BAR 0 +#define HINIC_PCI_DB_BAR 4#define HINIC_PCIE_ST_DISABLE 0#define HINIC_PCIE_AT_DISABLE 0
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c +166 -1
245 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +27 -0
@@ -18,11 +18,30 @@#include <linux/types.h> #include <linux/pci.h> +#include <linux/semaphore.h> +#include <linux/sizes.h> #include "hinic_hw_if.h" #include "hinic_hw_wq.h" #include "hinic_hw_qp.h" +#define HINIC_DB_PAGE_SIZE SZ_4K +#define HINIC_DB_SIZE SZ_4M + +#define HINIC_DB_MAX_AREAS (HINIC_DB_SIZE / HINIC_DB_PAGE_SIZE) + +struct hinic_free_db_area { +int db_idx[HINIC_DB_MAX_AREAS ]; + +int alloc_pos; +int return_pos; + +int num_free; + +/* Lock for getting db area */ +struct semaphore idx_lock; +}; +struct hinic_func_to_io {struct hinic_hwif *hwif;
@@ -33,6 +52,14 @@ struct hinic_func_to_io {struct hinic_qp *qps;u16 max_qps; + +void __iomem **sq_db; +void __iomem *db_base; + +void *ci_addr_base; +dma_addr_t ci_dma_base; + +struct hinic_free_db_area free_db_area; }; int hinic_io_create_qps(struct hinic_func_to_io *func_to_io,
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c new file +264 -0
264 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +58 -2
80 lines not on this page · raw message
Signature · 1 line
1.9.1
David Miller
maintainerRe: [PATCH V2 net-next 12/21] net-next/hinic: Add qp resources
From: Aviad Krawczyk <[email protected]>
Date: Wed, 19 Jul 2017 17:19:10 +0800
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/Makefile +0
-0
drivers/net/ethernet/huawei/hinic/Makefile line 5
Quoted 9 lines
drivers/net/ethernet/huawei/hinic/Makefile +2
-2@@ -1,5 +1,5 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ - hinic_hw_io.o hinic_hw_wq.o hinic_hw_mgmt.o hinic_hw_api_cmd.o \ - hinic_hw_eqs.o hinic_hw_if.o + hinic_hw_io.o hinic_hw_qp.o hinic_hw_wq.o hinic_hw_mgmt.o \ + hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o
Please add the missing newline to the end of this Makefile so that these patches don't keep emitting this message.
Re: [PATCH V2 net-next 12/21] net-next/hinic: Add qp resources
Hi David,
Strange that checkpatch.pl --strict didn't warn about it. We will fix it.
Thanks for review,
Aviad
Quoted 23 lines · David Miller
From: Aviad Krawczyk <[email protected]>
Date: Wed, 19 Jul 2017 17:19:10 +0800Quoted 5 lines
drivers/net/ethernet/huawei/hinic/Makefile +0
-0drivers/net/ethernet/huawei/hinic/Makefile line 5
Quoted 9 lines
drivers/net/ethernet/huawei/hinic/Makefile +2
-2@@ -1,5 +1,5 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ - hinic_hw_io.o hinic_hw_wq.o hinic_hw_mgmt.o hinic_hw_api_cmd.o \ - hinic_hw_eqs.o hinic_hw_if.o + hinic_hw_io.o hinic_hw_qp.o hinic_hw_wq.o hinic_hw_mgmt.o \ + hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.oPlease add the missing newline to the end of this
Makefileso that these patches don't keep emitting this message..
PATCH v2 13/21 net-next/hinic: Set qp context
In reply to Aviad KrawczykUpdate the nic about the resources of the queue pairs.
--- drivers/net/ethernet/huawei/hinic/Makefile | 5 +- drivers/net/ethernet/huawei/hinic/hinic_common.c | 55 ++++++ drivers/net/ethernet/huawei/hinic/hinic_common.h | 23 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 87 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 84 ++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 4 + drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 153 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 5 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 161 ++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 11 ++ .../net/ethernet/huawei/hinic/hinic_hw_qp_ctxt.h | 214 +++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 9 + 12 files changed, 809 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_common.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_common.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_hw_qp_ctxt.h
drivers/net/ethernet/huawei/hinic/Makefile +3 -2
@@ -1,5 +1,6 @@ obj-$(CONFIG_HINIC) += hinic.o hinic-y := hinic_main.o hinic_tx.o hinic_rx.o hinic_port.o hinic_hw_dev.o \ - hinic_hw_io.o hinic_hw_qp.o hinic_hw_wq.o hinic_hw_mgmt.o \ - hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o + hinic_hw_io.o hinic_hw_qp.o hinic_hw_cmdq.o hinic_hw_wq.o \ + hinic_hw_mgmt.o hinic_hw_api_cmd.o hinic_hw_eqs.o hinic_hw_if.o \ + hinic_common.o
drivers/net/ethernet/huawei/hinic/hinic_common.c new file +55 -0
55 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_common.h new file +23 -0
@@ -0,0 +1,23 @@ +/* +* Huawei HiNIC PCI Express Linux driver +* Copyright(c) 2017 Huawei Technologies Co., Ltd +* +* This program is free software; you can redistribute it and/or modify it +* under the terms and conditions of the GNU General Public License, +* version 2, as published by the Free Software Foundation. +* +* This program is distributed in the hope it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* for more details. +* +*/ + +#ifndef HINIC_COMMON_H +#define HINIC_COMMON_H + +void hinic_cpu_to_be32 (void *data,int len); + +void hinic_be32_to_cpu (void *data,int len); + +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c new file +87 -0
87 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h new file +84 -0
84 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +4 -0
@@ -24,6 +24,7 @@#include "hinic_hw_if.h" #include "hinic_hw_eqs.h" #include "hinic_hw_mgmt.h" +#include "hinic_hw_qp_ctxt.h" #include "hinic_hw_qp.h" #include "hinic_hw_io.h" #include "hinic_hw_dev.h"
@@ -76,6 +77,9 @@ static int get_capability(struct hinic_hwdev *hwdev,/* Each QP has its own (SQ + RQ) interrupts */ num_qps = (num_irqs - (num_aeqs + num_ceqs)) /2 ; +if (num_qps >HINIC_Q_CTXT_MAX ) + num_qps =HINIC_Q_CTXT_MAX ; +/* num_qps must be power of 2 */ num_qps =BIT (fls (num_qps) -1 );
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c +153 -0
199 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +5 -0
@@ -23,6 +23,7 @@#include "hinic_hw_if.h" #include "hinic_hw_wq.h" +#include "hinic_hw_cmdq.h" #include "hinic_hw_qp.h" #define HINIC_DB_PAGE_SIZE SZ_4K
@@ -60,6 +61,10 @@ struct hinic_func_to_io {dma_addr_t ci_dma_base;struct hinic_free_db_area free_db_area; + +void __iomem *cmdq_db_area[HINIC_MAX_CMDQ_TYPES ]; + +struct hinic_cmdqs cmdqs; }; int hinic_io_create_qps(struct hinic_func_to_io *func_to_io,
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c +161 -0
174 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +11 -0
@@ -22,6 +22,7 @@#include "hinic_hw_if.h" #include "hinic_hw_wq.h" +#include "hinic_hw_qp_ctxt.h" #define HINIC_SQ_WQEBB_SIZE 64#define HINIC_RQ_WQEBB_SIZE 32
@@ -91,6 +92,16 @@ struct hinic_qp {u16 q_id; }; +void hinic_qp_prepare_header (struct hinic_qp_ctxt_header *qp_ctxt_hdr, +enum hinic_qp_ctxt_type ctxt_type, +int num_queues,int max_queues); + +void hinic_sq_prepare_ctxt (struct hinic_sq *sq,u16 global_qid, +struct hinic_sq_ctxt *sq_ctxt); + +void hinic_rq_prepare_ctxt (struct hinic_rq *rq,u16 global_qid, +struct hinic_rq_ctxt *rq_ctxt); +int hinic_init_sq (struct hinic_sq *sq,struct hinic_hwif *hwif,struct hinic_wq *wq,struct msix_entry *entry,void *ci_addr,dma_addr_t ci_dma_addr,void __iomem *db_base);
drivers/net/ethernet/huawei/hinic/hinic_hw_qp_ctxt.h new file +214 -0
214 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h +9 -0
@@ -72,6 +72,15 @@ struct hinic_wqs {struct semaphore alloc_blocks_lock; }; +struct hinic_cmdq_pages { +/* The addresses are 64 bit in the HW */ +u64 page_paddr; +u64 *page_vaddr; +void **shadow_page_vaddr; + +struct hinic_hwif *hwif; +}; +int hinic_wqs_alloc (struct hinic_wqs *wqs,int num_wqs,struct hinic_hwif *hwif);
Signature · 1 line
1.9.1
PATCH v2 14/21 net-next/hinic: Initialize cmdq
In reply to Aviad KrawczykCreate the work queues for cmdq and update the nic about the work queue contexts. cmdq commands are used for updating the the nic about the qp contexts.
--- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 284 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 53 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 2 + drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 5 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 157 ++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 8 + 6 files changed, 503 insertions(+), 6 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +278 -6
@@ -13,11 +13,49 @@* */ +#include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> +#include <linux/pci.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <linux/spinlock.h> +#include <linux/sizes.h> +#include <linux/atomic.h> +#include <linux/log2.h> +#include <asm/byteorder.h> #include "hinic_hw_if.h" +#include "hinic_hw_mgmt.h" +#include "hinic_hw_wq.h" #include "hinic_hw_cmdq.h" +#include "hinic_hw_io.h" +#include "hinic_hw_dev.h" + +#define CMDQ_DB_OFF SZ_2K + +#define CMDQ_WQEBB_SIZE 64 +#define CMDQ_DEPTH SZ_4K + +#define CMDQ_WQ_PAGE_SIZE SZ_4K + +#define WQE_LCMD_SIZE 64 +#define WQE_SCMD_SIZE 64 + +#define CMDQ_PFN (addr, page_size) ((addr) >> (ilog2(page_size))) + +#define cmdq_to_cmdqs (cmdq) container_of((cmdq) - (cmdq)->cmdq_type, \ + struct hinic_cmdqs, cmdq[0]) + +#define cmdqs_to_func_to_io (cmdqs) container_of(cmdqs, \ + struct hinic_func_to_io, \ + cmdqs) + +enum cmdq_wqe_type { +WQE_LCMD_TYPE , +WQE_SCMD_TYPE , +};/** * hinic_alloc_cmdq_buf - alloc buffer for sending command
@@ -29,8 +67,17 @@int hinic_alloc_cmdq_buf (struct hinic_cmdqs *cmdqs,struct hinic_cmdq_buf *cmdq_buf) { -/* should be implemented */ -return -ENOMEM ; +struct hinic_hwif *hwif = cmdqs->hwif; +struct pci_dev *pdev = hwif->pdev; + + cmdq_buf->buf =pci_pool_alloc (cmdqs->cmdq_buf_pool,GFP_KERNEL , + &cmdq_buf->dma_addr); +if (!cmdq_buf->buf) { +dev_err (&pdev->dev,"Failed to allocate cmd from the pool\n" ); +return -ENOMEM ; + } + +return 0 ; }/**
@@ -41,7 +88,7 @@ int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,void hinic_free_cmdq_buf (struct hinic_cmdqs *cmdqs,struct hinic_cmdq_buf *cmdq_buf) { -/* should be implemented */ +pci_pool_free (cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr); }/**
@@ -63,6 +110,172 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, }/** +* cmdq_init_queue_ctxt - init the queue ctxt of a cmdq +* @cmdq: the cmdq +* @cmdq_pages: the memory of the queue +* @cmdq_ctxt: returned cmdq ctxt +**/ +static void cmdq_init_queue_ctxt (struct hinic_cmdq *cmdq, +struct hinic_cmdq_pages *cmdq_pages, +struct hinic_cmdq_ctxt *cmdq_ctxt) +{ +struct hinic_cmdqs *cmdqs =cmdq_to_cmdqs (cmdq); +struct hinic_hwif *hwif = cmdqs->hwif; +struct hinic_wq *wq = cmdq->wq; +struct hinic_cmdq_ctxt_info *ctxt_info = &cmdq_ctxt->ctxt_info; +u16 start_ci =atomic_read (&wq->cons_idx); +u64 wq_first_page_paddr, cmdq_first_block_paddr, pfn; + +/* The data in the HW is in Big Endian Format */ + wq_first_page_paddr =be64_to_cpu (*wq->block_vaddr); + + pfn =CMDQ_PFN (wq_first_page_paddr, wq->wq_page_size); + + ctxt_info->curr_wqe_page_pfn = +HINIC_CMDQ_CTXT_PAGE_INFO_SET (pfn,CURR_WQE_PAGE_PFN ) | +HINIC_CMDQ_CTXT_PAGE_INFO_SET (HINIC_CEQ_ID_CMDQ ,EQ_ID ) | +HINIC_CMDQ_CTXT_PAGE_INFO_SET (1 ,CEQ_ARM ) | +HINIC_CMDQ_CTXT_PAGE_INFO_SET (1 ,CEQ_EN ) | +HINIC_CMDQ_CTXT_PAGE_INFO_SET (cmdq->wrapped,WRAPPED ); + +/* block PFN - Read Modify Write */ + cmdq_first_block_paddr = cmdq_pages->page_paddr; + + pfn =CMDQ_PFN (cmdq_first_block_paddr, wq->wq_page_size); + + ctxt_info->wq_block_pfn = +HINIC_CMDQ_CTXT_BLOCK_INFO_SET (pfn,WQ_BLOCK_PFN ) | +HINIC_CMDQ_CTXT_BLOCK_INFO_SET (start_ci,CI ); + + cmdq_ctxt->func_idx =HINIC_HWIF_GLOB_IDX (hwif); + cmdq_ctxt->cmdq_type = cmdq->cmdq_type; +} + +/** +* init_cmdq - initialize cmdq +* @cmdq: the cmdq +* @wq: the wq attaced to the cmdq +* @q_type: the cmdq type of the cmdq +* @db_area: doorbell area for the cmdq +* +* Return 0 - Success, negative - Failure +**/ +static int init_cmdq (struct hinic_cmdq *cmdq,struct hinic_wq *wq, +enum hinic_cmdq_type q_type,void __iomem *db_area) +{ +int err; + + cmdq->wq = wq; + cmdq->cmdq_type = q_type; + cmdq->wrapped =1 ; + +spin_lock_init (&cmdq->cmdq_lock); + + cmdq->done =vzalloc (wq->q_depth *sizeof (*cmdq->done)); +if (!cmdq->done) +return -ENOMEM ; + + cmdq->errcode =vzalloc (wq->q_depth *sizeof (*cmdq->errcode)); +if (!cmdq->errcode) { + err = -ENOMEM ; + goto errcode_err; + } + + cmdq->db_base = db_area +CMDQ_DB_OFF ; +return 0 ; + +errcode_err: +vfree (cmdq->done); +return err; +} + +/** +* free_cmdq - Free cmdq +* @cmdq: the cmdq to free +**/ +static void free_cmdq (struct hinic_cmdq *cmdq) +{ +vfree (cmdq->errcode); +vfree (cmdq->done); +} + +/** +* init_cmdqs_ctxt - write the cmdq ctxt to HW after init all cmdq +* @hwdev: the NIC HW device +* @cmdqs: cmdqs to write the ctxts for +* &db_area: db_area for all the cmdqs +* +* Return 0 - Success, negative - Failure +**/ +static int init_cmdqs_ctxt (struct hinic_hwdev *hwdev, +struct hinic_cmdqs *cmdqs,void __iomem **db_area) +{ +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_pfhwdev *pfhwdev; +struct hinic_cmdq_ctxt *cmdq_ctxts; +enum hinic_cmdq_type type, cmdq_type; +size_t cmdq_ctxts_size; +int err; + +if (!HINIC_IS_PF (hwif) && !HINIC_IS_PPF (hwif)) { +dev_err (&pdev->dev,"Unsupported PCI function type\n" ); +return -EINVAL ; + } + + cmdq_ctxts_size =HINIC_MAX_CMDQ_TYPES *sizeof (*cmdq_ctxts); + cmdq_ctxts =devm_kzalloc (&pdev->dev, cmdq_ctxts_size,GFP_KERNEL ); +if (!cmdq_ctxts) +return -ENOMEM ; + + pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); + + cmdq_type =HINIC_CMDQ_SYNC ; +for (; cmdq_type <HINIC_MAX_CMDQ_TYPES ; cmdq_type++) { + err =init_cmdq (&cmdqs->cmdq[cmdq_type], + &cmdqs->saved_wqs[cmdq_type], cmdq_type, + db_area[cmdq_type]); +if (err) { +dev_err (&pdev->dev,"Failed to initialize cmdq\n" ); +devm_kfree (&pdev->dev, cmdq_ctxts); + goto init_cmdq_err; + } + +cmdq_init_queue_ctxt (&cmdqs->cmdq[cmdq_type], + &cmdqs->cmdq_pages, + &cmdq_ctxts[cmdq_type]); + } + +/* Write the CMDQ ctxts */ + cmdq_type =HINIC_CMDQ_SYNC ; +for (; cmdq_type <HINIC_MAX_CMDQ_TYPES ; cmdq_type++) { + err =hinic_msg_to_mgmt (&pfhwdev->pf_to_mgmt,HINIC_MOD_COMM , +HINIC_COMM_CMD_CMDQ_CTXT_SET , + &cmdq_ctxts[cmdq_type], +sizeof (cmdq_ctxts[cmdq_type]), +NULL ,NULL ,HINIC_MGMT_MSG_SYNC ); +if (err) { +dev_err (&pdev->dev,"Failed to set CMDQ CTXT type = %d\n" , + cmdq_type); +devm_kfree (&pdev->dev, cmdq_ctxts); + goto write_cmdq_ctxt_err; + } + } + +devm_kfree (&pdev->dev, cmdq_ctxts); +return 0 ; + +write_cmdq_ctxt_err: + cmdq_type =HINIC_MAX_CMDQ_TYPES ; + +init_cmdq_err: +for (type =HINIC_CMDQ_SYNC ; type < cmdq_type; type++) +free_cmdq (&cmdqs->cmdq[type]); + +return err; +} + +/** * hinic_init_cmdqs - init all cmdqs * @cmdqs: cmdqs to init * @hwif: HW interface for accessing cmdqs
@@ -73,8 +286,54 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs,int hinic_init_cmdqs (struct hinic_cmdqs *cmdqs,struct hinic_hwif *hwif,void __iomem **db_area) { -/* should be implemented */ -return -EINVAL ; +struct hinic_func_to_io *func_to_io =cmdqs_to_func_to_io (cmdqs); + struct hinic_hwdev *hwdev = container_of(func_to_io, struct hinic_hwdev, + func_to_io); +struct pci_dev *pdev = hwif->pdev; +size_t saved_wqs_size, max_wqe_size; +int err; + + cmdqs->hwif = hwif; + cmdqs->cmdq_buf_pool =pci_pool_create ("hinic_cmdq" , pdev, +HINIC_CMDQ_BUF_SIZE , +HINIC_CMDQ_BUF_SIZE ,0 ); +if (!cmdqs->cmdq_buf_pool) +return -ENOMEM ; + + saved_wqs_size =HINIC_MAX_CMDQ_TYPES *sizeof (struct hinic_wq ); + cmdqs->saved_wqs =devm_kzalloc (&pdev->dev, saved_wqs_size,GFP_KERNEL ); +if (!cmdqs->saved_wqs) { + err = -ENOMEM ; + goto saved_wqs_err; + } + + max_wqe_size =WQE_LCMD_SIZE ; + err =hinic_wqs_cmdq_alloc (&cmdqs->cmdq_pages, cmdqs->saved_wqs, hwif, +HINIC_MAX_CMDQ_TYPES ,CMDQ_WQEBB_SIZE , +CMDQ_WQ_PAGE_SIZE ,CMDQ_DEPTH , max_wqe_size); +if (err) { +dev_err (&pdev->dev,"Failed to allocate CMDQ wqs\n" ); + goto cmdq_wqs_error; + } + + err =init_cmdqs_ctxt (hwdev, cmdqs, db_area); +if (err) { +dev_err (&pdev->dev,"Failed to write cmdq ctxt\n" ); + goto cmdq_ctxt_err; + } + +return 0 ; + +cmdq_ctxt_err: +hinic_wqs_cmdq_free (&cmdqs->cmdq_pages, cmdqs->saved_wqs, +HINIC_MAX_CMDQ_TYPES ); + +cmdq_wqs_error: +devm_kfree (&pdev->dev, cmdqs->saved_wqs); + +saved_wqs_err: +pci_pool_destroy (cmdqs->cmdq_buf_pool); +return err; }/**
@@ -83,5 +342,18 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,**/ void hinic_free_cmdqs (struct hinic_cmdqs *cmdqs) { -/* should be implemented */ +struct hinic_hwif *hwif = cmdqs->hwif; +struct pci_dev *pdev = hwif->pdev; +enum hinic_cmdq_type cmdq_type; + + cmdq_type =HINIC_CMDQ_SYNC ; +for (; cmdq_type <HINIC_MAX_CMDQ_TYPES ; cmdq_type++) +free_cmdq (&cmdqs->cmdq[cmdq_type]); + +hinic_wqs_cmdq_free (&cmdqs->cmdq_pages, cmdqs->saved_wqs, +HINIC_MAX_CMDQ_TYPES ); + +devm_kfree (&pdev->dev, cmdqs->saved_wqs); + +pci_pool_destroy (cmdqs->cmdq_buf_pool); }
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h +53 -0
65 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h +2 -0
@@ -106,6 +106,8 @@#define HINIC_EQ_PAGE_SIZE SZ_4K +#define HINIC_CEQ_ID_CMDQ 0 +enum hinic_eq_type {HINIC_AEQ , };
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +5 -0
@@ -68,6 +68,11 @@ enum hinic_cfg_cmd { HINIC_CFG_NIC_CAP = 0, }; +enum hinic_comm_cmd { +HINIC_COMM_CMD_CMDQ_CTXT_SET =0x10 , +HINIC_COMM_CMD_CMDQ_CTXT_GET =0x11 , +}; +enum hinic_mgmt_cb_state {HINIC_MGMT_CB_ENABLED =BIT (0 ),HINIC_MGMT_CB_RUNNING =BIT (1 ),
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +157 -0
184 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h +8 -0
@@ -81,6 +81,14 @@ struct hinic_cmdq_pages {struct hinic_hwif *hwif; }; +int hinic_wqs_cmdq_alloc (struct hinic_cmdq_pages *cmdq_pages, +struct hinic_wq *wq,struct hinic_hwif *hwif, +int cmdq_blocks,u16 wqebb_size,u16 wq_page_size, +u16 q_depth,u16 max_wqe_size); + +void hinic_wqs_cmdq_free (struct hinic_cmdq_pages *cmdq_pages, +struct hinic_wq *wq,int cmdq_blocks); +int hinic_wqs_alloc (struct hinic_wqs *wqs,int num_wqs,struct hinic_hwif *hwif);
Signature · 1 line
1.9.1
PATCH v2 15/21 net-next/hinic: Add ceqs
In reply to Aviad KrawczykInitialize the completion event queues and handle ceq events by calling the registered handlers. Used for cmdq command completion.
--- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 17 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 29 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 7 +- drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c | 290 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 75 ++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 15 +- drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 3 + 7 files changed, 428 insertions(+), 8 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +17 -0
@@ -27,6 +27,7 @@#include <asm/byteorder.h> #include "hinic_hw_if.h" +#include "hinic_hw_eqs.h" #include "hinic_hw_mgmt.h" #include "hinic_hw_wq.h" #include "hinic_hw_cmdq.h"
@@ -110,6 +111,16 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, }/** +* cmdq_ceq_handler - cmdq completion event handler +* @handle: private data for the handler(cmdqs) +* @ceqe_data: ceq element data +**/ +static void cmdq_ceq_handler (void *handle,u32 ceqe_data) +{ +/* should be implemented */ +} + +/** * cmdq_init_queue_ctxt - init the queue ctxt of a cmdq * @cmdq: the cmdq * @cmdq_pages: the memory of the queue
@@ -322,6 +333,9 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, goto cmdq_ctxt_err; } +hinic_ceq_register_cb (&func_to_io->ceqs,HINIC_CEQ_CMDQ , cmdqs, + cmdq_ceq_handler); +return 0 ; cmdq_ctxt_err:
@@ -342,10 +356,13 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,**/ void hinic_free_cmdqs (struct hinic_cmdqs *cmdqs) { +struct hinic_func_to_io *func_to_io =cmdqs_to_func_to_io (cmdqs);struct hinic_hwif *hwif = cmdqs->hwif;struct pci_dev *pdev = hwif->pdev;enum hinic_cmdq_type cmdq_type; +hinic_ceq_unregister_cb (&func_to_io->ceqs,HINIC_CEQ_CMDQ ); + cmdq_type =HINIC_CMDQ_SYNC ;for (; cmdq_type <HINIC_MAX_CMDQ_TYPES ; cmdq_type++)free_cmdq (&cmdqs->cmdq[cmdq_type]);
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h +29 -0
@@ -81,27 +81,44 @@/* EQ registers */ #define HINIC_AEQ_MTT_OFF_BASE_ADDR 0x200 +#define HINIC_CEQ_MTT_OFF_BASE_ADDR 0x400#define HINIC_EQ_MTT_OFF_STRIDE 0x40#define HINIC_CSR_AEQ_MTT_OFF (id) \ (HINIC_AEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE) +#define HINIC_CSR_CEQ_MTT_OFF (id) \ + (HINIC_CEQ_MTT_OFF_BASE_ADDR + (id) * HINIC_EQ_MTT_OFF_STRIDE) +#define HINIC_CSR_EQ_PAGE_OFF_STRIDE 8#define HINIC_CSR_AEQ_HI_PHYS_ADDR_REG (q_id, pg_num) \ (HINIC_CSR_AEQ_MTT_OFF(q_id) + \ (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE) +#define HINIC_CSR_CEQ_HI_PHYS_ADDR_REG (q_id, pg_num) \ + (HINIC_CSR_CEQ_MTT_OFF(q_id) + \ + (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE) +#define HINIC_CSR_AEQ_LO_PHYS_ADDR_REG (q_id, pg_num) \ (HINIC_CSR_AEQ_MTT_OFF(q_id) + \ (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE + 4) +#define HINIC_CSR_CEQ_LO_PHYS_ADDR_REG (q_id, pg_num) \ + (HINIC_CSR_CEQ_MTT_OFF(q_id) + \ + (pg_num) * HINIC_CSR_EQ_PAGE_OFF_STRIDE + 4) +#define HINIC_AEQ_CTRL_0_ADDR_BASE 0xE00#define HINIC_AEQ_CTRL_1_ADDR_BASE 0xE04#define HINIC_AEQ_CONS_IDX_ADDR_BASE 0xE08#define HINIC_AEQ_PROD_IDX_ADDR_BASE 0xE0C +#define HINIC_CEQ_CTRL_0_ADDR_BASE 0x1000 +#define HINIC_CEQ_CTRL_1_ADDR_BASE 0x1004 +#define HINIC_CEQ_CONS_IDX_ADDR_BASE 0x1008 +#define HINIC_CEQ_PROD_IDX_ADDR_BASE 0x100C +#define HINIC_EQ_OFF_STRIDE 0x80#define HINIC_CSR_AEQ_CTRL_0_ADDR (idx) \
@@ -116,4 +133,16 @@#define HINIC_CSR_AEQ_PROD_IDX_ADDR (idx) \ (HINIC_AEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) +#define HINIC_CSR_CEQ_CTRL_0_ADDR (idx) \ + (HINIC_CEQ_CTRL_0_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) + +#define HINIC_CSR_CEQ_CTRL_1_ADDR (idx) \ + (HINIC_CEQ_CTRL_1_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) + +#define HINIC_CSR_CEQ_CONS_IDX_ADDR (idx) \ + (HINIC_CEQ_CONS_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) + +#define HINIC_CSR_CEQ_PROD_IDX_ADDR (idx) \ + (HINIC_CEQ_PROD_IDX_ADDR_BASE + (idx) * HINIC_EQ_OFF_STRIDE) +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +6 -1
@@ -281,6 +281,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)struct pci_dev *pdev = hwif->pdev;int num_qps = nic_cap->num_qps;int max_qps = nic_cap->max_qps; +struct msix_entry *ceq_msix_entries;struct msix_entry *sq_msix_entries;struct msix_entry *rq_msix_entries;u16 base_qpn;
@@ -294,7 +295,11 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev) num_aeqs =HINIC_HWIF_NUM_AEQS (hwif); num_ceqs =HINIC_HWIF_NUM_CEQS (hwif); - err =hinic_io_init (func_to_io, hwif, max_qps,0 ,NULL ); + + ceq_msix_entries = &hwdev->msix_entries[num_aeqs]; + + err =hinic_io_init (func_to_io, hwif, max_qps, num_ceqs, + ceq_msix_entries);if (err) {dev_err (&pdev->dev,"Failed to init IO channel\n" );return err;
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c +284 -6
394 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h +75 -0
135 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c +14 -1
@@ -24,6 +24,7 @@#include <linux/io.h> #include "hinic_hw_if.h" +#include "hinic_hw_eqs.h" #include "hinic_hw_wq.h" #include "hinic_hw_cmdq.h" #include "hinic_hw_qp_ctxt.h"
@@ -462,10 +463,18 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io, func_to_io->qps =NULL ; func_to_io->max_qps = max_qps; + err =hinic_ceqs_init (&func_to_io->ceqs, hwif, num_ceqs, +HINIC_DEFAULT_CEQ_LEN ,HINIC_EQ_PAGE_SIZE , + ceq_msix_entries); +if (err) { +dev_err (&pdev->dev,"Failed to init CEQs\n" ); +return err; + } + err =hinic_wqs_alloc (&func_to_io->wqs,2 * max_qps, hwif);if (err) {dev_err (&pdev->dev,"Failed to allocate WQS for IO\n" ); -return err; + goto wqs_alloc_err; } func_to_io->db_base =pci_ioremap_bar (pdev,HINIC_PCI_DB_BAR );
@@ -503,6 +512,9 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io, db_ioremap_err:hinic_wqs_free (&func_to_io->wqs); + +wqs_alloc_err: +hinic_ceqs_free (&func_to_io->ceqs);return err; }
@@ -521,4 +533,5 @@ void hinic_io_free(struct hinic_func_to_io *func_to_io)iounmap (func_to_io->db_base);hinic_wqs_free (&func_to_io->wqs); +hinic_ceqs_free (&func_to_io->ceqs); }
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +3 -0
@@ -22,6 +22,7 @@#include <linux/sizes.h> #include "hinic_hw_if.h" +#include "hinic_hw_eqs.h" #include "hinic_hw_wq.h" #include "hinic_hw_cmdq.h" #include "hinic_hw_qp.h"
@@ -46,6 +47,8 @@ struct hinic_free_db_area {struct hinic_func_to_io {struct hinic_hwif *hwif; +struct hinic_ceqs ceqs; +struct hinic_wqs wqs;struct hinic_wq *sq_wq;
Signature · 1 line
1.9.1
PATCH v2 16/21 net-next/hinic: Add cmdq commands
In reply to Aviad KrawczykAdd cmdq commands for setting queue pair contexts in the nic.
--- drivers/net/ethernet/huawei/hinic/hinic_common.c | 25 ++ drivers/net/ethernet/huawei/hinic/hinic_common.h | 15 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 284 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 153 ++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 9 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 193 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 8 + 7 files changed, 685 insertions(+), 2 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_common.c +25 -0
@@ -13,6 +13,7 @@* */ +#include <linux/kernel.h> #include <linux/types.h> #include <asm/byteorder.h>
@@ -53,3 +54,27 @@ void hinic_be32_to_cpu(void *data, int len) mem++; } } + +/** +* hinic_set_sge - set dma area in scatter gather entry +* @sge: scatter gather entry +* @addr: dma address +* @len: length of relevant data in the dma address +**/ +void hinic_set_sge (struct hinic_sge *sge,dma_addr_t addr,int len) +{ + sge->hi_addr =upper_32_bits (addr); + sge->lo_addr =lower_32_bits (addr); + sge->len = len; +} + +/** +* hinic_sge_to_dma - get dma address from scatter gather entry +* @sge: scatter gather entry +* +* Return dma address of sg entry +**/ +dma_addr_t hinic_sge_to_dma (struct hinic_sge *sge) +{ +return (dma_addr_t)((((u64 )sge->hi_addr) <<32 ) | sge->lo_addr); +}
drivers/net/ethernet/huawei/hinic/hinic_common.h +15 -0
@@ -16,8 +16,23 @@#ifndef HINIC_COMMON_H #define HINIC_COMMON_H +#include <linux/types.h> + +#define UPPER_8_BITS (data) (((data) >> 8) & 0xFF) +#define LOWER_8_BITS (data) ((data) & 0xFF) + +struct hinic_sge { +u32 hi_addr; +u32 lo_addr; +u32 len; +}; +void hinic_cpu_to_be32 (void *data,int len);void hinic_be32_to_cpu (void *data,int len); +void hinic_set_sge (struct hinic_sge *sge,dma_addr_t addr,int len); + +dma_addr_t hinic_sge_to_dma (struct hinic_sge *sge); +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +282 -2
325 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h +153 -0
179 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +9 -0
@@ -32,6 +32,15 @@#define HINIC_DB_MAX_AREAS (HINIC_DB_SIZE / HINIC_DB_PAGE_SIZE) +enum hinic_db_type { +HINIC_DB_CMDQ_TYPE , +HINIC_DB_SQ_TYPE , +}; + +enum hinic_io_path { +HINIC_CTRL_PATH , +}; +struct hinic_free_db_area {int db_idx[HINIC_DB_MAX_AREAS ];
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +193 -0
202 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h +8 -0
@@ -100,4 +100,12 @@ int hinic_wq_allocate(struct hinic_wqs *wqs, struct hinic_wq *wq,void hinic_wq_free (struct hinic_wqs *wqs,struct hinic_wq *wq); +void *hinic_get_wqe (struct hinic_wq *wq,unsigned int wqe_size,u16 *prod_idx); + +void hinic_put_wqe (struct hinic_wq *wq,unsigned int wqe_size); + +void *hinic_read_wqe (struct hinic_wq *wq,unsigned int wqe_size,u16 *cons_idx); + +void hinic_write_wqe (struct hinic_wq *wq,void *wqe,unsigned int wqe_size); +#endif
Signature · 1 line
1.9.1
PATCH v2 17/21 net-next/hinic: Add cmdq completion handler
In reply to Aviad KrawczykAdd cmdq completion handler for getting a notification about the completion of cmdq commands.
--- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 286 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 12 + 2 files changed, 297 insertions(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +285 -1
@@ -38,12 +38,31 @@#include "hinic_hw_io.h" #include "hinic_hw_dev.h" +#define CMDQ_CEQE_TYPE_SHIFT 0 + +#define CMDQ_CEQE_TYPE_MASK 0x7 + +#define CMDQ_CEQE_GET (val, member) \ + (((val) >> CMDQ_CEQE_##member##_SHIFT) \ + & CMDQ_CEQE_##member##_MASK) + +#define CMDQ_WQE_ERRCODE_VAL_SHIFT 20 + +#define CMDQ_WQE_ERRCODE_VAL_MASK 0xF + +#define CMDQ_WQE_ERRCODE_GET (val, member) \ + (((val) >> CMDQ_WQE_ERRCODE_##member##_SHIFT) \ + & CMDQ_WQE_ERRCODE_##member##_MASK) +#define CMDQ_DB_PI_OFF (pi) (((u16)LOWER_8_BITS(pi)) << 3)#define CMDQ_DB_ADDR (db_base, pi) ((db_base) + CMDQ_DB_PI_OFF(pi))#define CMDQ_WQE_HEADER (wqe) ((struct hinic_cmdq_header *)(wqe)) +#define CMDQ_WQE_COMPLETED (ctrl_info) \ + HINIC_CMDQ_CTRL_GET(ctrl_info, HW_BUSY_BIT) +#define FIRST_DATA_TO_WRITE_LAST sizeof(u64)#define CMDQ_DB_OFF SZ_2K
@@ -109,6 +128,9 @@ enum completion_request { CEQ_SET, }; +static void clear_wqe_complete_bit (struct hinic_cmdq *cmdq, +struct hinic_cmdq_wqe *wqe); +/** * hinic_alloc_cmdq_buf - alloc buffer for sending command * @cmdqs: the cmdqs
@@ -143,6 +165,22 @@ void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs,pci_pool_free (cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr); } +static int cmdq_wqe_size_from_bdlen (enum bufdesc_len len) +{ +int wqe_size =0 ; + +switch (len) { +case BUFDESC_LCMD_LEN : + wqe_size =WQE_LCMD_SIZE ; +break ; +case BUFDESC_SCMD_LEN : + wqe_size =WQE_SCMD_SIZE ; +break ; + } + +return wqe_size; +} +static void cmdq_set_sge_completion (struct hinic_cmdq_completion *completion,struct hinic_cmdq_buf *buf_out) {
@@ -209,6 +247,15 @@ static void cmdq_set_lcmd_bufdesc(struct hinic_cmdq_wqe_lcmd *wqe_lcmd,hinic_set_sge (&wqe_lcmd->buf_desc.sge, buf_in->dma_addr, buf_in->size); } +static void cmdq_set_direct_wqe_data (struct hinic_cmdq_direct_wqe *wqe, +void *buf_in,u32 in_size) +{ +struct hinic_cmdq_wqe_scmd *wqe_scmd = &wqe->wqe_scmd; + + wqe_scmd->buf_desc.buf_len = in_size; +memcpy (wqe_scmd->buf_desc.data, buf_in, in_size); +} + static void cmdq_set_lcmd_wqe(struct hinic_cmdq_wqe *wqe, enum cmdq_cmd_type cmd_type, struct hinic_cmdq_buf *buf_in,
@@ -237,6 +284,34 @@ static void cmdq_set_lcmd_wqe(struct hinic_cmdq_wqe *wqe,cmdq_set_lcmd_bufdesc (wqe_lcmd, buf_in); } +static void cmdq_set_direct_wqe (struct hinic_cmdq_wqe *wqe, +enum cmdq_cmd_type cmd_type, +void *buf_in,u16 in_size, +struct hinic_cmdq_buf *buf_out,int wrapped, +enum hinic_cmd_ack_type ack_type, +enum hinic_mod_type mod,u8 cmd,u16 prod_idx) +{ +struct hinic_cmdq_direct_wqe *direct_wqe = &wqe->direct_wqe; +struct hinic_cmdq_wqe_scmd *wqe_scmd = &direct_wqe->wqe_scmd; +enum completion_format complete_format; + +switch (cmd_type) { +case CMDQ_CMD_SYNC_SGE_RESP : + complete_format =COMPLETE_SGE ; +cmdq_set_sge_completion (&wqe_scmd->completion, buf_out); +break ; +case CMDQ_CMD_SYNC_DIRECT_RESP : + complete_format =COMPLETE_DIRECT ; + wqe_scmd->completion.direct_resp =0 ; +break ; + } + +cmdq_prepare_wqe_ctrl (wqe, wrapped, ack_type, mod, cmd, prod_idx, + complete_format,DATA_DIRECT ,BUFDESC_SCMD_LEN ); + +cmdq_set_direct_wqe_data (direct_wqe, buf_in, in_size); +} +static void cmdq_wqe_fill (void *dst,void *src) { memcpy(dst + FIRST_DATA_TO_WRITE_LAST, src + FIRST_DATA_TO_WRITE_LAST,
@@ -355,6 +430,50 @@ static int cmdq_sync_cmd_direct_resp(struct hinic_cmdq *cmdq,return 0 ; } +static int cmdq_set_arm_bit (struct hinic_cmdq *cmdq,void *buf_in, +u16 in_size) +{ +struct hinic_wq *wq = cmdq->wq; +struct hinic_cmdq_wqe *curr_wqe, wqe; +u16 curr_prod_idx, next_prod_idx; +int wrapped, num_wqebbs; + +/* Keep doorbell index correct */ +spin_lock (&cmdq->cmdq_lock); + +/* WQE_SIZE = WQEBB_SIZE, we will get the wq element and not shadow*/ + curr_wqe =hinic_get_wqe (wq,WQE_SCMD_SIZE , &curr_prod_idx); +if (!curr_wqe) { +spin_unlock (&cmdq->cmdq_lock); +return -EBUSY ; + } + + wrapped = cmdq->wrapped; + + num_wqebbs =ALIGN (WQE_SCMD_SIZE , wq->wqebb_size) / wq->wqebb_size; + next_prod_idx = curr_prod_idx + num_wqebbs; +if (next_prod_idx >= wq->q_depth) { + cmdq->wrapped = !cmdq->wrapped; + next_prod_idx -= wq->q_depth; + } + +cmdq_set_direct_wqe (&wqe,CMDQ_CMD_SYNC_DIRECT_RESP , buf_in, in_size, +NULL , wrapped,HINIC_CMD_ACK_TYPE_CMDQ , +HINIC_MOD_COMM ,CMDQ_SET_ARM_CMD , curr_prod_idx); + +/* The data that is written to HW should be in Big Endian Format */ +hinic_cpu_to_be32 (&wqe,WQE_SCMD_SIZE ); + +/* cmdq wqe is not shadow, therefore wqe will be written to wq */ +cmdq_wqe_fill (curr_wqe, &wqe); + +cmdq_set_db (cmdq,HINIC_CMDQ_SYNC , next_prod_idx); + +spin_unlock (&cmdq->cmdq_lock); + +return 0 ; +} +static int cmdq_params_valid (struct hinic_cmdq_buf *buf_in) {if (buf_in->size >HINIC_CMDQ_MAX_DATA_SIZE )
@@ -391,13 +510,178 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, }/** +* hinic_set_arm_bit - set arm bit for enable interrupt again +* @cmdqs: the cmdqs +* @q_type: type of queue to set the arm bit for +* @q_id: the queue number +* +* Return 0 - Success, negative - Failure +**/ +int hinic_set_arm_bit (struct hinic_cmdqs *cmdqs, +enum hinic_set_arm_qtype q_type,u32 q_id) +{ +struct hinic_cmdq *cmdq = &cmdqs->cmdq[HINIC_CMDQ_SYNC ]; +struct hinic_hwif *hwif = cmdqs->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_cmdq_arm_bit arm_bit; +int err; + + arm_bit.q_type = q_type; + arm_bit.q_id = q_id; + + err =cmdq_set_arm_bit (cmdq, &arm_bit,sizeof (arm_bit)); +if (err) { +dev_err (&pdev->dev,"Failed to set arm for qid %d\n" , q_id); +return err; + } + +return 0 ; +} + +static void clear_wqe_complete_bit (struct hinic_cmdq *cmdq, +struct hinic_cmdq_wqe *wqe) +{ +u32 header_info =be32_to_cpu (CMDQ_WQE_HEADER (wqe)->header_info); +int bufdesc_len =HINIC_CMDQ_WQE_HEADER_GET (header_info,BUFDESC_LEN ); +int wqe_size =cmdq_wqe_size_from_bdlen (bufdesc_len); +struct hinic_cmdq_wqe_lcmd *wqe_lcmd; +struct hinic_cmdq_direct_wqe *direct_wqe; +struct hinic_cmdq_wqe_scmd *wqe_scmd; +struct hinic_ctrl *ctrl; + +if (wqe_size ==WQE_LCMD_SIZE ) { + wqe_lcmd = &wqe->wqe_lcmd; + ctrl = &wqe_lcmd->ctrl; + }else { + direct_wqe = &wqe->direct_wqe; + wqe_scmd = &direct_wqe->wqe_scmd; + ctrl = &wqe_scmd->ctrl; + } + +/* clear HW busy bit */ + ctrl->ctrl_info =0 ; + +wmb ();/* verify wqe is clear */ +} + +/** +* cmdq_arm_ceq_handler - cmdq completion event handler for arm command +* @cmdq: the cmdq of the arm command +* @wqe: the wqe of the arm command +* +* Return 0 - Success, negative - Failure +**/ +static int cmdq_arm_ceq_handler (struct hinic_cmdq *cmdq, +struct hinic_cmdq_wqe *wqe) +{ +struct hinic_cmdq_direct_wqe *direct_wqe = &wqe->direct_wqe; +struct hinic_cmdq_wqe_scmd *wqe_scmd = &direct_wqe->wqe_scmd; +struct hinic_ctrl *ctrl = &wqe_scmd->ctrl; +u32 ctrl_info =be32_to_cpu (ctrl->ctrl_info); + +/* HW should toggle the HW BUSY BIT */ +if (!CMDQ_WQE_COMPLETED (ctrl_info)) +return -EBUSY ; + +clear_wqe_complete_bit (cmdq, wqe); + +hinic_put_wqe (cmdq->wq,WQE_SCMD_SIZE ); +return 0 ; +} + +static void cmdq_update_errcode (struct hinic_cmdq *cmdq,u16 prod_idx, +int errcode) +{ +if (cmdq->errcode[prod_idx]) + *cmdq->errcode[prod_idx] = errcode; +} + +/** +* cmdq_arm_ceq_handler - cmdq completion event handler for sync command +* @cmdq: the cmdq of the command +* @cons_idx: the consumer index to update the error code for +* @errcode: the error code +**/ +static void cmdq_sync_cmd_handler (struct hinic_cmdq *cmdq,u16 cons_idx, +int errcode) +{ +u16 prod_idx = cons_idx; + +spin_lock (&cmdq->cmdq_lock); +cmdq_update_errcode (cmdq, prod_idx, errcode); + +wmb ();/* write all before update for the command request */ + +if (cmdq->done[prod_idx]) +complete (cmdq->done[prod_idx]); + +spin_unlock (&cmdq->cmdq_lock); +} + +/** * cmdq_ceq_handler - cmdq completion event handler * @handle: private data for the handler(cmdqs) * @ceqe_data: ceq element data **/ static void cmdq_ceq_handler (void *handle,u32 ceqe_data) { -/* should be implemented */ +struct hinic_cmdqs *cmdqs = (struct hinic_cmdqs *)handle; +struct hinic_hwif *hwif = cmdqs->hwif; +struct pci_dev *pdev = hwif->pdev; +enum hinic_cmdq_type cmdq_type =CMDQ_CEQE_GET (ceqe_data,TYPE ); +struct hinic_cmdq *cmdq = &cmdqs->cmdq[cmdq_type]; +struct hinic_cmdq_wqe *wqe; +struct hinic_cmdq_wqe_lcmd *wqe_lcmd; +struct hinic_ctrl *ctrl; +struct hinic_status *status; +int err, errcode, set_arm =0 ; +u32 status_info, ctrl_info, saved_data; +u16 ci; + +/* Read the smallest wqe size for getting wqe size */ +while ((wqe =hinic_read_wqe (cmdq->wq,WQE_SCMD_SIZE , &ci))) { + saved_data =be32_to_cpu (CMDQ_WQE_HEADER (wqe)->saved_data); + +if (HINIC_SAVED_DATA_GET (saved_data,ARM )) { +/* arm_bit was set until here */ + set_arm =0 ; + +if (cmdq_arm_ceq_handler (cmdq, wqe)) +break ; + }else { + set_arm =1 ; + + wqe =hinic_read_wqe (cmdq->wq,WQE_LCMD_SIZE , &ci); +if (!wqe) +break ; + +/* only arm bit cmd is using scmd wqe, +* the wqe is lcmd +*/ + wqe_lcmd = &wqe->wqe_lcmd; + ctrl = &wqe_lcmd->ctrl; + ctrl_info =be32_to_cpu (ctrl->ctrl_info); + +if (!CMDQ_WQE_COMPLETED (ctrl_info)) +break ; + + status = &wqe_lcmd->status; + status_info =be32_to_cpu (status->status_info); + + errcode =CMDQ_WQE_ERRCODE_GET (status_info,VAL ); + +cmdq_sync_cmd_handler (cmdq, ci, errcode); + +clear_wqe_complete_bit (cmdq, wqe); +hinic_put_wqe (cmdq->wq,WQE_LCMD_SIZE ); + } + } + +if (set_arm) { + err =hinic_set_arm_bit (cmdqs,HINIC_SET_ARM_CMDQ , cmdq_type); +if (err) +dev_err (&pdev->dev,"Failed to set arm for CMDQ\n" ); + } }/**
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h +12 -0
@@ -147,6 +147,10 @@ enum hinic_cmdq_type { HINIC_MAX_CMDQ_TYPES, }; +enum hinic_set_arm_qtype { +HINIC_SET_ARM_CMDQ , +}; +enum hinic_cmd_ack_type {HINIC_CMD_ACK_TYPE_CMDQ , };
@@ -225,6 +229,11 @@ struct hinic_cmdq_wqe { }; }; +struct hinic_cmdq_arm_bit { +u32 q_type; +u32 q_id; +}; +struct hinic_cmdq_ctxt_info {u64 curr_wqe_page_pfn;u64 wq_block_pfn;
@@ -282,6 +291,9 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, enum hinic_mod_type mod, u8 cmd, struct hinic_cmdq_buf *buf_in, u64 *out_param); +int hinic_set_arm_bit (struct hinic_cmdqs *cmdqs, +enum hinic_set_arm_qtype q_type,u32 q_id); +int hinic_init_cmdqs (struct hinic_cmdqs *cmdqs,struct hinic_hwif *hwif,void __iomem **db_area);
Signature · 1 line
1.9.1
PATCH v2 18/21 net-next/hinic: Add Rx handler
In reply to Aviad KrawczykSet the io resources in the nic and handle rx events by qp operations.
--- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 361 ++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 77 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 36 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 35 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 15 +- drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 195 ++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 81 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 12 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 2 + drivers/net/ethernet/huawei/hinic/hinic_main.c | 24 ++ drivers/net/ethernet/huawei/hinic/hinic_port.c | 32 ++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 19 + drivers/net/ethernet/huawei/hinic/hinic_rx.c | 427 ++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_rx.h | 7 + 16 files changed, 1323 insertions(+), 2 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_dev.h +1 -0
@@ -43,6 +43,7 @@ struct hinic_dev {struct hinic_hwdev *hwdev;u32 msg_enable; +unsigned int rx_weight;unsigned int flags;
drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h +1 -0
@@ -20,6 +20,7 @@#define HINIC_CSR_FUNC_ATTR0_ADDR 0x0#define HINIC_CSR_FUNC_ATTR1_ADDR 0x4 +#define HINIC_CSR_FUNC_ATTR4_ADDR 0x10#define HINIC_CSR_FUNC_ATTR5_ADDR 0x14#define HINIC_DMA_ATTR_BASE 0xC80
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +361 -0
428 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +77 -0
87 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.c +36 -0
@@ -134,6 +134,42 @@ void hinic_set_pf_action(struct hinic_hwif *hwif, enum hinic_pf_action action)hinic_hwif_write_reg (hwif,HINIC_CSR_FUNC_ATTR5_ADDR , attr5); } +enum hinic_outbound_state hinic_outbound_state_get (struct hinic_hwif *hwif) +{ +u32 attr4 =hinic_hwif_read_reg (hwif,HINIC_CSR_FUNC_ATTR4_ADDR ); + +return HINIC_FA4_GET (attr4,OUTBOUND_STATE ); +} + +void hinic_outbound_state_set (struct hinic_hwif *hwif, +enum hinic_outbound_state outbound_state) +{ +u32 attr4 =hinic_hwif_read_reg (hwif,HINIC_CSR_FUNC_ATTR4_ADDR ); + + attr4 =HINIC_FA4_CLEAR (attr4,OUTBOUND_STATE ); + attr4 |=HINIC_FA4_SET (outbound_state,OUTBOUND_STATE ); + +hinic_hwif_write_reg (hwif,HINIC_CSR_FUNC_ATTR4_ADDR , attr4); +} + +enum hinic_db_state hinic_db_state_get (struct hinic_hwif *hwif) +{ +u32 attr4 =hinic_hwif_read_reg (hwif,HINIC_CSR_FUNC_ATTR4_ADDR ); + +return HINIC_FA4_GET (attr4,DB_STATE ); +} + +void hinic_db_state_set (struct hinic_hwif *hwif, +enum hinic_db_state db_state) +{ +u32 attr4 =hinic_hwif_read_reg (hwif,HINIC_CSR_FUNC_ATTR4_ADDR ); + + attr4 =HINIC_FA4_CLEAR (attr4,DB_STATE ); + attr4 |=HINIC_FA4_SET (db_state,DB_STATE ); + +hinic_hwif_write_reg (hwif,HINIC_CSR_FUNC_ATTR4_ADDR , attr4); +} +/** * hwif_ready - test if the HW is ready for use * @hwif: the HW interface of a pci function device
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +35 -0
@@ -73,6 +73,21 @@#define HINIC_FA1_GET (val, member) \ (((val) >> HINIC_FA1_##member##_SHIFT) & HINIC_FA1_##member##_MASK) +#define HINIC_FA4_OUTBOUND_STATE_SHIFT 0 +#define HINIC_FA4_DB_STATE_SHIFT 1 + +#define HINIC_FA4_OUTBOUND_STATE_MASK 0x1 +#define HINIC_FA4_DB_STATE_MASK 0x1 + +#define HINIC_FA4_GET (val, member) \ + (((val) >> HINIC_FA4_##member##_SHIFT) & HINIC_FA4_##member##_MASK) + +#define HINIC_FA4_SET (val, member) \ + ((((u32)val) & HINIC_FA4_##member##_MASK) << HINIC_FA4_##member##_SHIFT) + +#define HINIC_FA4_CLEAR (val, member) \ + ((val) & (~(HINIC_FA4_##member##_MASK << HINIC_FA4_##member##_SHIFT))) +#define HINIC_FA5_PF_ACTION_SHIFT 0#define HINIC_FA5_PF_ACTION_MASK 0xFFFF
@@ -182,6 +197,16 @@ enum hinic_pf_action { HINIC_PF_MGMT_ACTIVE = 0x11, }; +enum hinic_outbound_state { +HINIC_OUTBOUND_ENABLE =0 , +HINIC_OUTBOUND_DISABLE =1 , +}; + +enum hinic_db_state { +HINIC_DB_ENABLE =0 , +HINIC_DB_DISABLE =1 , +}; +struct hinic_func_attr {u16 func_global_idx;u8 pf_idx;
@@ -230,6 +255,16 @@ int hinic_msix_attr_get(struct hinic_hwif *hwif, u16 msix_index,void hinic_set_pf_action (struct hinic_hwif *hwif,enum hinic_pf_action action); +enum hinic_outbound_state hinic_outbound_state_get (struct hinic_hwif *hwif); + +void hinic_outbound_state_set (struct hinic_hwif *hwif, +enum hinic_outbound_state outbound_state); + +enum hinic_db_state hinic_db_state_get (struct hinic_hwif *hwif); + +void hinic_db_state_set (struct hinic_hwif *hwif, +enum hinic_db_state db_state); +int hinic_init_hwif (struct hinic_hwif *hwif,struct pci_dev *pdev);void hinic_free_hwif (struct hinic_hwif *hwif);
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +13 -2
@@ -69,8 +69,19 @@ enum hinic_cfg_cmd { };enum hinic_comm_cmd { -HINIC_COMM_CMD_CMDQ_CTXT_SET =0x10 , -HINIC_COMM_CMD_CMDQ_CTXT_GET =0x11 , +HINIC_COMM_CMD_IO_STATUS_GET =0x3 , + +HINIC_COMM_CMD_CMDQ_CTXT_SET =0x10 , +HINIC_COMM_CMD_CMDQ_CTXT_GET =0x11 , + +HINIC_COMM_CMD_HWCTXT_SET =0x12 , +HINIC_COMM_CMD_HWCTXT_GET =0x13 , + +HINIC_COMM_CMD_RES_STATE_SET =0x24 , + +HINIC_COMM_CMD_IO_RES_CLEAR =0x29 , + +HINIC_COMM_CMD_MAX =0x32 , };enum hinic_mgmt_cb_state {
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c +195 -0
210 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +81 -0
101 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +12 -0
@@ -833,6 +833,18 @@ void *hinic_read_wqe(struct hinic_wq *wq, unsigned int wqe_size, u16 *cons_idx) }/** +* hinic_read_wqe_direct - read wqe directly from ci position +* @wq: wq +* @cons_idx: ci position +* +* Return wqe +**/ +void *hinic_read_wqe_direct (struct hinic_wq *wq,u16 cons_idx) +{ +return WQ_PAGE_ADDR (wq, cons_idx) +WQE_PAGE_OFF (wq, cons_idx); +} + +/** * wqe_shadow - check if a wqe is shadow * @wq: wq of the wqe * @wqe: the wqe for shadow checking
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h +2 -0
@@ -106,6 +106,8 @@ int hinic_wq_allocate(struct hinic_wqs *wqs, struct hinic_wq *wq,void *hinic_read_wqe (struct hinic_wq *wq,unsigned int wqe_size,u16 *cons_idx); +void *hinic_read_wqe_direct (struct hinic_wq *wq,u16 cons_idx); +void hinic_write_wqe (struct hinic_wq *wq,void *wqe,unsigned int wqe_size);#endif
drivers/net/ethernet/huawei/hinic/hinic_main.c +24 -0
@@ -15,6 +15,7 @@#include <linux/kernel.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/pci.h> #include <linux/device.h> #include <linux/errno.h>
@@ -42,6 +43,10 @@MODULE_DESCRIPTION ("Huawei Intelligent NIC driver" );MODULE_LICENSE ("GPL" ); +static unsigned int rx_weight =64 ; +module_param (rx_weight, uint,0644 ); +MODULE_PARM_DESC (rx_weight,"Number Rx packets for NAPI budget (default=64)" ); +#define HINIC_WQ_NAME "hinic_dev"#define MSG_ENABLE_DEFAULT (NETIF_MSG_DRV | NETIF_MSG_PROBE | \
@@ -216,6 +221,12 @@ static int hinic_open(struct net_device *netdev) goto port_state_err; } + err =hinic_port_set_func_state (nic_dev,HINIC_FUNC_PORT_ENABLE ); +if (err) { +dev_err (&netdev->dev,"Failed to set func port state\n" ); + goto func_port_state_err; + } +/* Wait up to 3 sec between port enable to link state */ msleep (3000 );
@@ -247,6 +258,11 @@ static int hinic_open(struct net_device *netdev) port_link_err:up (&nic_dev->mgmt_lock); + ret =hinic_port_set_func_state (nic_dev,HINIC_FUNC_PORT_DISABLE ); +if (ret) +dev_warn (&netdev->dev,"Failed to revert func port state\n" ); + +func_port_state_err: ret =hinic_port_set_state (nic_dev,HINIC_PORT_DISABLE );if (ret)dev_warn (&netdev->dev,"Failed to revert port state\n" );
@@ -280,6 +296,13 @@ static int hinic_close(struct net_device *netdev)up (&nic_dev->mgmt_lock); + err =hinic_port_set_func_state (nic_dev,HINIC_FUNC_PORT_DISABLE ); +if (err) { +dev_err (&netdev->dev,"Failed to set func port state\n" ); + nic_dev->flags |= (flags &HINIC_INTF_UP ); +return err; + } + err =hinic_port_set_state (nic_dev,HINIC_PORT_DISABLE );if (err) {dev_err (&netdev->dev,"Failed to set port state\n" );
@@ -667,6 +690,7 @@ static int nic_dev_init(struct pci_dev *pdev) nic_dev->flags =0 ; nic_dev->txqs =NULL ; nic_dev->rxqs =NULL ; + nic_dev->rx_weight = rx_weight;sema_init (&nic_dev->mgmt_lock,1 );
drivers/net/ethernet/huawei/hinic/hinic_port.c +32 -0
@@ -340,3 +340,35 @@ int hinic_port_set_state(struct hinic_dev *nic_dev, enum hinic_port_state state)return 0 ; } + +/** +* hinic_port_set_func_state- set func device state +* @nic_dev: nic device +* @state: the state to set +* +* Return 0 - Success, negative - Failure +**/ +int hinic_port_set_func_state (struct hinic_dev *nic_dev, +enum hinic_func_port_state state) +{ +struct hinic_hwdev *hwdev = nic_dev->hwdev; +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; +struct hinic_port_func_state_cmd func_state; +u16 out_size; +int err; + + func_state.func_idx =HINIC_HWIF_GLOB_IDX (hwif); + func_state.state = state; + + err =hinic_port_msg_cmd (hwdev,HINIC_PORT_CMD_SET_FUNC_STATE , + &func_state,sizeof (func_state), + &func_state, &out_size); +if (err || (out_size !=sizeof (func_state)) || func_state.status) { +dev_err (&pdev->dev,"Failed to set port func state, ret = %d\n" , + func_state.status); +return -EFAULT ; + } + +return 0 ; +}
drivers/net/ethernet/huawei/hinic/hinic_port.h +19 -0
@@ -40,6 +40,11 @@ enum hinic_port_state { HINIC_PORT_ENABLE = 3, }; +enum hinic_func_port_state { +HINIC_FUNC_PORT_DISABLE =0 , +HINIC_FUNC_PORT_ENABLE =2 , +}; +struct hinic_port_mac_cmd {u8 status;u8 version;
@@ -109,6 +114,17 @@ struct hinic_port_link_status {u8 rsvd2; }; +struct hinic_port_func_state_cmd { +u8 status; +u8 version; +u8 rsvd0[6 ]; + +u16 func_idx; +u16 rsvd1; +u8 state; +u8 rsvd2[3 ]; +}; +int hinic_port_add_mac (struct hinic_dev *nic_dev,const u8 *addr,u16 vlan_id);
@@ -131,4 +147,7 @@ int hinic_port_link_state(struct hinic_dev *nic_dev,int hinic_port_set_state (struct hinic_dev *nic_dev,enum hinic_port_state state); +int hinic_port_set_func_state (struct hinic_dev *nic_dev, +enum hinic_func_port_state state); +#endif
drivers/net/ethernet/huawei/hinic/hinic_rx.c +427 -0
459 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_rx.h +7 -0
@@ -19,6 +19,7 @@#include <linux/types.h> #include <linux/netdevice.h> #include <linux/u64_stats_sync.h> +#include <linux/interrupt.h> #include "hinic_hw_qp.h"
@@ -34,6 +35,12 @@ struct hinic_rxq {struct hinic_rq *rq;struct hinic_rxq_stats rxq_stats; + +char *irq_name; + +struct tasklet_struct rx_task; + +struct napi_struct napi; };void hinic_rxq_clean_stats (struct hinic_rxq *rxq);
Signature · 1 line
1.9.1
PATCH v2 19/21 net-next/hinic: Add Tx operation
In reply to Aviad KrawczykAdd transmit operation for sending data by qp operations.
--- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 47 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 22 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 1 + drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 2 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 244 +++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 197 ++++++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 12 +- drivers/net/ethernet/huawei/hinic/hinic_tx.c | 419 ++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 11 + 10 files changed, 954 insertions(+), 2 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_dev.h +1 -0
@@ -43,6 +43,7 @@ struct hinic_dev {struct hinic_hwdev *hwdev;u32 msg_enable; +unsigned int tx_weight;unsigned int rx_weight;unsigned int flags;
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c +47 -0
56 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +22 -0
@@ -153,6 +153,25 @@ struct hinic_cmd_base_qpn {u16 qpn; }; +struct hinic_cmd_hw_ci { +u8 status; +u8 version; +u8 rsvd0[6 ]; + +u16 func_idx; + +u8 dma_attr_off; +u8 pending_limit; +u8 coalesc_timer; + +u8 msix_en; +u16 msix_entry_idx; + +u32 sq_id; +u32 rsvd1; +u64 ci_addr; +}; +struct hinic_hwdev {struct hinic_hwif *hwif;struct msix_entry *msix_entries;
@@ -214,4 +233,7 @@ int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index, u8 lli_timer_cfg, u8 lli_credit_limit, u8 resend_timer); +int hinic_hwdev_hw_ci_addr_set (struct hinic_hwdev *hwdev,struct hinic_sq *sq, +u8 pending_limit,u8 coalesc_timer); +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +1 -0
@@ -39,6 +39,7 @@ enum hinic_db_type {enum hinic_io_path {HINIC_CTRL_PATH , +HINIC_DATA_PATH , };struct hinic_free_db_area {
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h +2 -0
@@ -77,6 +77,8 @@ enum hinic_comm_cmd {HINIC_COMM_CMD_HWCTXT_SET =0x12 ,HINIC_COMM_CMD_HWCTXT_GET =0x13 , +HINIC_COMM_CMD_SQ_HI_CI_SET =0x14 , +HINIC_COMM_CMD_RES_STATE_SET =0x24 , HINIC_COMM_CMD_IO_RES_CLEAR = 0x29,
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c +244 -0
276 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +197 -0
229 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_main.c +10 -2
@@ -43,6 +43,10 @@MODULE_DESCRIPTION ("Huawei Intelligent NIC driver" );MODULE_LICENSE ("GPL" ); +static unsigned int tx_weight =64 ; +module_param (tx_weight, uint,0644 ); +MODULE_PARM_DESC (tx_weight,"Number Tx packets for NAPI budget (default=64)" ); +static unsigned int rx_weight =64 ;module_param (rx_weight, uint,0644 );MODULE_PARM_DESC (rx_weight,"Number Rx packets for NAPI budget (default=64)" );
@@ -568,9 +572,11 @@ static void hinic_set_rx_mode(struct net_device *netdev)queue_work (nic_dev->workq, &rx_mode_work->work); } -netdev_tx_t hinic_xmit_frame (struct sk_buff *skb,struct net_device *netdev) +static void hinic_tx_timeout (struct net_device *netdev) { -return NETDEV_TX_BUSY ; +struct hinic_dev *nic_dev =netdev_priv (netdev); + +netif_err (nic_dev, drv, netdev,"Tx timeout\n" ); }static const struct net_device_ops hinic_netdev_ops = {
@@ -583,6 +589,7 @@ netdev_tx_t hinic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) .ndo_vlan_rx_kill_vid = hinic_vlan_rx_kill_vid, .ndo_set_rx_mode = hinic_set_rx_mode, .ndo_start_xmit = hinic_xmit_frame, + .ndo_tx_timeout = hinic_tx_timeout,/* more operations should be filled */ };
@@ -690,6 +697,7 @@ static int nic_dev_init(struct pci_dev *pdev) nic_dev->flags =0 ; nic_dev->txqs =NULL ; nic_dev->rxqs =NULL ; + nic_dev->tx_weight = tx_weight; nic_dev->rx_weight = rx_weight;sema_init (&nic_dev->mgmt_lock,1 );
drivers/net/ethernet/huawei/hinic/hinic_tx.c +419 -0
452 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_tx.h +11 -0
@@ -18,8 +18,10 @@#include <linux/types.h> #include <linux/netdevice.h> +#include <linux/skbuff.h> #include <linux/u64_stats_sync.h> +#include "hinic_common.h" #include "hinic_hw_qp.h" struct hinic_txq_stats {
@@ -37,10 +39,19 @@ struct hinic_txq {struct hinic_sq *sq;struct hinic_txq_stats txq_stats; + +int max_sges; +struct hinic_sge *sges; +struct hinic_sge *free_sges; + +char *irq_name; +struct napi_struct napi; };void hinic_txq_clean_stats (struct hinic_txq *txq); +netdev_tx_t hinic_xmit_frame (struct sk_buff *skb,struct net_device *netdev); +int hinic_init_txq (struct hinic_txq *txq,struct hinic_sq *sq,struct net_device *netdev);
Signature · 1 line
1.9.1
PATCH v2 20/21 net-next/hinic: Add ethtool and stats
In reply to Aviad KrawczykAdd ethtool operations and statistics operations.
--- drivers/net/ethernet/huawei/hinic/hinic_dev.h | 3 + drivers/net/ethernet/huawei/hinic/hinic_main.c | 218 ++++++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_port.c | 29 ++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 45 +++++ drivers/net/ethernet/huawei/hinic/hinic_rx.c | 19 +++ drivers/net/ethernet/huawei/hinic/hinic_rx.h | 2 + drivers/net/ethernet/huawei/hinic/hinic_tx.c | 22 +++ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 2 + 8 files changed, 339 insertions(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_dev.h +3 -0
@@ -56,6 +56,9 @@ struct hinic_dev {struct hinic_txq *txqs;struct hinic_rxq *rxqs; + +struct hinic_txq_stats tx_stats; + struct hinic_rxq_stats rx_stats; };#endif
drivers/net/ethernet/huawei/hinic/hinic_main.c +217 -1
260 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.c +29 -0
@@ -372,3 +372,32 @@ int hinic_port_set_func_state(struct hinic_dev *nic_dev,return 0 ; } + +/** +* hinic_port_get_cap - get port capabilities +* @nic_dev: nic device +* @port_cap: returned port capabilities +* +* Return 0 - Success, negative - Failure +**/ +int hinic_port_get_cap (struct hinic_dev *nic_dev, +struct hinic_port_cap *port_cap) +{ +struct hinic_hwdev *hwdev = nic_dev->hwdev; +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; +u16 out_size; +int err; + + port_cap->func_idx =HINIC_HWIF_GLOB_IDX (hwif); + + err =hinic_port_msg_cmd (hwdev,HINIC_PORT_CMD_GET_CAP , + port_cap,sizeof (*port_cap), + port_cap, &out_size); +if (err || (out_size !=sizeof (*port_cap)) || port_cap->status) { +dev_err (&pdev->dev,"Failed to get port capabilities\n" ); +return -EINVAL ; + } + +return 0 ; +}
drivers/net/ethernet/huawei/hinic/hinic_port.h +45 -0
61 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_rx.c +19 -0
@@ -57,6 +57,25 @@ void hinic_rxq_clean_stats(struct hinic_rxq *rxq) }/** +* hinic_rxq_get_stats - get statistics of Rx Queue +* @rxq: Logical Rx Queue +* @stats: return updated stats here +**/ +void hinic_rxq_get_stats (struct hinic_rxq *rxq,struct hinic_rxq_stats *stats) +{ +struct hinic_rxq_stats *rxq_stats = &rxq->rxq_stats; +unsigned int start; + +u64_stats_update_begin (&stats->syncp); +do { + start =u64_stats_fetch_begin (&rxq_stats->syncp); + stats->pkts = rxq_stats->pkts; + stats->bytes = rxq_stats->bytes; + }while (u64_stats_fetch_retry (&rxq_stats->syncp, start)); +u64_stats_update_end (&stats->syncp); +} + +/** * rxq_stats_init - Initialize the statistics of specific queue * @rxq: Logical Rx Queue **/
drivers/net/ethernet/huawei/hinic/hinic_rx.h +2 -0
@@ -45,6 +45,8 @@ struct hinic_rxq {void hinic_rxq_clean_stats (struct hinic_rxq *rxq); +void hinic_rxq_get_stats (struct hinic_rxq *rxq,struct hinic_rxq_stats *stats); +int hinic_init_rxq (struct hinic_rxq *rxq,struct hinic_rq *rq,struct net_device *netdev);
drivers/net/ethernet/huawei/hinic/hinic_tx.c +22 -0
@@ -66,6 +66,28 @@ void hinic_txq_clean_stats(struct hinic_txq *txq) }/** +* hinic_txq_get_stats - get statistics of Tx Queue +* @txq: Logical Tx Queue +* @stats: return updated stats here +**/ +void hinic_txq_get_stats (struct hinic_txq *txq,struct hinic_txq_stats *stats) +{ +struct hinic_txq_stats *txq_stats = &txq->txq_stats; +unsigned int start; + +u64_stats_update_begin (&stats->syncp); +do { + start =u64_stats_fetch_begin (&txq_stats->syncp); + stats->pkts = txq_stats->pkts; + stats->bytes = txq_stats->bytes; + stats->tx_busy = txq_stats->tx_busy; + stats->tx_wake = txq_stats->tx_wake; + stats->tx_dropped = txq_stats->tx_dropped; + }while (u64_stats_fetch_retry (&txq_stats->syncp, start)); +u64_stats_update_end (&stats->syncp); +} + +/** * txq_stats_init - Initialize the statistics of specific queue * @txq: Logical Tx Queue **/
drivers/net/ethernet/huawei/hinic/hinic_tx.h +2 -0
@@ -50,6 +50,8 @@ struct hinic_txq {void hinic_txq_clean_stats (struct hinic_txq *txq); +void hinic_txq_get_stats (struct hinic_txq *txq,struct hinic_txq_stats *stats); +netdev_tx_t hinic_xmit_frame (struct sk_buff *skb,struct net_device *netdev); int hinic_init_txq(struct hinic_txq *txq, struct hinic_sq *sq,
Signature · 1 line
1.9.1
Re: [PATCH V2 net-next 20/21] net-next/hinic: Add ethtool and stats
Quoted 1 line · Aviad Krawczyk
Add ethtool operations and statistics operations.
series trivia:
drivers/net/ethernet/huawei/hinic/hinic_main.c
Quoted 1 line
drivers/net/ethernet/huawei/hinic/hinic_main.c +0
-0
[]
drivers/net/ethernet/huawei/hinic/hinic_main.c
Quoted 1 line
drivers/net/ethernet/huawei/hinic/hinic_main.c +0
-0@@ -67,6 +67,178 @@
[]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 73
Quoted 4 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c +4
-0+static int hinic_get_link_ksettings (struct net_device *netdev, +struct ethtool_link_ksettings + *link_ksettings) +{
[]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 93
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c +5
-0+ err =hinic_port_get_cap (nic_dev, &port_cap); +if (err) { +dev_err (&netdev->dev,"Failed to get port capabilities\n" ); +return err; + }
it looks like a lot of these dev_<level> calls
should be converted to netdev_<level>
from:
dev_err(&netdev->dev, ...); to: netdev_err(netdev, ...);
etc...
Re: [PATCH V2 net-next 20/21] net-next/hinic: Add ethtool and stats
Hi Joe,
I tried to be consistent with the comments before, that requested that we will use dev_err exclude some special cases for use netif.
We will replace the dev_err(&netdev->dev,.. to netdev_err in the next fix.
Thanks for review,
Aviad
Quoted 33 lines · Joe Perches
Quoted 1 line · Aviad Krawczyk
Add ethtool operations and statistics operations.
series trivia:
drivers/net/ethernet/huawei/hinic/hinic_main.c
Quoted 1 line
drivers/net/ethernet/huawei/hinic/hinic_main.c +0
-0[]
drivers/net/ethernet/huawei/hinic/hinic_main.c
Quoted 1 line
drivers/net/ethernet/huawei/hinic/hinic_main.c +0
-0@@ -67,6 +67,178 @@[]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 73
Quoted 4 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c +4
-0+static int hinic_get_link_ksettings (struct net_device *netdev, +struct ethtool_link_ksettings + *link_ksettings) +{[]
drivers/net/ethernet/huawei/hinic/hinic_main.c line 93
Quoted 5 lines
drivers/net/ethernet/huawei/hinic/hinic_main.c +5
-0+ err =hinic_port_get_cap (nic_dev, &port_cap); +if (err) { +dev_err (&netdev->dev,"Failed to get port capabilities\n" ); +return err; + }it looks like a lot of these dev_<level> calls
should be converted to netdev_<level>from:
dev_err(&netdev->dev, ...); to: netdev_err(netdev, ...);etc...
.
Re: [PATCH V2 net-next 20/21] net-next/hinic: Add ethtool and stats
Quoted 7 lines · Aviad Krawczyk
Hi Joe,
I tried to be consistent with the comments before, that requested that we will use
dev_errexclude some special cases for use netif.We will replace the dev_err(&netdev->dev,.. to
netdev_errin the next fix.
netdev_err() should be used when possible. You just have to be careful in the probe() function, before netdev exists and you get "(NULL net_device):" or before it is registered and you get "(unnamed net_device)" instead of "eth42" etc.
Andrew
Re: [PATCH V2 net-next 20/21] net-next/hinic: Add ethtool and stats
Hi,
I saw that netif_err is more common in code, is it preferred on netdev_err? What is the preferred style, netif_ or netdev_?
Best Regards,
Aviad
Quoted 18 lines · Andrew Lunn
Quoted 7 lines · Aviad Krawczyk
Hi Joe,
I tried to be consistent with the comments before, that requested that we will use
dev_errexclude some special cases for use netif.We will replace the dev_err(&netdev->dev,.. to
netdev_errin the next fix.
netdev_err()should be used when possible. You just have to be careful in theprobe()function, before netdev exists and you get "(NULLnet_device):" or before it is registered and you get "(unnamednet_device)" instead of "eth42" etc.Andrew
.
PATCH v2 21/21 net-next/hinic: Add select_queue and netpoll
In reply to Aviad KrawczykAdd more netdev operations.
--- MAINTAINERS | 7 ++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 35 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+)
MAINTAINERS +7 -0
@@ -6269,6 +6269,13 @@ L: [email protected] S: Maintained F: drivers/input/touchscreen/htcpen.c +HUAWEI ETHERNET DRIVER +M: Aviad Krawczyk <[email protected]> +L: [email protected] +S: Supported +F: Documentation/networking/hinic.txt +F: drivers/net/ethernet/huawei/* + HUGETLB FILESYSTEM M: Nadia Yvette Chambers <[email protected]> S: Maintained
drivers/net/ethernet/huawei/hinic/hinic_main.c +35 -0
@@ -786,6 +786,37 @@ static void hinic_get_stats64(struct net_device *netdev, stats->tx_errors = nic_tx_stats->tx_dropped; } +static u16 hinic_select_queue (struct net_device *netdev,struct sk_buff *skb, +void *accel_priv, +select_queue_fallback_t fallback) +{ +u16 qid; + +if (skb_rx_queue_recorded (skb)) + qid =skb_get_rx_queue (skb); +else + qid =fallback (netdev, skb); + +return qid; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void hinic_netpoll (struct net_device *netdev) +{ +struct hinic_dev *nic_dev =netdev_priv (netdev); +struct hinic_hwdev *hwdev = nic_dev->hwdev; +int i, num_qps =hinic_hwdev_num_qps (hwdev); + +for (i =0 ; i < num_qps; i++) { +struct hinic_txq *txq = &nic_dev->txqs[i]; +struct hinic_rxq *rxq = &nic_dev->rxqs[i]; + +napi_schedule (&txq->napi); +napi_schedule (&rxq->napi); + } +} +#endif +static const struct net_device_ops hinic_netdev_ops = { .ndo_open = hinic_open, .ndo_stop = hinic_close,
@@ -798,6 +829,10 @@ static void hinic_get_stats64(struct net_device *netdev, .ndo_start_xmit = hinic_xmit_frame, .ndo_tx_timeout = hinic_tx_timeout, .ndo_get_stats64 = hinic_get_stats64, + .ndo_select_queue = hinic_select_queue, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = hinic_netpoll, +#endif };static void netdev_features_init (struct net_device *netdev)
Signature · 1 line
1.9.1
Re: [PATCH V2 net-next 21/21] net-next/hinic: Add select_queue and netpoll
Quoted 14 lines · Aviad Krawczyk
Add more netdev operations.
Signed-off-by Aviad Krawczyk <[email protected]>Signed-off-by Zhao Chen <[email protected]>--- MAINTAINERS | 7 ++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 35 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+)MAINTAINERS +0
-0
MAINTAINERS L: [email protected] · line 6277
Quoted 9 lines
MAINTAINERS +6
-0@@ -6269,6 +6269,13 @@ L: [email protected] S: Maintained F: drivers/input/touchscreen/htcpen.c +HUAWEI ETHERNET DRIVER +M: Aviad Krawczyk <[email protected]> +L: [email protected] +S: Supported +F: Documentation/networking/hinic.txt +F: drivers/net/ethernet/huawei/*
This means that subdirs there are not maintained, did you really mean it?
[...]
MNR, Sergei
Re: [PATCH V2 net-next 21/21] net-next/hinic: Add select_queue and netpoll
Hi Sergei,
I meant that drivers/net/ethernet/huawei/* is all the dir under huawei dir. (I saw this style of '*' is used in the maintainers file)
I will change it to drivers/net/ethernet/huawei/hinic/ in the next fix.
Thanks for review,
Aviad
Quoted 33 lines · Sergei Shtylyov
Quoted 14 lines · Aviad Krawczyk
Add more netdev operations.
Signed-off-by Aviad Krawczyk <[email protected]>Signed-off-by Zhao Chen <[email protected]>--- MAINTAINERS | 7 ++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 35 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+)MAINTAINERS +0
-0MAINTAINERS L: [email protected] · line 6276
Quoted 8 lines
MAINTAINERS +5
-0@@ -6269,6 +6269,13 @@ L: [email protected] S: Maintained F: drivers/input/touchscreen/htcpen.c +HUAWEI ETHERNET DRIVER +M: Aviad Krawczyk <[email protected]> +L: [email protected] +S: Supported +F: Documentation/networking/hinic.txt +F: drivers/net/ethernet/huawei/*This means that subdirs there are not maintained, did you really mean it?
[...]
MNR, Sergei
.