Jintao 50c46e6857 Add LingYao
Change-Id: Iae6634ce565940904ee320c678d0f77473bebb90
2025-01-03 16:08:55 +08:00

737 lines
18 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2023, Jaguar Micro. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef _CRETE_H_
#define _CRETE_H_
#include <linux/pci.h>
#include <linux/timecounter.h>
#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/bitops.h>
#include <linux/if_vlan.h>
#include <linux/version.h>
#include <net/dst_metadata.h>
#ifndef USE_JM_AUX_BUS
#include <linux/auxiliary_bus.h>
#else
#include "linux/auxiliary_bus.h"
#endif
#include "kcompat_std_defs.h"
#include "rdma.h"
#include "crete_txrx.h"
#include "crete_sriov.h"
#include "crete_eswitch.h"
#include "crete_dcb_nl.h"
#include "crete_lag.h"
#include "crete_debugfs_statistics.h"
/*micro filed*/
#define MAX_MSIX_ENTRIES 10
#define MAX_Q_VECTORS 8
#define CRETE_MAX_TX_QUEUES 8
#define CRETE_MAX_RX_QUEUES 8
#define CRETE_DEFAULT_TXD 256
#define CRETE_DEFAULT_TX_WORK 128
#define CRETE_MIN_TXD 80
#define CRETE_MAX_TXD 4096
#define CRETE_DEFAULT_RXD 256
#define CRETE_MIN_RXD 80
#define CRETE_MAX_RXD 4096
#define CRETE_DEFAULT_ITR 3 /* dynamic */
#define CRETE_MAX_ITR_USECS 10000
#define CRETE_MIN_ITR_USECS 10
#define CRETE_Q_VECTORS 1
#define CRETE_ETH_PKT_HDR_PAD (ETH_HLEN + ETH_FCS_LEN)
/* As per the EAS the maximum supported size is 9.5KB (9728 bytes) */
#define MAX_JUMBO_FRAME_SIZE 0x2600
#define MAX_STD_JUMBO_FRAME_SIZE 9216
/* Supported Rx Buffer Sizes */
#define CRETE_RXBUFFER_256 256
#define CRETE_RXBUFFER_1536 1536
#define CRETE_RXBUFFER_2048 2048
#define CRETE_TS_HDR_LEN 16
#define ALIGN_TO_DW(a) (((a) + 3ULL) & (~3))
#define CRETE_CMD_WQ_MAX_NAME 32
/* device desc offset */
#define CRETE_JDH_OFFSET (CRETE_LEGACY_RESV)
#define CRETE_JND_OFFSET (CRETE_JDH_OFFSET + sizeof(struct crete_desc_hdr))
#define CRETE_JRD_OFFSET (CRETE_JND_OFFSET + sizeof(struct crete_ndc_dpt))
#define CRETE_CAP_OFFSET 8
enum {
CRETE_FLAG_DISABLE_ALL_ADEV = 1 << 0,
CRETE_PAGE_MODE = 1 << 1,
CRETE_FLAG_HAS_MSIX = 1 << 13,
};
#define CRETE_LEGACY_RESV 0x0
#define CRETE_MAGIC_NUM 0xdeadbeef
#define CRETE_EVENT_VECTOR 0
#define CRETE_CMD_DATA_BLOCK_SIZE 512
enum crete_coredev_type {
CRETE_COREDEV_PF,
CRETE_COREDEV_VF,
CRETE_COREDEV_SF,
};
enum crete_device_type {
CRETE_DEVICE_CRETE,
CRETE_DEVICE_PNIC,
CRETE_DEVICE_RNIC,
CRETE_DEVICE_FAKE,
};
enum {
CRETE_PCI_DEV_IS_VF = 1 << 0,
};
#define CRETE_ADEV_NAME "crete_core"
/*enum filed*/
enum crete_state_t {
__CRETE_TESTING,
__CRETE_RESETING,
__CRETE_DOWN,
};
/* Device Capability type */
enum crete_cap_type {
CRETE_NET_CONF_CAP = 2,
CRETE_RDMA_CONF_CAP = 3,
CRETE_OFFLOAD_CONF_CAP = 4,
CRETE_RES_CONF_CAP = 5,
CRETE_DEVS_CONF_CAP = 6,
CRETE_SHARES_DB_CAP = 7,
CRETE_CAP_MAX,
};
struct crete_init_seg {
uint16_t fw_ver_minor;
uint16_t fw_ver_major;
uint16_t fw_revision;
uint16_t cmd_interface_rev;
uint8_t cp_status;
uint8_t cp_caps;
uint8_t dev_status;
uint8_t reset_dev;
uint32_t cmd_path_db;
uint32_t cmd_path_entry[16];
uint32_t resv1[8];
uint32_t event_buffer[8];
uint32_t event_buffer_addr_low;
uint32_t event_buffer_addr_hi;
uint8_t event_busy;
uint8_t event_buffer_size;
uint16_t event_vector;
uint32_t event_credit_doorbell;
uint16_t resv2;
uint16_t aq_queue_size;
uint32_t aq_queue_db;
uint32_t aq_base_addr_low;
uint32_t aq_base_addr_hi;
uint32_t shared_res_lock;
uint32_t shared_res_db;
uint32_t extra_admin_db;
uint32_t resv3[13];
uint32_t timestamp[2];
} __packed;
struct cmd_info {
uint32_t owner:1;
uint32_t out_inline:1;
uint32_t in_inline:1;
uint32_t event_notify:1;
uint32_t status:4;
uint32_t sig:8;
uint32_t cmd_encap_type:8;
uint32_t cid:8;
};
struct crete_cmd_entry {
uint32_t in_len;
uint32_t out_len;
uint64_t in_ptr;
uint64_t out_ptr;
uint8_t inline_data[36];
union {
struct cmd_info cmd_info;
uint32_t cmd_info_data;
};
} __packed;
struct crete_cmd_prot_block {
u8 sig;
u8 block_num;
u8 rsvd0;
u8 cid;
uint32_t cmd_data_len;//CRETE_CMD_DATA_BLOCK_SIZE
uint64_t next;
uint32_t next_len;
uint32_t cmd_data[];
} __packed;
struct crete_cmd_mailbox {
void *buf;
dma_addr_t dma;
struct crete_cmd_mailbox *next;
};
struct crete_cmd_msg {
struct list_head list;
u32 msg_mode;
u32 len;
struct crete_cmd_mailbox *next;
u8 inline_data[36]; //inline bd Optimize todo
}__aligned(8);
#define CRETE_MAX_COMMANDS 32
struct crete_cmd_work_ent {
unsigned long state;
struct crete_cmd_msg *inb;
struct crete_cmd_msg *outb;
void *out;
int out_size;
int idx;
struct completion handling;
struct completion done;
struct crete_cmd *cmd;
struct work_struct work;
struct crete_cmd_entry *lay;
int ret;
u8 status;//fw return cmd status
u16 cmd_id;
bool polling;
u64 ts1;
u64 ts2;
/* Track the max comp handlers */
refcount_t refcnt;
};
struct crete_cmd {
struct crete_nb nb;
u8 mode;
u8 poll_mode;
void *cmd_buf;
dma_addr_t cmd_dma;
u32 cmd_size;
u32 cmd_stride;
struct dma_pool *pool;
int max_cmds;
unsigned long bitmask;
char wq_name[CRETE_CMD_WQ_MAX_NAME];
struct workqueue_struct *wq;
struct semaphore sem;
spinlock_t alloc_lock;
struct crete_cmd_work_ent *ent_arr[CRETE_MAX_COMMANDS];
};
/* for test qp create */
struct crete_qbase_info {
void *va;
dma_addr_t pa;
};
struct crete_queue_info {
uint8_t rx_qid;
uint16_t q_size;
uint16_t vec[2];
struct crete_qbase_info sq[2];
struct crete_qbase_info cq[2];
};
/*
*Device Capability Descriptor
*Device Capability Descriptor Header
*/
struct crete_desc_hdr {
uint32_t magic;
uint32_t cap_cnt:8;
uint32_t len:12;
uint32_t offset:12;
};
// net device configuration descriptor,cap_type = 2
struct crete_ndc_dpt {
uint32_t type:8;
uint32_t resv:24;
uint32_t len:12;
uint32_t offset:20;
};
// Rdma Device Configuration Descriptor,cap_type = 3
struct crete_rdma_cfg_desc {
uint32_t cap_type:8;
uint32_t resv:24;
uint32_t len:12;
uint32_t offset:20;
};
// Offload Configuration Descriptor,cap_type = 4
struct crete_offload_cfg_desc {
uint32_t cap_type:8;
uint32_t resv:24;
uint32_t len:12;
uint32_t offset:20;
};
// resource configuration descriptor,cap_type = 5
struct crete_rc_dpt {
uint32_t type:8;
uint32_t ru_size:12;
uint32_t ru_max:12;
uint32_t len:12;
uint32_t offset:20;
};
//Device-specific Configuration Descriptor,cap_type = 6
struct crete_devs_dpt {
uint32_t cap_type:8;
uint32_t resv:24;
uint32_t len:12;
uint32_t offset:20;
};
//Shared Data Descriptor,cap_type = 7
struct crete_shared_dpt {
uint32_t cap_type:8;
uint32_t len:24;
uint32_t offset;
};
/* hw */
struct crete_hw {
struct crete_init_seg __iomem *io_addr;
struct crete_desc_hdr jdh;
struct crete_ndc_dpt jnd;
struct crete_rdma_cfg_desc rdma_desc;
struct crete_offload_cfg_desc offload_desc;
struct crete_rc_dpt jrd;
struct crete_devs_dpt dev_spec_desc;
struct crete_shared_dpt share_data_desc;
};
struct crete_aux_dev {
struct crete_core_dev *core_dev;
struct auxiliary_device adev;
int idx;
};
#define CRETE_MAX_UC_ADDRS 4
#define CRETE_MAX_MC_ADDRS 16
#define L2_SET_RX_MASK_REQ_MASK_MCAST 0x1UL
#define L2_SET_RX_MASK_REQ_MASK_ALL_MCAST 0x2UL
#define L2_SET_RX_MASK_REQ_MASK_BCAST 0x4UL
#define L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS 0x8UL
struct crete_priv {
struct crete_core_dev *coredev;
struct crete_esw_rep *rep;
struct net_device *netdev;
struct workqueue_struct *wq;
struct work_struct set_rx_mode_work;
struct crete_dcbx dcbx;
struct crete_dcbx_dp dcbx_dp;
/* vport rx mode */
u32 rx_mask;
__le64 fw_l2_filter_id[CRETE_MAX_UC_ADDRS];
/* index 0 always dev_addr */
u16 uc_filter_count;
u8 *uc_list;
u8 *mc_list;
int mc_list_size;
int mc_list_count;
int vlan_range_num;
};
struct crete_debugfs_entries {
struct dentry *dbg_root;
struct dentry *lag_debugfs;
struct dentry *statistics_debugfs;
};
struct crete_irq_info {
char name[IFNAMSIZ + 2];
irq_handler_t handler;
unsigned int vector;
u8 requested:1;
u8 have_cpumask:1;
};
struct crete_pf_info {
u16 fw_fid;
u16 port_id;
u8 mac_addr[ETH_ALEN];
u32 first_vf_id;
u16 active_vfs;
u16 registered_vfs;
u16 max_vfs;
void *hwrm_cmd_req_addr[4];
dma_addr_t hwrm_cmd_req_dma_addr[4];
struct crete_vf_info *vf;
struct kobject *config;
struct kobject *groups_config;
struct crete_sriov_vf_sysfs *vf_sysfs;
};
struct rdma_dev_adapt {
unsigned int flags;
unsigned int priv_flags;
unsigned int bar_offset;
unsigned int bar_len;
phys_addr_t uar_base;
unsigned int uar_size;
void __iomem *reg_addr; /*bar addr*/
__le32 *cmd_db_reg; /* cmd db addr*/
__le32 __iomem *eq_db_reg;
struct mutex intf_state_mutex;
unsigned int vector_base;
unsigned int vector_num;
};
struct crete_qp_context {
__le16 rx_qid; /* must be even */
__le16 event_credit;
__le16 rx_sq_vq_size; /* vnet rx vq size */
__le16 rx_cq_size; /* unless for vnet */
__le16 tx_sq_vq_size; /* tx vq size for vnet */
__le16 tx_cq_size; /* useless for vnet */
__le16 rx_queue_vec; /* rx queue interrupt vector */
__le16 tx_queue_vec; /* tx queue interrupt vector */
__le64 rx_sq_desc_base; /* rx queue desc base address for vnet */
__le64 rx_cq_used_base; /* rx cq address ,rx used ring address for vnet */
__le64 tx_sq_desc_base; /* tx sq address, tx queue desc address for vnet */
__le64 tx_cq_used_base; /* tx cq address, tx queue used ring address for vnet */
};
struct crete_queue_context {
__le16 qid; /* must be even */
__le16 queue_size; /* vnet io vq size */
__le16 cq_size; /* vnet cq size */
__le16 queue_vec; /*queue interrupt vector */
__le16 resv; /*reserved */
__le64 queue_desc_base; /* rx queue desc base address for vnet */
__le64 queue_used_base; /* rx cq address ,rx used ring address for vnet */
};
struct crete_core_qpcap {
u16 max_queue_size;
u8 max_qp_num;
u8 ctrl_queue_size;
};
struct crete_core_cap {
struct crete_core_qpcap qpcap;
__le64 hw_features;
__le64 driver_features;
// pf core cap need more
};
struct crete_qp_cap {
u8 ctrl_queue_size;
u8 max_qp_num;
__le16 max_queue_size;
} __packed;
struct crete_txq_stats {
struct u64_stats_sync syncp;
u64 packets;
u64 bytes;
u64 kicks;
};
struct crete_rxq_stats {
struct u64_stats_sync syncp;
u64 packets;
u64 bytes;
u64 drops;
u64 kicks;
};
#define CRETE_TXQ_STATS(m) offsetof(struct crete_txq_stats, m)
#define CRETE_RXQ_STATS(m) offsetof(struct crete_rxq_stats, m)
struct crete_core_dev {
#define CRETE_MAX_MSIX_NUM 4096U
spinlock_t lock;
struct device *device;
void __iomem *db_base;
struct pci_dev *pdev;
struct crete_core_cap cap;
struct crete_txring_info *txring;
u16 *txring_mapping;
// u16 txring_size;
struct crete_rxring_info *rxring;
u16 *rxring_mapping;
// u16 rxring_size;
u16 ring_size;
// ring parameters
u32 rx_buf_size;
u32 rx_buf_use_size; /* useable size */
u16 rx_offset;
u16 rx_dma_offset;
struct crete_db *db;
//struct crete_core_cap *cap;
struct crete_napi *jnapi;
struct crete_rxcp_ring_info *rxcpring;
struct crete_txcp_ring_info *txcpring;
u16 max_qp_num;
unsigned long state;
struct net_device *netdev;
u64 netdev_features;
u64 offload_features;
unsigned int flags;
u32 rss_queues;
u8 __iomem *io_addr;
phys_addr_t bar_addr; //for further consider
struct crete_hw hw;
struct crete_queue_info q_info; // for create qp test
struct crete_aux_dev **adev;
int adev_idx;
struct crete_irq_info *irq_info;
struct crete_cmd cmd;
struct crete_event_irq *event_irq;
u16 irq_num;
unsigned long irqbit[BITS_TO_LONGS(CRETE_MAX_MSIX_NUM)];
struct msix_entry *msix_ent;
enum crete_coredev_type coredev_type;
enum crete_device_type device_type;
struct crete_pf_info pf;
struct crete_vf_info vf;
bool sriov_cfg;
struct jm_rdma_core rdma_coredev;
struct rdma_dev_adapt rdma_adp;
struct crete_eswitch *eswitch;
struct crete_lag_cap lag_cap;
struct crete_debugfs_entries dbg;
struct crete_lag *lag_dev;
struct crete_debugfs_statistics *debugfs_statis;
u16 sfi_id;
u16 lag_enable;
};
enum crete_feature_type {
CRETE_FEATURE_NETDEV,
CRETE_FEATURE_OFFLOAD
};
static inline unsigned int crete_rd32(struct crete_core_dev *p, u32 reg)
{
u8 __iomem *ioaddr = READ_ONCE(p->io_addr);
u32 value = 0;
value = readl(&ioaddr[reg]);
return value;
}
static inline void crete_ioread32(void __iomem *addr, void *buffer,
unsigned int count)
{
int i = 0;
u32 *buf = buffer;
u8 __iomem *address = addr;
if (count) {
for (i = 0; i < count; i++)
readsl(address + i * 4, buf++, 1);
}
}
static inline void crete_iowrite32(void __iomem *addr, void *buffer,
unsigned int count)
{
int i = 0;
u32 *buf = buffer;
u8 __iomem *address = addr;
if (count) {
for (i = 0; i < count; i++)
writesl(address + i * 4, buf++, 1);
}
}
static inline struct device *crete_hw_to_dev(struct crete_hw *hw)
{
struct crete_core_dev *core_dev = container_of(hw, struct crete_core_dev, hw);
return &core_dev->pdev->dev;
}
int crete_adev_idx_alloc(void);
void crete_adev_idx_free(int idx);
static inline bool crete_sriov_is_enabled(struct crete_core_dev *dev)
{
return pci_num_vf(dev->pdev) ? true : false;
}
static inline bool crete_core_is_pf(const struct crete_core_dev *dev)
{
return dev->coredev_type == CRETE_COREDEV_PF;
}
static inline bool crete_core_is_vf(const struct crete_core_dev *dev)
{
return dev->coredev_type == CRETE_COREDEV_VF;
}
static inline bool crete_have_rdma_cap(const struct crete_core_dev *dev)
{
return dev->hw.rdma_desc.cap_type == CRETE_RDMA_CONF_CAP;
}
static inline bool crete_have_net_cap(const struct crete_core_dev *dev)
{
return dev->hw.jnd.type == CRETE_NET_CONF_CAP;
}
static inline u16 fw_ver_maj(struct crete_core_dev *dev)
{
struct crete_hw *hw = &dev->hw;
return readw(&hw->io_addr->fw_ver_major);
}
static inline u16 fw_ver_min(struct crete_core_dev *dev)
{
struct crete_hw *hw = &dev->hw;
return readw(&hw->io_addr->fw_ver_minor);
}
static inline u16 fw_ver_sub(struct crete_core_dev *dev)
{
struct crete_hw *hw = &dev->hw;
return readw(&hw->io_addr->cmd_interface_rev);
}
static inline u16 fw_ver_rev(struct crete_core_dev *dev)
{
struct crete_hw *hw = &dev->hw;
return readw(&hw->io_addr->fw_revision);
}
int crete_req_msixirq(struct crete_core_dev *core_dev);
void crete_free_msixirq(struct crete_core_dev *core_dev, int irq);
static inline bool __crete_test_bit(const u64 features, unsigned int fbit)
{
/* Did you forget to fix assumptions on max features? */
if (__builtin_constant_p(fbit))
BUILD_BUG_ON(fbit >= 64);
else
WARN_ON_ONCE(fbit >= 64);
return features & BIT_ULL(fbit);
}
static inline bool crete_has_feature(const struct crete_core_dev *cdev,
enum crete_feature_type feature_type, unsigned int fbit)
{
if (feature_type == CRETE_FEATURE_NETDEV)
return __crete_test_bit(cdev->netdev_features, fbit);
else
return __crete_test_bit(cdev->offload_features, fbit);
}
/* NEED_ETH_HW_ADDR_SET
*
* eth_hw_addr_set was added by upstream commit
* 48eab831ae8b ("net: create netdev->dev_addr assignment helpers")
*
* Using eth_hw_addr_set became required in 5.17, when the dev_addr field in
* the netdev struct was constified. See 48eab831ae8b ("net: create
* netdev->dev_addr assignment helpers")
*/
#ifdef NEED_ETH_HW_ADDR_SET
static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr)
{
ether_addr_copy(dev->dev_addr, addr);
}
#endif /* NEED_ETH_HW_ADDR_SET */
int crete_cmd_init(struct crete_core_dev *cdev);
int crete_event_init(struct crete_hw *hw);
void crete_cmd_exit(struct crete_core_dev *cdev);
void crete_event_exit(struct crete_hw *hw);
int crete_adev_init(struct crete_core_dev *core_dev);
void crete_adev_cleanup(struct crete_core_dev *core_dev);
int crete_rescan_drivers_locked(struct crete_core_dev *core_dev);
int crete_rescan_drivers(struct crete_core_dev *dev);
void crete_dev_list_lock(void);
void crete_dev_list_unlock(void);
int crete_dev_list_trylock(void);
void crete_sriov_disable(struct pci_dev *pdev);
int crete_register_device(struct crete_core_dev *core_dev);
void crete_unregister_device(struct crete_core_dev *core_dev);
void crete_detach_device(struct crete_core_dev *core_dev);
int crete_attach_device(struct crete_core_dev *core_dev);
int crete_change_mac_addr(struct net_device *netdev, void *p);
void crete_set_rx_mode(struct net_device *dev);
void crete_init_msix(struct crete_core_dev *core_dev);
void crete_exit_irq(struct crete_core_dev *core_dev);
extern struct dentry *crete_debugfs_root;
void crete_register_debugfs(void);
void crete_unregister_debugfs(void);
struct dentry *crete_debugfs_get_dev_root(struct crete_core_dev *dev);
extern const struct net_device_ops crete_netdev_ops;
extern const struct ethtool_ops crete_ethtool_ops;
#endif