1 #ifndef __COMMAND_H__ 2 #define __COMMAND_H__ 3 4 /* This file containes the slow-path send queue and the L2 Command code */ 5 #include "57712_reg.h" 6 #include "577xx_int_offsets.h" 7 #include "context.h" 8 #include "lm5710.h" 9 //#include "5710_hsi.h" 10 //#define MAX_PROTO 2 11 12 /* How many slow-path-queue elements can be sent in parallel divided into normal and high priority */ 13 #define MAX_NORMAL_PRIORITY_SPE 7 14 #define MAX_HIGH_PRIORITY_SPE 1 15 #define MAX_NUM_SPE 8 16 17 #define CMD_PRIORITY_NORMAL 0x10 18 #define CMD_PRIORITY_MEDIUM 0x20 19 #define CMD_PRIORITY_HIGH 0x30 20 21 22 23 24 /* structure representing a list of slow-path-completions */ 25 typedef struct _sp_cqes_info { 26 union eth_rx_cqe sp_cqe[MAX_NUM_SPE]; 27 u8_t idx; 28 } sp_cqes_info; 29 30 31 static __inline void _lm_sq_post(struct _lm_device_t *pdev,struct sq_pending_command * pending) 32 { 33 u32_t func = FUNC_ID(pdev); 34 35 /* TODO replace this with the proper struct */ 36 /* CID needs port number to be encoded int it */ 37 mm_memcpy(pdev->sq_info.sq_chain.prod_bd, &pending->command, sizeof(pending->command)); 38 39 pdev->sq_info.sq_chain.prod_idx ++; 40 pdev->sq_info.sq_chain.bd_left --; 41 42 if (pdev->sq_info.sq_chain.prod_bd == pdev->sq_info.sq_chain.last_bd) { 43 pdev->sq_info.sq_chain.prod_bd = pdev->sq_info.sq_chain.sq_chain_virt; 44 }else{ 45 pdev->sq_info.sq_chain.prod_bd ++ ; 46 } 47 48 49 DbgMessage(pdev,VERBOSEl2sp | VERBOSEl4sp, "Writing SP prod %d, conn_and_cmd_data=%x, type=%d \n",pdev->sq_info.sq_chain.prod_idx, pending->command.hdr.conn_and_cmd_data, pending->command.hdr.type); 50 51 if (IS_PFDEV(pdev) && pdev->sq_info.sq_state == SQ_STATE_NORMAL) { 52 LM_INTMEM_WRITE16(pdev, XSTORM_SPQ_PROD_OFFSET(func), pdev->sq_info.sq_chain.prod_idx, BAR_XSTRORM_INTMEM); 53 } 54 #ifdef VF_INVOLVED 55 else { 56 LM_INTMEM_WRITE16(PFDEV(pdev),XSTORM_VF_SPQ_PROD_OFFSET(ABS_VFID(pdev)), pdev->sq_info.sq_chain.prod_idx, BAR_XSTRORM_INTMEM); 57 } 58 #endif 59 } 60 61 /** 62 * @Description: This function fills a command that is received 63 * as a parameter given the input... 64 * 65 * @param pdev 66 * @param pending - OUT: this entry is filled given the input 67 * below 68 * @param cid 69 * @param command - FW Command ID 70 * @param type - The type of connection, can optionally 71 * include the function id as well if it differs 72 * from the function of pdev (for example for VFs) 73 * 74 * @param data - Data for FW ramrod 75 * @param release_mem_flag - Determines whether the sp pending 76 * command will be returned to the pool 77 * at the end of usage. 78 */ 79 static __inline void lm_sq_post_fill_entry(struct _lm_device_t* pdev, 80 struct sq_pending_command * pending, 81 u32_t cid, 82 u8_t command, 83 u16_t type, 84 u64_t data, 85 u8_t release_mem_flag) 86 { 87 /* In some cases type may already contain the func-id (VF specifically) so we add it only if it's not there... */ 88 if (!(type & SPE_HDR_T_FUNCTION_ID)) 89 { 90 type |= (FUNC_ID(pdev) << SPE_HDR_T_FUNCTION_ID_SHIFT); 91 } 92 93 // CID MSB is function number 94 pending->command.hdr.conn_and_cmd_data = mm_cpu_to_le32((command << SPE_HDR_T_CMD_ID_SHIFT ) | HW_CID(pdev,cid)); 95 pending->command.hdr.type = mm_cpu_to_le16(type); 96 pending->command.protocol_data.hi = mm_cpu_to_le32(U64_HI(data)); 97 pending->command.protocol_data.lo = mm_cpu_to_le32(U64_LO(data)); 98 pending->flags = 0; 99 100 if (release_mem_flag) 101 { 102 SET_FLAGS(pending->flags, SQ_PEND_RELEASE_MEM); 103 } 104 105 pending->cid = cid; 106 pending->type = type; /* don't kill function ID, RSC VF update really uses the value (& SPE_HDR_T_CONN_TYPE);*/ 107 pending->cmd = command; 108 109 } 110 111 /** 112 * Description 113 * Add the entry to the pending SP list. 114 * Try to add entry's from the list to the sq_chain if possible.(there is are less then 8 ramrod commands pending) 115 * 116 * @param pdev 117 * @param pending - The pending list entry. 118 * @param priority - (high or low) to witch list to insert the pending list entry. 119 * 120 * @return lm_status_t: LM_STATUS_SUCCESS on success or 121 * LM_STATUS_REQUEST_NOT_ACCEPTED if slowpath queue is 122 * in blocked state. 123 */ 124 lm_status_t lm_sq_post_entry(struct _lm_device_t * pdev, 125 struct sq_pending_command * pending, 126 u8_t priority); 127 128 /* 129 post a ramrod to the sq 130 takes the sq pending list spinlock and adds the request 131 will not block 132 but the actuall posting to the sq might be deffered until there is room 133 MUST only have one request pending per CID (this is up to the caller to enforce) 134 */ 135 lm_status_t lm_sq_post(struct _lm_device_t *pdev, 136 u32_t cid, 137 u8_t command, 138 u8_t priority, 139 u16_t type, 140 u64_t data); 141 142 /** 143 * @Description 144 * inform the sq mechanism of completed ramrods because the 145 * completions arrive on the fast-path rings the fast-path 146 * needs to inform the sq that the ramrod has been serviced 147 * will not block, it also needs to notify which ramrod has 148 * been completed since completions can arrive in a different 149 * sequence than sent. 150 * @param pdev 151 * @param priority: priority of ramrod being completed 152 * (different credits) 153 * @param command: which command is completed 154 * @param type: connection type 155 * @param cid: connection id that ramrod was sent with 156 */ 157 void lm_sq_complete(struct _lm_device_t *pdev, u8_t priority, 158 u8_t command, u16_t type, u32_t cid ); 159 160 /** 161 * @description 162 * do any deffered posting pending on the sq, will take the list spinlock 163 * will not block. Check sq state, if its pending (it means no hw...) call flush 164 * at the end, which will take care of completing these completions internally. 165 * @param pdev 166 * 167 * @return lm_status_t SUCCESS: is no pending requests were sent. PENDING if a 168 * if pending request was sent. 169 */ 170 lm_status_t lm_sq_post_pending(struct _lm_device_t *pdev); 171 172 /* 173 post a slow-path command 174 takes a spinlock, does not sleep 175 actuall command posting may be delayed 176 */ 177 static __inline lm_status_t lm_command_post( struct _lm_device_t* pdev, 178 u32_t cid, 179 u8_t command, 180 u8_t priority, 181 u16_t type, 182 u64_t data ) 183 { 184 return lm_sq_post(pdev, cid, command, priority, type, data ); 185 } 186 187 188 /* TODO: move functions above to lm_sp.c */ 189 /** 190 * @Description 191 * change state of slowpath queue. 192 * 193 * @param pdev 194 * @param state NORMAL, PENDING, BLOCKED 195 */ 196 void lm_sq_change_state(struct _lm_device_t *pdev, lm_sq_state_t state); 197 198 /** 199 * @Description 200 * This function completes any pending slowpath requests. 201 * It does this as if they were completed via cookie... 202 * It needs to know all the possible cookies and which 203 * completions to give. Any new ramrod should be added to 204 * this function. Also if it should be ignored. 205 * 206 * @param pdev 207 */ 208 void lm_sq_complete_pending_requests(struct _lm_device_t *pdev); 209 210 /** 211 * @Description 212 * This function takes care of registering a DPC for 213 * completing slowpaths internally in the driver (if such 214 * exist) 215 * @param pdev 216 * 217 * @return lm_status_t SUCCESS: if all flushed (i.e. dpc not 218 * scheduled) 219 * PENDING: if dpc is scheduled 220 */ 221 lm_status_t lm_sq_flush(struct _lm_device_t *pdev); 222 223 /** 224 * @Description 225 * Checks if the sq is empty 226 * 227 * @param pdev 228 * 229 * @return u8_t TRUE if empty FALSE o/w 230 */ 231 u8_t lm_sq_is_empty(struct _lm_device_t *pdev); 232 233 234 lm_status_t lm_sq_comp_cb_register(struct _lm_device_t *pdev, u8_t type, lm_sq_comp_cb_t cb); 235 236 lm_status_t lm_sq_comp_cb_deregister(struct _lm_device_t *pdev, u8_t type); 237 238 239 240 #endif //__COMMAND_H__ 241