Huawei HiNIC Ethernet Driver
Subsystems (4)
v6 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 V5 -> V6:
1. Fix cover letter Message-Id
Changes V4 -> V5:
1. Remove select_queue NOP - David Miller comment
https://lkml.org/lkml/2017/8/16/625
Changes V3 -> V4:
1. Reverse christmas tree order - David Miller comment
https://lkml.org/lkml/2017/8/3/862
Changes V2 -> V3:
1. Replace dev_ functions by netif_ functions - Joe Perches comment
https://lkml.org/lkml/2017/7/19/424 2. Fix the driver directory in MAINTAINERS file - Sergei Shtylyov comment https://lkml.org/lkml/2017/7/19/615 3. Add a newline at the end of Makefile - David Miller comment https://lkml.org/lkml/2017/7/19/1345 4. Return a pointer as a val instead of in arg - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319 5. Change the error labels to err_xyz - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319 6. Remove check of Func Type in free function - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319 7. Remove !netdev check in remove function - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319 8. Use module_pci_driver - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319 9. Move the PCI device ID to the .c file - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319 10. Remove void * to avoid passing wrong ptr - Francois Romieu comment https://lkml.org/lkml/2017/7/19/1319
Changes V1 -> V2:
1. remove driver verstion - 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 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 | 977 +++++++++++++++++ .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 208 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 946 +++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 187 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 149 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c | 1045 ++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 239 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c | 888 ++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 265 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 352 +++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 272 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 533 ++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 97 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c | 597 +++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 153 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 892 ++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 180 ++++ .../net/ethernet/huawei/hinic/hinic_hw_qp_ctxt.h | 214 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 879 ++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 117 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_wqe.h | 368 +++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 1111 ++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_port.c | 379 +++++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 198 ++++ drivers/net/ethernet/huawei/hinic/hinic_rx.c | 510 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_rx.h | 55 + drivers/net/ethernet/huawei/hinic/hinic_tx.c | 503 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 62 ++ 39 files changed, 12735 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_hw_wqe.h create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_main.c 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 v6 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 | 201 ++++++++++++++++++++++ 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 | 195 +++++++++++++++++++++ 14 files changed, 1042 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
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 +201 -0
201 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 +195 -0
195 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v6 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 | 172 ++++++++++++++++++++-- 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 | 92 ++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 45 ++++++ 8 files changed, 576 insertions(+), 14 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 +160 -12
227 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; };struct hinic_hwdev *hinic_init_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_idx;u8 pf_idx;
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c new file +92 -0
92 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 v6 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 | 446 +++++++++++++++++++++ .../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, 563 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 +446 -0
446 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 (pf_to_mgmt->cmd_chain, hwif); +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);
@@ -89,4 +98,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 v6 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 | 26 ++++ 3 files changed, 236 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>
@@ -21,8 +22,12 @@#include <linux/dma-mapping.h> #include <linux/bitops.h> #include <linux/err.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"
@@ -35,8 +40,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; +int err = -ETIMEDOUT ; +unsigned long end; +u32 reg_addr, val; + +/* 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
@@ -45,7 +199,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 ; }
@@ -373,6 +543,7 @@ static void api_chain_free(struct hinic_api_cmd_chain *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 +26 -0
@@ -33,4 +33,30 @@#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 v6 5/21 net-next/hinic: Add management messages
In reply to Aviad KrawczykAdd the management messages for sending to api cmd and add 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 | 439 ++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 59 +++ 5 files changed, 538 insertions(+), 3 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +35 -0
@@ -54,6 +54,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,u8 *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,u8 *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,u8 *cmd,u16 size); +int hinic_api_cmd_init (struct hinic_api_cmd_chain **chain,struct hinic_hwif *hwif);
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_FUNC_IDX (hwif) ((hwif)->attr.func_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_idx;u8 pf_idx;
drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +436 -3
472 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 v6 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 | 329 ++++++++++++++++++++- .../net/ethernet/huawei/hinic/hinic_hw_api_cmd.h | 65 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_csr.h | 6 + 3 files changed, 398 insertions(+), 2 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_api_cmd.c +327 -2
@@ -25,7 +25,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"
@@ -45,14 +47,313 @@#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) +{ +enum hinic_api_cmd_chain_type chain_type = chain->chain_type; +struct hinic_hwif *hwif = chain->hwif; +u32 hw_prod_idx_addr, prod_idx; + + hw_prod_idx_addr =HINIC_CSR_API_CMD_CHAIN_PI_ADDR (chain_type); + 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) +{ +u8 chksum; +u64 ctrl; + + 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 +* @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, +enum hinic_node_id dest, +void *cmd,u16 cmd_size) +{ +struct hinic_api_cmd_cell *cell = chain->curr_node; +struct hinic_api_cmd_cell_ctxt *cell_ctxt; +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; + + 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, 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) +{ +enum hinic_api_cmd_chain_type chain_type; +struct hinic_api_cmd_status *wb_status; +struct hinic_hwif *hwif = chain->hwif; +struct pci_dev *pdev = hwif->pdev; +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) +{ +int err = -ETIMEDOUT ; +unsigned long end; + + 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
@@ -65,8 +366,30 @@ enum api_cmd_xor_chk_level {static int api_cmd (struct hinic_api_cmd_chain *chain,enum hinic_node_id dest,u8 *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; }/**
@@ -491,6 +814,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 +6 -0
@@ -56,7 +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 v6 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 | 464 ++++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.h | 81 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.c | 91 +++++ drivers/net/ethernet/huawei/hinic/hinic_hw_if.h | 46 +++ 5 files changed, 729 insertions(+), 2 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 +462 -2
500 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 +91 -0
97 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_if.h +46 -0
64 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v6 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 | 195 +++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_port.c | 224 +++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 68 +++++++ 7 files changed, 551 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
@@ -200,6 +200,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_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 -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); +struct hinic_hwdev *hinic_init_hwdev (struct pci_dev *pdev);void hinic_free_hwdev (struct hinic_hwdev *hwdev);
drivers/net/ethernet/huawei/hinic/hinic_main.c +194 -1
234 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.c new file +224 -0
224 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 v6 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 | 118 +++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h | 37 +++ 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 | 64 ++++- drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.h | 28 +++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 284 ++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_port.c | 92 +++++++ drivers/net/ethernet/huawei/hinic/hinic_port.h | 66 +++++ 11 files changed, 741 insertions(+), 1 deletion(-)
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 +118 -0
136 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_dev.h +37 -0
@@ -18,6 +18,7 @@#include <linux/pci.h> #include <linux/types.h> +#include <linux/bitops.h> #include "hinic_hw_if.h" #include "hinic_hw_eqs.h"
@@ -25,6 +26,9 @@#define HINIC_MAX_QPS 32 +#define HINIC_MGMT_NUM_MSG_CMD (HINIC_MGMT_MSG_CMD_MAX - \ + HINIC_MGMT_MSG_CMD_BASE) +struct hinic_cap {u16 max_qps;u16 num_qps;
@@ -55,6 +59,19 @@ enum hinic_port_cmd { HINIC_PORT_CMD_GET_CAP = 170, }; +enum hinic_mgmt_msg_cmd { +HINIC_MGMT_MSG_CMD_BASE =160 , + +HINIC_MGMT_MSG_CMD_LINK_STATUS =160 , + +HINIC_MGMT_MSG_CMD_MAX , +}; + +enum hinic_cb_state { +HINIC_CB_ENABLED =BIT (0 ), +HINIC_CB_RUNNING =BIT (1 ), +}; +struct hinic_hwdev {struct hinic_hwif *hwif;struct msix_entry *msix_entries;
@@ -64,12 +81,32 @@ struct hinic_hwdev {struct hinic_cap nic_cap; }; +struct hinic_nic_cb { +void (*handler)(void *handle,void *buf_in, +u16 in_size,void *buf_out, +u16 *out_size); + +void *handle; +unsigned long cb_state; +}; +struct hinic_pfhwdev {struct hinic_hwdev hwdev;struct hinic_pf_to_mgmt pf_to_mgmt; + +struct hinic_nic_cb nic_cb[HINIC_MGMT_NUM_MSG_CMD ]; }; +void hinic_hwdev_cb_register (struct hinic_hwdev *hwdev, +enum hinic_mgmt_msg_cmd cmd,void *handle, +void (*handler)(void *handle,void *buf_in, +u16 in_size,void *buf_out, +u16 *out_size)); + +void hinic_hwdev_cb_unregister (struct hinic_hwdev *hwdev, +enum hinic_mgmt_msg_cmd cmd); +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);
drivers/net/ethernet/huawei/hinic/hinic_hw_if.c +17 -0
@@ -117,6 +117,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_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 +63 -1
78 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 {u8 *msg;u8 *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 -0
378 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_port.c +92 -0
95 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 v6 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 | 131 +++++++++++++++++ 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, 793 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 +131 -0
146 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); +struct hinic_hwdev *hinic_init_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
213 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 v6 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_common.h | 25 ++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.c | 69 ++- drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 6 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 14 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 517 +++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 86 ++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wqe.h | 253 +++++++++++ 8 files changed, 969 insertions(+), 5 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_common.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_hw_wqe.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_common.h new file +25 -0
@@ -0,0 +1,25 @@ +/* +* 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 + +struct hinic_sge { +u32 hi_addr; +u32 lo_addr; +u32 len; +}; + +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c +66 -3
126 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 +14 -0
@@ -16,6 +16,18 @@#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 +struct hinic_sq {/* should be implemented */ };
@@ -27,6 +39,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 +517 -0
517 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
drivers/net/ethernet/huawei/hinic/hinic_hw_wqe.h new file +253 -0
253 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v6 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 | 164 ++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 27 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 266 ++++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 50 ++++- 6 files changed, 507 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 +163 -1
242 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 +266 -0
266 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +48 -2
70 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v6 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 | 4 + 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 | 151 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 5 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 159 +++++++++++++++ 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, 786 insertions(+), 2 deletions(-) create mode 100644 drivers/net/ethernet/huawei/hinic/hinic_common.c 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 +4 -0
@@ -22,4 +22,8 @@ struct hinic_sge { u32 len; }; +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
@@ -25,6 +25,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 */ nic_cap->num_qps = (num_irqs - (num_aeqs + num_ceqs)) /2 ; +if (nic_cap->num_qps >HINIC_Q_CTXT_MAX ) + nic_cap->num_qps =HINIC_Q_CTXT_MAX ; +/* num_qps must be power of 2 */ nic_cap->num_qps =BIT (fls (nic_cap->num_qps) -1 );
drivers/net/ethernet/huawei/hinic/hinic_hw_io.c +151 -0
197 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 +159 -0
172 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +11 -0
@@ -24,6 +24,7 @@#include "hinic_hw_if.h" #include "hinic_hw_wqe.h" #include "hinic_hw_wq.h" +#include "hinic_hw_qp_ctxt.h" #define HINIC_SQ_WQEBB_SIZE 64#define HINIC_RQ_WQEBB_SIZE 32
@@ -78,6 +79,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_ctxt *sq_ctxt, +struct hinic_sq *sq,u16 global_qid); + +void hinic_rq_prepare_ctxt (struct hinic_rq_ctxt *rq_ctxt, +struct hinic_rq *rq,u16 global_qid); +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 v6 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 nic about the qp contexts.
--- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 282 +++++++++++++++++++++- 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 | 156 ++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 8 + 6 files changed, 500 insertions(+), 6 deletions(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +276 -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 =0 , +WQE_SCMD_TYPE =1 , +};/** * 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,169 @@ int hinic_cmdq_direct_resp(struct hinic_cmdqs *cmdqs, }/** +* cmdq_init_queue_ctxt - init the queue ctxt of a cmdq +* @cmdq_ctxt: cmdq ctxt to initialize +* @cmdq: the cmdq +* @cmdq_pages: the memory of the queue +**/ +static void cmdq_init_queue_ctxt (struct hinic_cmdq_ctxt *cmdq_ctxt, +struct hinic_cmdq *cmdq, +struct hinic_cmdq_pages *cmdq_pages) +{ +struct hinic_cmdq_ctxt_info *ctxt_info = &cmdq_ctxt->ctxt_info; +u64 wq_first_page_paddr, cmdq_first_block_paddr, pfn; +struct hinic_cmdqs *cmdqs =cmdq_to_cmdqs (cmdq); +struct hinic_wq *wq = cmdq->wq; + +/* 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 (atomic_read (&wq->cons_idx),CI ); + + cmdq_ctxt->func_idx =HINIC_HWIF_FUNC_IDX (cmdqs->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 err_errcode; + } + + cmdq->db_base = db_area +CMDQ_DB_OFF ; +return 0 ; + +err_errcode: +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; +enum hinic_cmdq_type type, cmdq_type; +struct hinic_cmdq_ctxt *cmdq_ctxts; +struct pci_dev *pdev = hwif->pdev; +struct hinic_pfhwdev *pfhwdev; +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" ); + goto err_init_cmdq; + } + +cmdq_init_queue_ctxt (&cmdq_ctxts[cmdq_type], + &cmdqs->cmdq[cmdq_type], + &cmdqs->cmdq_pages); + } + +/* 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); + goto err_write_cmdq_ctxt; + } + } + +devm_kfree (&pdev->dev, cmdq_ctxts); +return 0 ; + +err_write_cmdq_ctxt: + cmdq_type =HINIC_MAX_CMDQ_TYPES ; + +err_init_cmdq: +for (type =HINIC_CMDQ_SYNC ; type < cmdq_type; type++) +free_cmdq (&cmdqs->cmdq[type]); + +devm_kfree (&pdev->dev, cmdq_ctxts); +return err; +} + +/** * hinic_init_cmdqs - init all cmdqs * @cmdqs: cmdqs to init * @hwif: HW interface for accessing cmdqs
@@ -73,8 +283,55 @@ 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 pci_dev *pdev = hwif->pdev; +struct hinic_hwdev *hwdev; +size_t saved_wqs_size; +u16 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 err_saved_wqs; + } + + 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 err_cmdq_wqs; + } + + hwdev = container_of(func_to_io, struct hinic_hwdev, func_to_io); + err =init_cmdqs_ctxt (hwdev, cmdqs, db_area); +if (err) { +dev_err (&pdev->dev,"Failed to write cmdq ctxt\n" ); + goto err_cmdq_ctxt; + } + +return 0 ; + +err_cmdq_ctxt: +hinic_wqs_cmdq_free (&cmdqs->cmdq_pages, cmdqs->saved_wqs, +HINIC_MAX_CMDQ_TYPES ); + +err_cmdq_wqs: +devm_kfree (&pdev->dev, cmdqs->saved_wqs); + +err_saved_wqs: +pci_pool_destroy (cmdqs->cmdq_buf_pool); +return err; }/**
@@ -83,5 +340,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 +156 -0
183 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 v6 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 | 16 ++ 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 | 291 +++++++++++++++++++++- 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 +16 -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_ctxt: cmdq ctxt to initialize * @cmdq: the cmdq
@@ -320,6 +331,8 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif, goto err_cmdq_ctxt; } +hinic_ceq_register_cb (&func_to_io->ceqs,HINIC_CEQ_CMDQ , cmdqs, + cmdq_ceq_handler);return 0 ; err_cmdq_ctxt:
@@ -340,10 +353,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
@@ -277,6 +277,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)struct hinic_cap *nic_cap = &hwdev->nic_cap;struct hinic_hwif *hwif = hwdev->hwif;int err, num_aeqs, num_ceqs, num_qps; +struct msix_entry *ceq_msix_entries;struct msix_entry *sq_msix_entries;struct msix_entry *rq_msix_entries;struct pci_dev *pdev = hwif->pdev;
@@ -290,7 +291,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, nic_cap->max_qps,0 ,NULL ); + + ceq_msix_entries = &hwdev->msix_entries[num_aeqs]; + + err =hinic_io_init (func_to_io, hwif, nic_cap->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 +285 -6
401 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
@@ -25,6 +25,7 @@#include <linux/err.h> #include "hinic_hw_if.h" +#include "hinic_hw_eqs.h" #include "hinic_hw_wqe.h" #include "hinic_hw_wq.h" #include "hinic_hw_cmdq.h"
@@ -455,10 +456,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 err_wqs_alloc; } func_to_io->db_base =pci_ioremap_bar (pdev,HINIC_PCI_DB_BAR );
@@ -499,6 +508,9 @@ int hinic_io_init(struct hinic_func_to_io *func_to_io, err_db_ioremap:hinic_wqs_free (&func_to_io->wqs); + +err_wqs_alloc: +hinic_ceqs_free (&func_to_io->ceqs);return err; }
@@ -517,4 +529,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 v6 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 | 9 + drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c | 282 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 38 +++ drivers/net/ethernet/huawei/hinic/hinic_hw_io.h | 10 + drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c | 194 +++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h | 12 + drivers/net/ethernet/huawei/hinic/hinic_hw_wqe.h | 115 +++++++++ 8 files changed, 683 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 +9 -0
@@ -16,6 +16,11 @@ #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;
@@ -26,4 +31,8 @@ struct hinic_sge {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 +280 -2
325 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h +38 -0
@@ -58,14 +58,52 @@ ((val) & (~((u64)HINIC_CMDQ_CTXT_##member##_MASK \ << HINIC_CMDQ_CTXT_##member##_SHIFT))) +#define HINIC_SAVED_DATA_ARM_SHIFT 31 + +#define HINIC_SAVED_DATA_ARM_MASK 0x1 + +#define HINIC_SAVED_DATA_SET (val, member) \ + (((u32)(val) & HINIC_SAVED_DATA_##member##_MASK) \ + << HINIC_SAVED_DATA_##member##_SHIFT) + +#define HINIC_SAVED_DATA_GET (val, member) \ + (((val) >> HINIC_SAVED_DATA_##member##_SHIFT) \ + & HINIC_SAVED_DATA_##member##_MASK) + +#define HINIC_SAVED_DATA_CLEAR (val, member) \ + ((val) & (~(HINIC_SAVED_DATA_##member##_MASK \ + << HINIC_SAVED_DATA_##member##_SHIFT))) + +#define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_SHIFT 0 +#define HINIC_CMDQ_DB_INFO_PATH_SHIFT 23 +#define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_SHIFT 24 +#define HINIC_CMDQ_DB_INFO_DB_TYPE_SHIFT 27 + +#define HINIC_CMDQ_DB_INFO_HI_PROD_IDX_MASK 0xFF +#define HINIC_CMDQ_DB_INFO_PATH_MASK 0x1 +#define HINIC_CMDQ_DB_INFO_CMDQ_TYPE_MASK 0x7 +#define HINIC_CMDQ_DB_INFO_DB_TYPE_MASK 0x1F + +#define HINIC_CMDQ_DB_INFO_SET (val, member) \ + (((u32)(val) & HINIC_CMDQ_DB_INFO_##member##_MASK) \ + << HINIC_CMDQ_DB_INFO_##member##_SHIFT) +#define HINIC_CMDQ_BUF_SIZE 2048 +#define HINIC_CMDQ_BUF_HW_RSVD 8 +#define HINIC_CMDQ_MAX_DATA_SIZE (HINIC_CMDQ_BUF_SIZE - \ + HINIC_CMDQ_BUF_HW_RSVD) +enum hinic_cmdq_type {HINIC_CMDQ_SYNC ,HINIC_MAX_CMDQ_TYPES , }; +enum hinic_cmd_ack_type { +HINIC_CMD_ACK_TYPE_CMDQ , +}; +struct hinic_cmdq_buf {void *buf;dma_addr_t dma_addr;
drivers/net/ethernet/huawei/hinic/hinic_hw_io.h +10 -0
@@ -32,6 +32,16 @@#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 , +HINIC_DATA_PATH , +}; +struct hinic_free_db_area {int db_idx[HINIC_DB_MAX_AREAS ];
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +194 -0
212 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.h +12 -0
@@ -21,6 +21,7 @@#include <linux/atomic.h> #include "hinic_hw_if.h" +#include "hinic_hw_wqe.h" struct hinic_free_block {int page_idx;
@@ -100,4 +101,15 @@ int hinic_wq_allocate(struct hinic_wqs *wqs, struct hinic_wq *wq,void hinic_wq_free (struct hinic_wqs *wqs,struct hinic_wq *wq); +struct hinic_hw_wqe *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); + +struct hinic_hw_wqe *hinic_read_wqe (struct hinic_wq *wq,unsigned int wqe_size, +u16 *cons_idx); + +void hinic_write_wqe (struct hinic_wq *wq,struct hinic_hw_wqe *wqe, +unsigned int wqe_size); +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_wqe.h +115 -0
139 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v6 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 | 297 +++++++++++++++++++++- drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h | 12 + 2 files changed, 308 insertions(+), 1 deletion(-)
drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c +296 -1
@@ -40,12 +40,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
@@ -145,6 +164,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 unsigned int cmdq_wqe_size_from_bdlen (enum bufdesc_len len) +{ +unsigned 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) {
@@ -211,6 +246,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,
@@ -239,6 +283,36 @@ 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; +enum completion_format complete_format; +struct hinic_cmdq_wqe_scmd *wqe_scmd; + + wqe_scmd = &direct_wqe->wqe_scmd; + +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,
@@ -352,6 +426,52 @@ 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_cmdq_wqe *curr_cmdq_wqe, cmdq_wqe; +u16 curr_prod_idx, next_prod_idx; +struct hinic_wq *wq = cmdq->wq; +struct hinic_hw_wqe *hw_wqe; +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*/ + hw_wqe =hinic_get_wqe (wq,WQE_SCMD_SIZE , &curr_prod_idx); +if (IS_ERR (hw_wqe)) { +spin_unlock (&cmdq->cmdq_lock); +return -EBUSY ; + } + + curr_cmdq_wqe = &hw_wqe->cmdq_wqe; + + 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 (&cmdq_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 (&cmdq_wqe,WQE_SCMD_SIZE ); + +/* cmdq wqe is not shadow, therefore wqe will be written to wq */ +cmdq_wqe_fill (curr_cmdq_wqe, &cmdq_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 )
@@ -389,13 +509,188 @@ 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); +unsigned int bufdesc_len, wqe_size; +struct hinic_ctrl *ctrl; + + bufdesc_len =HINIC_CMDQ_WQE_HEADER_GET (header_info,BUFDESC_LEN ); + wqe_size =cmdq_wqe_size_from_bdlen (bufdesc_len); +if (wqe_size ==WQE_LCMD_SIZE ) { +struct hinic_cmdq_wqe_lcmd *wqe_lcmd = &wqe->wqe_lcmd; + + ctrl = &wqe_lcmd->ctrl; + }else { +struct hinic_cmdq_direct_wqe *direct_wqe = &wqe->direct_wqe; +struct hinic_cmdq_wqe_scmd *wqe_scmd; + + 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; +struct hinic_ctrl *ctrl; +u32 ctrl_info; + + wqe_scmd = &direct_wqe->wqe_scmd; + ctrl = &wqe_scmd->ctrl; + 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); +} + +static int cmdq_cmd_ceq_handler (struct hinic_cmdq *cmdq,u16 ci, +struct hinic_cmdq_wqe *cmdq_wqe) +{ +struct hinic_cmdq_wqe_lcmd *wqe_lcmd = &cmdq_wqe->wqe_lcmd; +struct hinic_status *status = &wqe_lcmd->status; +struct hinic_ctrl *ctrl = &wqe_lcmd->ctrl; +int errcode; + +if (!CMDQ_WQE_COMPLETED (be32_to_cpu (ctrl->ctrl_info))) +return -EBUSY ; + + errcode =CMDQ_WQE_ERRCODE_GET (be32_to_cpu (status->status_info),VAL ); + +cmdq_sync_cmd_handler (cmdq, ci, errcode); + +clear_wqe_complete_bit (cmdq, cmdq_wqe); +hinic_put_wqe (cmdq->wq,WQE_LCMD_SIZE ); +return 0 ; +} + +/** * 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 */ +enum hinic_cmdq_type cmdq_type =CMDQ_CEQE_GET (ceqe_data,TYPE ); +struct hinic_cmdqs *cmdqs = (struct hinic_cmdqs *)handle; +struct hinic_cmdq *cmdq = &cmdqs->cmdq[cmdq_type]; +struct hinic_cmdq_header *header; +struct hinic_hw_wqe *hw_wqe; +int err, set_arm =0 ; +u32 saved_data; +u16 ci; + +/* Read the smallest wqe size for getting wqe size */ +while ((hw_wqe =hinic_read_wqe (cmdq->wq,WQE_SCMD_SIZE , &ci))) { +if (IS_ERR (hw_wqe)) +break ; + + header =CMDQ_WQE_HEADER (&hw_wqe->cmdq_wqe); + saved_data =be32_to_cpu (header->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, &hw_wqe->cmdq_wqe)) +break ; + }else { + set_arm =1 ; + + hw_wqe =hinic_read_wqe (cmdq->wq,WQE_LCMD_SIZE , &ci); +if (IS_ERR (hw_wqe)) +break ; + +if (cmdq_cmd_ceq_handler (cmdq, ci, &hw_wqe->cmdq_wqe)) +break ; + } + } + +if (set_arm) { +struct hinic_hwif *hwif = cmdqs->hwif; +struct pci_dev *pdev = hwif->pdev; + + 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
@@ -100,6 +100,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 , };
@@ -110,6 +114,11 @@ struct hinic_cmdq_buf {size_t size; }; +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;
@@ -167,6 +176,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 v6 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 | 13 + drivers/net/ethernet/huawei/hinic/hinic_hw_qp.c | 210 +++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 29 ++ 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 | 27 ++ 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 | 419 ++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_rx.h | 7 + 16 files changed, 1281 insertions(+)
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
@@ -133,6 +133,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_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 -0
@@ -69,8 +69,21 @@ enum hinic_cfg_cmd { };enum hinic_comm_cmd { +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_SQ_HI_CI_SET =0x14 , + +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 +210 -0
229 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +29 -0
@@ -21,6 +21,7 @@#include <linux/pci.h> #include <linux/skbuff.h> +#include "hinic_common.h" #include "hinic_hw_if.h" #include "hinic_hw_wqe.h" #include "hinic_hw_wq.h"
@@ -100,4 +101,32 @@ int hinic_init_rq(struct hinic_rq *rq, struct hinic_hwif *hwif,void hinic_clean_rq (struct hinic_rq *rq); +int hinic_get_rq_free_wqebbs (struct hinic_rq *rq); + +struct hinic_rq_wqe *hinic_rq_get_wqe (struct hinic_rq *rq, +unsigned int wqe_size,u16 *prod_idx); + +void hinic_rq_write_wqe (struct hinic_rq *rq,u16 prod_idx, +struct hinic_rq_wqe *wqe,struct sk_buff *skb); + +struct hinic_rq_wqe *hinic_rq_read_wqe (struct hinic_rq *rq, +unsigned int wqe_size, +struct sk_buff **skb,u16 *cons_idx); + +struct hinic_rq_wqe *hinic_rq_read_next_wqe (struct hinic_rq *rq, +unsigned int wqe_size, +struct sk_buff **skb, +u16 *cons_idx); + +void hinic_rq_put_wqe (struct hinic_rq *rq,u16 cons_idx, +unsigned int wqe_size); + +void hinic_rq_get_sge (struct hinic_rq *rq,struct hinic_rq_wqe *wqe, +u16 cons_idx,struct hinic_sge *sge); + +void hinic_rq_prepare_wqe (struct hinic_rq *rq,u16 prod_idx, +struct hinic_rq_wqe *wqe,struct hinic_sge *sge); + +void hinic_rq_update (struct hinic_rq *rq,u16 prod_idx); +#endif
drivers/net/ethernet/huawei/hinic/hinic_hw_wq.c +12 -0
@@ -828,6 +828,18 @@ struct hinic_hw_wqe *hinic_read_wqe(struct hinic_wq *wq, unsigned int wqe_size, }/** +* hinic_read_wqe_direct - read wqe directly from ci position +* @wq: wq +* @cons_idx: ci position +* +* Return wqe +**/ +struct hinic_hw_wqe *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
@@ -109,6 +109,8 @@ struct hinic_hw_wqe *hinic_get_wqe(struct hinic_wq *wq, unsigned int wqe_size,struct hinic_hw_wqe *hinic_read_wqe (struct hinic_wq *wq,unsigned int wqe_size,u16 *cons_idx); +struct hinic_hw_wqe *hinic_read_wqe_direct (struct hinic_wq *wq,u16 cons_idx); +void hinic_write_wqe (struct hinic_wq *wq,struct hinic_hw_wqe *wqe,unsigned int wqe_size);
drivers/net/ethernet/huawei/hinic/hinic_main.c +27 -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 PCI_DEVICE_ID_HI1822_PF 0x1822#define HINIC_WQ_NAME "hinic_dev"
@@ -220,6 +225,13 @@ static int hinic_open(struct net_device *netdev) goto err_port_state; } + err =hinic_port_set_func_state (nic_dev,HINIC_FUNC_PORT_ENABLE ); +if (err) { +netif_err (nic_dev, drv, netdev, +"Failed to set func port state\n" ); + goto err_func_port_state; + } +/* Wait up to 3 sec between port enable to link state */ msleep (3000 );
@@ -250,6 +262,12 @@ static int hinic_open(struct net_device *netdev) err_port_link:up (&nic_dev->mgmt_lock); + ret =hinic_port_set_func_state (nic_dev,HINIC_FUNC_PORT_DISABLE ); +if (ret) +netif_warn (nic_dev, drv, netdev, +"Failed to revert func port state\n" ); + +err_func_port_state: ret =hinic_port_set_state (nic_dev,HINIC_PORT_DISABLE );if (ret) netif_warn(nic_dev, drv, netdev,
@@ -283,6 +301,14 @@ 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) { +netif_err (nic_dev, drv, netdev, +"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) {netif_err (nic_dev, drv, netdev,"Failed to set port state\n" );
@@ -664,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
@@ -314,3 +314,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_port_func_state_cmd func_state; +struct hinic_hwdev *hwdev = nic_dev->hwdev; +struct hinic_hwif *hwif = hwdev->hwif; +struct pci_dev *pdev = hwif->pdev; +u16 out_size; +int err; + + func_state.func_idx =HINIC_HWIF_FUNC_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 +419 -0
451 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 v6 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_qp.c | 257 ++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h | 48 +++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 12 +- drivers/net/ethernet/huawei/hinic/hinic_tx.c | 406 +++++++++++++++++++++++ drivers/net/ethernet/huawei/hinic/hinic_tx.h | 11 + 8 files changed, 802 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_qp.c +257 -0
289 lines not on this page · raw message
drivers/net/ethernet/huawei/hinic/hinic_hw_qp.h +48 -0
74 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)" );
@@ -569,9 +573,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 = {
@@ -584,6 +590,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 +406 -0
439 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 v6 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 | 31 ++++ 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, 341 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 +31 -0
@@ -346,3 +346,34 @@ 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_FUNC_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, ret = %d\n" , + port_cap->status); +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
@@ -58,6 +58,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
@@ -67,6 +67,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
PATCH v6 21/21 net-next/hinic: Add netpoll
In reply to Aviad KrawczykAdd more netdev operation - netpoll.
--- MAINTAINERS | 7 +++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+)
MAINTAINERS +7 -0
@@ -6240,6 +6240,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/hinic/ + HUGETLB FILESYSTEM M: Nadia Yvette Chambers <[email protected]> S: Maintained
drivers/net/ethernet/huawei/hinic/hinic_main.c +20 -0
@@ -787,6 +787,23 @@ static void hinic_get_stats64(struct net_device *netdev, stats->tx_errors = nic_tx_stats->tx_dropped; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void hinic_netpoll (struct net_device *netdev) +{ +struct hinic_dev *nic_dev =netdev_priv (netdev); +int i, num_qps; + + num_qps =hinic_hwdev_num_qps (nic_dev->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,
@@ -799,6 +816,9 @@ 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, +#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 V6 21/21] net-next/hinic: Add netpoll
Hello.
Quoted 14 lines · Aviad Krawczyk
Add more netdev operation - netpoll.
Signed-off-by Aviad Krawczyk <[email protected]>Signed-off-by Zhao Chen <[email protected]>--- MAINTAINERS | 7 +++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+)MAINTAINERS +0
-0
MAINTAINERS L: [email protected] · line 6249
Quoted 10 lines
MAINTAINERS +7
-0@@ -6240,6 +6240,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/hinic/ +
Sorry for not asking this question before: how is the new MAINTAINERS
record related to the netpoll support? This should be in a separate patch.
[...]
MBR, Sergei
Re: [PATCH V6 21/21] net-next/hinic: Add netpoll
Will be fixed in V7
Thanks
Quoted 36 lines · Sergei Shtylyov
Hello.
Quoted 14 lines · Aviad Krawczyk
Add more netdev operation - netpoll.
Signed-off-by Aviad Krawczyk <[email protected]>Signed-off-by Zhao Chen <[email protected]>--- MAINTAINERS | 7 +++++++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+)MAINTAINERS +0
-0MAINTAINERS L: [email protected] · line 6248
Quoted 9 lines
MAINTAINERS +6
-0@@ -6240,6 +6240,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/hinic/ +Sorry for not asking this question before: how is the new
MAINTAINERSrecord related to the netpoll support? This should be in a separate patch.[...]
MBR, Sergei
.