1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 2*4882a593Smuzhiyun /* QLogic qed NIC Driver 3*4882a593Smuzhiyun * Copyright (c) 2015-2017 QLogic Corporation 4*4882a593Smuzhiyun * Copyright (c) 2019-2020 Marvell International Ltd. 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef _QED_LL2_H 8*4882a593Smuzhiyun #define _QED_LL2_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/types.h> 11*4882a593Smuzhiyun #include <linux/kernel.h> 12*4882a593Smuzhiyun #include <linux/list.h> 13*4882a593Smuzhiyun #include <linux/mutex.h> 14*4882a593Smuzhiyun #include <linux/slab.h> 15*4882a593Smuzhiyun #include <linux/spinlock.h> 16*4882a593Smuzhiyun #include <linux/qed/qed_chain.h> 17*4882a593Smuzhiyun #include <linux/qed/qed_ll2_if.h> 18*4882a593Smuzhiyun #include "qed.h" 19*4882a593Smuzhiyun #include "qed_hsi.h" 20*4882a593Smuzhiyun #include "qed_sp.h" 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun #define QED_MAX_NUM_OF_LL2_CONNECTIONS (4) 23*4882a593Smuzhiyun /* LL2 queues handles will be split as follows: 24*4882a593Smuzhiyun * first will be legacy queues, and then the ctx based queues. 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun #define QED_MAX_NUM_OF_LL2_CONNS_PF (4) 27*4882a593Smuzhiyun #define QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF (3) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define QED_MAX_NUM_OF_CTX_LL2_CONNS_PF \ 30*4882a593Smuzhiyun (QED_MAX_NUM_OF_LL2_CONNS_PF - QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF) 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #define QED_LL2_LEGACY_CONN_BASE_PF 0 33*4882a593Smuzhiyun #define QED_LL2_CTX_CONN_BASE_PF QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun struct qed_ll2_rx_packet { 37*4882a593Smuzhiyun struct list_head list_entry; 38*4882a593Smuzhiyun struct core_rx_bd_with_buff_len *rxq_bd; 39*4882a593Smuzhiyun dma_addr_t rx_buf_addr; 40*4882a593Smuzhiyun u16 buf_length; 41*4882a593Smuzhiyun void *cookie; 42*4882a593Smuzhiyun u8 placement_offset; 43*4882a593Smuzhiyun u16 parse_flags; 44*4882a593Smuzhiyun u16 packet_length; 45*4882a593Smuzhiyun u16 vlan; 46*4882a593Smuzhiyun u32 opaque_data[2]; 47*4882a593Smuzhiyun }; 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun struct qed_ll2_tx_packet { 50*4882a593Smuzhiyun struct list_head list_entry; 51*4882a593Smuzhiyun u16 bd_used; 52*4882a593Smuzhiyun bool notify_fw; 53*4882a593Smuzhiyun void *cookie; 54*4882a593Smuzhiyun /* Flexible Array of bds_set determined by max_bds_per_packet */ 55*4882a593Smuzhiyun struct { 56*4882a593Smuzhiyun struct core_tx_bd *txq_bd; 57*4882a593Smuzhiyun dma_addr_t tx_frag; 58*4882a593Smuzhiyun u16 frag_len; 59*4882a593Smuzhiyun } bds_set[]; 60*4882a593Smuzhiyun }; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun struct qed_ll2_rx_queue { 63*4882a593Smuzhiyun /* Lock protecting the Rx queue manipulation */ 64*4882a593Smuzhiyun spinlock_t lock; 65*4882a593Smuzhiyun struct qed_chain rxq_chain; 66*4882a593Smuzhiyun struct qed_chain rcq_chain; 67*4882a593Smuzhiyun u8 rx_sb_index; 68*4882a593Smuzhiyun u8 ctx_based; 69*4882a593Smuzhiyun bool b_cb_registered; 70*4882a593Smuzhiyun __le16 *p_fw_cons; 71*4882a593Smuzhiyun struct list_head active_descq; 72*4882a593Smuzhiyun struct list_head free_descq; 73*4882a593Smuzhiyun struct list_head posting_descq; 74*4882a593Smuzhiyun struct qed_ll2_rx_packet *descq_array; 75*4882a593Smuzhiyun void __iomem *set_prod_addr; 76*4882a593Smuzhiyun struct core_pwm_prod_update_data db_data; 77*4882a593Smuzhiyun }; 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun struct qed_ll2_tx_queue { 80*4882a593Smuzhiyun /* Lock protecting the Tx queue manipulation */ 81*4882a593Smuzhiyun spinlock_t lock; 82*4882a593Smuzhiyun struct qed_chain txq_chain; 83*4882a593Smuzhiyun u8 tx_sb_index; 84*4882a593Smuzhiyun bool b_cb_registered; 85*4882a593Smuzhiyun __le16 *p_fw_cons; 86*4882a593Smuzhiyun struct list_head active_descq; 87*4882a593Smuzhiyun struct list_head free_descq; 88*4882a593Smuzhiyun struct list_head sending_descq; 89*4882a593Smuzhiyun u16 cur_completing_bd_idx; 90*4882a593Smuzhiyun void __iomem *doorbell_addr; 91*4882a593Smuzhiyun struct core_db_data db_msg; 92*4882a593Smuzhiyun u16 bds_idx; 93*4882a593Smuzhiyun u16 cur_send_frag_num; 94*4882a593Smuzhiyun u16 cur_completing_frag_num; 95*4882a593Smuzhiyun bool b_completing_packet; 96*4882a593Smuzhiyun void *descq_mem; /* memory for variable sized qed_ll2_tx_packet*/ 97*4882a593Smuzhiyun struct qed_ll2_tx_packet *cur_send_packet; 98*4882a593Smuzhiyun struct qed_ll2_tx_packet cur_completing_packet; 99*4882a593Smuzhiyun }; 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun struct qed_ll2_info { 102*4882a593Smuzhiyun /* Lock protecting the state of LL2 */ 103*4882a593Smuzhiyun struct mutex mutex; 104*4882a593Smuzhiyun 105*4882a593Smuzhiyun struct qed_ll2_acquire_data_inputs input; 106*4882a593Smuzhiyun u32 cid; 107*4882a593Smuzhiyun u8 my_id; 108*4882a593Smuzhiyun u8 queue_id; 109*4882a593Smuzhiyun u8 tx_stats_id; 110*4882a593Smuzhiyun bool b_active; 111*4882a593Smuzhiyun enum core_tx_dest tx_dest; 112*4882a593Smuzhiyun u8 tx_stats_en; 113*4882a593Smuzhiyun bool main_func_queue; 114*4882a593Smuzhiyun struct qed_ll2_rx_queue rx_queue; 115*4882a593Smuzhiyun struct qed_ll2_tx_queue tx_queue; 116*4882a593Smuzhiyun struct qed_ll2_cbs cbs; 117*4882a593Smuzhiyun }; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun extern const struct qed_ll2_ops qed_ll2_ops_pass; 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun /** 122*4882a593Smuzhiyun * @brief qed_ll2_acquire_connection - allocate resources, 123*4882a593Smuzhiyun * starts rx & tx (if relevant) queues pair. Provides 124*4882a593Smuzhiyun * connecion handler as output parameter. 125*4882a593Smuzhiyun * 126*4882a593Smuzhiyun * 127*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 128*4882a593Smuzhiyun * @param data - describes connection parameters 129*4882a593Smuzhiyun * @return int 130*4882a593Smuzhiyun */ 131*4882a593Smuzhiyun int qed_ll2_acquire_connection(void *cxt, struct qed_ll2_acquire_data *data); 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun /** 134*4882a593Smuzhiyun * @brief qed_ll2_establish_connection - start previously 135*4882a593Smuzhiyun * allocated LL2 queues pair 136*4882a593Smuzhiyun * 137*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 138*4882a593Smuzhiyun * @param p_ptt 139*4882a593Smuzhiyun * @param connection_handle LL2 connection's handle obtained from 140*4882a593Smuzhiyun * qed_ll2_require_connection 141*4882a593Smuzhiyun * 142*4882a593Smuzhiyun * @return 0 on success, failure otherwise 143*4882a593Smuzhiyun */ 144*4882a593Smuzhiyun int qed_ll2_establish_connection(void *cxt, u8 connection_handle); 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun /** 147*4882a593Smuzhiyun * @brief qed_ll2_post_rx_buffers - submit buffers to LL2 Rx queue. 148*4882a593Smuzhiyun * 149*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 150*4882a593Smuzhiyun * @param connection_handle LL2 connection's handle obtained from 151*4882a593Smuzhiyun * qed_ll2_require_connection 152*4882a593Smuzhiyun * @param addr rx (physical address) buffers to submit 153*4882a593Smuzhiyun * @param cookie 154*4882a593Smuzhiyun * @param notify_fw produce corresponding Rx BD immediately 155*4882a593Smuzhiyun * 156*4882a593Smuzhiyun * @return 0 on success, failure otherwise 157*4882a593Smuzhiyun */ 158*4882a593Smuzhiyun int qed_ll2_post_rx_buffer(void *cxt, 159*4882a593Smuzhiyun u8 connection_handle, 160*4882a593Smuzhiyun dma_addr_t addr, 161*4882a593Smuzhiyun u16 buf_len, void *cookie, u8 notify_fw); 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun /** 164*4882a593Smuzhiyun * @brief qed_ll2_prepare_tx_packet - request for start Tx BD 165*4882a593Smuzhiyun * to prepare Tx packet submission to FW. 166*4882a593Smuzhiyun * 167*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 168*4882a593Smuzhiyun * @param connection_handle 169*4882a593Smuzhiyun * @param pkt - info regarding the tx packet 170*4882a593Smuzhiyun * @param notify_fw - issue doorbell to fw for this packet 171*4882a593Smuzhiyun * 172*4882a593Smuzhiyun * @return 0 on success, failure otherwise 173*4882a593Smuzhiyun */ 174*4882a593Smuzhiyun int qed_ll2_prepare_tx_packet(void *cxt, 175*4882a593Smuzhiyun u8 connection_handle, 176*4882a593Smuzhiyun struct qed_ll2_tx_pkt_info *pkt, 177*4882a593Smuzhiyun bool notify_fw); 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun /** 180*4882a593Smuzhiyun * @brief qed_ll2_release_connection - releases resources 181*4882a593Smuzhiyun * allocated for LL2 connection 182*4882a593Smuzhiyun * 183*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 184*4882a593Smuzhiyun * @param connection_handle LL2 connection's handle obtained from 185*4882a593Smuzhiyun * qed_ll2_require_connection 186*4882a593Smuzhiyun */ 187*4882a593Smuzhiyun void qed_ll2_release_connection(void *cxt, u8 connection_handle); 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun /** 190*4882a593Smuzhiyun * @brief qed_ll2_set_fragment_of_tx_packet - provides fragments to fill 191*4882a593Smuzhiyun * Tx BD of BDs requested by 192*4882a593Smuzhiyun * qed_ll2_prepare_tx_packet 193*4882a593Smuzhiyun * 194*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 195*4882a593Smuzhiyun * @param connection_handle LL2 connection's handle 196*4882a593Smuzhiyun * obtained from 197*4882a593Smuzhiyun * qed_ll2_require_connection 198*4882a593Smuzhiyun * @param addr 199*4882a593Smuzhiyun * @param nbytes 200*4882a593Smuzhiyun * 201*4882a593Smuzhiyun * @return 0 on success, failure otherwise 202*4882a593Smuzhiyun */ 203*4882a593Smuzhiyun int qed_ll2_set_fragment_of_tx_packet(void *cxt, 204*4882a593Smuzhiyun u8 connection_handle, 205*4882a593Smuzhiyun dma_addr_t addr, u16 nbytes); 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun /** 208*4882a593Smuzhiyun * @brief qed_ll2_terminate_connection - stops Tx/Rx queues 209*4882a593Smuzhiyun * 210*4882a593Smuzhiyun * 211*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 212*4882a593Smuzhiyun * @param connection_handle LL2 connection's handle 213*4882a593Smuzhiyun * obtained from 214*4882a593Smuzhiyun * qed_ll2_require_connection 215*4882a593Smuzhiyun * 216*4882a593Smuzhiyun * @return 0 on success, failure otherwise 217*4882a593Smuzhiyun */ 218*4882a593Smuzhiyun int qed_ll2_terminate_connection(void *cxt, u8 connection_handle); 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun /** 221*4882a593Smuzhiyun * @brief qed_ll2_get_stats - get LL2 queue's statistics 222*4882a593Smuzhiyun * 223*4882a593Smuzhiyun * 224*4882a593Smuzhiyun * @param cxt - pointer to the hw-function [opaque to some] 225*4882a593Smuzhiyun * @param connection_handle LL2 connection's handle obtained from 226*4882a593Smuzhiyun * qed_ll2_require_connection 227*4882a593Smuzhiyun * @param p_stats 228*4882a593Smuzhiyun * 229*4882a593Smuzhiyun * @return 0 on success, failure otherwise 230*4882a593Smuzhiyun */ 231*4882a593Smuzhiyun int qed_ll2_get_stats(void *cxt, 232*4882a593Smuzhiyun u8 connection_handle, struct qed_ll2_stats *p_stats); 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun /** 235*4882a593Smuzhiyun * @brief qed_ll2_alloc - Allocates LL2 connections set 236*4882a593Smuzhiyun * 237*4882a593Smuzhiyun * @param p_hwfn 238*4882a593Smuzhiyun * 239*4882a593Smuzhiyun * @return int 240*4882a593Smuzhiyun */ 241*4882a593Smuzhiyun int qed_ll2_alloc(struct qed_hwfn *p_hwfn); 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /** 244*4882a593Smuzhiyun * @brief qed_ll2_setup - Inits LL2 connections set 245*4882a593Smuzhiyun * 246*4882a593Smuzhiyun * @param p_hwfn 247*4882a593Smuzhiyun * 248*4882a593Smuzhiyun */ 249*4882a593Smuzhiyun void qed_ll2_setup(struct qed_hwfn *p_hwfn); 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun /** 252*4882a593Smuzhiyun * @brief qed_ll2_free - Releases LL2 connections set 253*4882a593Smuzhiyun * 254*4882a593Smuzhiyun * @param p_hwfn 255*4882a593Smuzhiyun * 256*4882a593Smuzhiyun */ 257*4882a593Smuzhiyun void qed_ll2_free(struct qed_hwfn *p_hwfn); 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun #endif 260