// SPDX-License-Identifier: GPL-2.0-only /* * Huawei HiNIC PCI Express Linux driver * Copyright(c) 2017 Huawei Technologies Co., Ltd */ #include <linux/kernel.h> #include <linux/types.h> #include <linux/pci.h> #include <linux/device.h> #include <linux/errno.h> #include <linux/slab.h> #include <linux/bitops.h> #include <linux/delay.h> #include <linux/jiffies.h> #include <linux/log2.h> #include <linux/err.h> #include <linux/netdevice.h> #include <net/devlink.h> #include "hinic_devlink.h" #include "hinic_sriov.h" #include "hinic_dev.h" #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" #define OUTBOUND_STATE_TIMEOUT … #define DB_STATE_TIMEOUT … #define MAX_IRQS(max_qps, num_aeqs, num_ceqs) … #define ADDR_IN_4BYTES(addr) … enum intr_type { … }; /** * parse_capability - convert device capabilities to NIC capabilities * @hwdev: the HW device to set and convert device capabilities for * @dev_cap: device capabilities from FW * * Return 0 - Success, negative - Failure **/ static int parse_capability(struct hinic_hwdev *hwdev, struct hinic_dev_cap *dev_cap) { … } /** * get_capability - get device capabilities from FW * @pfhwdev: the PF HW device to get capabilities for * * Return 0 - Success, negative - Failure **/ static int get_capability(struct hinic_pfhwdev *pfhwdev) { … } /** * get_dev_cap - get device capabilities * @hwdev: the NIC HW device to get capabilities for * * Return 0 - Success, negative - Failure **/ static int get_dev_cap(struct hinic_hwdev *hwdev) { … } /** * init_msix - enable the msix and save the entries * @hwdev: the NIC HW device * * Return 0 - Success, negative - Failure **/ static int init_msix(struct hinic_hwdev *hwdev) { … } /** * disable_msix - disable the msix * @hwdev: the NIC HW device **/ 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) { … } int hinic_hilink_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_hilink_cmd cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { … } /** * init_fw_ctxt- Init Firmware tables before network mgmt and io operations * @hwdev: the NIC HW device * * Return 0 - Success, negative - Failure **/ static int init_fw_ctxt(struct hinic_hwdev *hwdev) { … } /** * set_hw_ioctxt - set the shape of the IO queues in FW * @hwdev: the NIC HW device * @rq_depth: rq depth * @sq_depth: sq depth * * Return 0 - Success, negative - Failure **/ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth, unsigned int rq_depth) { … } static int wait_for_outbound_state(struct hinic_hwdev *hwdev) { … } static int wait_for_db_state(struct hinic_hwdev *hwdev) { … } /** * clear_io_resources - set the IO resources as not active in the NIC * @hwdev: the NIC HW device * * Return 0 - Success, negative - Failure **/ static int clear_io_resources(struct hinic_hwdev *hwdev) { … } /** * set_resources_state - set the state of the resources in the NIC * @hwdev: the NIC HW device * @state: the state to set * * Return 0 - Success, negative - Failure **/ static int set_resources_state(struct hinic_hwdev *hwdev, enum hinic_res_state state) { … } /** * get_base_qpn - get the first qp number * @hwdev: the NIC HW device * @base_qpn: returned qp number * * Return 0 - Success, negative - Failure **/ static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn) { … } /** * hinic_hwdev_ifup - Preparing the HW for passing IO * @hwdev: the NIC HW device * @sq_depth: the send queue depth * @rq_depth: the receive queue depth * * Return 0 - Success, negative - Failure **/ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth) { … } /** * hinic_hwdev_ifdown - Closing the HW for passing IO * @hwdev: the NIC HW device * **/ void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev) { … } /** * hinic_hwdev_cb_register - register callback handler for MGMT events * @hwdev: the NIC HW device * @cmd: the mgmt event * @handle: private data for the handler * @handler: event handler **/ 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)) { … } /** * hinic_hwdev_cb_unregister - unregister callback handler for MGMT events * @hwdev: the NIC HW device * @cmd: the mgmt event **/ void hinic_hwdev_cb_unregister(struct hinic_hwdev *hwdev, enum hinic_mgmt_msg_cmd cmd) { … } /** * nic_mgmt_msg_handler - nic mgmt event handler * @handle: private data for the handler * @cmd: message command * @buf_in: input buffer * @in_size: input size * @buf_out: output buffer * @out_size: returned output size **/ static void nic_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { … } static void hinic_comm_recv_mgmt_self_cmd_reg(struct hinic_pfhwdev *pfhwdev, u8 cmd, comm_mgmt_self_msg_proc proc) { … } static void hinic_comm_recv_mgmt_self_cmd_unreg(struct hinic_pfhwdev *pfhwdev, u8 cmd) { … } static void comm_mgmt_msg_handler(void *handle, u8 cmd, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { … } /* pf fault report event */ static void pf_fault_event_handler(void *dev, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { … } static void mgmt_watchdog_timeout_event_handler(void *dev, void *buf_in, u16 in_size, void *buf_out, u16 *out_size) { … } /** * init_pfhwdev - Initialize the extended components of PF * @pfhwdev: the HW device for PF * * Return 0 - success, negative - failure **/ static int init_pfhwdev(struct hinic_pfhwdev *pfhwdev) { … } /** * free_pfhwdev - Free the extended components of PF * @pfhwdev: the HW device for PF **/ static void free_pfhwdev(struct hinic_pfhwdev *pfhwdev) { … } static int hinic_l2nic_reset(struct hinic_hwdev *hwdev) { … } static int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev, struct hinic_msix_config *interrupt_info) { … } int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev, struct hinic_msix_config *interrupt_info) { … } /** * hinic_init_hwdev - Initialize the NIC HW * @pdev: the NIC pci device * @devlink: the poniter of hinic devlink * * Return initialized NIC HW device * * Initialize the NIC HW device and return a pointer to it **/ struct hinic_hwdev *hinic_init_hwdev(struct pci_dev *pdev, struct devlink *devlink) { … } /** * hinic_free_hwdev - Free the NIC HW device * @hwdev: the NIC HW device **/ void hinic_free_hwdev(struct hinic_hwdev *hwdev) { … } /** * hinic_hwdev_num_qps - return the number QPs available for use * @hwdev: the NIC HW device * * Return number QPs available for use **/ int hinic_hwdev_num_qps(struct hinic_hwdev *hwdev) { … } /** * hinic_hwdev_get_sq - get SQ * @hwdev: the NIC HW device * @i: the position of the SQ * * Return: the SQ in the i position **/ struct hinic_sq *hinic_hwdev_get_sq(struct hinic_hwdev *hwdev, int i) { … } /** * hinic_hwdev_get_rq - get RQ * @hwdev: the NIC HW device * @i: the position of the RQ * * Return: the RQ in the i position **/ struct hinic_rq *hinic_hwdev_get_rq(struct hinic_hwdev *hwdev, int i) { … } /** * hinic_hwdev_msix_cnt_set - clear message attribute counters for msix entry * @hwdev: the NIC HW device * @msix_index: msix_index * * Return 0 - Success, negative - Failure **/ int hinic_hwdev_msix_cnt_set(struct hinic_hwdev *hwdev, u16 msix_index) { … } /** * hinic_hwdev_msix_set - set message attribute for msix entry * @hwdev: the NIC HW device * @msix_index: msix_index * @pending_limit: the maximum pending interrupt events (unit 8) * @coalesc_timer: coalesc period for interrupt (unit 8 us) * @lli_timer_cfg: replenishing period for low latency credit (unit 8 us) * @lli_credit_limit: maximum credits for low latency msix messages (unit 8) * @resend_timer: maximum wait for resending msix (unit coalesc period) * * Return 0 - Success, negative - Failure **/ int hinic_hwdev_msix_set(struct hinic_hwdev *hwdev, u16 msix_index, u8 pending_limit, u8 coalesc_timer, u8 lli_timer_cfg, u8 lli_credit_limit, u8 resend_timer) { … } /** * hinic_hwdev_hw_ci_addr_set - set cons idx addr and attributes in HW for sq * @hwdev: the NIC HW device * @sq: send queue * @pending_limit: the maximum pending update ci events (unit 8) * @coalesc_timer: coalesc period for update ci (unit 8 us) * * Return 0 - Success, negative - Failure **/ int hinic_hwdev_hw_ci_addr_set(struct hinic_hwdev *hwdev, struct hinic_sq *sq, u8 pending_limit, u8 coalesc_timer) { … } /** * hinic_hwdev_set_msix_state- set msix state * @hwdev: the NIC HW device * @msix_index: IRQ corresponding index number * @flag: msix state * **/ void hinic_hwdev_set_msix_state(struct hinic_hwdev *hwdev, u16 msix_index, enum hinic_msix_state flag) { … } int hinic_get_board_info(struct hinic_hwdev *hwdev, struct hinic_comm_board_info *board_info) { … }