Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,22 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Emulex driver configuration
#
config NET_VENDOR_EMULEX
bool "Emulex devices"
default y
depends on PCI
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 Emulex cards. If you say Y, you will be asked for
your specific card in the following questions.
if NET_VENDOR_EMULEX
source "drivers/net/ethernet/emulex/benet/Kconfig"
endif # NET_VENDOR_EMULEX
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the Emulex device drivers.
#
obj-$(CONFIG_BE2NET) += benet/
@@ -0,0 +1,52 @@
# SPDX-License-Identifier: GPL-2.0-only
config BE2NET
tristate "ServerEngines' 10Gbps NIC - BladeEngine"
depends on PCI
help
This driver implements the NIC functionality for ServerEngines'
10Gbps network adapter - BladeEngine.
config BE2NET_HWMON
bool "HWMON support for be2net driver"
depends on BE2NET && HWMON
depends on !(BE2NET=y && HWMON=m)
default y
help
Say Y here if you want to expose thermal sensor data on
be2net network adapter.
config BE2NET_BE2
bool "Support for BE2 chipsets"
depends on BE2NET
default y
help
Say Y here if you want to use devices based on BE2
chipsets. (e.g. OneConnect OCe10xxx)
config BE2NET_BE3
bool "Support for BE3 chipsets"
depends on BE2NET
default y
help
Say Y here if you want to use devices based on BE3
chipsets. (e.g. OneConnect OCe11xxx)
config BE2NET_LANCER
bool "Support for Lancer chipsets"
depends on BE2NET
default y
help
Say Y here if you want to use devices based on Lancer
chipsets. (e.g LightPulse LPe12xxx)
config BE2NET_SKYHAWK
bool "Support for Skyhawk chipsets"
depends on BE2NET
default y
help
Say Y here if you want to use devices based on Skyhawk
chipsets. (e.g. OneConnect OCe14xxx)
comment "WARNING: be2net is useless without any enabled chip"
depends on BE2NET_BE2=n && BE2NET_BE3=n && BE2NET_LANCER=n && \
BE2NET_SKYHAWK=n && BE2NET
@@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile to build the network driver for ServerEngine's BladeEngine.
#
obj-$(CONFIG_BE2NET) += be2net.o
be2net-y := be_main.o be_cmds.o be_ethtool.o be_roce.o
@@ -0,0 +1,985 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2005 - 2016 Broadcom
* All rights reserved.
*
* Contact Information:
* linux-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*/
#ifndef BE_H
#define BE_H
#include <linux/pci.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <net/tcp.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/u64_stats_sync.h>
#include <linux/cpumask.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include "be_hw.h"
#include "be_roce.h"
#define DRV_NAME "be2net"
#define BE_NAME "Emulex BladeEngine2"
#define BE3_NAME "Emulex BladeEngine3"
#define OC_NAME "Emulex OneConnect"
#define OC_NAME_BE OC_NAME "(be3)"
#define OC_NAME_LANCER OC_NAME "(Lancer)"
#define OC_NAME_SH OC_NAME "(Skyhawk)"
#define DRV_DESC "Emulex OneConnect NIC Driver"
#define BE_VENDOR_ID 0x19a2
#define EMULEX_VENDOR_ID 0x10df
#define BE_DEVICE_ID1 0x211
#define BE_DEVICE_ID2 0x221
#define OC_DEVICE_ID1 0x700 /* Device Id for BE2 cards */
#define OC_DEVICE_ID2 0x710 /* Device Id for BE3 cards */
#define OC_DEVICE_ID3 0xe220 /* Device id for Lancer cards */
#define OC_DEVICE_ID4 0xe228 /* Device id for VF in Lancer */
#define OC_DEVICE_ID5 0x720 /* Device Id for Skyhawk cards */
#define OC_DEVICE_ID6 0x728 /* Device id for VF in SkyHawk */
#define OC_SUBSYS_DEVICE_ID1 0xE602
#define OC_SUBSYS_DEVICE_ID2 0xE642
#define OC_SUBSYS_DEVICE_ID3 0xE612
#define OC_SUBSYS_DEVICE_ID4 0xE652
/* Number of bytes of an RX frame that are copied to skb->data */
#define BE_HDR_LEN ((u16) 64)
/* allocate extra space to allow tunneling decapsulation without head reallocation */
#define BE_RX_SKB_ALLOC_SIZE 256
#define BE_MAX_JUMBO_FRAME_SIZE 9018
#define BE_MIN_MTU 256
#define BE_MAX_MTU (BE_MAX_JUMBO_FRAME_SIZE - \
(ETH_HLEN + ETH_FCS_LEN))
/* Accommodate for QnQ configurations where VLAN insertion is enabled in HW */
#define BE_MAX_GSO_SIZE (65535 - 2 * VLAN_HLEN)
#define BE_NUM_VLANS_SUPPORTED 64
#define BE_MAX_EQD 128u
#define BE_MAX_TX_FRAG_COUNT 30
#define EVNT_Q_LEN 1024
#define TX_Q_LEN 2048
#define TX_CQ_LEN 1024
#define RX_Q_LEN 1024 /* Does not support any other value */
#define RX_CQ_LEN 1024
#define MCC_Q_LEN 128 /* total size not to exceed 8 pages */
#define MCC_CQ_LEN 256
#define BE2_MAX_RSS_QS 4
#define BE3_MAX_RSS_QS 16
#define BE3_MAX_TX_QS 16
#define BE3_MAX_EVT_QS 16
#define BE3_SRIOV_MAX_EVT_QS 8
#define SH_VF_MAX_NIC_EQS 3 /* Skyhawk VFs can have a max of 4 EQs
* and at least 1 is granted to either
* SURF/DPDK
*/
#define MAX_PORT_RSS_TABLES 15
#define MAX_NIC_FUNCS 16
#define MAX_RX_QS 32
#define MAX_EVT_QS 32
#define MAX_TX_QS 32
#define MAX_ROCE_EQS 5
#define MAX_MSIX_VECTORS 32
#define MIN_MSIX_VECTORS 1
#define MAX_RX_POST NAPI_POLL_WEIGHT /* Frags posted at a time */
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
#define MAX_NUM_POST_ERX_DB 255u
#define MAX_VFS 30 /* Max VFs supported by BE3 FW */
#define FW_VER_LEN 32
#define CNTL_SERIAL_NUM_WORDS 8 /* Controller serial number words */
#define CNTL_SERIAL_NUM_WORD_SZ (sizeof(u16)) /* Byte-sz of serial num word */
#define RSS_INDIR_TABLE_LEN 128
#define RSS_HASH_KEY_LEN 40
#define BE_UNKNOWN_PHY_STATE 0xFF
struct be_dma_mem {
void *va;
dma_addr_t dma;
u32 size;
};
struct be_queue_info {
u32 len;
u32 entry_size; /* Size of an element in the queue */
u32 tail, head;
atomic_t used; /* Number of valid elements in the queue */
u32 id;
struct be_dma_mem dma_mem;
bool created;
};
static inline u32 MODULO(u32 val, u32 limit)
{
BUG_ON(limit & (limit - 1));
return val & (limit - 1);
}
static inline void index_adv(u32 *index, u32 val, u32 limit)
{
*index = MODULO((*index + val), limit);
}
static inline void index_inc(u32 *index, u32 limit)
{
*index = MODULO((*index + 1), limit);
}
static inline void *queue_head_node(struct be_queue_info *q)
{
return q->dma_mem.va + q->head * q->entry_size;
}
static inline void *queue_tail_node(struct be_queue_info *q)
{
return q->dma_mem.va + q->tail * q->entry_size;
}
static inline void *queue_index_node(struct be_queue_info *q, u16 index)
{
return q->dma_mem.va + index * q->entry_size;
}
static inline void queue_head_inc(struct be_queue_info *q)
{
index_inc(&q->head, q->len);
}
static inline void index_dec(u32 *index, u32 limit)
{
*index = MODULO((*index - 1), limit);
}
static inline void queue_tail_inc(struct be_queue_info *q)
{
index_inc(&q->tail, q->len);
}
struct be_eq_obj {
struct be_queue_info q;
char desc[32];
struct be_adapter *adapter;
struct napi_struct napi;
u8 idx; /* array index */
u8 msix_idx;
u16 spurious_intr;
cpumask_var_t affinity_mask;
} ____cacheline_aligned_in_smp;
struct be_aic_obj { /* Adaptive interrupt coalescing (AIC) info */
u32 min_eqd; /* in usecs */
u32 max_eqd; /* in usecs */
u32 prev_eqd; /* in usecs */
u32 et_eqd; /* configured val when aic is off */
ulong jiffies;
u64 rx_pkts_prev; /* Used to calculate RX pps */
u64 tx_reqs_prev; /* Used to calculate TX pps */
};
struct be_mcc_obj {
struct be_queue_info q;
struct be_queue_info cq;
bool rearm_cq;
};
struct be_tx_stats {
u64 tx_bytes;
u64 tx_pkts;
u64 tx_vxlan_offload_pkts;
u64 tx_reqs;
u64 tx_compl;
u32 tx_stops;
u32 tx_drv_drops; /* pkts dropped by driver */
/* the error counters are described in be_ethtool.c */
u32 tx_hdr_parse_err;
u32 tx_dma_err;
u32 tx_tso_err;
u32 tx_spoof_check_err;
u32 tx_qinq_err;
u32 tx_internal_parity_err;
u32 tx_sge_err;
struct u64_stats_sync sync;
struct u64_stats_sync sync_compl;
};
/* Structure to hold some data of interest obtained from a TX CQE */
struct be_tx_compl_info {
u8 status; /* Completion status */
u16 end_index; /* Completed TXQ Index */
};
struct be_tx_obj {
u32 db_offset;
struct be_tx_compl_info txcp;
struct be_queue_info q;
struct be_queue_info cq;
/* Remember the skbs that were transmitted */
struct sk_buff *sent_skb_list[TX_Q_LEN];
struct be_tx_stats stats;
u16 pend_wrb_cnt; /* Number of WRBs yet to be given to HW */
u16 last_req_wrb_cnt; /* wrb cnt of the last req in the Q */
u16 last_req_hdr; /* index of the last req's hdr-wrb */
} ____cacheline_aligned_in_smp;
/* Struct to remember the pages posted for rx frags */
struct be_rx_page_info {
struct page *page;
/* set to page-addr for last frag of the page & frag-addr otherwise */
DEFINE_DMA_UNMAP_ADDR(bus);
u16 page_offset;
bool last_frag; /* last frag of the page */
};
struct be_rx_stats {
u64 rx_bytes;
u64 rx_pkts;
u64 rx_vxlan_offload_pkts;
u32 rx_drops_no_skbs; /* skb allocation errors */
u32 rx_drops_no_frags; /* HW has no fetched frags */
u32 rx_post_fail; /* page post alloc failures */
u32 rx_compl;
u32 rx_mcast_pkts;
u32 rx_compl_err; /* completions with err set */
struct u64_stats_sync sync;
};
struct be_rx_compl_info {
u32 rss_hash;
u16 vlan_tag;
u16 pkt_size;
u16 port;
u8 vlanf;
u8 num_rcvd;
u8 err;
u8 ipf;
u8 tcpf;
u8 udpf;
u8 ip_csum;
u8 l4_csum;
u8 ipv6;
u8 qnq;
u8 pkt_type;
u8 ip_frag;
u8 tunneled;
};
struct be_rx_obj {
struct be_adapter *adapter;
struct be_queue_info q;
struct be_queue_info cq;
struct be_rx_compl_info rxcp;
struct be_rx_page_info page_info_tbl[RX_Q_LEN];
struct be_rx_stats stats;
u8 rss_id;
bool rx_post_starved; /* Zero rx frags have been posted to BE */
} ____cacheline_aligned_in_smp;
struct be_drv_stats {
u32 eth_red_drops;
u32 dma_map_errors;
u32 rx_drops_no_pbuf;
u32 rx_drops_no_txpb;
u32 rx_drops_no_erx_descr;
u32 rx_drops_no_tpre_descr;
u32 rx_drops_too_many_frags;
u32 forwarded_packets;
u32 rx_drops_mtu;
u32 rx_crc_errors;
u32 rx_alignment_symbol_errors;
u32 rx_pause_frames;
u32 rx_priority_pause_frames;
u32 rx_control_frames;
u32 rx_in_range_errors;
u32 rx_out_range_errors;
u32 rx_frame_too_long;
u32 rx_address_filtered;
u32 rx_dropped_too_small;
u32 rx_dropped_too_short;
u32 rx_dropped_header_too_small;
u32 rx_dropped_tcp_length;
u32 rx_dropped_runt;
u32 rx_ip_checksum_errs;
u32 rx_tcp_checksum_errs;
u32 rx_udp_checksum_errs;
u32 tx_pauseframes;
u32 tx_priority_pauseframes;
u32 tx_controlframes;
u32 rxpp_fifo_overflow_drop;
u32 rx_input_fifo_overflow_drop;
u32 pmem_fifo_overflow_drop;
u32 jabber_events;
u32 rx_roce_bytes_lsd;
u32 rx_roce_bytes_msd;
u32 rx_roce_frames;
u32 roce_drops_payload_len;
u32 roce_drops_crc;
};
/* A vlan-id of 0xFFFF must be used to clear transparent vlan-tagging */
#define BE_RESET_VLAN_TAG_ID 0xFFFF
struct be_vf_cfg {
unsigned char mac_addr[ETH_ALEN];
int if_handle;
int pmac_id;
u16 vlan_tag;
u32 tx_rate;
u32 plink_tracking;
u32 privileges;
bool spoofchk;
};
enum vf_state {
ENABLED = 0,
ASSIGNED = 1
};
#define BE_FLAGS_LINK_STATUS_INIT BIT(1)
#define BE_FLAGS_SRIOV_ENABLED BIT(2)
#define BE_FLAGS_WORKER_SCHEDULED BIT(3)
#define BE_FLAGS_NAPI_ENABLED BIT(6)
#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD BIT(7)
#define BE_FLAGS_VXLAN_OFFLOADS BIT(8)
#define BE_FLAGS_SETUP_DONE BIT(9)
#define BE_FLAGS_PHY_MISCONFIGURED BIT(10)
#define BE_FLAGS_ERR_DETECTION_SCHEDULED BIT(11)
#define BE_FLAGS_OS2BMC BIT(12)
#define BE_FLAGS_TRY_RECOVERY BIT(13)
#define BE_UC_PMAC_COUNT 30
#define BE_VF_UC_PMAC_COUNT 2
#define MAX_ERR_RECOVERY_RETRY_COUNT 3
#define ERR_DETECTION_DELAY 1000
/* Ethtool set_dump flags */
#define LANCER_INITIATE_FW_DUMP 0x1
#define LANCER_DELETE_FW_DUMP 0x2
struct phy_info {
/* From SFF-8472 spec */
#define SFP_VENDOR_NAME_LEN 17
u8 transceiver;
u8 autoneg;
u8 fc_autoneg;
u8 port_type;
u16 phy_type;
u16 interface_type;
u32 misc_params;
u16 auto_speeds_supported;
u16 fixed_speeds_supported;
int link_speed;
u32 advertising;
u32 supported;
u8 cable_type;
u8 vendor_name[SFP_VENDOR_NAME_LEN];
u8 vendor_pn[SFP_VENDOR_NAME_LEN];
};
struct be_resources {
u16 max_vfs; /* Total VFs "really" supported by FW/HW */
u16 max_mcast_mac;
u16 max_tx_qs;
u16 max_rss_qs;
u16 max_rx_qs;
u16 max_cq_count;
u16 max_uc_mac; /* Max UC MACs programmable */
u16 max_vlans; /* Number of vlans supported */
u16 max_iface_count;
u16 max_mcc_count;
u16 max_evt_qs;
u16 max_nic_evt_qs; /* NIC's share of evt qs */
u32 if_cap_flags;
u32 vf_if_cap_flags; /* VF if capability flags */
u32 flags;
/* Calculated PF Pool's share of RSS Tables. This is not enforced by
* the FW, but is a self-imposed driver limitation.
*/
u16 max_rss_tables;
};
/* These are port-wide values */
struct be_port_resources {
u16 max_vfs;
u16 nic_pfs;
};
#define be_is_os2bmc_enabled(adapter) (adapter->flags & BE_FLAGS_OS2BMC)
struct rss_info {
u8 rsstable[RSS_INDIR_TABLE_LEN];
u8 rss_queue[RSS_INDIR_TABLE_LEN];
u8 rss_hkey[RSS_HASH_KEY_LEN];
u64 rss_flags;
};
#define BE_INVALID_DIE_TEMP 0xFF
struct be_hwmon {
struct device *hwmon_dev;
u8 be_on_die_temp; /* Unit: millidegree Celsius */
};
/* Macros to read/write the 'features' word of be_wrb_params structure.
*/
#define BE_WRB_F_BIT(name) BE_WRB_F_##name##_BIT
#define BE_WRB_F_MASK(name) BIT_MASK(BE_WRB_F_##name##_BIT)
#define BE_WRB_F_GET(word, name) \
(((word) & (BE_WRB_F_MASK(name))) >> BE_WRB_F_BIT(name))
#define BE_WRB_F_SET(word, name, val) \
((word) |= (((val) << BE_WRB_F_BIT(name)) & BE_WRB_F_MASK(name)))
/* Feature/offload bits */
enum {
BE_WRB_F_CRC_BIT, /* Ethernet CRC */
BE_WRB_F_IPCS_BIT, /* IP csum */
BE_WRB_F_TCPCS_BIT, /* TCP csum */
BE_WRB_F_UDPCS_BIT, /* UDP csum */
BE_WRB_F_LSO_BIT, /* LSO */
BE_WRB_F_LSO6_BIT, /* LSO6 */
BE_WRB_F_VLAN_BIT, /* VLAN */
BE_WRB_F_VLAN_SKIP_HW_BIT, /* Skip VLAN tag (workaround) */
BE_WRB_F_OS2BMC_BIT /* Send packet to the management ring */
};
/* The structure below provides a HW-agnostic abstraction of WRB params
* retrieved from a TX skb. This is in turn passed to chip specific routines
* during transmit, to set the corresponding params in the WRB.
*/
struct be_wrb_params {
u32 features; /* Feature bits */
u16 vlan_tag; /* VLAN tag */
u16 lso_mss; /* MSS for LSO */
};
struct be_eth_addr {
unsigned char mac[ETH_ALEN];
};
#define BE_SEC 1000 /* in msec */
#define BE_MIN (60 * BE_SEC) /* in msec */
#define BE_HOUR (60 * BE_MIN) /* in msec */
#define ERR_RECOVERY_MAX_RETRY_COUNT 3
#define ERR_RECOVERY_DETECTION_DELAY BE_SEC
#define ERR_RECOVERY_RETRY_DELAY (30 * BE_SEC)
/* UE-detection-duration in BEx/Skyhawk:
* All PFs must wait for this duration after they detect UE before reading
* SLIPORT_SEMAPHORE register. At the end of this duration, the Firmware
* guarantees that the SLIPORT_SEMAPHORE register is updated to indicate
* if the UE is recoverable.
*/
#define ERR_RECOVERY_UE_DETECT_DURATION BE_SEC
/* Initial idle time (in msec) to elapse after driver load,
* before UE recovery is allowed.
*/
#define ERR_IDLE_HR 24
#define ERR_RECOVERY_IDLE_TIME (ERR_IDLE_HR * BE_HOUR)
/* Time interval (in msec) after which UE recovery can be repeated */
#define ERR_INTERVAL_HR 72
#define ERR_RECOVERY_INTERVAL (ERR_INTERVAL_HR * BE_HOUR)
/* BEx/SH UE recovery state machine */
enum {
ERR_RECOVERY_ST_NONE = 0, /* No Recovery */
ERR_RECOVERY_ST_DETECT = 1, /* UE detection duration */
ERR_RECOVERY_ST_RESET = 2, /* Reset Phase (PF0 only) */
ERR_RECOVERY_ST_PRE_POLL = 3, /* Pre-Poll Phase (all PFs) */
ERR_RECOVERY_ST_REINIT = 4 /* Re-initialize Phase */
};
struct be_error_recovery {
union {
u8 recovery_retries; /* used for Lancer */
u8 recovery_state; /* used for BEx and Skyhawk */
};
/* BEx/Skyhawk error recovery variables */
bool recovery_supported;
u16 ue_to_reset_time; /* Time after UE, to soft reset
* the chip - PF0 only
*/
u16 ue_to_poll_time; /* Time after UE, to Restart Polling
* of SLIPORT_SEMAPHORE reg
*/
u16 last_err_code;
unsigned long probe_time;
unsigned long last_recovery_time;
/* Common to both Lancer & BEx/SH error recovery */
u32 resched_delay;
struct delayed_work err_detection_work;
};
/* Ethtool priv_flags */
#define BE_DISABLE_TPE_RECOVERY 0x1
struct be_vxlan_port {
struct list_head list;
__be16 port; /* VxLAN UDP dst port */
int port_aliases; /* alias count */
};
struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;
u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
u8 __iomem *db; /* Door Bell */
u8 __iomem *pcicfg; /* On SH,BEx only. Shadow of PCI config space */
struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
* is stored for freeing purpose */
struct be_dma_mem mbox_mem_alloced;
struct be_mcc_obj mcc_obj;
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
spinlock_t mcc_cq_lock;
u16 cfg_num_rx_irqs; /* configured via set-channels */
u16 cfg_num_tx_irqs; /* configured via set-channels */
u16 num_evt_qs;
u16 num_msix_vec;
struct be_eq_obj eq_obj[MAX_EVT_QS];
struct msix_entry msix_entries[MAX_MSIX_VECTORS];
bool isr_registered;
/* TX Rings */
u16 num_tx_qs;
struct be_tx_obj tx_obj[MAX_TX_QS];
/* Rx rings */
u16 num_rx_qs;
u16 num_rss_qs;
u16 need_def_rxq;
struct be_rx_obj rx_obj[MAX_RX_QS];
u32 big_page_size; /* Compounded page size shared by rx wrbs */
struct be_drv_stats drv_stats;
struct be_aic_obj aic_obj[MAX_EVT_QS];
bool aic_enabled;
u8 vlan_prio_bmap; /* Available Priority BitMap */
u16 recommended_prio_bits;/* Recommended Priority bits in vlan tag */
struct be_dma_mem rx_filter; /* Cmd DMA mem for rx-filter */
struct be_dma_mem stats_cmd;
/* Work queue used to perform periodic tasks like getting statistics */
struct delayed_work work;
u16 work_counter;
u8 recovery_retries;
u8 err_flags;
bool pcicfg_mapped; /* pcicfg obtained via pci_iomap() */
u32 flags;
u32 cmd_privileges;
/* Ethtool knobs and info */
char fw_ver[FW_VER_LEN];
char fw_on_flash[FW_VER_LEN];
/* IFACE filtering fields */
int if_handle; /* Used to configure filtering */
u32 if_flags; /* Interface filtering flags */
u32 *pmac_id; /* MAC addr handle used by BE card */
struct be_eth_addr *uc_list;/* list of uc-addrs programmed (not perm) */
u32 uc_macs; /* Count of secondary UC MAC programmed */
struct be_eth_addr *mc_list;/* list of mcast addrs programmed */
u32 mc_count;
unsigned long vids[BITS_TO_LONGS(VLAN_N_VID)];
u16 vlans_added;
bool update_uc_list;
bool update_mc_list;
struct mutex rx_filter_lock;/* For protecting vids[] & mc/uc_list[] */
u32 beacon_state; /* for set_phys_id */
u32 port_num;
char port_name;
u8 mc_type;
u32 function_mode;
u32 function_caps;
u32 rx_fc; /* Rx flow control */
u32 tx_fc; /* Tx flow control */
bool stats_cmd_sent;
struct {
u32 size;
u32 total_size;
u64 io_addr;
} roce_db;
u32 num_msix_roce_vec;
struct ocrdma_dev *ocrdma_dev;
struct list_head entry;
u32 flash_status;
struct completion et_cmd_compl;
struct be_resources pool_res; /* resources available for the port */
struct be_resources res; /* resources available for the func */
u16 num_vfs; /* Number of VFs provisioned by PF */
u8 pf_num; /* Numbering used by FW, starts at 0 */
u8 vf_num; /* Numbering used by FW, starts at 1 */
u8 virtfn;
struct be_vf_cfg *vf_cfg;
bool be3_native;
u32 sli_family;
u8 hba_port_num;
u16 pvid;
__be16 vxlan_port; /* offloaded vxlan port num */
struct phy_info phy;
u8 wol_cap;
bool wol_en;
u16 asic_rev;
u16 qnq_vid;
u32 msg_enable;
int be_get_temp_freq;
struct be_hwmon hwmon_info;
struct rss_info rss_info;
/* Filters for packets that need to be sent to BMC */
u32 bmc_filt_mask;
u32 fat_dump_len;
u16 serial_num[CNTL_SERIAL_NUM_WORDS];
u8 phy_state; /* state of sfp optics (functional, faulted, etc.,) */
u8 dev_mac[ETH_ALEN];
u32 priv_flags; /* ethtool get/set_priv_flags() */
struct be_error_recovery error_recovery;
};
/* Used for deferred FW config cmds. Add fields to this struct as reqd */
struct be_cmd_work {
struct work_struct work;
struct be_adapter *adapter;
};
#define be_physfn(adapter) (!adapter->virtfn)
#define be_virtfn(adapter) (adapter->virtfn)
#define sriov_enabled(adapter) (adapter->flags & \
BE_FLAGS_SRIOV_ENABLED)
#define for_all_vfs(adapter, vf_cfg, i) \
for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
i++, vf_cfg++)
#define ON 1
#define OFF 0
#define be_max_vlans(adapter) (adapter->res.max_vlans)
#define be_max_uc(adapter) (adapter->res.max_uc_mac)
#define be_max_mc(adapter) (adapter->res.max_mcast_mac)
#define be_max_vfs(adapter) (adapter->pool_res.max_vfs)
#define be_max_rss(adapter) (adapter->res.max_rss_qs)
#define be_max_txqs(adapter) (adapter->res.max_tx_qs)
#define be_max_prio_txqs(adapter) (adapter->res.max_prio_tx_qs)
#define be_max_rxqs(adapter) (adapter->res.max_rx_qs)
/* Max number of EQs available for the function (NIC + RoCE (if enabled)) */
#define be_max_func_eqs(adapter) (adapter->res.max_evt_qs)
/* Max number of EQs available only for NIC */
#define be_max_nic_eqs(adapter) (adapter->res.max_nic_evt_qs)
#define be_if_cap_flags(adapter) (adapter->res.if_cap_flags)
#define be_max_pf_pool_rss_tables(adapter) \
(adapter->pool_res.max_rss_tables)
/* Max irqs available for NIC */
#define be_max_irqs(adapter) \
(min_t(u16, be_max_nic_eqs(adapter), num_online_cpus()))
/* Max irqs *needed* for RX queues */
static inline u16 be_max_rx_irqs(struct be_adapter *adapter)
{
/* If no RSS, need at least one irq for def-RXQ */
u16 num = max_t(u16, be_max_rss(adapter), 1);
return min_t(u16, num, be_max_irqs(adapter));
}
/* Max irqs *needed* for TX queues */
static inline u16 be_max_tx_irqs(struct be_adapter *adapter)
{
return min_t(u16, be_max_txqs(adapter), be_max_irqs(adapter));
}
/* Max irqs *needed* for combined queues */
static inline u16 be_max_qp_irqs(struct be_adapter *adapter)
{
return min(be_max_tx_irqs(adapter), be_max_rx_irqs(adapter));
}
/* Max irqs *needed* for RX and TX queues together */
static inline u16 be_max_any_irqs(struct be_adapter *adapter)
{
return max(be_max_tx_irqs(adapter), be_max_rx_irqs(adapter));
}
/* Is BE in pvid_tagging mode */
#define be_pvid_tagging_enabled(adapter) (adapter->pvid)
/* Is BE in QNQ multi-channel mode */
#define be_is_qnq_mode(adapter) (adapter->function_mode & QNQ_MODE)
#ifdef CONFIG_BE2NET_LANCER
#define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3 || \
adapter->pdev->device == OC_DEVICE_ID4)
#else
#define lancer_chip(adapter) (0)
#endif /* CONFIG_BE2NET_LANCER */
#ifdef CONFIG_BE2NET_SKYHAWK
#define skyhawk_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID5 || \
adapter->pdev->device == OC_DEVICE_ID6)
#else
#define skyhawk_chip(adapter) (0)
#endif /* CONFIG_BE2NET_SKYHAWK */
#ifdef CONFIG_BE2NET_BE3
#define BE3_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID2 || \
adapter->pdev->device == OC_DEVICE_ID2)
#else
#define BE3_chip(adapter) (0)
#endif /* CONFIG_BE2NET_BE3 */
#ifdef CONFIG_BE2NET_BE2
#define BE2_chip(adapter) (adapter->pdev->device == BE_DEVICE_ID1 || \
adapter->pdev->device == OC_DEVICE_ID1)
#else
#define BE2_chip(adapter) (0)
#endif /* CONFIG_BE2NET_BE2 */
#define BEx_chip(adapter) (BE3_chip(adapter) || BE2_chip(adapter))
#define be_roce_supported(adapter) (skyhawk_chip(adapter) && \
(adapter->function_mode & RDMA_ENABLED))
extern const struct ethtool_ops be_ethtool_ops;
#define msix_enabled(adapter) (adapter->num_msix_vec > 0)
#define num_irqs(adapter) (msix_enabled(adapter) ? \
adapter->num_msix_vec : 1)
#define tx_stats(txo) (&(txo)->stats)
#define rx_stats(rxo) (&(rxo)->stats)
/* The default RXQ is the last RXQ */
#define default_rxo(adpt) (&adpt->rx_obj[adpt->num_rx_qs - 1])
#define for_all_rx_queues(adapter, rxo, i) \
for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \
i++, rxo++)
#define for_all_rss_queues(adapter, rxo, i) \
for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rss_qs; \
i++, rxo++)
#define for_all_tx_queues(adapter, txo, i) \
for (i = 0, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs; \
i++, txo++)
#define for_all_evt_queues(adapter, eqo, i) \
for (i = 0, eqo = &adapter->eq_obj[i]; i < adapter->num_evt_qs; \
i++, eqo++)
#define for_all_rx_queues_on_eq(adapter, eqo, rxo, i) \
for (i = eqo->idx, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs;\
i += adapter->num_evt_qs, rxo += adapter->num_evt_qs)
#define for_all_tx_queues_on_eq(adapter, eqo, txo, i) \
for (i = eqo->idx, txo = &adapter->tx_obj[i]; i < adapter->num_tx_qs;\
i += adapter->num_evt_qs, txo += adapter->num_evt_qs)
#define is_mcc_eqo(eqo) (eqo->idx == 0)
#define mcc_eqo(adapter) (&adapter->eq_obj[0])
#define PAGE_SHIFT_4K 12
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
/* Returns number of pages spanned by the data starting at the given addr */
#define PAGES_4K_SPANNED(_address, size) \
((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
/* Returns bit offset within a DWORD of a bitfield */
#define AMAP_BIT_OFFSET(_struct, field) \
(((size_t)&(((_struct *)0)->field))%32)
/* Returns the bit mask of the field that is NOT shifted into location. */
static inline u32 amap_mask(u32 bitsize)
{
return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
}
static inline void
amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value)
{
u32 *dw = (u32 *) ptr + dw_offset;
*dw &= ~(mask << offset);
*dw |= (mask & value) << offset;
}
#define AMAP_SET_BITS(_struct, field, ptr, val) \
amap_set(ptr, \
offsetof(_struct, field)/32, \
amap_mask(sizeof(((_struct *)0)->field)), \
AMAP_BIT_OFFSET(_struct, field), \
val)
static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
{
u32 *dw = (u32 *) ptr;
return mask & (*(dw + dw_offset) >> offset);
}
#define AMAP_GET_BITS(_struct, field, ptr) \
amap_get(ptr, \
offsetof(_struct, field)/32, \
amap_mask(sizeof(((_struct *)0)->field)), \
AMAP_BIT_OFFSET(_struct, field))
#define GET_RX_COMPL_V0_BITS(field, ptr) \
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, field, ptr)
#define GET_RX_COMPL_V1_BITS(field, ptr) \
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, field, ptr)
#define GET_TX_COMPL_BITS(field, ptr) \
AMAP_GET_BITS(struct amap_eth_tx_compl, field, ptr)
#define SET_TX_WRB_HDR_BITS(field, ptr, val) \
AMAP_SET_BITS(struct amap_eth_hdr_wrb, field, ptr, val)
#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
static inline void swap_dws(void *wrb, int len)
{
#ifdef __BIG_ENDIAN
u32 *dw = wrb;
BUG_ON(len % 4);
do {
*dw = cpu_to_le32(*dw);
dw++;
len -= 4;
} while (len);
#endif /* __BIG_ENDIAN */
}
#define be_cmd_status(status) (status > 0 ? -EIO : status)
static inline u8 is_tcp_pkt(struct sk_buff *skb)
{
u8 val = 0;
if (ip_hdr(skb)->version == 4)
val = (ip_hdr(skb)->protocol == IPPROTO_TCP);
else if (ip_hdr(skb)->version == 6)
val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP);
return val;
}
static inline u8 is_udp_pkt(struct sk_buff *skb)
{
u8 val = 0;
if (ip_hdr(skb)->version == 4)
val = (ip_hdr(skb)->protocol == IPPROTO_UDP);
else if (ip_hdr(skb)->version == 6)
val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP);
return val;
}
static inline bool is_ipv4_pkt(struct sk_buff *skb)
{
return skb->protocol == htons(ETH_P_IP) && ip_hdr(skb)->version == 4;
}
static inline bool is_ipv6_ext_hdr(struct sk_buff *skb)
{
if (ip_hdr(skb)->version == 6)
return ipv6_ext_hdr(ipv6_hdr(skb)->nexthdr);
else
return false;
}
#define be_error_recovering(adapter) \
(adapter->flags & BE_FLAGS_TRY_RECOVERY)
#define BE_ERROR_EEH 1
#define BE_ERROR_UE BIT(1)
#define BE_ERROR_FW BIT(2)
#define BE_ERROR_TX BIT(3)
#define BE_ERROR_HW (BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_TX)
#define BE_ERROR_ANY (BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_FW | \
BE_ERROR_TX)
#define BE_CLEAR_ALL 0xFF
static inline u8 be_check_error(struct be_adapter *adapter, u32 err_type)
{
return (adapter->err_flags & err_type);
}
static inline void be_set_error(struct be_adapter *adapter, int err_type)
{
struct net_device *netdev = adapter->netdev;
adapter->err_flags |= err_type;
netif_carrier_off(netdev);
dev_info(&adapter->pdev->dev, "%s: Link down\n", netdev->name);
}
static inline void be_clear_error(struct be_adapter *adapter, int err_type)
{
adapter->err_flags &= ~err_type;
}
static inline bool be_multi_rxq(const struct be_adapter *adapter)
{
return adapter->num_rx_qs > 1;
}
void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
u16 num_popped);
void be_link_status_update(struct be_adapter *adapter, u8 link_status);
void be_parse_stats(struct be_adapter *adapter);
int be_load_fw(struct be_adapter *adapter, u8 *func);
bool be_pause_supported(struct be_adapter *adapter);
int be_update_queues(struct be_adapter *adapter);
int be_poll(struct napi_struct *napi, int budget);
void be_eqd_update(struct be_adapter *adapter, bool force_update);
/*
* internal function to initialize-cleanup roce device.
*/
void be_roce_dev_add(struct be_adapter *);
void be_roce_dev_remove(struct be_adapter *);
/*
* internal function to open-close roce device during ifup-ifdown.
*/
void be_roce_dev_shutdown(struct be_adapter *);
#endif /* BE_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,371 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2005-2016 Broadcom.
* All rights reserved.
*
* Contact Information:
* linux-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*/
/********* Mailbox door bell *************/
/* Used for driver communication with the FW.
* The software must write this register twice to post any command. First,
* it writes the register with hi=1 and the upper bits of the physical address
* for the MAILBOX structure. Software must poll the ready bit until this
* is acknowledged. Then, software writes the register with hi=0 with the lower
* bits in the address. It must poll the ready bit until the command is
* complete. Upon completion, the MAILBOX will contain a valid completion
* queue entry.
*/
#define MPU_MAILBOX_DB_OFFSET 0x160
#define MPU_MAILBOX_DB_RDY_MASK 0x1 /* bit 0 */
#define MPU_MAILBOX_DB_HI_MASK 0x2 /* bit 1 */
#define MPU_EP_CONTROL 0
/********** MPU semaphore: used for SH & BE *************/
#define SLIPORT_SOFTRESET_OFFSET 0x5c /* CSR BAR offset */
#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */
#define POST_STAGE_MASK 0x0000FFFF
#define POST_ERR_MASK 0x1
#define POST_ERR_SHIFT 31
#define POST_ERR_RECOVERY_CODE_MASK 0xFFF
/* Soft Reset register masks */
#define SLIPORT_SOFTRESET_SR_MASK 0x00000080 /* SR bit */
/* MPU semaphore POST stage values */
#define POST_STAGE_AWAITING_HOST_RDY 0x1 /* FW awaiting goahead from host */
#define POST_STAGE_HOST_RDY 0x2 /* Host has given go-ahed to FW */
#define POST_STAGE_BE_RESET 0x3 /* Host wants to reset chip */
#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
#define POST_STAGE_RECOVERABLE_ERR 0xE000 /* Recoverable err detected */
/* FW has detected a UE and is dumping FAT log data */
#define POST_STAGE_FAT_LOG_START 0x0D00
#define POST_STAGE_ARMFW_UE 0xF000 /*FW has asserted an UE*/
/* Lancer SLIPORT registers */
#define SLIPORT_STATUS_OFFSET 0x404
#define SLIPORT_CONTROL_OFFSET 0x408
#define SLIPORT_ERROR1_OFFSET 0x40C
#define SLIPORT_ERROR2_OFFSET 0x410
#define PHYSDEV_CONTROL_OFFSET 0x414
#define SLIPORT_STATUS_ERR_MASK 0x80000000
#define SLIPORT_STATUS_DIP_MASK 0x02000000
#define SLIPORT_STATUS_RN_MASK 0x01000000
#define SLIPORT_STATUS_RDY_MASK 0x00800000
#define SLI_PORT_CONTROL_IP_MASK 0x08000000
#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002
#define PHYSDEV_CONTROL_DD_MASK 0x00000004
#define PHYSDEV_CONTROL_INP_MASK 0x40000000
#define SLIPORT_ERROR_NO_RESOURCE1 0x2
#define SLIPORT_ERROR_NO_RESOURCE2 0x9
#define SLIPORT_ERROR_FW_RESET1 0x2
#define SLIPORT_ERROR_FW_RESET2 0x0
/********* Memory BAR register ************/
#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
/* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
* Disable" may still globally block interrupts in addition to individual
* interrupt masks; a mechanism for the device driver to block all interrupts
* atomically without having to arbitrate for the PCI Interrupt Disable bit
* with the OS.
*/
#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK BIT(29) /* bit 29 */
/********* PCI Function Capability *********/
#define BE_FUNCTION_CAPS_RSS 0x2
#define BE_FUNCTION_CAPS_SUPER_NIC 0x40
/********* Power management (WOL) **********/
#define PCICFG_PM_CONTROL_OFFSET 0x44
#define PCICFG_PM_CONTROL_MASK 0x108 /* bits 3 & 8 */
/********* Online Control Registers *******/
#define PCICFG_ONLINE0 0xB0
#define PCICFG_ONLINE1 0xB4
/********* UE Status and Mask Registers ***/
#define PCICFG_UE_STATUS_LOW 0xA0
#define PCICFG_UE_STATUS_HIGH 0xA4
#define PCICFG_UE_STATUS_LOW_MASK 0xA8
#define PCICFG_UE_STATUS_HI_MASK 0xAC
/******** SLI_INTF ***********************/
#define SLI_INTF_REG_OFFSET 0x58
#define SLI_INTF_VALID_MASK 0xE0000000
#define SLI_INTF_VALID 0xC0000000
#define SLI_INTF_HINT2_MASK 0x1F000000
#define SLI_INTF_HINT2_SHIFT 24
#define SLI_INTF_HINT1_MASK 0x00FF0000
#define SLI_INTF_HINT1_SHIFT 16
#define SLI_INTF_FAMILY_MASK 0x00000F00
#define SLI_INTF_FAMILY_SHIFT 8
#define SLI_INTF_IF_TYPE_MASK 0x0000F000
#define SLI_INTF_IF_TYPE_SHIFT 12
#define SLI_INTF_REV_MASK 0x000000F0
#define SLI_INTF_REV_SHIFT 4
#define SLI_INTF_FT_MASK 0x00000001
#define SLI_INTF_TYPE_2 2
#define SLI_INTF_TYPE_3 3
/********* ISR0 Register offset **********/
#define CEV_ISR0_OFFSET 0xC18
#define CEV_ISR_SIZE 4
/********* Event Q door bell *************/
#define DB_EQ_OFFSET DB_CQ_OFFSET
#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */
#define DB_EQ_RING_ID_EXT_MASK 0x3e00 /* bits 9-13 */
#define DB_EQ_RING_ID_EXT_MASK_SHIFT (2) /* qid bits 9-13 placing at 11-15 */
/* Clear the interrupt for this eq */
#define DB_EQ_CLR_SHIFT (9) /* bit 9 */
/* Must be 1 */
#define DB_EQ_EVNT_SHIFT (10) /* bit 10 */
/* Number of event entries processed */
#define DB_EQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
/* Rearm bit */
#define DB_EQ_REARM_SHIFT (29) /* bit 29 */
/* Rearm to interrupt delay encoding */
#define DB_EQ_R2I_DLY_SHIFT (30) /* bits 30 - 31 */
/* Rearm to interrupt (R2I) delay multiplier encoding represents 3 different
* values configured in CEV_REARM2IRPT_DLY_MULT_CSR register. This value is
* programmed by host driver while ringing an EQ doorbell(EQ_DB) if a delay
* between rearming the EQ and next interrupt on this EQ is desired.
*/
#define R2I_DLY_ENC_0 0 /* No delay */
#define R2I_DLY_ENC_1 1 /* maps to 160us EQ delay */
#define R2I_DLY_ENC_2 2 /* maps to 96us EQ delay */
#define R2I_DLY_ENC_3 3 /* maps to 48us EQ delay */
/********* Compl Q door bell *************/
#define DB_CQ_OFFSET 0x120
#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
#define DB_CQ_RING_ID_EXT_MASK 0x7C00 /* bits 10-14 */
#define DB_CQ_RING_ID_EXT_MASK_SHIFT (1) /* qid bits 10-14
placing at 11-15 */
/* Number of event entries processed */
#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
/* Rearm bit */
#define DB_CQ_REARM_SHIFT (29) /* bit 29 */
/********** TX ULP door bell *************/
#define DB_TXULP1_OFFSET 0x60
#define DB_TXULP_RING_ID_MASK 0x7FF /* bits 0 - 10 */
/* Number of tx entries posted */
#define DB_TXULP_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */
#define DB_TXULP_NUM_POSTED_MASK 0x3FFF /* bits 16 - 29 */
/********** RQ(erx) door bell ************/
#define DB_RQ_OFFSET 0x100
#define DB_RQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
/* Number of rx frags posted */
#define DB_RQ_NUM_POSTED_SHIFT (24) /* bits 24 - 31 */
/********** MCC door bell ************/
#define DB_MCCQ_OFFSET 0x140
#define DB_MCCQ_RING_ID_MASK 0x7FF /* bits 0 - 10 */
/* Number of entries posted */
#define DB_MCCQ_NUM_POSTED_SHIFT (16) /* bits 16 - 29 */
/********** SRIOV VF PCICFG OFFSET ********/
#define SRIOV_VF_PCICFG_OFFSET (4096)
/********** FAT TABLE ********/
#define RETRIEVE_FAT 0
#define QUERY_FAT 1
/************* Rx Packet Type Encoding **************/
#define BE_UNICAST_PACKET 0
#define BE_MULTICAST_PACKET 1
#define BE_BROADCAST_PACKET 2
#define BE_RSVD_PACKET 3
/*
* BE descriptors: host memory data structures whose formats
* are hardwired in BE silicon.
*/
/* Event Queue Descriptor */
#define EQ_ENTRY_VALID_MASK 0x1 /* bit 0 */
#define EQ_ENTRY_RES_ID_MASK 0xFFFF /* bits 16 - 31 */
#define EQ_ENTRY_RES_ID_SHIFT 16
struct be_eq_entry {
u32 evt;
};
/* TX Queue Descriptor */
#define ETH_WRB_FRAG_LEN_MASK 0xFFFF
struct be_eth_wrb {
__le32 frag_pa_hi; /* dword 0 */
__le32 frag_pa_lo; /* dword 1 */
u32 rsvd0; /* dword 2 */
__le32 frag_len; /* dword 3: bits 0 - 15 */
} __packed;
/* Pseudo amap definition for eth_hdr_wrb in which each bit of the
* actual structure is defined as a byte : used to calculate
* offset/shift/mask of each field */
struct amap_eth_hdr_wrb {
u8 rsvd0[32]; /* dword 0 */
u8 rsvd1[32]; /* dword 1 */
u8 complete; /* dword 2 */
u8 event;
u8 crc;
u8 forward;
u8 lso6;
u8 mgmt;
u8 ipcs;
u8 udpcs;
u8 tcpcs;
u8 lso;
u8 vlan;
u8 gso[2];
u8 num_wrb[5];
u8 lso_mss[14];
u8 len[16]; /* dword 3 */
u8 vlan_tag[16];
} __packed;
#define TX_HDR_WRB_COMPL 1 /* word 2 */
#define TX_HDR_WRB_EVT BIT(1) /* word 2 */
#define TX_HDR_WRB_NUM_SHIFT 13 /* word 2: bits 13:17 */
#define TX_HDR_WRB_NUM_MASK 0x1F /* word 2: bits 13:17 */
struct be_eth_hdr_wrb {
__le32 dw[4];
};
/********* Tx Compl Status Encoding *********/
#define BE_TX_COMP_HDR_PARSE_ERR 0x2
#define BE_TX_COMP_NDMA_ERR 0x3
#define BE_TX_COMP_ACL_ERR 0x5
#define LANCER_TX_COMP_LSO_ERR 0x1
#define LANCER_TX_COMP_HSW_DROP_MAC_ERR 0x3
#define LANCER_TX_COMP_HSW_DROP_VLAN_ERR 0x5
#define LANCER_TX_COMP_QINQ_ERR 0x7
#define LANCER_TX_COMP_SGE_ERR 0x9
#define LANCER_TX_COMP_PARITY_ERR 0xb
#define LANCER_TX_COMP_DMA_ERR 0xd
/* TX Compl Queue Descriptor */
/* Pseudo amap definition for eth_tx_compl in which each bit of the
* actual structure is defined as a byte: used to calculate
* offset/shift/mask of each field */
struct amap_eth_tx_compl {
u8 wrb_index[16]; /* dword 0 */
u8 ct[2]; /* dword 0 */
u8 port[2]; /* dword 0 */
u8 rsvd0[8]; /* dword 0 */
u8 status[4]; /* dword 0 */
u8 user_bytes[16]; /* dword 1 */
u8 nwh_bytes[8]; /* dword 1 */
u8 lso; /* dword 1 */
u8 cast_enc[2]; /* dword 1 */
u8 rsvd1[5]; /* dword 1 */
u8 rsvd2[32]; /* dword 2 */
u8 pkts[16]; /* dword 3 */
u8 ringid[11]; /* dword 3 */
u8 hash_val[4]; /* dword 3 */
u8 valid; /* dword 3 */
} __packed;
struct be_eth_tx_compl {
u32 dw[4];
};
/* RX Queue Descriptor */
struct be_eth_rx_d {
u32 fragpa_hi;
u32 fragpa_lo;
};
/* RX Compl Queue Descriptor */
/* Pseudo amap definition for BE2 and BE3 legacy mode eth_rx_compl in which
* each bit of the actual structure is defined as a byte: used to calculate
* offset/shift/mask of each field */
struct amap_eth_rx_compl_v0 {
u8 vlan_tag[16]; /* dword 0 */
u8 pktsize[14]; /* dword 0 */
u8 port; /* dword 0 */
u8 ip_opt; /* dword 0 */
u8 err; /* dword 1 */
u8 rsshp; /* dword 1 */
u8 ipf; /* dword 1 */
u8 tcpf; /* dword 1 */
u8 udpf; /* dword 1 */
u8 ipcksm; /* dword 1 */
u8 l4_cksm; /* dword 1 */
u8 ip_version; /* dword 1 */
u8 macdst[6]; /* dword 1 */
u8 vtp; /* dword 1 */
u8 ip_frag; /* dword 1 */
u8 fragndx[10]; /* dword 1 */
u8 ct[2]; /* dword 1 */
u8 sw; /* dword 1 */
u8 numfrags[3]; /* dword 1 */
u8 rss_flush; /* dword 2 */
u8 cast_enc[2]; /* dword 2 */
u8 qnq; /* dword 2 */
u8 rss_bank; /* dword 2 */
u8 rsvd1[23]; /* dword 2 */
u8 lro_pkt; /* dword 2 */
u8 rsvd2[2]; /* dword 2 */
u8 valid; /* dword 2 */
u8 rsshash[32]; /* dword 3 */
} __packed;
/* Pseudo amap definition for BE3 native mode eth_rx_compl in which
* each bit of the actual structure is defined as a byte: used to calculate
* offset/shift/mask of each field */
struct amap_eth_rx_compl_v1 {
u8 vlan_tag[16]; /* dword 0 */
u8 pktsize[14]; /* dword 0 */
u8 vtp; /* dword 0 */
u8 ip_opt; /* dword 0 */
u8 err; /* dword 1 */
u8 rsshp; /* dword 1 */
u8 ipf; /* dword 1 */
u8 tcpf; /* dword 1 */
u8 udpf; /* dword 1 */
u8 ipcksm; /* dword 1 */
u8 l4_cksm; /* dword 1 */
u8 ip_version; /* dword 1 */
u8 macdst[7]; /* dword 1 */
u8 rsvd0; /* dword 1 */
u8 fragndx[10]; /* dword 1 */
u8 ct[2]; /* dword 1 */
u8 sw; /* dword 1 */
u8 numfrags[3]; /* dword 1 */
u8 rss_flush; /* dword 2 */
u8 cast_enc[2]; /* dword 2 */
u8 qnq; /* dword 2 */
u8 rss_bank; /* dword 2 */
u8 port[2]; /* dword 2 */
u8 vntagp; /* dword 2 */
u8 header_len[8]; /* dword 2 */
u8 header_split[2]; /* dword 2 */
u8 rsvd1[12]; /* dword 2 */
u8 tunneled;
u8 valid; /* dword 2 */
u8 rsshash[32]; /* dword 3 */
} __packed;
struct be_eth_rx_compl {
u32 dw[4];
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2005 - 2016 Broadcom
* All rights reserved.
*
* Contact Information:
* linux-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*/
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/module.h>
#include "be.h"
#include "be_cmds.h"
static struct ocrdma_driver *ocrdma_drv;
static LIST_HEAD(be_adapter_list);
static DEFINE_MUTEX(be_adapter_list_lock);
static void _be_roce_dev_add(struct be_adapter *adapter)
{
struct be_dev_info dev_info;
int i, num_vec;
struct pci_dev *pdev = adapter->pdev;
if (!ocrdma_drv)
return;
if (ocrdma_drv->be_abi_version != BE_ROCE_ABI_VERSION) {
dev_warn(&pdev->dev, "Cannot initialize RoCE due to ocrdma ABI mismatch\n");
return;
}
if (pdev->device == OC_DEVICE_ID5) {
/* only msix is supported on these devices */
if (!msix_enabled(adapter))
return;
/* DPP region address and length */
dev_info.dpp_unmapped_addr = pci_resource_start(pdev, 2);
dev_info.dpp_unmapped_len = pci_resource_len(pdev, 2);
} else {
dev_info.dpp_unmapped_addr = 0;
dev_info.dpp_unmapped_len = 0;
}
dev_info.pdev = adapter->pdev;
dev_info.db = adapter->db;
dev_info.unmapped_db = adapter->roce_db.io_addr;
dev_info.db_page_size = adapter->roce_db.size;
dev_info.db_total_size = adapter->roce_db.total_size;
dev_info.netdev = adapter->netdev;
memcpy(dev_info.mac_addr, adapter->netdev->dev_addr, ETH_ALEN);
dev_info.dev_family = adapter->sli_family;
if (msix_enabled(adapter)) {
/* provide all the vectors, so that EQ creation response
* can decide which one to use.
*/
num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;
dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX;
dev_info.msix.num_vectors = min(num_vec, MAX_MSIX_VECTORS);
/* provide start index of the vector,
* so in case of linear usage,
* it can use the base as starting point.
*/
dev_info.msix.start_vector = adapter->num_evt_qs;
for (i = 0; i < dev_info.msix.num_vectors; i++) {
dev_info.msix.vector_list[i] =
adapter->msix_entries[i].vector;
}
} else {
dev_info.msix.num_vectors = 0;
dev_info.intr_mode = BE_INTERRUPT_MODE_INTX;
}
adapter->ocrdma_dev = ocrdma_drv->add(&dev_info);
}
void be_roce_dev_add(struct be_adapter *adapter)
{
if (be_roce_supported(adapter)) {
INIT_LIST_HEAD(&adapter->entry);
mutex_lock(&be_adapter_list_lock);
list_add_tail(&adapter->entry, &be_adapter_list);
/* invoke add() routine of roce driver only if
* valid driver registered with add method and add() is not yet
* invoked on a given adapter.
*/
_be_roce_dev_add(adapter);
mutex_unlock(&be_adapter_list_lock);
}
}
static void _be_roce_dev_remove(struct be_adapter *adapter)
{
if (ocrdma_drv && ocrdma_drv->remove && adapter->ocrdma_dev)
ocrdma_drv->remove(adapter->ocrdma_dev);
adapter->ocrdma_dev = NULL;
}
void be_roce_dev_remove(struct be_adapter *adapter)
{
if (be_roce_supported(adapter)) {
mutex_lock(&be_adapter_list_lock);
_be_roce_dev_remove(adapter);
list_del(&adapter->entry);
mutex_unlock(&be_adapter_list_lock);
}
}
void be_roce_dev_shutdown(struct be_adapter *adapter)
{
if (be_roce_supported(adapter)) {
mutex_lock(&be_adapter_list_lock);
if (ocrdma_drv && adapter->ocrdma_dev &&
ocrdma_drv->state_change_handler)
ocrdma_drv->state_change_handler(adapter->ocrdma_dev,
BE_DEV_SHUTDOWN);
mutex_unlock(&be_adapter_list_lock);
}
}
int be_roce_register_driver(struct ocrdma_driver *drv)
{
struct be_adapter *dev;
mutex_lock(&be_adapter_list_lock);
if (ocrdma_drv) {
mutex_unlock(&be_adapter_list_lock);
return -EINVAL;
}
ocrdma_drv = drv;
list_for_each_entry(dev, &be_adapter_list, entry) {
_be_roce_dev_add(dev);
}
mutex_unlock(&be_adapter_list_lock);
return 0;
}
EXPORT_SYMBOL(be_roce_register_driver);
void be_roce_unregister_driver(struct ocrdma_driver *drv)
{
struct be_adapter *dev;
mutex_lock(&be_adapter_list_lock);
list_for_each_entry(dev, &be_adapter_list, entry) {
if (dev->ocrdma_dev)
_be_roce_dev_remove(dev);
}
ocrdma_drv = NULL;
mutex_unlock(&be_adapter_list_lock);
}
EXPORT_SYMBOL(be_roce_unregister_driver);
@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2005 - 2016 Broadcom
* All rights reserved.
*
* Contact Information:
* linux-drivers@emulex.com
*
* Emulex
* 3333 Susan Street
* Costa Mesa, CA 92626
*/
#ifndef BE_ROCE_H
#define BE_ROCE_H
#include <linux/pci.h>
#include <linux/netdevice.h>
#define BE_ROCE_ABI_VERSION 1
struct ocrdma_dev;
enum be_interrupt_mode {
BE_INTERRUPT_MODE_MSIX = 0,
BE_INTERRUPT_MODE_INTX = 1,
BE_INTERRUPT_MODE_MSI = 2,
};
#define MAX_MSIX_VECTORS 32
struct be_dev_info {
u8 __iomem *db;
u64 unmapped_db;
u32 db_page_size;
u32 db_total_size;
u64 dpp_unmapped_addr;
u32 dpp_unmapped_len;
struct pci_dev *pdev;
struct net_device *netdev;
u8 mac_addr[ETH_ALEN];
u32 dev_family;
enum be_interrupt_mode intr_mode;
struct {
int num_vectors;
int start_vector;
u32 vector_list[MAX_MSIX_VECTORS];
} msix;
};
/* ocrdma driver register's the callback functions with nic driver. */
struct ocrdma_driver {
unsigned char name[32];
u32 be_abi_version;
struct ocrdma_dev *(*add) (struct be_dev_info *dev_info);
void (*remove) (struct ocrdma_dev *);
void (*state_change_handler) (struct ocrdma_dev *, u32 new_state);
};
enum be_roce_event {
BE_DEV_SHUTDOWN = 2
};
/* APIs for RoCE driver to register callback handlers,
* which will be invoked when device is added, removed, ifup, ifdown
*/
int be_roce_register_driver(struct ocrdma_driver *drv);
void be_roce_unregister_driver(struct ocrdma_driver *drv);
/* API for RoCE driver to issue mailbox commands */
int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
int wrb_payload_size, u16 *cmd_status, u16 *ext_status);
#endif /* BE_ROCE_H */