diff options
Diffstat (limited to 'drivers/net/ethernet/intel/idpf/idpf.h')
| -rw-r--r-- | drivers/net/ethernet/intel/idpf/idpf.h | 278 |
1 files changed, 238 insertions, 40 deletions
diff --git a/drivers/net/ethernet/intel/idpf/idpf.h b/drivers/net/ethernet/intel/idpf/idpf.h index 2c31ad87587a..8cfc68cbfa06 100644 --- a/drivers/net/ethernet/intel/idpf/idpf.h +++ b/drivers/net/ethernet/intel/idpf/idpf.h @@ -12,12 +12,16 @@ struct idpf_vport_max_q; #include <net/pkt_sched.h> #include <linux/aer.h> #include <linux/etherdevice.h> +#include <linux/ioport.h> #include <linux/pci.h> #include <linux/bitfield.h> #include <linux/sctp.h> #include <linux/ethtool_netlink.h> #include <net/gro.h> +#include <linux/net/intel/iidc_rdma.h> +#include <linux/net/intel/iidc_rdma_idpf.h> + #include "virtchnl2.h" #include "idpf_txrx.h" #include "idpf_controlq.h" @@ -36,6 +40,7 @@ struct idpf_vport_max_q; #define IDPF_NUM_CHUNKS_PER_MSG(struct_sz, chunk_sz) \ ((IDPF_CTLQ_MAX_BUF_LEN - (struct_sz)) / (chunk_sz)) +#define IDPF_WAIT_FOR_MARKER_TIMEO 500 #define IDPF_MAX_WAIT 500 /* available message levels */ @@ -126,14 +131,12 @@ enum idpf_cap_field { /** * enum idpf_vport_state - Current vport state - * @__IDPF_VPORT_DOWN: Vport is down - * @__IDPF_VPORT_UP: Vport is up - * @__IDPF_VPORT_STATE_LAST: Must be last, number of states + * @IDPF_VPORT_UP: Vport is up + * @IDPF_VPORT_STATE_NBITS: Must be last, number of states */ enum idpf_vport_state { - __IDPF_VPORT_DOWN, - __IDPF_VPORT_UP, - __IDPF_VPORT_STATE_LAST, + IDPF_VPORT_UP, + IDPF_VPORT_STATE_NBITS }; /** @@ -141,7 +144,10 @@ enum idpf_vport_state { * @adapter: Adapter back pointer * @vport: Vport back pointer * @vport_id: Vport identifier + * @link_speed_mbps: Link speed in mbps * @vport_idx: Relative vport index + * @max_tx_hdr_size: Max header length hardware can support + * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather * @state: See enum idpf_vport_state * @netstats: Packet and byte stats * @stats_lock: Lock to protect stats update @@ -150,8 +156,11 @@ struct idpf_netdev_priv { struct idpf_adapter *adapter; struct idpf_vport *vport; u32 vport_id; + u32 link_speed_mbps; u16 vport_idx; - enum idpf_vport_state state; + u16 max_tx_hdr_size; + u16 tx_max_bufs; + DECLARE_BITMAP(state, IDPF_VPORT_STATE_NBITS); struct rtnl_link_stats64 netstats; spinlock_t stats_lock; }; @@ -187,22 +196,38 @@ struct idpf_vport_max_q { * @mb_intr_reg_init: Mailbox interrupt register initialization * @reset_reg_init: Reset register initialization * @trigger_reset: Trigger a reset to occur + * @ptp_reg_init: PTP register initialization */ struct idpf_reg_ops { - void (*ctlq_reg_init)(struct idpf_ctlq_create_info *cq); + void (*ctlq_reg_init)(struct idpf_adapter *adapter, + struct idpf_ctlq_create_info *cq); int (*intr_reg_init)(struct idpf_vport *vport); void (*mb_intr_reg_init)(struct idpf_adapter *adapter); void (*reset_reg_init)(struct idpf_adapter *adapter); void (*trigger_reset)(struct idpf_adapter *adapter, enum idpf_flags trig_cause); + void (*ptp_reg_init)(const struct idpf_adapter *adapter); }; +#define IDPF_MMIO_REG_NUM_STATIC 2 +#define IDPF_PF_MBX_REGION_SZ 4096 +#define IDPF_PF_RSTAT_REGION_SZ 2048 +#define IDPF_VF_MBX_REGION_SZ 10240 +#define IDPF_VF_RSTAT_REGION_SZ 2048 + /** * struct idpf_dev_ops - Device specific operations * @reg_ops: Register operations + * @idc_init: IDC initialization + * @static_reg_info: array of mailbox and rstat register info */ struct idpf_dev_ops { struct idpf_reg_ops reg_ops; + + int (*idc_init)(struct idpf_adapter *adapter); + + /* static_reg_info[0] is mailbox region, static_reg_info[1] is rstat */ + struct resource static_reg_info[IDPF_MMIO_REG_NUM_STATIC]; }; /** @@ -222,16 +247,28 @@ enum idpf_vport_reset_cause { /** * enum idpf_vport_flags - Vport flags * @IDPF_VPORT_DEL_QUEUES: To send delete queues message - * @IDPF_VPORT_SW_MARKER: Indicate TX pipe drain software marker packets - * processing is done * @IDPF_VPORT_FLAGS_NBITS: Must be last */ enum idpf_vport_flags { IDPF_VPORT_DEL_QUEUES, - IDPF_VPORT_SW_MARKER, IDPF_VPORT_FLAGS_NBITS, }; +/** + * struct idpf_tstamp_stats - Tx timestamp statistics + * @stats_sync: See struct u64_stats_sync + * @packets: Number of packets successfully timestamped by the hardware + * @discarded: Number of Tx skbs discarded due to cached PHC + * being too old to correctly extend timestamp + * @flushed: Number of Tx skbs flushed due to interface closed + */ +struct idpf_tstamp_stats { + struct u64_stats_sync stats_sync; + u64_stats_t packets; + u64_stats_t discarded; + u64_stats_t flushed; +}; + struct idpf_port_stats { struct u64_stats_sync stats_sync; u64_stats_t rx_hw_csum_err; @@ -245,6 +282,12 @@ struct idpf_port_stats { struct virtchnl2_vport_stats vport_stats; }; +struct idpf_fsteer_fltr { + struct list_head list; + u32 loc; + u32 q_index; +}; + /** * struct idpf_vport - Handle for netdevices and queue resources * @num_txq: Number of allocated TX queues @@ -257,6 +300,10 @@ struct idpf_port_stats { * @txq_model: Split queue or single queue queuing model * @txqs: Used only in hotpath to get to the right queue very fast * @crc_enable: Enable CRC insertion offload + * @xdpsq_share: whether XDPSQ sharing is enabled + * @num_xdp_txq: number of XDPSQs + * @xdp_txq_offset: index of the first XDPSQ (== number of regular SQs) + * @xdp_prog: installed XDP program * @num_rxq: Number of allocated RX queues * @num_bufq: Number of allocated buffer queues * @rxq_desc_count: RX queue descriptor count. *MUST* have enough descriptors @@ -269,6 +316,7 @@ struct idpf_port_stats { * group will yield total number of RX queues. * @rxq_model: Splitq queue or single queue queuing model * @rx_ptype_lkup: Lookup table for ptypes on RX + * @vdev_info: IDC vport device info pointer * @adapter: back pointer to associated adapter * @netdev: Associated net_device. Each vport should have one and only one * associated netdev. @@ -281,14 +329,19 @@ struct idpf_port_stats { * @num_q_vectors: Number of IRQ vectors allocated * @q_vectors: Array of queue vectors * @q_vector_idxs: Starting index of queue vectors + * @noirq_dyn_ctl: register to enable/disable the vector for NOIRQ queues + * @noirq_dyn_ctl_ena: value to write to the above to enable it + * @noirq_v_idx: ID of the NOIRQ vector * @max_mtu: device given max possible MTU * @default_mac_addr: device will give a default MAC to use * @rx_itr_profile: RX profiles for Dynamic Interrupt Moderation * @tx_itr_profile: TX profiles for Dynamic Interrupt Moderation * @port_stats: per port csum, header split, and other offload stats * @link_up: True if link is up - * @link_speed_mbps: Link speed in mbps - * @sw_marker_wq: workqueue for marker packets + * @tx_tstamp_caps: Capabilities negotiated for Tx timestamping + * @tstamp_config: The Tx tstamp config + * @tstamp_task: Tx timestamping task + * @tstamp_stats: Tx timestamping statistics */ struct idpf_vport { u16 num_txq; @@ -302,6 +355,11 @@ struct idpf_vport { struct idpf_tx_queue **txqs; bool crc_enable; + bool xdpsq_share; + u16 num_xdp_txq; + u16 xdp_txq_offset; + struct bpf_prog *xdp_prog; + u16 num_rxq; u16 num_bufq; u32 rxq_desc_count; @@ -312,6 +370,8 @@ struct idpf_vport { u32 rxq_model; struct libeth_rx_pt *rx_ptype_lkup; + struct iidc_rdma_vport_dev_info *vdev_info; + struct idpf_adapter *adapter; struct net_device *netdev; DECLARE_BITMAP(flags, IDPF_VPORT_FLAGS_NBITS); @@ -324,6 +384,11 @@ struct idpf_vport { u16 num_q_vectors; struct idpf_q_vector *q_vectors; u16 *q_vector_idxs; + + void __iomem *noirq_dyn_ctl; + u32 noirq_dyn_ctl_ena; + u16 noirq_v_idx; + u16 max_mtu; u8 default_mac_addr[ETH_ALEN]; u16 rx_itr_profile[IDPF_DIM_PROFILE_SLOTS]; @@ -331,9 +396,11 @@ struct idpf_vport { struct idpf_port_stats port_stats; bool link_up; - u32 link_speed_mbps; - wait_queue_head_t sw_marker_wq; + struct idpf_ptp_vport_tx_tstamp_caps *tx_tstamp_caps; + struct kernel_hwtstamp_config tstamp_config; + struct work_struct tstamp_task; + struct idpf_tstamp_stats tstamp_stats; }; /** @@ -368,28 +435,53 @@ struct idpf_rss_data { }; /** + * struct idpf_q_coalesce - User defined coalescing configuration values for + * a single queue. + * @tx_intr_mode: Dynamic TX ITR or not + * @rx_intr_mode: Dynamic RX ITR or not + * @tx_coalesce_usecs: TX interrupt throttling rate + * @rx_coalesce_usecs: RX interrupt throttling rate + * + * Used to restore user coalescing configuration after a reset. + */ +struct idpf_q_coalesce { + u32 tx_intr_mode; + u32 rx_intr_mode; + u32 tx_coalesce_usecs; + u32 rx_coalesce_usecs; +}; + +/** * struct idpf_vport_user_config_data - User defined configuration values for * each vport. * @rss_data: See struct idpf_rss_data + * @q_coalesce: Array of per queue coalescing data * @num_req_tx_qs: Number of user requested TX queues through ethtool * @num_req_rx_qs: Number of user requested RX queues through ethtool * @num_req_txq_desc: Number of user requested TX queue descriptors through * ethtool * @num_req_rxq_desc: Number of user requested RX queue descriptors through * ethtool + * @xdp_prog: requested XDP program to install * @user_flags: User toggled config flags * @mac_filter_list: List of MAC filters + * @num_fsteer_fltrs: number of flow steering filters + * @flow_steer_list: list of flow steering filters * * Used to restore configuration after a reset as the vport will get wiped. */ struct idpf_vport_user_config_data { struct idpf_rss_data rss_data; + struct idpf_q_coalesce *q_coalesce; u16 num_req_tx_qs; u16 num_req_rx_qs; u32 num_req_txq_desc; u32 num_req_rxq_desc; + struct bpf_prog *xdp_prog; DECLARE_BITMAP(user_flags, __IDPF_USER_FLAGS_NBITS); struct list_head mac_filter_list; + u32 num_fsteer_fltrs; + struct list_head flow_steer_list; }; /** @@ -478,6 +570,13 @@ struct idpf_vport_config { struct idpf_vc_xn_manager; +#define idpf_for_each_vport(adapter, iter) \ + for (struct idpf_vport **__##iter = &(adapter)->vports[0], \ + *iter = (adapter)->max_vports ? *__##iter : NULL; \ + iter; \ + iter = (++__##iter) < &(adapter)->vports[(adapter)->max_vports] ? \ + *__##iter : NULL) + /** * struct idpf_adapter - Device data struct generated on probe * @pdev: PCI device struct given on probe @@ -489,10 +588,11 @@ struct idpf_vc_xn_manager; * @flags: See enum idpf_flags * @reset_reg: See struct idpf_reset_reg * @hw: Device access data - * @num_req_msix: Requested number of MSIX vectors * @num_avail_msix: Available number of MSIX vectors * @num_msix_entries: Number of entries in MSIX table * @msix_entries: MSIX table + * @num_rdma_msix_entries: Available number of MSIX vectors for RDMA + * @rdma_msix_entries: RDMA MSIX table * @req_vec_chunks: Requested vector chunk data * @mb_vector: Mailbox vector data * @vector_stack: Stack to store the msix vector indexes @@ -521,6 +621,7 @@ struct idpf_vc_xn_manager; * @caps: Negotiated capabilities with device * @vcxn_mngr: Virtchnl transaction manager * @dev_ops: See idpf_dev_ops + * @cdev_info: IDC core device info pointer * @num_vfs: Number of allocated VFs through sysfs. PF does not directly talk * to VFs but is used to initialize them * @crc_enable: Enable CRC insertion offload @@ -530,6 +631,7 @@ struct idpf_vc_xn_manager; * @vector_lock: Lock to protect vector distribution * @queue_lock: Lock to protect queue distribution * @vc_buf_lock: Lock to protect virtchnl buffer + * @ptp: Storage for PTP-related data */ struct idpf_adapter { struct pci_dev *pdev; @@ -542,10 +644,11 @@ struct idpf_adapter { DECLARE_BITMAP(flags, IDPF_FLAGS_NBITS); struct idpf_reset_reg reset_reg; struct idpf_hw hw; - u16 num_req_msix; u16 num_avail_msix; u16 num_msix_entries; struct msix_entry *msix_entries; + u16 num_rdma_msix_entries; + struct msix_entry *rdma_msix_entries; struct virtchnl2_alloc_vectors *req_vec_chunks; struct idpf_q_vector mb_vector; struct idpf_vector_lifo vector_stack; @@ -578,6 +681,7 @@ struct idpf_adapter { struct idpf_vc_xn_manager *vcxn_mngr; struct idpf_dev_ops dev_ops; + struct iidc_rdma_core_dev_info *cdev_info; int num_vfs; bool crc_enable; bool req_tx_splitq; @@ -587,6 +691,8 @@ struct idpf_adapter { struct mutex vector_lock; struct mutex queue_lock; struct mutex vc_buf_lock; + + struct idpf_ptp *ptp; }; /** @@ -601,6 +707,11 @@ static inline int idpf_is_queue_model_split(u16 q_model) q_model == VIRTCHNL2_QUEUE_MODEL_SPLIT; } +static inline bool idpf_xdp_enabled(const struct idpf_vport *vport) +{ + return vport->adapter && vport->xdp_prog; +} + #define idpf_is_cap_ena(adapter, field, flag) \ idpf_is_capability_ena(adapter, false, field, flag) #define idpf_is_cap_ena_all(adapter, field, flag) \ @@ -609,17 +720,26 @@ static inline int idpf_is_queue_model_split(u16 q_model) bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, enum idpf_cap_field field, u64 flag); +/** + * idpf_is_rdma_cap_ena - Determine if RDMA is supported + * @adapter: private data struct + * + * Return: true if RDMA capability is enabled, false otherwise + */ +static inline bool idpf_is_rdma_cap_ena(struct idpf_adapter *adapter) +{ + return idpf_is_cap_ena(adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_RDMA); +} + #define IDPF_CAP_RSS (\ - VIRTCHNL2_CAP_RSS_IPV4_TCP |\ - VIRTCHNL2_CAP_RSS_IPV4_TCP |\ - VIRTCHNL2_CAP_RSS_IPV4_UDP |\ - VIRTCHNL2_CAP_RSS_IPV4_SCTP |\ - VIRTCHNL2_CAP_RSS_IPV4_OTHER |\ - VIRTCHNL2_CAP_RSS_IPV6_TCP |\ - VIRTCHNL2_CAP_RSS_IPV6_TCP |\ - VIRTCHNL2_CAP_RSS_IPV6_UDP |\ - VIRTCHNL2_CAP_RSS_IPV6_SCTP |\ - VIRTCHNL2_CAP_RSS_IPV6_OTHER) + VIRTCHNL2_FLOW_IPV4_TCP |\ + VIRTCHNL2_FLOW_IPV4_UDP |\ + VIRTCHNL2_FLOW_IPV4_SCTP |\ + VIRTCHNL2_FLOW_IPV4_OTHER |\ + VIRTCHNL2_FLOW_IPV6_TCP |\ + VIRTCHNL2_FLOW_IPV6_UDP |\ + VIRTCHNL2_FLOW_IPV6_SCTP |\ + VIRTCHNL2_FLOW_IPV6_OTHER) #define IDPF_CAP_RSC (\ VIRTCHNL2_CAP_RSC_IPV4_TCP |\ @@ -629,13 +749,13 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V4 |\ VIRTCHNL2_CAP_RX_HSPLIT_AT_L4V6) -#define IDPF_CAP_RX_CSUM_L4V4 (\ - VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_TCP |\ - VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_UDP) +#define IDPF_CAP_TX_CSUM_L4V4 (\ + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_TCP |\ + VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_UDP) -#define IDPF_CAP_RX_CSUM_L4V6 (\ - VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\ - VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP) +#define IDPF_CAP_TX_CSUM_L4V6 (\ + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_TCP |\ + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_UDP) #define IDPF_CAP_RX_CSUM (\ VIRTCHNL2_CAP_RX_CSUM_L3_IPV4 |\ @@ -644,11 +764,9 @@ bool idpf_is_capability_ena(struct idpf_adapter *adapter, bool all, VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_TCP |\ VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_UDP) -#define IDPF_CAP_SCTP_CSUM (\ +#define IDPF_CAP_TX_SCTP_CSUM (\ VIRTCHNL2_CAP_TX_CSUM_L4_IPV4_SCTP |\ - VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP |\ - VIRTCHNL2_CAP_RX_CSUM_L4_IPV4_SCTP |\ - VIRTCHNL2_CAP_RX_CSUM_L4_IPV6_SCTP) + VIRTCHNL2_CAP_TX_CSUM_L4_IPV6_SCTP) #define IDPF_CAP_TUNNEL_TX_CSUM (\ VIRTCHNL2_CAP_TX_CSUM_L3_SINGLE_TUNNEL |\ @@ -664,6 +782,17 @@ static inline u16 idpf_get_reserved_vecs(struct idpf_adapter *adapter) } /** + * idpf_get_reserved_rdma_vecs - Get reserved RDMA vectors + * @adapter: private data struct + * + * Return: number of vectors reserved for RDMA + */ +static inline u16 idpf_get_reserved_rdma_vecs(struct idpf_adapter *adapter) +{ + return le16_to_cpu(adapter->caps.num_rdma_allocated_vectors); +} + +/** * idpf_get_default_vports - Get default number of vports * @adapter: private data struct */ @@ -702,6 +831,34 @@ static inline u8 idpf_get_min_tx_pkt_len(struct idpf_adapter *adapter) } /** + * idpf_get_mbx_reg_addr - Get BAR0 mailbox register address + * @adapter: private data struct + * @reg_offset: register offset value + * + * Return: BAR0 mailbox register address based on register offset. + */ +static inline void __iomem *idpf_get_mbx_reg_addr(struct idpf_adapter *adapter, + resource_size_t reg_offset) +{ + return adapter->hw.mbx.vaddr + reg_offset; +} + +/** + * idpf_get_rstat_reg_addr - Get BAR0 rstat register address + * @adapter: private data struct + * @reg_offset: register offset value + * + * Return: BAR0 rstat register address based on register offset. + */ +static inline void __iomem *idpf_get_rstat_reg_addr(struct idpf_adapter *adapter, + resource_size_t reg_offset) +{ + reg_offset -= adapter->dev_ops.static_reg_info[1].start; + + return adapter->hw.rstat.vaddr + reg_offset; +} + +/** * idpf_get_reg_addr - Get BAR0 register address * @adapter: private data struct * @reg_offset: register offset value @@ -711,7 +868,30 @@ static inline u8 idpf_get_min_tx_pkt_len(struct idpf_adapter *adapter) static inline void __iomem *idpf_get_reg_addr(struct idpf_adapter *adapter, resource_size_t reg_offset) { - return (void __iomem *)(adapter->hw.hw_addr + reg_offset); + struct idpf_hw *hw = &adapter->hw; + + for (int i = 0; i < hw->num_lan_regs; i++) { + struct idpf_mmio_reg *region = &hw->lan_regs[i]; + + if (reg_offset >= region->addr_start && + reg_offset < (region->addr_start + region->addr_len)) { + /* Convert the offset so that it is relative to the + * start of the region. Then add the base address of + * the region to get the final address. + */ + reg_offset -= region->addr_start; + + return region->vaddr + reg_offset; + } + } + + /* It's impossible to hit this case with offsets from the CP. But if we + * do for any other reason, the kernel will panic on that register + * access. Might as well do it here to make it clear what's happening. + */ + BUG(); + + return NULL; } /** @@ -725,7 +905,7 @@ static inline bool idpf_is_reset_detected(struct idpf_adapter *adapter) if (!adapter->hw.arq) return true; - return !(readl(idpf_get_reg_addr(adapter, adapter->hw.arq->reg.len)) & + return !(readl(idpf_get_mbx_reg_addr(adapter, adapter->hw.arq->reg.len)) & adapter->hw.arq->reg.len_mask); } @@ -811,6 +991,13 @@ static inline void idpf_vport_ctrl_unlock(struct net_device *netdev) mutex_unlock(&np->adapter->vport_ctrl_lock); } +static inline bool idpf_vport_ctrl_is_locked(struct net_device *netdev) +{ + struct idpf_netdev_priv *np = netdev_priv(netdev); + + return mutex_is_locked(&np->adapter->vport_ctrl_lock); +} + void idpf_statistics_task(struct work_struct *work); void idpf_init_task(struct work_struct *work); void idpf_service_task(struct work_struct *work); @@ -834,5 +1021,16 @@ int idpf_sriov_configure(struct pci_dev *pdev, int num_vfs); u8 idpf_vport_get_hsplit(const struct idpf_vport *vport); bool idpf_vport_set_hsplit(const struct idpf_vport *vport, u8 val); - +int idpf_idc_init(struct idpf_adapter *adapter); +int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter, + enum iidc_function_type ftype); +void idpf_idc_deinit_core_aux_device(struct iidc_rdma_core_dev_info *cdev_info); +void idpf_idc_deinit_vport_aux_device(struct iidc_rdma_vport_dev_info *vdev_info); +void idpf_idc_issue_reset_event(struct iidc_rdma_core_dev_info *cdev_info); +void idpf_idc_vdev_mtu_event(struct iidc_rdma_vport_dev_info *vdev_info, + enum iidc_rdma_event_type event_type); + +int idpf_add_del_fsteer_filters(struct idpf_adapter *adapter, + struct virtchnl2_flow_rule_add_del *rule, + enum virtchnl2_op opcode); #endif /* !_IDPF_H_ */ |
