1fb4ac04eSJunfeng Guo /* SPDX-License-Identifier: BSD-3-Clause 26b35be99SWenjing Qiao * Copyright(c) 2001-2023 Intel Corporation 3fb4ac04eSJunfeng Guo */ 4fb4ac04eSJunfeng Guo 5fb4ac04eSJunfeng Guo #ifndef _IDPF_CONTROLQ_API_H_ 6fb4ac04eSJunfeng Guo #define _IDPF_CONTROLQ_API_H_ 7fb4ac04eSJunfeng Guo 8fb4ac04eSJunfeng Guo #include "idpf_osdep.h" 91094dd94SDavid Marchand 10fb4ac04eSJunfeng Guo struct idpf_hw; 11fb4ac04eSJunfeng Guo 12fb4ac04eSJunfeng Guo /* Used for queue init, response and events */ 13fb4ac04eSJunfeng Guo enum idpf_ctlq_type { 14fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_MAILBOX_TX = 0, 15fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_MAILBOX_RX = 1, 16fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_CONFIG_TX = 2, 17fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_CONFIG_RX = 3, 18fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_EVENT_RX = 4, 19fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_RDMA_TX = 5, 20fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_RDMA_RX = 6, 21fb4ac04eSJunfeng Guo IDPF_CTLQ_TYPE_RDMA_COMPL = 7 22fb4ac04eSJunfeng Guo }; 23fb4ac04eSJunfeng Guo 24a97fb92cSSimei Su /* Generic Control Queue Structures */ 25fb4ac04eSJunfeng Guo struct idpf_ctlq_reg { 26fb4ac04eSJunfeng Guo /* used for queue tracking */ 27fb4ac04eSJunfeng Guo u32 head; 28fb4ac04eSJunfeng Guo u32 tail; 29fb4ac04eSJunfeng Guo /* Below applies only to default mb (if present) */ 30fb4ac04eSJunfeng Guo u32 len; 31fb4ac04eSJunfeng Guo u32 bah; 32fb4ac04eSJunfeng Guo u32 bal; 33fb4ac04eSJunfeng Guo u32 len_mask; 34fb4ac04eSJunfeng Guo u32 len_ena_mask; 35fb4ac04eSJunfeng Guo u32 head_mask; 36fb4ac04eSJunfeng Guo }; 37fb4ac04eSJunfeng Guo 38fb4ac04eSJunfeng Guo /* Generic queue msg structure */ 39fb4ac04eSJunfeng Guo struct idpf_ctlq_msg { 40fb4ac04eSJunfeng Guo u8 vmvf_type; /* represents the source of the message on recv */ 41fb4ac04eSJunfeng Guo #define IDPF_VMVF_TYPE_VF 0 42fb4ac04eSJunfeng Guo #define IDPF_VMVF_TYPE_VM 1 43fb4ac04eSJunfeng Guo #define IDPF_VMVF_TYPE_PF 2 44fb4ac04eSJunfeng Guo u8 host_id; 45fb4ac04eSJunfeng Guo /* 3b field used only when sending a message to peer - to be used in 46fb4ac04eSJunfeng Guo * combination with target func_id to route the message 47fb4ac04eSJunfeng Guo */ 48fb4ac04eSJunfeng Guo #define IDPF_HOST_ID_MASK 0x7 49fb4ac04eSJunfeng Guo 50fb4ac04eSJunfeng Guo u16 opcode; 51fb4ac04eSJunfeng Guo u16 data_len; /* data_len = 0 when no payload is attached */ 52fb4ac04eSJunfeng Guo union { 53fb4ac04eSJunfeng Guo u16 func_id; /* when sending a message */ 54fb4ac04eSJunfeng Guo u16 status; /* when receiving a message */ 55fb4ac04eSJunfeng Guo }; 56fb4ac04eSJunfeng Guo union { 57428533f8SWenjing Qiao #ifndef __KERNEL__ 58428533f8SWenjing Qiao #define FILL_OPCODE_V1(msg, opcode) ((msg).cookie.cfg.mbx.chnl_opcode = opcode) 59428533f8SWenjing Qiao #define FILL_RETVAL_V1(msg, retval) ((msg).cookie.cfg.mbx.chnl_retval = retval) 60428533f8SWenjing Qiao #endif /* __KERNEL__ */ 61fb4ac04eSJunfeng Guo struct { 62fb4ac04eSJunfeng Guo u32 chnl_opcode; 63428533f8SWenjing Qiao u32 chnl_retval; 64fb4ac04eSJunfeng Guo } mbx; 65fb4ac04eSJunfeng Guo } cookie; 66fb4ac04eSJunfeng Guo union { 67fb4ac04eSJunfeng Guo #define IDPF_DIRECT_CTX_SIZE 16 68fb4ac04eSJunfeng Guo #define IDPF_INDIRECT_CTX_SIZE 8 69fb4ac04eSJunfeng Guo /* 16 bytes of context can be provided or 8 bytes of context 70fb4ac04eSJunfeng Guo * plus the address of a DMA buffer 71fb4ac04eSJunfeng Guo */ 72fb4ac04eSJunfeng Guo u8 direct[IDPF_DIRECT_CTX_SIZE]; 73fb4ac04eSJunfeng Guo struct { 74fb4ac04eSJunfeng Guo u8 context[IDPF_INDIRECT_CTX_SIZE]; 75fb4ac04eSJunfeng Guo struct idpf_dma_mem *payload; 76fb4ac04eSJunfeng Guo } indirect; 770ea5fb5bSSimei Su struct { 780ea5fb5bSSimei Su u32 rsvd; 790ea5fb5bSSimei Su u16 data; 800ea5fb5bSSimei Su u16 flags; 810ea5fb5bSSimei Su } sw_cookie; 82fb4ac04eSJunfeng Guo } ctx; 83fb4ac04eSJunfeng Guo }; 84fb4ac04eSJunfeng Guo 85fb4ac04eSJunfeng Guo /* Generic queue info structures */ 86fb4ac04eSJunfeng Guo /* MB, CONFIG and EVENT q do not have extended info */ 87fb4ac04eSJunfeng Guo struct idpf_ctlq_create_info { 88fb4ac04eSJunfeng Guo enum idpf_ctlq_type type; 89fb4ac04eSJunfeng Guo int id; /* absolute queue offset passed as input 90fb4ac04eSJunfeng Guo * -1 for default mailbox if present 91fb4ac04eSJunfeng Guo */ 92fb4ac04eSJunfeng Guo u16 len; /* Queue length passed as input */ 93fb4ac04eSJunfeng Guo u16 buf_size; /* buffer size passed as input */ 94fb4ac04eSJunfeng Guo u64 base_address; /* output, HPA of the Queue start */ 95fb4ac04eSJunfeng Guo struct idpf_ctlq_reg reg; /* registers accessed by ctlqs */ 96fb4ac04eSJunfeng Guo 97fb4ac04eSJunfeng Guo int ext_info_size; 98fb4ac04eSJunfeng Guo void *ext_info; /* Specific to q type */ 99fb4ac04eSJunfeng Guo }; 100fb4ac04eSJunfeng Guo 101fb4ac04eSJunfeng Guo /* Control Queue information */ 102fb4ac04eSJunfeng Guo struct idpf_ctlq_info { 103fb4ac04eSJunfeng Guo LIST_ENTRY_TYPE(idpf_ctlq_info) cq_list; 104fb4ac04eSJunfeng Guo 105fb4ac04eSJunfeng Guo enum idpf_ctlq_type cq_type; 106fb4ac04eSJunfeng Guo int q_id; 107fb4ac04eSJunfeng Guo idpf_lock cq_lock; /* queue lock 108fb4ac04eSJunfeng Guo * idpf_lock is defined in OSdep.h 109fb4ac04eSJunfeng Guo */ 110fb4ac04eSJunfeng Guo /* used for interrupt processing */ 111fb4ac04eSJunfeng Guo u16 next_to_use; 112fb4ac04eSJunfeng Guo u16 next_to_clean; 113fb4ac04eSJunfeng Guo u16 next_to_post; /* starting descriptor to post buffers 114fb4ac04eSJunfeng Guo * to after recev 115fb4ac04eSJunfeng Guo */ 116fb4ac04eSJunfeng Guo 117fb4ac04eSJunfeng Guo struct idpf_dma_mem desc_ring; /* descriptor ring memory 118fb4ac04eSJunfeng Guo * idpf_dma_mem is defined in OSdep.h 119fb4ac04eSJunfeng Guo */ 120fb4ac04eSJunfeng Guo union { 121fb4ac04eSJunfeng Guo struct idpf_dma_mem **rx_buff; 122fb4ac04eSJunfeng Guo struct idpf_ctlq_msg **tx_msg; 123fb4ac04eSJunfeng Guo } bi; 124fb4ac04eSJunfeng Guo 125fb4ac04eSJunfeng Guo u16 buf_size; /* queue buffer size */ 126fb4ac04eSJunfeng Guo u16 ring_size; /* Number of descriptors */ 127fb4ac04eSJunfeng Guo struct idpf_ctlq_reg reg; /* registers accessed by ctlqs */ 128fb4ac04eSJunfeng Guo }; 129fb4ac04eSJunfeng Guo 130fb4ac04eSJunfeng Guo /* PF/VF mailbox commands */ 131fb4ac04eSJunfeng Guo enum idpf_mbx_opc { 132fb4ac04eSJunfeng Guo /* idpf_mbq_opc_send_msg_to_pf: 133fb4ac04eSJunfeng Guo * usage: used by PF or VF to send a message to its CPF 134fb4ac04eSJunfeng Guo * target: RX queue and function ID of parent PF taken from HW 135fb4ac04eSJunfeng Guo */ 136fb4ac04eSJunfeng Guo idpf_mbq_opc_send_msg_to_pf = 0x0801, 137fb4ac04eSJunfeng Guo 138fb4ac04eSJunfeng Guo /* idpf_mbq_opc_send_msg_to_vf: 139fb4ac04eSJunfeng Guo * usage: used by PF to send message to a VF 140fb4ac04eSJunfeng Guo * target: VF control queue ID must be specified in descriptor 141fb4ac04eSJunfeng Guo */ 142fb4ac04eSJunfeng Guo idpf_mbq_opc_send_msg_to_vf = 0x0802, 143fb4ac04eSJunfeng Guo 144fb4ac04eSJunfeng Guo /* idpf_mbq_opc_send_msg_to_peer_pf: 145fb4ac04eSJunfeng Guo * usage: used by any function to send message to any peer PF 146fb4ac04eSJunfeng Guo * target: RX queue and host of parent PF taken from HW 147fb4ac04eSJunfeng Guo */ 148fb4ac04eSJunfeng Guo idpf_mbq_opc_send_msg_to_peer_pf = 0x0803, 149fb4ac04eSJunfeng Guo 150fb4ac04eSJunfeng Guo /* idpf_mbq_opc_send_msg_to_peer_drv: 151fb4ac04eSJunfeng Guo * usage: used by any function to send message to any peer driver 152fb4ac04eSJunfeng Guo * target: RX queue and target host must be specific in descriptor 153fb4ac04eSJunfeng Guo */ 154fb4ac04eSJunfeng Guo idpf_mbq_opc_send_msg_to_peer_drv = 0x0804, 155fb4ac04eSJunfeng Guo }; 156fb4ac04eSJunfeng Guo 157*9510c5f8SSoumyadeep Hore /* Define the APF hardware struct to replace other control structs as needed 158*9510c5f8SSoumyadeep Hore * Align to ctlq_hw_info 159*9510c5f8SSoumyadeep Hore */ 160*9510c5f8SSoumyadeep Hore struct idpf_hw { 161*9510c5f8SSoumyadeep Hore /* Some part of BAR0 address space is not mapped by the LAN driver. 162*9510c5f8SSoumyadeep Hore * This results in 2 regions of BAR0 to be mapped by LAN driver which 163*9510c5f8SSoumyadeep Hore * will have its own base hardware address when mapped. 164*9510c5f8SSoumyadeep Hore */ 165*9510c5f8SSoumyadeep Hore u8 *hw_addr; 166*9510c5f8SSoumyadeep Hore u8 *hw_addr_region2; 167*9510c5f8SSoumyadeep Hore u64 hw_addr_len; 168*9510c5f8SSoumyadeep Hore u64 hw_addr_region2_len; 169*9510c5f8SSoumyadeep Hore 170*9510c5f8SSoumyadeep Hore void *back; 171*9510c5f8SSoumyadeep Hore 172*9510c5f8SSoumyadeep Hore /* control queue - send and receive */ 173*9510c5f8SSoumyadeep Hore struct idpf_ctlq_info *asq; 174*9510c5f8SSoumyadeep Hore struct idpf_ctlq_info *arq; 175*9510c5f8SSoumyadeep Hore 176*9510c5f8SSoumyadeep Hore /* subsystem structs */ 177*9510c5f8SSoumyadeep Hore struct idpf_mac_info mac; 178*9510c5f8SSoumyadeep Hore struct idpf_bus_info bus; 179*9510c5f8SSoumyadeep Hore struct idpf_hw_func_caps func_caps; 180*9510c5f8SSoumyadeep Hore 181*9510c5f8SSoumyadeep Hore /* pci info */ 182*9510c5f8SSoumyadeep Hore u16 device_id; 183*9510c5f8SSoumyadeep Hore u16 vendor_id; 184*9510c5f8SSoumyadeep Hore u16 subsystem_device_id; 185*9510c5f8SSoumyadeep Hore u16 subsystem_vendor_id; 186*9510c5f8SSoumyadeep Hore u8 revision_id; 187*9510c5f8SSoumyadeep Hore bool adapter_stopped; 188*9510c5f8SSoumyadeep Hore 189*9510c5f8SSoumyadeep Hore LIST_HEAD_TYPE(list_head, idpf_ctlq_info) cq_list_head; 190*9510c5f8SSoumyadeep Hore }; 191*9510c5f8SSoumyadeep Hore 192a97fb92cSSimei Su /* API supported for control queue management */ 193fb4ac04eSJunfeng Guo /* Will init all required q including default mb. "q_info" is an array of 194fb4ac04eSJunfeng Guo * create_info structs equal to the number of control queues to be created. 195fb4ac04eSJunfeng Guo */ 196fb4ac04eSJunfeng Guo int idpf_ctlq_init(struct idpf_hw *hw, u8 num_q, 197fb4ac04eSJunfeng Guo struct idpf_ctlq_create_info *q_info); 198fb4ac04eSJunfeng Guo 199fb4ac04eSJunfeng Guo /* Allocate and initialize a single control queue, which will be added to the 200fb4ac04eSJunfeng Guo * control queue list; returns a handle to the created control queue 201fb4ac04eSJunfeng Guo */ 202fb4ac04eSJunfeng Guo int idpf_ctlq_add(struct idpf_hw *hw, 203fb4ac04eSJunfeng Guo struct idpf_ctlq_create_info *qinfo, 204fb4ac04eSJunfeng Guo struct idpf_ctlq_info **cq); 205fb4ac04eSJunfeng Guo 206fb4ac04eSJunfeng Guo /* Deinitialize and deallocate a single control queue */ 207fb4ac04eSJunfeng Guo void idpf_ctlq_remove(struct idpf_hw *hw, 208fb4ac04eSJunfeng Guo struct idpf_ctlq_info *cq); 209fb4ac04eSJunfeng Guo 210fb4ac04eSJunfeng Guo /* Sends messages to HW and will also free the buffer*/ 211fb4ac04eSJunfeng Guo int idpf_ctlq_send(struct idpf_hw *hw, 212fb4ac04eSJunfeng Guo struct idpf_ctlq_info *cq, 213fb4ac04eSJunfeng Guo u16 num_q_msg, 214fb4ac04eSJunfeng Guo struct idpf_ctlq_msg q_msg[]); 215fb4ac04eSJunfeng Guo 216fb4ac04eSJunfeng Guo /* Receives messages and called by interrupt handler/polling 217fb4ac04eSJunfeng Guo * initiated by app/process. Also caller is supposed to free the buffers 218fb4ac04eSJunfeng Guo */ 219fb4ac04eSJunfeng Guo int idpf_ctlq_recv(struct idpf_ctlq_info *cq, u16 *num_q_msg, 220fb4ac04eSJunfeng Guo struct idpf_ctlq_msg *q_msg); 221fb4ac04eSJunfeng Guo 222d6c84a1fSWenjing Qiao /* Reclaims all descriptors on HW write back */ 223d6c84a1fSWenjing Qiao int idpf_ctlq_clean_sq_force(struct idpf_ctlq_info *cq, u16 *clean_count, 224d6c84a1fSWenjing Qiao struct idpf_ctlq_msg *msg_status[]); 225d6c84a1fSWenjing Qiao 226fb4ac04eSJunfeng Guo /* Reclaims send descriptors on HW write back */ 227fb4ac04eSJunfeng Guo int idpf_ctlq_clean_sq(struct idpf_ctlq_info *cq, u16 *clean_count, 228fb4ac04eSJunfeng Guo struct idpf_ctlq_msg *msg_status[]); 229fb4ac04eSJunfeng Guo 230fb4ac04eSJunfeng Guo /* Indicate RX buffers are done being processed */ 231fb4ac04eSJunfeng Guo int idpf_ctlq_post_rx_buffs(struct idpf_hw *hw, 232fb4ac04eSJunfeng Guo struct idpf_ctlq_info *cq, 233fb4ac04eSJunfeng Guo u16 *buff_count, 234fb4ac04eSJunfeng Guo struct idpf_dma_mem **buffs); 235fb4ac04eSJunfeng Guo 236fb4ac04eSJunfeng Guo /* Will destroy all q including the default mb */ 237a97fb92cSSimei Su void idpf_ctlq_deinit(struct idpf_hw *hw); 238fb4ac04eSJunfeng Guo 239fb4ac04eSJunfeng Guo #endif /* _IDPF_CONTROLQ_API_H_ */ 240