1 #ifdef VF_INVOLVED
2
3 #include "lm5710.h"
4 #include "bd_chain.h"
5 #include "577xx_int_offsets.h"
6 #include "context.h"
7 #include "command.h"
8
9 extern void lm_int_igu_ack_sb(lm_device_t *pdev, u8_t rss_id, u8_t storm_id, u16_t sb_index, u8_t int_op, u8_t is_update_idx);
10 //#define LM_VF_PM_MESS_STATE_READY_TO_SEND 0
11 //#define LM_VF_PM_MESS_STATE_SENT 1
12
13 /**********************VF_PF FUNCTIONS**************************************/
14 /**
15 * Function send a message over the pf/vf channel, first writes the message low/high addr
16 * and then writes to the "addr-valid" in the trigger-zone... this causes the FW to wake
17 * up and handle the message.
18 *
19 * @param pdev
20 * @param mess
21 *
22 * @return lm_status_t
23 */
24
lm_vf_is_lamac_restricted(struct _lm_device_t * pdev)25 u8_t lm_vf_is_lamac_restricted(struct _lm_device_t *pdev)
26 {
27 return (pdev->vars.is_pf_provides_mac && (pdev->vars.is_pf_restricts_lamac || pdev->vars.is_pf_rejected_lamac));
28 }
29
lm_vf_check_mac_restriction(struct _lm_device_t * pdev,struct pfvf_acquire_resp_tlv * pf_resp)30 static u8_t lm_vf_check_mac_restriction(struct _lm_device_t *pdev, struct pfvf_acquire_resp_tlv *pf_resp)
31 {
32 return (!(pf_resp->pfdev_info.pf_cap | PFVF_CAP_ALLOW_MAC));
33 }
34
lm_pf_get_queues_number(struct _lm_device_t * pdev,lm_vf_info_t * vf_info,u8_t * num_rxqs,u8_t * num_txqs)35 static lm_status_t lm_pf_get_queues_number(struct _lm_device_t *pdev, lm_vf_info_t *vf_info, u8_t *num_rxqs, u8_t * num_txqs)
36 {
37 return mm_pf_get_queues_number(pdev, vf_info, num_rxqs, num_txqs);
38 }
39
lm_pf_get_filters_number(struct _lm_device_t * pdev,lm_vf_info_t * vf_info,u8_t * num_mac_filters,u8_t * num_vlan_filters,u8_t * num_mc_filters)40 static lm_status_t lm_pf_get_filters_number(struct _lm_device_t *pdev, lm_vf_info_t *vf_info,
41 u8_t *num_mac_filters,
42 u8_t *num_vlan_filters,
43 u8_t *num_mc_filters)
44 {
45 return mm_pf_get_filters_number(pdev, vf_info, num_mac_filters, num_vlan_filters, num_mc_filters);
46 }
47
lm_pf_get_macs(struct _lm_device_t * pdev,lm_vf_info_t * vf_info,u8_t * permanent_mac_addr,u8_t * current_mac_addr)48 static lm_status_t lm_pf_get_macs(struct _lm_device_t *pdev, lm_vf_info_t *vf_info, u8_t *permanent_mac_addr, u8_t *current_mac_addr)
49 {
50 return mm_pf_get_macs(pdev, vf_info, permanent_mac_addr, current_mac_addr);
51 }
52
lm_pf_vf_check_compatibility(struct _lm_device_t * pdev,lm_vf_info_t * vf_info,struct vf_pf_msg_acquire * request)53 static u8 lm_pf_vf_check_compatibility(struct _lm_device_t *pdev,
54 lm_vf_info_t *vf_info,
55 struct vf_pf_msg_acquire *request)
56 {
57 u8 status = SW_PFVF_STATUS_SUCCESS;
58 if( 0 == request->vfdev_info.vf_fw_hsi_version )
59 {
60 // here we handle cases where HSI version of PF is not compatible with HSI version of VF
61 // Until this code section was added, VF always returned 0 so we fail request for old VF's
62 // Currenly (22/9/2011) we consider all VF that return ANY value (not 0) as valid
63 // once HSI will change, we'll need to enter here logic that will say:
64 // if( ( 0 == vf_fw_hsi_version) || ( some condition with vf_fw_hsi_version )
65 status = SW_PFVF_STATUS_MISMATCH_FW_HSI;
66 }
67 else
68 {
69 #define FW_REV_INTERFACE_SUPPORTED 0x07084b00 // 7.8.75.0
70
71 if (request->vfdev_info.vf_fw_hsi_version >= FW_REV_INTERFACE_SUPPORTED)
72 {
73 vf_info->fp_hsi_ver = request->vfdev_info.fp_hsi_ver;
74 }
75 else
76 {
77 vf_info->fp_hsi_ver = 0;
78 }
79 }
80 if (vf_info->fp_hsi_ver > ETH_FP_HSI_VERSION)
81 {
82 /* VF FP HSI VER is newer than PF... treat as mismatch */
83 status = SW_PFVF_STATUS_MISMATCH_FW_HSI;
84 }
85
86 if (!(request->vfdev_info.vf_aux & SW_VFPF_VFDEF_INFO_AUX_DIRECT_DQ))
87 {
88 status = SW_PFVF_STATUS_MISMATCH_FW_HSI;
89 }
90
91 return status;
92 }
93
lm_pf_vf_fill_acquire_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)94 static lm_status_t lm_pf_vf_fill_acquire_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
95 {
96 lm_status_t lm_status = LM_STATUS_SUCCESS;
97 struct vf_pf_msg_acquire* request = NULL;
98 struct pf_vf_msg_acquire_resp* response = NULL;
99 u8_t i = 0;
100 u8_t num_mac_filters = 0;
101 u8_t num_vlan_filters = 0;
102 u8_t num_mc_filters = 0;
103 u8_t status;
104
105 DbgBreakIf(!(pdev && vf_info && vf_info->pf_vf_response.request_virt_addr && vf_info->pf_vf_response.response_virt_addr));
106
107 request = vf_info->pf_vf_response.request_virt_addr;
108 response = vf_info->pf_vf_response.response_virt_addr;
109
110 status = lm_pf_vf_check_compatibility(pdev, vf_info, request);
111 if (status != SW_PFVF_STATUS_SUCCESS)
112 {
113 response->hdr.status = status;
114 return lm_status;
115 }
116
117 response->pfdev_info.chip_num = pdev->hw_info.chip_id;//CHIP_NUM(pdev);
118 response->pfdev_info.pf_cap = PFVF_CAP_DHC | PFVF_CAP_TPA;
119 if (pdev->params.debug_sriov_vfs)
120 {
121 response->pfdev_info.pf_cap |= PFVF_DEBUG;
122 }
123 response->pfdev_info.db_size = LM_VF_DQ_CID_SIZE;
124 response->pfdev_info.indices_per_sb = HC_SB_MAX_INDICES_E2;
125 vf_info->num_vf_chains_requested = request->resc_request.num_sbs;
126 vf_info->num_sbs = response->resc.num_sbs = min (vf_info->num_allocated_chains, request->resc_request.num_sbs);
127 response->resc.igu_cnt = vf_info->num_sbs;
128
129 for (i = 0; i < response->resc.num_sbs; i++)
130 {
131 response->resc.hw_sbs[i].hw_sb_id = LM_VF_IGU_SB_ID(vf_info, i);
132 response->resc.hw_sbs[i].sb_qid = LM_FW_VF_DHC_QZONE_ID(vf_info, i);
133 response->resc.hw_qid[i] = LM_FW_VF_QZONE_ID(vf_info, i);
134 }
135
136 if (response->resc.num_sbs < vf_info->num_allocated_chains)
137 {
138 for (i = response->resc.num_sbs; i < vf_info->num_allocated_chains; i++)
139 {
140 lm_pf_release_vf_igu_block(pdev, vf_info->vf_chains[i].igu_sb_id);
141 lm_pf_release_separate_vf_chain_resources(pdev, vf_info->relative_vf_id, i);
142 }
143 #ifdef _VBD_
144 //Generate message
145 #endif
146 vf_info->num_allocated_chains = response->resc.num_sbs;
147 }
148
149 vf_info->num_rxqs = response->resc.num_rxqs = min(vf_info->num_sbs, request->resc_request.num_rxqs);
150 vf_info->num_txqs = response->resc.num_txqs = min(vf_info->num_sbs, request->resc_request.num_txqs);
151 vf_info->num_rxqs = response->resc.num_rxqs = min(vf_info->num_rxqs, response->resc.num_sbs);
152 vf_info->num_txqs = response->resc.num_txqs = min(vf_info->num_txqs, response->resc.num_sbs);
153
154 lm_pf_get_filters_number(pdev,vf_info,
155 &num_mac_filters,
156 &num_vlan_filters,
157 &num_mc_filters);
158
159 vf_info->num_mac_filters = response->resc.num_mac_filters = min(num_mac_filters, request->resc_request.num_mac_filters);
160 vf_info->num_vlan_filters = response->resc.num_vlan_filters = min(num_vlan_filters, request->resc_request.num_vlan_filters);
161 vf_info->num_mc_filters = response->resc.num_mc_filters = min(num_mc_filters, request->resc_request.num_mc_filters);
162
163 lm_pf_get_macs(pdev,vf_info, response->resc.permanent_mac_addr, response->resc.current_mac_addr);
164 //#ifdef UPDATED_MAC
165 if (pdev->params.sriov_inc_mac)
166 {
167 u8_t mac_addition = (u8_t)pdev->params.sriov_inc_mac;
168 response->resc.current_mac_addr[5] += mac_addition;
169 }
170 //#endif
171 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
172 vf_info->vf_si_state = PF_SI_ACQUIRED;
173 return lm_status;
174 }
175
lm_pf_vf_fill_init_vf_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)176 static lm_status_t lm_pf_vf_fill_init_vf_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
177 {
178 lm_status_t lm_status = LM_STATUS_SUCCESS;
179 struct vf_pf_msg_init_vf * request = NULL;
180 struct pf_vf_msg_resp * response = NULL;
181 u8_t sb_idx = 0;
182 u8_t q_idx = 0;
183 u8_t function_fw_id;
184 u32_t i;
185
186 DbgBreakIf(!(pdev && vf_info && vf_info->pf_vf_response.request_virt_addr && vf_info->pf_vf_response.response_virt_addr));
187 // DbgBreak();
188 request = vf_info->pf_vf_response.request_virt_addr;
189 response = vf_info->pf_vf_response.response_virt_addr;
190
191 //lm_status = lm_pf_enable_vf(pdev, vf_info->abs_vf_id);
192
193 MM_ACQUIRE_VFS_STATS_LOCK(pdev);
194 DbgBreakIf(vf_info->vf_stats.vf_stats_state != VF_STATS_NONE);
195 vf_info->vf_stats.vf_fw_stats_phys_data.as_u64 = request->stats_addr;
196 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY;
197 vf_info->vf_stats.stop_collect_stats = TRUE;
198 vf_info->vf_stats.vf_stats_flag = 0;
199 vf_info->vf_stats.vf_stats_cnt = 0;
200 vf_info->vf_stats.vf_exracted_stats_cnt = 0;
201 MM_RELEASE_VFS_STATS_LOCK(pdev);
202
203 for (sb_idx = 0; sb_idx < vf_info->num_sbs; sb_idx++) {
204 lm_pf_init_vf_non_def_sb(pdev, vf_info, sb_idx, request->sb_addr[sb_idx]);
205 }
206
207 DbgBreakIf((XSTORM_SPQ_DATA_SIZE % 4) != 0);
208 for (i = 0; i < XSTORM_SPQ_DATA_SIZE/sizeof(u32_t); i++) {
209 REG_WR(PFDEV(pdev),XSEM_REG_FAST_MEMORY + XSTORM_VF_SPQ_DATA_OFFSET(vf_info->abs_vf_id) + i*sizeof(u32_t),0);
210 }
211
212 REG_WR(PFDEV(pdev),XSEM_REG_FAST_MEMORY + (XSTORM_VF_SPQ_PAGE_BASE_OFFSET(vf_info->abs_vf_id)),0);
213 REG_WR(PFDEV(pdev),XSEM_REG_FAST_MEMORY + (XSTORM_VF_SPQ_PAGE_BASE_OFFSET(vf_info->abs_vf_id)) + 4,0);
214 REG_WR(PFDEV(pdev),XSEM_REG_FAST_MEMORY + (XSTORM_VF_SPQ_PROD_OFFSET(vf_info->abs_vf_id)),0);
215
216 for (q_idx = 0; q_idx < vf_info->num_rxqs; q_idx++) {
217 u32_t reg = PXP_REG_HST_ZONE_PERMISSION_TABLE + LM_FW_VF_QZONE_ID(vf_info,q_idx) * 4;
218 u32_t val = vf_info->abs_vf_id | (1 << 6);
219 REG_WR(PFDEV(pdev), reg, val);
220
221 }
222 /*lm_status = lm_set_rx_mask(pdev, LM_CLI_IDX_NDIS, LM_RX_MASK_ACCEPT_NONE);
223 if(LM_STATUS_SUCCESS != lm_status)
224 {
225 DbgMessage(pdev, FATAL, "lm_set_rx_mask(LM_RX_MASK_ACCEPT_NONE) returns %d\n",lm_status);
226 return lm_status;
227 }*/
228 /*
229 Enable the function in STORMs
230 */
231 function_fw_id = 8 + vf_info->abs_vf_id;
232
233 LM_INTMEM_WRITE8(PFDEV(pdev), XSTORM_VF_TO_PF_OFFSET(function_fw_id), FUNC_ID(pdev), BAR_XSTRORM_INTMEM);
234 LM_INTMEM_WRITE8(PFDEV(pdev), CSTORM_VF_TO_PF_OFFSET(function_fw_id), FUNC_ID(pdev), BAR_CSTRORM_INTMEM);
235 LM_INTMEM_WRITE8(PFDEV(pdev), TSTORM_VF_TO_PF_OFFSET(function_fw_id), FUNC_ID(pdev), BAR_TSTRORM_INTMEM);
236 LM_INTMEM_WRITE8(PFDEV(pdev), USTORM_VF_TO_PF_OFFSET(function_fw_id), FUNC_ID(pdev), BAR_USTRORM_INTMEM);
237
238 LM_INTMEM_WRITE8(PFDEV(pdev), XSTORM_FUNC_EN_OFFSET(function_fw_id), 1, BAR_XSTRORM_INTMEM);
239 LM_INTMEM_WRITE8(PFDEV(pdev), CSTORM_FUNC_EN_OFFSET(function_fw_id), 1, BAR_CSTRORM_INTMEM);
240 LM_INTMEM_WRITE8(PFDEV(pdev), TSTORM_FUNC_EN_OFFSET(function_fw_id), 1, BAR_TSTRORM_INTMEM);
241 LM_INTMEM_WRITE8(PFDEV(pdev), USTORM_FUNC_EN_OFFSET(function_fw_id), 1, BAR_USTRORM_INTMEM);
242
243 lm_status = lm_pf_enable_vf_igu_int(pdev, vf_info->abs_vf_id);
244
245 if (lm_status == LM_STATUS_SUCCESS) {
246 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
247 vf_info->vf_si_state = PF_SI_VF_INITIALIZED;
248 } else {
249 response->hdr.status = SW_PFVF_STATUS_FAILURE;
250 DbgBreak();
251 }
252 return lm_status;
253 }
254
255
lm_pf_vf_fill_setup_q_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)256 static lm_status_t lm_pf_vf_fill_setup_q_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
257 {
258 lm_status_t lm_status = LM_STATUS_SUCCESS;
259 struct vf_pf_msg_setup_q * request = NULL;
260 struct pf_vf_msg_resp * response = NULL;
261 struct sw_vf_pf_rxq_params * rxq_params = NULL;
262 struct sw_vf_pf_txq_params * txq_params = NULL;
263 // lm_rcq_chain_t * rcq_chain = NULL;
264 u8_t cmd_id = 0;
265 u8_t type = 0;
266 u8_t q_id = 0;
267 u8_t valid = 0;
268 u32_t vf_cid_of_pf = 0;
269
270 DbgBreakIf(!(pdev && vf_info && vf_info->pf_vf_response.request_virt_addr && vf_info->pf_vf_response.response_virt_addr));
271
272 request = vf_info->pf_vf_response.request_virt_addr;
273 response = vf_info->pf_vf_response.response_virt_addr;
274 q_id = request->vf_qid;
275 valid = request->param_valid;
276
277
278 if (request->param_valid & VFPF_RXQ_VALID) {
279 u32_t mem_size = sizeof(struct tpa_update_ramrod_data);
280 rxq_params = &request->rxq;
281 vf_info->vf_chains[q_id].mtu = rxq_params->mtu;
282 if (rxq_params->flags & SW_VFPF_QUEUE_FLG_TPA) {
283 DbgBreakIf(rxq_params->sge_addr == 0);
284 vf_info->vf_chains[q_id].sge_addr = rxq_params->sge_addr;
285 vf_info->vf_chains[q_id].tpa_ramrod_data_virt = mm_alloc_phys_mem(pdev, mem_size, &vf_info->vf_chains[q_id].tpa_ramrod_data_phys, 0, LM_RESOURCE_NDIS);
286
287 if(CHK_NULL(vf_info->vf_chains[q_id].tpa_ramrod_data_virt))
288 {
289 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
290 response->hdr.status = SW_PFVF_STATUS_FAILURE;
291 return LM_STATUS_RESOURCE ;
292 }
293 mm_mem_zero((void *)vf_info->vf_chains[q_id].tpa_ramrod_data_virt, mem_size);
294 }
295 }
296 if (request->param_valid & VFPF_TXQ_VALID) {
297 txq_params = &request->txq;
298 }
299
300 lm_status = lm_pf_init_vf_client_init_data(pdev, vf_info, q_id, rxq_params, txq_params);
301 if (lm_status == LM_STATUS_SUCCESS) {
302 vf_cid_of_pf = LM_VF_Q_ID_TO_PF_CID(pdev, vf_info, q_id);
303 lm_init_connection_context(pdev, vf_cid_of_pf, 0);
304 cmd_id = RAMROD_CMD_ID_ETH_CLIENT_SETUP;
305 type = (ETH_CONNECTION_TYPE | ((8 + vf_info->abs_vf_id) << SPE_HDR_T_FUNCTION_ID_SHIFT));
306 lm_set_con_state(pdev, vf_cid_of_pf, LM_CON_STATE_OPEN_SENT);
307
308 lm_sq_post(pdev,
309 vf_cid_of_pf,
310 cmd_id,
311 CMD_PRIORITY_MEDIUM,
312 type,
313 pdev->client_info[LM_SW_VF_CLI_ID(vf_info,q_id)].client_init_data_phys.as_u64);
314
315 lm_status = lm_eth_wait_state_change(pdev, LM_CON_STATE_OPEN, vf_cid_of_pf);
316
317 }
318
319 if (lm_status == LM_STATUS_SUCCESS) {
320 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
321 mm_atomic_inc(&vf_info->vf_si_num_of_active_q);
322 if (q_id == 0) {
323 MM_ACQUIRE_VFS_STATS_LOCK(pdev);
324 DbgBreakIf(vf_info->vf_stats.vf_stats_state != VF_STATS_REQ_READY)
325 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_SUBMITTED;
326 vf_info->vf_stats.stop_collect_stats = FALSE;
327 if (!vf_info->vf_stats.do_not_collect_pf_stats) {
328 vf_info->vf_stats.vf_stats_flag = VF_STATS_COLLECT_FW_STATS_FOR_PF;
329 }
330 if (vf_info->vf_stats.vf_fw_stats_phys_data.as_u64) {
331 vf_info->vf_stats.vf_stats_flag |= VF_STATS_COLLECT_FW_STATS_FOR_VF;
332 }
333 MM_RELEASE_VFS_STATS_LOCK(pdev);
334 }
335 } else if (lm_status == LM_STATUS_PENDING) {
336 response->hdr.status = SW_PFVF_STATUS_WAITING;
337 } else {
338 response->hdr.status = SW_PFVF_STATUS_FAILURE;
339 }
340
341 return lm_status;
342 }
343
344 // ASSUMPTION: CALLED IN PASSIVE LEVEL!!!
345
lm_pf_vf_fill_set_q_filters_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)346 static lm_status_t lm_pf_vf_fill_set_q_filters_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
347 {
348 lm_status_t lm_status = LM_STATUS_SUCCESS;
349 struct vf_pf_msg_set_q_filters * request = NULL;
350 struct pf_vf_msg_resp * response = NULL;
351 lm_rx_mask_t rx_mask = 0;
352
353 request = vf_info->pf_vf_response.request_virt_addr;
354 response = vf_info->pf_vf_response.response_virt_addr;
355
356 // DbgBreak();
357 if (request->flags & VFPF_SET_Q_FILTERS_RX_MASK_CHANGED) {
358 if (VFPF_RX_MASK_ACCEPT_NONE == request->rx_mask) {
359 lm_status = lm_set_rx_mask(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid), LM_RX_MASK_ACCEPT_NONE, NULL);
360 if (lm_status == LM_STATUS_PENDING)
361 {
362 lm_status = lm_wait_set_rx_mask_done(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid));
363 }
364 } else {
365 if (GET_FLAGS(request->rx_mask,VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST | VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST |
366 VFPF_RX_MASK_ACCEPT_ALL_MULTICAST | VFPF_RX_MASK_ACCEPT_ALL_UNICAST | VFPF_RX_MASK_ACCEPT_BROADCAST) ==
367 (VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST | VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST |
368 VFPF_RX_MASK_ACCEPT_ALL_MULTICAST | VFPF_RX_MASK_ACCEPT_ALL_UNICAST | VFPF_RX_MASK_ACCEPT_BROADCAST)) {
369 if (!vf_info->is_promiscuous_mode_restricted)
370 {
371 rx_mask = LM_RX_MASK_PROMISCUOUS_MODE;
372 lm_status = lm_set_rx_mask(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid), LM_RX_MASK_PROMISCUOUS_MODE, NULL);
373 if (lm_status == LM_STATUS_PENDING)
374 {
375 lm_status = lm_wait_set_rx_mask_done(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid));
376 }
377 }
378 else
379 {
380 request->rx_mask &= ~(VFPF_RX_MASK_ACCEPT_ALL_UNICAST | VFPF_RX_MASK_ACCEPT_ALL_MULTICAST);
381 }
382 }
383
384 if (!rx_mask)
385 {
386 if (GET_FLAGS(request->rx_mask,VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST)) {
387 rx_mask |= LM_RX_MASK_ACCEPT_UNICAST;
388 }
389 if (GET_FLAGS(request->rx_mask,VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST)) {
390 rx_mask |= LM_RX_MASK_ACCEPT_MULTICAST;
391 }
392 if (GET_FLAGS(request->rx_mask,VFPF_RX_MASK_ACCEPT_ALL_MULTICAST)) {
393 rx_mask |= LM_RX_MASK_ACCEPT_ALL_MULTICAST;
394 }
395 if (GET_FLAGS(request->rx_mask, VFPF_RX_MASK_ACCEPT_BROADCAST)) {
396 rx_mask |= LM_RX_MASK_ACCEPT_BROADCAST;
397 }
398 lm_status = lm_set_rx_mask(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid), rx_mask, NULL);
399 if (lm_status == LM_STATUS_PENDING)
400 {
401 lm_status = lm_wait_set_rx_mask_done(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid));
402 }
403 }
404 }
405 }
406 if (request->flags & VFPF_SET_Q_FILTERS_MAC_VLAN_CHANGED) {
407 u8_t mac_idx;
408 u8_t set_mac;
409 for (mac_idx = 0; mac_idx < request->n_mac_vlan_filters; mac_idx++) {
410 if (request->filters[mac_idx].flags & VFPF_Q_FILTER_DEST_MAC_PRESENT) {
411 if (request->filters[mac_idx].flags & VFPF_Q_FILTER_SET_MAC) {
412 set_mac = TRUE;
413 } else {
414 set_mac = FALSE;
415 }
416 lm_status = lm_set_mac_addr(pdev, request->filters[mac_idx].dest_mac,
417 LM_SET_CAM_NO_VLAN_FILTER, LM_SW_VF_CLI_ID(vf_info,request->vf_qid), NULL, set_mac, 0);
418 if (lm_status == LM_STATUS_PENDING) {
419 lm_status = lm_wait_set_mac_done(pdev, LM_SW_VF_CLI_ID(vf_info,request->vf_qid));
420 }
421 } else {
422 //
423 }
424 }
425 }
426 if (lm_status == LM_STATUS_SUCCESS) {
427 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
428 } else if (lm_status == LM_STATUS_PENDING) {
429 DbgBreak();
430 response->hdr.status = SW_PFVF_STATUS_WAITING;
431 } else {
432 response->hdr.status = SW_PFVF_STATUS_FAILURE;
433 }
434 return lm_status;
435 }
436
lm_pf_vf_fill_teardown_q_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)437 static lm_status_t lm_pf_vf_fill_teardown_q_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
438 {
439 lm_status_t lm_status = LM_STATUS_FAILURE;
440 struct vf_pf_msg_q_op * request = NULL;
441 struct pf_vf_msg_resp * response = NULL;
442 u8_t q_id = 0;
443 u32_t cid;
444
445 //DbgBreak();
446 request = vf_info->pf_vf_response.request_virt_addr;
447 response = vf_info->pf_vf_response.response_virt_addr;
448 q_id = request->vf_qid;
449
450 if (q_id == 0) {
451 MM_ACQUIRE_VFS_STATS_LOCK(pdev);
452 if (vf_info->vf_stats.vf_stats_state != VF_STATS_REQ_IN_PROCESSING) {
453 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY;
454 }
455 vf_info->vf_stats.stop_collect_stats = TRUE;
456 vf_info->vf_stats.vf_stats_flag = 0;
457 MM_RELEASE_VFS_STATS_LOCK(pdev);
458 DbgMessage(pdev, WARN, "lm_pf_vf_fill_teardown_q_response for VF[%d]: stats_cnt: %d\n",vf_info->relative_vf_id,vf_info->vf_stats.vf_stats_cnt);
459
460 lm_status = lm_pf_vf_wait_for_stats_ready(pdev, vf_info);
461 DbgMessage(pdev, WARN, "lm_pf_vf_fill_teardown_q_response for VF[%d]: stats_cnt: %d\n",vf_info->relative_vf_id,vf_info->vf_stats.vf_stats_cnt);
462 if (lm_status != LM_STATUS_SUCCESS) {
463 if (lm_status != LM_STATUS_ABORTED)
464 {
465 DbgBreak();
466 }
467 response->hdr.status = SW_PFVF_STATUS_FAILURE;
468 return lm_status;
469 }
470 }
471
472 cid = LM_VF_Q_ID_TO_PF_CID(pdev, vf_info, q_id);
473
474
475 if (vf_info->was_malicious || vf_info->was_flred)
476 {
477 lm_status = LM_STATUS_SUCCESS;
478 lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
479 }
480 else
481 {
482 lm_status = lm_close_eth_con(pdev, cid, TRUE);
483 }
484
485 if (lm_status == LM_STATUS_SUCCESS) {
486 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
487 mm_atomic_dec(&vf_info->vf_si_num_of_active_q);
488 } else if (lm_status == LM_STATUS_PENDING) {
489 DbgBreak();
490 response->hdr.status = SW_PFVF_STATUS_WAITING;
491 } else {
492 response->hdr.status = SW_PFVF_STATUS_FAILURE;
493 }
494 return lm_status;
495 }
496
lm_pf_vf_fill_close_vf_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)497 static lm_status_t lm_pf_vf_fill_close_vf_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
498 {
499 lm_status_t lm_status = LM_STATUS_SUCCESS;
500 u8_t function_fw_id;
501 u8_t sb_idx;
502 u8_t q_idx;
503 struct vf_pf_msg_close_vf * request = NULL;
504 struct pf_vf_msg_resp * response = NULL;
505 u32_t cid;
506
507 //DbgBreak();
508 request = vf_info->pf_vf_response.request_virt_addr;
509 response = vf_info->pf_vf_response.response_virt_addr;
510
511 MM_ACQUIRE_VFS_STATS_LOCK(pdev);
512 if (vf_info->vf_stats.vf_stats_state != VF_STATS_REQ_IN_PROCESSING) {
513 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY;
514 }
515 vf_info->vf_stats.stop_collect_stats = TRUE;
516 vf_info->vf_stats.vf_stats_flag = 0;
517 MM_RELEASE_VFS_STATS_LOCK(pdev);
518
519 lm_status = lm_pf_vf_wait_for_stats_ready(pdev, vf_info);
520 if (lm_status != LM_STATUS_SUCCESS) {
521 DbgBreak();
522 } else {
523 vf_info->vf_stats.vf_stats_state = VF_STATS_NONE;
524 }
525
526 for (q_idx = 0; q_idx < vf_info->vf_si_num_of_active_q; q_idx++) {
527 cid = LM_VF_Q_ID_TO_PF_CID(pdev, vf_info, q_idx);
528 if (vf_info->was_malicious || vf_info->was_flred)
529 {
530 lm_status = LM_STATUS_SUCCESS;
531 lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
532 }
533 else
534 {
535 lm_status = lm_close_eth_con(pdev, cid, TRUE);
536 }
537 }
538 vf_info->vf_si_num_of_active_q = 0;
539
540 lm_pf_disable_vf_igu_int(pdev, vf_info->abs_vf_id);
541 /*
542 Disable the function in STORMs
543 */
544 function_fw_id = 8 + vf_info->abs_vf_id;
545
546 LM_INTMEM_WRITE8(PFDEV(pdev), XSTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_XSTRORM_INTMEM);
547 LM_INTMEM_WRITE8(PFDEV(pdev), CSTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_CSTRORM_INTMEM);
548 LM_INTMEM_WRITE8(PFDEV(pdev), TSTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_TSTRORM_INTMEM);
549 LM_INTMEM_WRITE8(PFDEV(pdev), USTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_USTRORM_INTMEM);
550
551 for (sb_idx = 0; sb_idx < vf_info->num_sbs; sb_idx++) {
552 lm_clear_non_def_status_block(pdev, LM_FW_VF_SB_ID(vf_info, sb_idx));
553 }
554
555 for (q_idx = 0; q_idx < vf_info->num_rxqs; q_idx++) {
556 u32_t reg = PXP_REG_HST_ZONE_PERMISSION_TABLE + LM_FW_VF_QZONE_ID(vf_info,q_idx) * 4;
557 u32_t val = 0;
558 REG_WR(PFDEV(pdev), reg, val);
559 }
560
561 vf_info->vf_si_state = PF_SI_ACQUIRED;
562 if (lm_status == LM_STATUS_SUCCESS) {
563 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
564 } else if (lm_status == LM_STATUS_PENDING) {
565 DbgBreak();
566 response->hdr.status = SW_PFVF_STATUS_WAITING;
567 } else {
568 response->hdr.status = SW_PFVF_STATUS_FAILURE;
569 }
570 return lm_status;
571 }
572
lm_pf_vf_fill_release_vf_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)573 static lm_status_t lm_pf_vf_fill_release_vf_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
574 {
575 struct pf_vf_msg_resp * response = NULL;
576 lm_status_t lm_status = LM_STATUS_SUCCESS;
577
578 response = vf_info->pf_vf_response.response_virt_addr;
579 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
580 vf_info->vf_si_state = PF_SI_WAIT_FOR_ACQUIRING_REQUEST;
581
582 return lm_status;
583 }
584
585
lm_pf_vf_fill_update_rss_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)586 static lm_status_t lm_pf_vf_fill_update_rss_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
587 {
588 struct pf_vf_msg_resp * response = NULL;
589 struct vf_pf_msg_rss * request = NULL;
590 struct ecore_config_rss_params * rss_params = NULL;
591 lm_status_t lm_status = LM_STATUS_SUCCESS;
592 u8_t ind_table_size;
593 u8_t ind_table_idx;
594
595 // DbgBreak();
596 request = vf_info->pf_vf_response.request_virt_addr;
597 response = vf_info->pf_vf_response.response_virt_addr;
598 rss_params = &vf_info->vf_slowpath_info.rss_params;
599 mm_mem_zero(rss_params, sizeof(struct ecore_config_rss_params));
600 ECORE_SET_BIT(RAMROD_COMP_WAIT, &rss_params->ramrod_flags);
601 rss_params->rss_flags = request->rss_flags;
602 rss_params->rss_result_mask = request->rss_result_mask;
603 mm_memcpy(rss_params->rss_key, request->rss_key, sizeof(u32_t) * 10);
604
605 ind_table_size = request->rss_result_mask + 1;
606 for (ind_table_idx = 0; ind_table_idx < ind_table_size; ind_table_idx++) {
607 rss_params->ind_table[ind_table_idx] = LM_FW_VF_CLI_ID(vf_info, request->ind_table[ind_table_idx]);
608 }
609 rss_params->rss_obj = &vf_info->vf_slowpath_info.rss_conf_obj;
610 lm_status = ecore_config_rss(pdev, rss_params);
611 if (lm_status == LM_STATUS_SUCCESS) {
612 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
613 } else {
614 response->hdr.status = SW_PFVF_STATUS_FAILURE;
615 }
616
617 return lm_status;
618 }
619
lm_pf_vf_fill_update_rsc_response(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)620 lm_status_t lm_pf_vf_fill_update_rsc_response(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
621 {
622 struct pf_vf_msg_resp * response = NULL;
623 struct vf_pf_msg_rsc * request = NULL;
624 lm_status_t lm_status = LM_STATUS_SUCCESS;
625 u32_t q_idx;
626
627 //DbgBreak();
628 request = vf_info->pf_vf_response.request_virt_addr;
629 response = vf_info->pf_vf_response.response_virt_addr;
630
631 vf_info->vf_tpa_info.ramrod_recv_cnt = vf_info->vf_si_num_of_active_q;
632 for (q_idx = 0; q_idx < vf_info->vf_si_num_of_active_q; q_idx++) {
633 lm_status = lm_pf_tpa_send_vf_ramrod(pdev, vf_info, q_idx, (u8_t)request->rsc_ipv4_state, (u8_t)request->rsc_ipv6_state);
634
635 if(LM_STATUS_SUCCESS != lm_status)
636 {
637 DbgBreakMsg(" Ramrod send failed ");
638 break;
639 }
640 }
641 lm_status = lm_wait_state_change(pdev, &vf_info->vf_tpa_info.ramrod_recv_cnt, 0);
642 if (lm_status == LM_STATUS_SUCCESS) {
643 response->hdr.status = SW_PFVF_STATUS_SUCCESS;
644 } else {
645 response->hdr.status = SW_PFVF_STATUS_FAILURE;
646 }
647 return lm_status;
648 }
649
lm_pf_process_standard_request(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)650 lm_status_t lm_pf_process_standard_request(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
651 {
652 lm_status_t lm_status = LM_STATUS_SUCCESS;
653 struct vf_pf_msg_hdr * requst_hdr = vf_info->pf_vf_response.request_virt_addr;
654 struct pf_vf_msg_hdr * resp_hdr = vf_info->pf_vf_response.response_virt_addr;
655
656 DbgBreakIf(!(pdev && IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev) && vf_info && (vf_info->pf_vf_response.req_resp_state == VF_PF_REQUEST_IN_PROCESSING)));
657 DbgMessage(pdev, WARNvf, "lm_pf_process_standard_request %d for VF[%d]\n",requst_hdr->opcode,vf_info->relative_vf_id);
658
659 resp_hdr->opcode = requst_hdr->opcode;
660 resp_hdr->status = SW_PFVF_STATUS_WAITING;
661 vf_info->pf_vf_response.response_size = sizeof(struct pf_vf_msg_hdr);
662 vf_info->pf_vf_response.response_offset = 0;
663
664 // Check PF/VF interface
665 if ( PFVF_IF_VERSION != requst_hdr->if_ver )
666 {
667 resp_hdr->status = SW_PFVF_STATUS_MISMATCH_PF_VF_VERSION;
668 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
669 }
670 else
671 {
672 switch (requst_hdr->opcode)
673 {
674 case PFVF_OP_ACQUIRE:
675 resp_hdr->opcode_ver = PFVF_ACQUIRE_VER;
676 if (vf_info->vf_si_state != PF_SI_WAIT_FOR_ACQUIRING_REQUEST)
677 {
678 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
679 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
680 break;
681 }
682 if (PFVF_ACQUIRE_VER != requst_hdr->opcode_ver)
683 {
684 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
685 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
686 break;
687 }
688 lm_status = lm_pf_vf_fill_acquire_response(pdev,vf_info);
689 if (lm_status == LM_STATUS_SUCCESS)
690 {
691 vf_info->pf_vf_response.response_size = sizeof(struct pf_vf_msg_acquire_resp);
692 }
693 break;
694 case PFVF_OP_INIT_VF:
695 resp_hdr->opcode_ver = PFVF_INIT_VF_VER;
696 if (vf_info->vf_si_state != PF_SI_ACQUIRED)
697 {
698 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
699 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
700 break;
701 }
702 if (PFVF_INIT_VF_VER != requst_hdr->opcode_ver) {
703 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
704 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
705 break;
706 }
707 lm_status = lm_pf_vf_fill_init_vf_response(pdev,vf_info);
708 break;
709 case PFVF_OP_SETUP_Q:
710 resp_hdr->opcode_ver = PFVF_SETUP_Q_VER;
711 if (vf_info->vf_si_state != PF_SI_VF_INITIALIZED) {
712 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
713 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
714 break;
715 }
716 if (PFVF_SETUP_Q_VER != requst_hdr->opcode_ver) {
717 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
718 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
719 break;
720 }
721 lm_status = lm_pf_vf_fill_setup_q_response(pdev,vf_info);
722 break;
723 case PFVF_OP_SET_Q_FILTERS:
724 resp_hdr->opcode_ver = PFVF_SET_Q_FILTERS_VER;
725 if (PFVF_SET_Q_FILTERS_VER != requst_hdr->opcode_ver) {
726 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
727 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
728 break;
729 }
730 lm_status = lm_pf_vf_fill_set_q_filters_response(pdev,vf_info);
731 break;
732 case PFVF_OP_ACTIVATE_Q:
733 resp_hdr->opcode_ver = PFVF_ACTIVATE_Q_VER;
734 if (PFVF_ACTIVATE_Q_VER != requst_hdr->opcode_ver) {
735 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
736 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
737 break;
738 }
739 break;
740 case PFVF_OP_DEACTIVATE_Q:
741 resp_hdr->opcode_ver = PFVF_DEACTIVATE_Q_VER;
742 if (PFVF_DEACTIVATE_Q_VER != requst_hdr->opcode_ver) {
743 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
744 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
745 break;
746 }
747 break;
748 case PFVF_OP_TEARDOWN_Q:
749 resp_hdr->opcode_ver = PFVF_TEARDOWN_Q_VER;
750 if (vf_info->vf_si_state != PF_SI_VF_INITIALIZED) {
751 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
752 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
753 break;
754 }
755 if (PFVF_TEARDOWN_Q_VER != requst_hdr->opcode_ver) {
756 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
757 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
758 break;
759 }
760 lm_status = lm_pf_vf_fill_teardown_q_response(pdev,vf_info);
761 break;
762 case PFVF_OP_CLOSE_VF:
763 resp_hdr->opcode_ver = PFVF_CLOSE_VF_VER;
764 if (vf_info->vf_si_state != PF_SI_VF_INITIALIZED) {
765 resp_hdr->status = SW_PFVF_STATUS_SUCCESS;
766 DbgMessage(pdev, FATAL, "VF[%d] already closesd!\n",vf_info->relative_vf_id);
767 break;
768 }
769 if (PFVF_CLOSE_VF_VER != requst_hdr->opcode_ver)
770 {
771 resp_hdr->status = SW_PFVF_STATUS_MISMATCH_PF_VF_VERSION;
772 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
773 break;
774 }
775 lm_status = lm_pf_vf_fill_close_vf_response(pdev,vf_info);
776 break;
777 case PFVF_OP_RELEASE_VF:
778 if (vf_info->vf_si_state != PF_SI_ACQUIRED) {
779 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
780 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
781 break;
782 }
783 resp_hdr->opcode_ver = PFVF_RELEASE_VF_VER;
784 if (PFVF_RELEASE_VF_VER != requst_hdr->opcode_ver) {
785 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
786 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
787 break;
788 }
789 lm_status = lm_pf_vf_fill_release_vf_response(pdev,vf_info);
790 break;
791 case PFVF_OP_UPDATE_RSS:
792 resp_hdr->opcode_ver = PFVF_UPDATE_RSS_VER;
793 if (PFVF_UPDATE_RSS_VER != requst_hdr->opcode_ver) {
794 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
795 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
796 break;
797 }
798 lm_status = lm_pf_vf_fill_update_rss_response(pdev,vf_info);
799 break;
800 case PFVF_OP_UPDATE_RSC:
801 resp_hdr->opcode_ver = PFVF_UPDATE_RSC_VER;
802 if (PFVF_UPDATE_RSC_VER != requst_hdr->opcode_ver) {
803 resp_hdr->status = SW_PFVF_STATUS_NOT_SUPPORTED;
804 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
805 break;
806 }
807 lm_status = lm_pf_vf_fill_update_rsc_response(pdev,vf_info);
808 break;
809 default:
810 return LM_STATUS_FAILURE;
811 }
812 }
813 if (lm_status != LM_STATUS_PENDING)
814 {
815 vf_info->pf_vf_response.req_resp_state = VF_PF_RESPONSE_READY;
816 }
817 return lm_status;
818 }
819
lm_pf_notify_standard_request_ready(struct _lm_device_t * pdev,lm_vf_info_t * vf_info,u8_t * set_done)820 lm_status_t lm_pf_notify_standard_request_ready(struct _lm_device_t *pdev, lm_vf_info_t *vf_info, u8_t * set_done)
821 {
822 lm_status_t lm_status = LM_STATUS_SUCCESS;
823 struct vf_pf_msg_hdr * requst_hdr = vf_info->pf_vf_response.request_virt_addr;
824 struct pf_vf_msg_hdr * resp_hdr = vf_info->pf_vf_response.response_virt_addr;
825
826 DbgBreakIf(!(pdev && IS_CHANNEL_VIRT_MODE_MASTER_PFDEV(pdev) && vf_info && (vf_info->pf_vf_response.req_resp_state != VF_PF_REQUEST_IN_PROCESSING)));
827 DbgMessage(pdev, WARNvf, "lm_pf_process_standard_request\n");
828
829
830 switch (requst_hdr->opcode) {
831 case PFVF_OP_ACQUIRE:
832 DbgBreak();
833 break;
834 case PFVF_OP_INIT_VF:
835 DbgBreak();
836 break;
837 case PFVF_OP_SETUP_Q:
838 resp_hdr->opcode_ver = PFVF_SETUP_Q_VER;
839 if (vf_info->vf_si_state != PF_SI_VF_INITIALIZED) {
840 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
841 DbgBreak();
842 break;
843 }
844 break;
845 case PFVF_OP_SET_Q_FILTERS:
846 break;
847 case PFVF_OP_ACTIVATE_Q:
848 break;
849 case PFVF_OP_DEACTIVATE_Q:
850 break;
851 case PFVF_OP_TEARDOWN_Q:
852 break;
853 case PFVF_OP_CLOSE_VF:
854 if (vf_info->vf_si_state != PF_SI_VF_INITIALIZED) {
855 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
856 DbgBreak();
857 break;
858 }
859 break;
860 case PFVF_OP_RELEASE_VF:
861 if (vf_info->vf_si_state != PF_SI_ACQUIRED) {
862 resp_hdr->status = SW_PFVF_STATUS_FAILURE;
863 //return LM_STATUS_FAILURE;
864 DbgBreak();
865 break;
866 }
867 break;
868 default:
869 lm_status = LM_STATUS_FAILURE;
870 DbgBreak();
871 break;
872 }
873
874
875 return lm_status;
876 }
877
lm_vf_pf_send_message_to_hw_channel(struct _lm_device_t * pdev,lm_vf_pf_message_t * mess)878 static lm_status_t lm_vf_pf_send_message_to_hw_channel(struct _lm_device_t * pdev, lm_vf_pf_message_t * mess)
879 {
880 lm_address_t * message_phys_addr;
881
882 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)));
883
884 DbgMessage(pdev, WARNvf, "lm_vf_pf_channel_send\n");
885
886 if (mess != NULL) {
887 message_phys_addr = &mess->message_phys_addr;
888 } else {
889 message_phys_addr = &pdev->vars.vf_pf_mess.message_phys_addr;
890 }
891
892 VF_REG_WR(pdev, (VF_BAR0_CSDM_GLOBAL_OFFSET +
893 OFFSETOF(struct cstorm_vf_zone_data,non_trigger)
894 + OFFSETOF(struct non_trigger_vf_zone,vf_pf_channel)
895 + OFFSETOF(struct vf_pf_channel_zone_data, msg_addr_lo)),
896 message_phys_addr->as_u32.low);
897
898 VF_REG_WR(pdev, (VF_BAR0_CSDM_GLOBAL_OFFSET +
899 OFFSETOF(struct cstorm_vf_zone_data,non_trigger)
900 + OFFSETOF(struct non_trigger_vf_zone,vf_pf_channel)
901 + OFFSETOF(struct vf_pf_channel_zone_data, msg_addr_hi)),
902 message_phys_addr->as_u32.high);
903
904 LM_INTMEM_WRITE8(pdev,(OFFSETOF(struct cstorm_vf_zone_data,trigger)
905 + OFFSETOF(struct trigger_vf_zone,vf_pf_channel)
906 + OFFSETOF(struct vf_pf_channel_zone_trigger, addr_valid)),
907 1,VF_BAR0_CSDM_GLOBAL_OFFSET);
908
909 /* VF_REG_WR(pdev, VF_BAR0_CSDM_GLOBAL_OFFSET +
910 OFFSETOF(struct cstorm_function_zone_data,non_trigger)
911 + OFFSETOF(struct trigger_function_zone,vf_pf_channel)
912 + OFFSETOF(struct vf_pf_channel_zone_trigger, addr_valid),
913 message_phys_addr.as_u32.low);*/
914
915 return LM_STATUS_SUCCESS;
916 }
917
lm_vf_pf_send_request_to_sw_channel(struct _lm_device_t * pdev,lm_vf_pf_message_t * mess)918 lm_status_t lm_vf_pf_send_request_to_sw_channel(struct _lm_device_t * pdev, lm_vf_pf_message_t * mess)
919 {
920 lm_status_t lm_status = LM_STATUS_SUCCESS;
921 struct vf_pf_msg_hdr *hdr = (struct vf_pf_msg_hdr*)pdev->vars.vf_pf_mess.message_virt_addr;
922 void * buffer = mess->message_virt_addr;
923 u32_t length = hdr->resp_msg_offset;
924
925 lm_status = mm_vf_pf_write_block_to_sw_channel(pdev, VF_TO_PF_STANDARD_BLOCK_ID, buffer, length);
926 return lm_status;
927 }
928
lm_vf_pf_recv_response_from_sw_channel(struct _lm_device_t * pdev,lm_vf_pf_message_t * mess)929 lm_status_t lm_vf_pf_recv_response_from_sw_channel(struct _lm_device_t * pdev, lm_vf_pf_message_t * mess)
930 {
931 lm_status_t lm_status = LM_STATUS_SUCCESS;
932 struct vf_pf_msg_hdr *hdr = (struct vf_pf_msg_hdr*)pdev->vars.vf_pf_mess.message_virt_addr;
933 void * buffer = (u8_t*)mess->message_virt_addr + hdr->resp_msg_offset;
934 u32_t length = 0;
935 u32_t received_length;
936 u32_t received_offset = 0;
937
938 //mess->message_size - hdr->resp_msg_offset;
939 if (hdr->opcode == PFVF_OP_ACQUIRE) {
940 received_length = length = sizeof(struct pf_vf_msg_acquire_resp);
941 } else {
942 received_length = length = sizeof(struct pf_vf_msg_resp);
943 }
944 while (length) {
945 received_length = length;
946 lm_status = mm_vf_pf_read_block_from_sw_channel(pdev, VF_TO_PF_STANDARD_BLOCK_ID, (u8_t*)buffer + received_offset, &received_length);
947 if (lm_status != LM_STATUS_SUCCESS) {
948 break;
949 }
950 if (!received_offset) {
951 if (((struct pf_vf_msg_hdr*)buffer)->status != SW_PFVF_STATUS_SUCCESS) {
952 break;
953 }
954 }
955 length -= received_length;
956 received_offset += received_length;
957 }
958
959 return lm_status;
960 }
961
lm_vf_pf_channel_send(struct _lm_device_t * pdev,lm_vf_pf_message_t * mess)962 static lm_status_t lm_vf_pf_channel_send(struct _lm_device_t * pdev, lm_vf_pf_message_t * mess)
963 {
964 lm_status_t lm_status = LM_STATUS_SUCCESS;
965
966 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)));
967
968 DbgMessage(pdev, WARNvf, "lm_vf_pf_channel_send\n");
969
970 if (IS_HW_CHANNEL_VIRT_MODE(pdev)) {
971 lm_vf_pf_send_message_to_hw_channel(pdev, mess);
972 } else if (IS_SW_CHANNEL_VIRT_MODE(pdev)) {
973 lm_status = lm_vf_pf_send_request_to_sw_channel(pdev, mess);
974 } else {
975 DbgBreakMsg("lm_vf_pf_channel_send: UNKNOWN channel type\n");
976 return LM_STATUS_FAILURE;
977 }
978
979
980 if (!mess->do_not_arm_trigger && (lm_status == LM_STATUS_SUCCESS)) {
981 mm_vf_pf_arm_trigger(pdev, mess);
982 }
983
984 return lm_status;
985 }
986
lm_vf_pf_channel_wait_response(struct _lm_device_t * pdev,lm_vf_pf_message_t * mess)987 static lm_status_t lm_vf_pf_channel_wait_response(struct _lm_device_t * pdev, lm_vf_pf_message_t * mess)
988 {
989 u32_t delay_us = 0;
990 u32_t sum_delay_us = 0;
991 u32_t to_cnt = 10000 + 2360; // We'll wait 10,000 times 100us (1 second) + 2360 times 25000us (59sec) = total 60 sec
992 lm_status_t lm_status = LM_STATUS_SUCCESS;
993
994 /* check args */
995 if ERR_IF(!(pdev && IS_CHANNEL_VFDEV(pdev) && mess && pdev->vars.vf_pf_mess.message_virt_addr)) {
996 DbgBreak();
997 return LM_STATUS_INVALID_PARAMETER;
998 }
999
1000 /* wait for message done */
1001 DbgMessage(pdev, WARN, "lm_vf_pf_channel_wait_response\n");
1002 if (mess == NULL) {
1003 mess = &pdev->vars.vf_pf_mess;
1004 }
1005
1006 if ((*mess->done == FALSE) && IS_SW_CHANNEL_VIRT_MODE(pdev) && !lm_reset_is_inprogress(pdev)) {
1007 lm_status = lm_vf_pf_recv_response_from_sw_channel(pdev, mess);
1008 }
1009
1010 while ((lm_status == LM_STATUS_SUCCESS) && (*mess->done == FALSE) && to_cnt--)
1011 {
1012 delay_us = (to_cnt >= 2360) ? 100 : 25000 ;
1013 sum_delay_us += delay_us;
1014 mm_wait(pdev, delay_us);
1015
1016 // in case reset in progress
1017 // we won't get completion so no need to wait
1018 if( lm_reset_is_inprogress(pdev) ) {
1019 break;
1020 } else if (IS_SW_CHANNEL_VIRT_MODE(pdev)) {
1021 lm_status = lm_vf_pf_recv_response_from_sw_channel(pdev,mess);
1022 }
1023 }
1024 if (*mess->done) {
1025 DbgMessage(pdev, WARN, "lm_vf_pf_channel_wait_response: message done(%dus waiting)\n",sum_delay_us);
1026 } else {
1027 switch (lm_status)
1028 {
1029 case LM_STATUS_REQUEST_NOT_ACCEPTED:
1030 break;
1031 case LM_STATUS_SUCCESS:
1032 lm_status = LM_STATUS_TIMEOUT;
1033 default:
1034 if (!lm_reset_is_inprogress(pdev))
1035 {
1036 #if defined(_VBD_)
1037 DbgBreak();
1038 #endif
1039 }
1040 break;
1041 }
1042 DbgMessage(pdev, FATAL, "lm_vf_pf_channel_wait_response returns %d\n", lm_status);
1043 }
1044 return lm_status;
1045 }
1046
lm_vf_pf_channel_release_message(struct _lm_device_t * pdev,lm_vf_pf_message_t * mess)1047 static void lm_vf_pf_channel_release_message(struct _lm_device_t * pdev, lm_vf_pf_message_t * mess)
1048 {
1049 if (mess->cookie) { //TODO don't indicate in case of error processing
1050 DbgMessage(pdev, WARN, "VF_PF channel: assuming REQ_SET_INFORMATION - indicating back to NDIS!\n");
1051 mm_set_done(pdev, LM_SW_LEADING_RSS_CID(pdev), mess->cookie);
1052 mess->cookie = NULL;
1053 }
1054 mm_atomic_dec(&mess->state);
1055 }
1056
lm_vf_pf_channel_get_message_to_send(struct _lm_device_t * pdev,const u32_t opcode)1057 static lm_vf_pf_message_t * lm_vf_pf_channel_get_message_to_send(struct _lm_device_t * pdev, const u32_t opcode)
1058 {
1059 u16_t resp_offset = 0;
1060 struct vf_pf_msg_hdr *sw_hdr;
1061 struct pf_vf_msg_hdr *sw_resp_hdr;
1062 struct vfpf_first_tlv *hw_first_tlv;
1063 struct channel_list_end_tlv *hw_list_end_tlv;
1064 struct pfvf_tlv *hw_resp_hdr;
1065
1066 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)));
1067
1068 #ifndef __LINUX
1069 if (mm_atomic_inc(&pdev->vars.vf_pf_mess.state) != 1) {
1070 DbgMessage(pdev, FATAL, "VF_PF Channel: pdev->vars.vf_pf_mess.state is %d\n",pdev->vars.vf_pf_mess.state);
1071 mm_atomic_dec(&pdev->vars.vf_pf_mess.state);
1072
1073 return NULL;
1074 }
1075 #else
1076 mm_atomic_inc(&pdev->vars.vf_pf_mess.state);
1077 DbgMessage(pdev, FATAL, "VF_PF Channel: pdev->vars.vf_pf_mess.state is %d\n",pdev->vars.vf_pf_mess.state);
1078 #endif
1079 if (pdev->vars.vf_pf_mess.message_virt_addr == NULL) {
1080 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1081 {
1082 pdev->vars.vf_pf_mess.message_size = ((sizeof(union vf_pf_msg) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK)
1083 + ((sizeof(union pf_vf_msg) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK);
1084 }
1085 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1086 {
1087 pdev->vars.vf_pf_mess.message_size = ((sizeof(union vfpf_tlvs) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK)
1088 + ((sizeof(union pfvf_tlvs) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK)
1089 + ((sizeof(union pf_vf_bulletin) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK);
1090 }
1091 else
1092 {
1093 DbgBreakMsg("lm_vf_pf_channel_get_message_to_send: UNKNOWN channel type\n");
1094 return NULL;
1095 }
1096 pdev->vars.vf_pf_mess.message_virt_addr = mm_alloc_phys_mem(pdev, pdev->vars.vf_pf_mess.message_size,
1097 &pdev->vars.vf_pf_mess.message_phys_addr, 0, LM_RESOURCE_COMMON);
1098 if CHK_NULL(pdev->vars.vf_pf_mess.message_virt_addr)
1099 {
1100 DbgMessage(pdev, FATAL, "VF_PF Channel: pdev->vvars.vf_pf_mess.message_virt_addr is NULL\n");
1101 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
1102 mm_atomic_dec(&pdev->vars.vf_pf_mess.state);
1103 return NULL;
1104 }
1105 if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1106 {
1107 u32_t buletin_offset;
1108 buletin_offset = pdev->vars.vf_pf_mess.message_size =
1109 ((sizeof(union vfpf_tlvs) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK)
1110 + ((sizeof(union pfvf_tlvs) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK);
1111 pdev->vars.vf_pf_mess.bulletin_virt_addr = (u8_t*)pdev->vars.vf_pf_mess.message_virt_addr + buletin_offset;
1112 pdev->vars.vf_pf_mess.bulletin_phys_addr = pdev->vars.vf_pf_mess.message_phys_addr;
1113 LM_INC64(&pdev->vars.vf_pf_mess.bulletin_phys_addr, buletin_offset);
1114 }
1115 }
1116 mm_mem_zero(pdev->vars.vf_pf_mess.message_virt_addr, pdev->vars.vf_pf_mess.message_size);
1117 sw_hdr = (struct vf_pf_msg_hdr*)pdev->vars.vf_pf_mess.message_virt_addr;
1118 hw_first_tlv = (struct vfpf_first_tlv*)pdev->vars.vf_pf_mess.message_virt_addr;
1119 switch (opcode) {
1120 case PFVF_OP_ACQUIRE:
1121 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1122 {
1123 resp_offset = (sizeof(struct vf_pf_msg_acquire) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1124 sw_hdr->opcode_ver = PFVF_ACQUIRE_VER;
1125 }
1126 else
1127 {
1128 resp_offset = (sizeof(struct vfpf_acquire_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1129 hw_first_tlv->tl.type = CHANNEL_TLV_ACQUIRE;
1130 hw_first_tlv->tl.length = sizeof(struct vfpf_acquire_tlv);
1131 }
1132 break;
1133 case PFVF_OP_INIT_VF:
1134 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1135 {
1136 resp_offset = (sizeof(struct vf_pf_msg_init_vf) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1137 sw_hdr->opcode_ver = PFVF_INIT_VF_VER;
1138 }
1139 else
1140 {
1141 resp_offset = (sizeof(struct vfpf_init_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1142 hw_first_tlv->tl.type = CHANNEL_TLV_INIT;
1143 hw_first_tlv->tl.length = sizeof(struct vfpf_init_tlv);
1144 }
1145 break;
1146 case PFVF_OP_SETUP_Q:
1147 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1148 {
1149 resp_offset = (sizeof(struct vf_pf_msg_setup_q) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1150 sw_hdr->opcode_ver = PFVF_SETUP_Q_VER;
1151 }
1152 else
1153 {
1154 resp_offset = (sizeof(struct vfpf_setup_q_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1155 hw_first_tlv->tl.type = CHANNEL_TLV_SETUP_Q;
1156 hw_first_tlv->tl.length = sizeof(struct vfpf_setup_q_tlv);
1157 }
1158 break;
1159 case PFVF_OP_SET_Q_FILTERS:
1160 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1161 {
1162 sw_hdr->opcode_ver = PFVF_SET_Q_FILTERS_VER;
1163 resp_offset = (sizeof(struct vf_pf_msg_set_q_filters) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1164 }
1165 else
1166 {
1167 resp_offset = (sizeof(struct vfpf_set_q_filters_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1168 hw_first_tlv->tl.type = CHANNEL_TLV_SET_Q_FILTERS;
1169 hw_first_tlv->tl.length = sizeof(struct vfpf_set_q_filters_tlv);
1170 }
1171 break;
1172 #if 0
1173 case PFVF_OP_ACTIVATE_Q:
1174 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1175 {
1176 resp_offset = (sizeof(struct vf_pf_msg_q_op) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1177 sw_hdr->opcode_ver = PFVF_ACTIVATE_Q_VER;
1178 }
1179 else
1180 {
1181 DbgBreakMsg("lm_vf_pf_channel_get_message_to_send: HW_CHANNEL is not implemented yet\n");
1182 return NULL;
1183 }
1184 break;
1185 case PFVF_OP_DEACTIVATE_Q:
1186 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1187 {
1188 resp_offset = (sizeof(struct vf_pf_msg_q_op) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1189 sw_hdr->opcode_ver = PFVF_DEACTIVATE_Q_VER;
1190 }
1191 else
1192 {
1193 DbgBreakMsg("lm_vf_pf_channel_get_message_to_send: HW_CHANNEL is not implemented yet\n");
1194 return NULL;
1195 }
1196 break;
1197 #endif
1198 case PFVF_OP_TEARDOWN_Q:
1199 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1200 {
1201 resp_offset = (sizeof(struct vf_pf_msg_q_op) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1202 sw_hdr->opcode_ver = PFVF_TEARDOWN_Q_VER;
1203 }
1204 else
1205 {
1206 resp_offset = (sizeof(struct vfpf_q_op_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1207 hw_first_tlv->tl.type = CHANNEL_TLV_TEARDOWN_Q;
1208 hw_first_tlv->tl.length = sizeof(struct vfpf_q_op_tlv);
1209 }
1210 break;
1211 case PFVF_OP_CLOSE_VF:
1212 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1213 {
1214 resp_offset = (sizeof(struct vf_pf_msg_close_vf) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1215 sw_hdr->opcode_ver = PFVF_CLOSE_VF_VER;
1216 }
1217 else
1218 {
1219 resp_offset = (sizeof(struct vfpf_close_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1220 hw_first_tlv->tl.type = CHANNEL_TLV_CLOSE;
1221 hw_first_tlv->tl.length = sizeof(struct vfpf_close_tlv);
1222 }
1223 break;
1224 case PFVF_OP_RELEASE_VF:
1225 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1226 {
1227 resp_offset = (sizeof(struct vf_pf_msg_release_vf) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1228 sw_hdr->opcode_ver = PFVF_RELEASE_VF_VER;
1229 }
1230 else
1231 {
1232 resp_offset = (sizeof(struct vfpf_release_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1233 hw_first_tlv->tl.type = CHANNEL_TLV_RELEASE;
1234 hw_first_tlv->tl.length = sizeof(struct vfpf_release_tlv);
1235 }
1236 break;
1237 case PFVF_OP_UPDATE_RSS:
1238 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1239 {
1240 resp_offset = (sizeof(struct vf_pf_msg_rss) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1241 sw_hdr->opcode_ver = PFVF_UPDATE_RSS_VER;
1242 }
1243 else
1244 {
1245 resp_offset = (sizeof(struct vfpf_rss_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1246 hw_first_tlv->tl.type = CHANNEL_TLV_UPDATE_RSS;
1247 hw_first_tlv->tl.length = sizeof(struct vfpf_rss_tlv);
1248 }
1249 break;
1250 case PFVF_OP_UPDATE_RSC:
1251 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1252 {
1253 resp_offset = (sizeof(struct vf_pf_msg_rsc) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1254 sw_hdr->opcode_ver = PFVF_UPDATE_RSC_VER;
1255 }
1256 else
1257 {
1258 resp_offset = (sizeof(struct vfpf_tpa_tlv) + sizeof(struct channel_list_end_tlv) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
1259 hw_first_tlv->tl.type = CHANNEL_TLV_UPDATE_TPA;
1260 hw_first_tlv->tl.length = sizeof(struct vfpf_tpa_tlv);
1261 }
1262 break;
1263 default:
1264 mm_atomic_dec(&pdev->vars.vf_pf_mess.state);
1265 DbgMessage(pdev, FATAL, "VF_PF channel: Opcode %d is not supported\n",opcode);
1266 DbgBreak();
1267 return NULL;
1268 }
1269 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1270 {
1271 sw_hdr->if_ver = PFVF_IF_VERSION;
1272 sw_hdr->opcode = (u16_t)opcode;
1273 sw_hdr->resp_msg_offset = resp_offset;
1274 sw_resp_hdr = (struct pf_vf_msg_hdr *)((u8_t*)sw_hdr + resp_offset);
1275 sw_resp_hdr->status = SW_PFVF_STATUS_WAITING;
1276 pdev->vars.vf_pf_mess.done = (u16_t*)((u8_t *)pdev->vars.vf_pf_mess.message_virt_addr + resp_offset);
1277 }
1278 else
1279 {
1280 hw_list_end_tlv = (struct channel_list_end_tlv *)((u8_t*)hw_first_tlv + hw_first_tlv->tl.length);
1281 hw_list_end_tlv->tl.type = CHANNEL_TLV_LIST_END;
1282 hw_first_tlv->resp_msg_offset = resp_offset;
1283 hw_resp_hdr = (struct pfvf_tlv *)((u8_t*)hw_first_tlv + hw_first_tlv->resp_msg_offset);
1284 pdev->vars.vf_pf_mess.done = (u16_t*)(&hw_resp_hdr->status);
1285 }
1286 return &pdev->vars.vf_pf_mess;
1287 }
1288
lm_vf_pf_get_sb_running_index(lm_device_t * pdev,u8_t sb_id,u8_t sm_idx)1289 u16_t lm_vf_pf_get_sb_running_index(lm_device_t *pdev, u8_t sb_id, u8_t sm_idx)
1290 {
1291 u16_t running_index = 0;
1292 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && pdev->pf_vf_acquiring_resp));
1293 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1294 {
1295 struct pf_vf_msg_acquire_resp * p_sw_resp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
1296 running_index = pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.vf_sb[p_sw_resp->pfdev_info.indices_per_sb + sm_idx];
1297 }
1298 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1299 {
1300 struct pfvf_acquire_resp_tlv * p_hw_resp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;;
1301 running_index = pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.vf_sb[p_hw_resp->pfdev_info.indices_per_sb + sm_idx];
1302 }
1303 else
1304 {
1305 DbgBreak();
1306 }
1307
1308 return mm_le16_to_cpu(running_index);
1309 }
1310
1311
lm_vf_pf_get_sb_index(lm_device_t * pdev,u8_t sb_id,u8_t idx)1312 u16_t lm_vf_pf_get_sb_index(lm_device_t *pdev, u8_t sb_id, u8_t idx)
1313 {
1314 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && pdev->pf_vf_acquiring_resp));
1315 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1316 {
1317 struct pf_vf_msg_acquire_resp * p_sw_resp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
1318 DbgBreakIf(!(p_sw_resp && (sb_id < p_sw_resp->pfdev_info.indices_per_sb)));
1319 }
1320 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1321 {
1322 struct pfvf_acquire_resp_tlv * p_hw_resp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;;
1323 DbgBreakIf(!(p_hw_resp && (sb_id < p_hw_resp->pfdev_info.indices_per_sb)));
1324 }
1325 else
1326 {
1327 DbgBreak();
1328 }
1329 return mm_le16_to_cpu(pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.vf_sb[sb_id]);
1330 }
1331
lm_vf_get_doorbell_size(struct _lm_device_t * pdev)1332 u16_t lm_vf_get_doorbell_size(struct _lm_device_t *pdev)
1333 {
1334 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && pdev->pf_vf_acquiring_resp));
1335 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1336 {
1337 struct pf_vf_msg_acquire_resp * p_sw_resp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
1338 DbgBreakIf(!p_sw_resp->pfdev_info.db_size);
1339 return p_sw_resp->pfdev_info.db_size;
1340 }
1341 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1342 {
1343 struct pfvf_acquire_resp_tlv * p_hw_resp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;;
1344 DbgBreakIf(!p_hw_resp->pfdev_info.db_size);
1345 return p_hw_resp->pfdev_info.db_size;
1346 }
1347 else
1348 {
1349 DbgBreak();
1350 }
1351 return 0;
1352 }
1353
lm_vf_pf_wait_no_messages_pending(struct _lm_device_t * pdev)1354 lm_status_t lm_vf_pf_wait_no_messages_pending(struct _lm_device_t * pdev)
1355 {
1356 lm_status_t lm_status = LM_STATUS_SUCCESS;
1357 lm_vf_pf_message_t * pf_mess = NULL;
1358 pf_mess = &pdev->vars.vf_pf_mess;
1359 lm_status = lm_vf_pf_channel_wait_response(pdev, pf_mess);
1360
1361 DbgMessage(pdev, WARNvf, "lm_vf_pf_wait_no_messages_pending\n");
1362
1363 if (lm_status == LM_STATUS_SUCCESS) {
1364 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1365 {
1366 struct vf_pf_msg_hdr * mess_hdr = NULL;
1367 struct pf_vf_msg_hdr * resp_hdr = NULL;
1368 mess_hdr = (struct vf_pf_msg_hdr *)pf_mess->message_virt_addr;
1369 resp_hdr = (struct pf_vf_msg_hdr *)((u8_t*)mess_hdr + mess_hdr->resp_msg_offset);
1370 switch (resp_hdr->status) {
1371 case SW_PFVF_STATUS_SUCCESS:
1372 DbgMessage(pdev, WARN, "VF_PF Channel: Message %d(%d) is completed successfully\n",mess_hdr->opcode, resp_hdr->opcode);
1373 lm_status = LM_STATUS_SUCCESS;
1374 break;
1375 case SW_PFVF_STATUS_FAILURE:
1376 case SW_PFVF_STATUS_MISMATCH_PF_VF_VERSION:
1377 case SW_PFVF_STATUS_MISMATCH_FW_HSI:
1378 case SW_PFVF_STATUS_NO_RESOURCE:
1379 DbgMessage(pdev, FATAL, "VF_PF Channel: Status %d is not supported yet\n", resp_hdr->status);
1380 lm_status = LM_STATUS_FAILURE;
1381 pf_mess->bad_response.sw_channel_hdr = *resp_hdr;
1382 break;
1383 default:
1384 DbgMessage(pdev, FATAL, "VF_PF Channel: Unknown status %d\n", resp_hdr->status);
1385 pf_mess->bad_response.sw_channel_hdr = *resp_hdr;
1386 lm_status = LM_STATUS_FAILURE;
1387 break;
1388 }
1389 }
1390 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1391 {
1392 struct vfpf_first_tlv * mess_hdr = NULL;
1393 struct pfvf_tlv * resp_hdr = NULL;
1394 mess_hdr = (struct vfpf_first_tlv *)pf_mess->message_virt_addr;
1395 resp_hdr = (struct pfvf_tlv *)((u8_t*)mess_hdr + mess_hdr->resp_msg_offset);
1396 switch (resp_hdr->status)
1397 {
1398 case PFVF_STATUS_SUCCESS:
1399 lm_status = LM_STATUS_SUCCESS;
1400 break;
1401 case PFVF_STATUS_FAILURE:
1402 case PFVF_STATUS_NOT_SUPPORTED:
1403 case PFVF_STATUS_NO_RESOURCE:
1404 DbgMessage(pdev, FATAL, "VF_PF Channel: Status %d is not supported yet\n", resp_hdr->status);
1405 pf_mess->bad_response.hw_channel_hdr = *resp_hdr;
1406 lm_status = LM_STATUS_FAILURE;
1407 break;
1408 default:
1409 DbgMessage(pdev, FATAL, "VF_PF Channel: Unknown status %d\n", resp_hdr->status);
1410 pf_mess->bad_response.hw_channel_hdr = *resp_hdr;
1411 lm_status = LM_STATUS_FAILURE;
1412 break;
1413 }
1414 }
1415 else
1416 {
1417 DbgBreak();
1418 }
1419 }
1420 lm_vf_pf_channel_release_message(pdev,pf_mess);
1421 return lm_status;
1422 }
1423
lm_vf_pf_acquire_msg(struct _lm_device_t * pdev)1424 lm_status_t lm_vf_pf_acquire_msg(struct _lm_device_t * pdev)
1425 {
1426 lm_status_t lm_status = LM_STATUS_SUCCESS;
1427 lm_vf_pf_message_t * pf_mess = NULL;
1428 struct vf_pf_msg_acquire * sw_mess = NULL;
1429 struct vfpf_acquire_tlv * hw_mess = NULL;
1430 struct pf_vf_msg_acquire_resp * sw_resp = NULL;
1431 struct pfvf_acquire_resp_tlv * hw_resp = NULL;
1432 u8_t max_dq = 0;
1433
1434 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)));
1435
1436 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_ACQUIRE);
1437
1438 if (!pf_mess)
1439 {
1440 DbgMessage(pdev, FATAL, "VF_PF Channel: lm_vf_pf_channel_get_message_to_send returns NULL\n");
1441 lm_status = LM_STATUS_RESOURCE;
1442 DbgBreak();
1443 return lm_status;
1444 }
1445
1446 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1447 {
1448 sw_mess = (struct vf_pf_msg_acquire*)pf_mess->message_virt_addr;
1449
1450 // mess->vfdev_info.vf_pf_msg_size = sizeof(union vf_pf_msg);
1451 /* the following fields are for debug purposes */
1452 sw_mess->vfdev_info.vf_id = ABS_VFID(pdev); /* ME register value */
1453 sw_mess->vfdev_info.vf_os = 0; /* e.g. Linux, W2K8 */
1454 sw_mess->vfdev_info.vf_aux = SW_VFPF_VFDEF_INFO_AUX_DIRECT_DQ;
1455 sw_mess->vfdev_info.vf_fw_hsi_version = pdev->ver_num_fw; /* Must not be zero otherwise, VF will yellow bang */
1456 sw_mess->vfdev_info.fp_hsi_ver = ETH_FP_HSI_VER_1; /* We don't want to break support for old/new VF/PF so we retrun v1 */
1457 DbgBreakIf( 0 == sw_mess->vfdev_info.vf_fw_hsi_version );
1458
1459 sw_mess->resc_request.num_rxqs = sw_mess->resc_request.num_txqs = sw_mess->resc_request.num_sbs = LM_SB_CNT(pdev);
1460 sw_mess->resc_request.num_mac_filters = 1;
1461 sw_mess->resc_request.num_vlan_filters = 0;
1462 sw_mess->resc_request.num_mc_filters = 0;
1463
1464 }
1465 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1466 {
1467 hw_mess = (struct vfpf_acquire_tlv*)pf_mess->message_virt_addr;
1468 hw_mess->vfdev_info.vf_id = ABS_VFID(pdev); /* ME register value */
1469 hw_mess->vfdev_info.vf_os = 0; /* e.g. Linux, W2K8 */
1470 hw_mess->vfdev_info.fp_hsi_ver = ETH_FP_HSI_VER_1; /* We don't want to break support for old/new VF/PF so we retrun v1 */
1471 hw_mess->resc_request.num_rxqs = hw_mess->resc_request.num_txqs = hw_mess->resc_request.num_sbs = LM_SB_CNT(pdev);
1472 hw_mess->resc_request.num_mac_filters = 1;
1473 hw_mess->resc_request.num_vlan_filters = 0;
1474 hw_mess->resc_request.num_mc_filters = PFVF_MAX_MULTICAST_PER_VF;
1475 hw_mess->bulletin_addr = pf_mess->bulletin_phys_addr.as_u64;
1476 }
1477 else
1478 {
1479 DbgBreak();
1480 lm_vf_pf_channel_release_message(pdev,pf_mess);
1481 return LM_STATUS_FAILURE;
1482 }
1483
1484 pf_mess->do_not_arm_trigger = TRUE;
1485 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
1486
1487 if (lm_status != LM_STATUS_SUCCESS)
1488 {
1489 lm_vf_pf_channel_release_message(pdev,pf_mess);
1490 return lm_status;
1491 }
1492 lm_status = lm_vf_pf_channel_wait_response(pdev, pf_mess);
1493
1494 // FIXME TODO
1495 if (lm_status == LM_STATUS_SUCCESS)
1496 {
1497 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1498 {
1499 sw_resp = (struct pf_vf_msg_acquire_resp *)((u8_t*)sw_mess + sw_mess->hdr.resp_msg_offset);
1500 if (sw_resp->hdr.opcode != PFVF_OP_ACQUIRE)
1501 {
1502 lm_status = LM_STATUS_FAILURE;
1503 }
1504 else
1505 {
1506 switch (sw_resp->hdr.status)
1507 {
1508 case SW_PFVF_STATUS_SUCCESS:
1509 lm_status = LM_STATUS_SUCCESS;
1510 break;
1511 case SW_PFVF_STATUS_FAILURE:
1512 case SW_PFVF_STATUS_MISMATCH_PF_VF_VERSION:
1513 case SW_PFVF_STATUS_MISMATCH_FW_HSI:
1514 case SW_PFVF_STATUS_NO_RESOURCE:
1515 DbgMessage(pdev, FATAL, "VF_PF Channel: Status %d is not supported yet\n", sw_resp->hdr.status);
1516 lm_status = LM_STATUS_FAILURE;
1517 break;
1518 default:
1519 DbgMessage(pdev, FATAL, "VF_PF Channel: Unknown status %d\n", sw_resp->hdr.status);
1520 lm_status = LM_STATUS_FAILURE;
1521 break;
1522 }
1523 // We update here the status of pf_acquire
1524 // in order to let the UM layer of the VF to report
1525 // in the event log the relevant event log message
1526 pdev->params.pf_acquire_status = sw_resp->hdr.status;
1527 }
1528 }
1529 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1530 {
1531 hw_resp = (struct pfvf_acquire_resp_tlv *)((u8_t*)hw_mess + hw_mess->first_tlv.resp_msg_offset);
1532 if (hw_resp->hdr.tl.type != CHANNEL_TLV_ACQUIRE)
1533 {
1534 lm_status = LM_STATUS_FAILURE;
1535 }
1536 else
1537 {
1538 switch (hw_resp->hdr.status)
1539 {
1540 case PFVF_STATUS_SUCCESS:
1541 lm_status = LM_STATUS_SUCCESS;
1542 break;
1543 case PFVF_STATUS_FAILURE:
1544 case PFVF_STATUS_NOT_SUPPORTED:
1545 case PFVF_STATUS_NO_RESOURCE:
1546 DbgMessage(pdev, FATAL, "VF_PF Channel: Status %d is not supported yet\n", hw_resp->hdr.status);
1547 lm_status = LM_STATUS_FAILURE;
1548 break;
1549 default:
1550 DbgMessage(pdev, FATAL, "VF_PF Channel: Unknown status %d\n", hw_resp->hdr.status);
1551 lm_status = LM_STATUS_FAILURE;
1552 break;
1553 }
1554 // We update here the status of pf_acquire
1555 // in order to let the UM layer of the VF to report
1556 // in the event log the relevant event log message
1557 pdev->params.pf_acquire_status = hw_resp->hdr.status;
1558 }
1559 }
1560 else
1561 {
1562 DbgBreak();
1563 lm_status = LM_STATUS_FAILURE;
1564 }
1565 }
1566
1567 if (lm_status == LM_STATUS_SUCCESS)
1568 {
1569 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1570 {
1571 struct pf_vf_msg_acquire_resp * presp;
1572
1573 if (pdev->pf_vf_acquiring_resp == NULL)
1574 {
1575 pdev->pf_vf_acquiring_resp = mm_alloc_mem(pdev, sizeof(struct pf_vf_msg_acquire_resp),LM_RESOURCE_COMMON);
1576
1577 if CHK_NULL(pdev->pf_vf_acquiring_resp)
1578 {
1579 lm_vf_pf_channel_release_message(pdev, pf_mess);
1580 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
1581 return LM_STATUS_RESOURCE;
1582 }
1583 else
1584 {
1585 DbgMessage(pdev, FATAL, "VF_PF Channel: pdev->pf_vf_acquiring_resp is allocated (%db)\n",sizeof(struct pf_vf_msg_acquire_resp));
1586 }
1587 }
1588
1589 // FIXME TODO
1590 presp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
1591
1592 // override for now to make sure we get correct answer...
1593 presp->pfdev_info.chip_num = CHIP_NUM_5712E;
1594
1595 mm_memcpy(pdev->pf_vf_acquiring_resp, sw_resp, sizeof(struct pf_vf_msg_acquire_resp));
1596 if (!pdev->params.debug_sriov)
1597 {
1598 pdev->params.debug_sriov = presp->pfdev_info.pf_cap & PFVF_DEBUG;
1599 }
1600 DbgMessage(pdev, FATALvf, "presp->pfdev_info.db_size = %d\n", presp->pfdev_info.db_size);
1601 DbgMessage(pdev, FATALvf, "presp->pfdev_info.indices_per_sb = %d\n", presp->pfdev_info.indices_per_sb);
1602 DbgMessage(pdev, FATALvf, "presp->pfdev_info.pf_cap = %d\n", presp->pfdev_info.pf_cap);
1603 DbgMessage(pdev, FATALvf, "presp->pfdev_info.chip_num = %d\n", presp->pfdev_info.chip_num);
1604 DbgMessage(pdev, FATALvf, "presp->resc.hw_qid[0] = %d\n", presp->resc.hw_qid[0]);
1605 DbgMessage(pdev, FATALvf, "presp->resc.hw_sbs[0].hw_sb_id = %d\n", presp->resc.hw_sbs[0].hw_sb_id);
1606 DbgMessage(pdev, FATALvf, "presp->resc.hw_sbs[0].sb_qid = %d\n", presp->resc.hw_sbs[0].sb_qid);
1607 DbgMessage(pdev, FATALvf, "presp->resc.num_sbs = %d\n", presp->resc.num_sbs);
1608 DbgMessage(pdev, FATALvf, "presp->resc.igu_cnt = %d\n", presp->resc.igu_cnt);
1609 DbgMessage(pdev, FATALvf, "presp->resc.igu_test_cnt = %d\n", presp->resc.igu_test_cnt);
1610 DbgMessage(pdev, FATALvf, "presp->resc.num_rxqs = %d\n", presp->resc.num_rxqs);
1611 DbgMessage(pdev, FATALvf, "presp->resc.num_txqs = %d\n", presp->resc.num_txqs);
1612 DbgMessage(pdev, FATALvf, "presp->resc.num_mac_filters = %d\n", presp->resc.num_mac_filters);
1613 DbgMessage(pdev, FATALvf, "presp->resc.num_mc_filters = %d\n", presp->resc.num_mc_filters);
1614 DbgMessage(pdev, FATALvf, "presp->resc.num_vlan_filters = %d\n", presp->resc.num_vlan_filters);
1615
1616 if (presp->pfdev_info.db_size)
1617 {
1618 max_dq = VF_BAR0_DB_SIZE / presp->pfdev_info.db_size;
1619 if (!max_dq)
1620 {
1621 max_dq = 1;
1622 }
1623 }
1624 else
1625 {
1626 lm_vf_pf_channel_release_message(pdev, pf_mess);
1627 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
1628 return LM_STATUS_INVALID_PARAMETER;
1629 }
1630 pdev->params.fw_base_qzone_cnt = pdev->params.sb_cnt = min(presp->resc.num_sbs, max_dq);
1631 pdev->params.max_rss_chains = pdev->params.rss_chain_cnt = min(presp->resc.num_rxqs, max_dq);
1632 pdev->params.tss_chain_cnt = min(presp->resc.num_txqs, max_dq);
1633
1634 pdev->hw_info.chip_id = presp->pfdev_info.chip_num;
1635 pdev->hw_info.intr_blk_info.blk_type = INTR_BLK_IGU;
1636 pdev->hw_info.intr_blk_info.blk_mode = INTR_BLK_MODE_NORM;
1637 pdev->hw_info.intr_blk_info.access_type = INTR_BLK_ACCESS_IGUMEM;
1638
1639 /* IGU specific data */
1640 pdev->hw_info.intr_blk_info.igu_info.igu_base_sb = presp->resc.hw_sbs[0].hw_sb_id;
1641 pdev->hw_info.intr_blk_info.igu_info.igu_sb_cnt = presp->resc.igu_cnt;
1642 pdev->hw_info.intr_blk_info.igu_info.igu_test_sb_cnt = presp->resc.igu_test_cnt;
1643 /* TODO: don't assume consecutiveness... */
1644 {
1645 u8_t idx;
1646 for (idx = 0; idx < pdev->params.fw_base_qzone_cnt; idx++)
1647 {
1648 pdev->params.fw_qzone_id[idx] = presp->resc.hw_qid[idx];
1649 IGU_VF_NDSB(pdev,idx) = presp->resc.hw_sbs[idx].hw_sb_id;
1650 }
1651 }
1652
1653
1654 /* TODO: get this from presp... here for purpose of rx_mask... */
1655 //pdev->hw_info.chip_id |= CHIP_REV_EMUL;
1656 if (presp->resc.num_mc_filters == 0xFF)
1657 {
1658 presp->resc.num_mc_filters = 0;
1659 }
1660 if (presp->resc.current_mac_addr[0]
1661 || presp->resc.current_mac_addr[1]
1662 || presp->resc.current_mac_addr[2]
1663 || presp->resc.current_mac_addr[3]
1664 || presp->resc.current_mac_addr[4]
1665 || presp->resc.current_mac_addr[5])
1666 {
1667 DbgMessage(pdev, WARN, "VF received MAC from PF\n");
1668 pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0] = presp->resc.current_mac_addr[0];
1669 pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1] = presp->resc.current_mac_addr[1];
1670 pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2] = presp->resc.current_mac_addr[2];
1671 pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3] = presp->resc.current_mac_addr[3];
1672 pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4] = presp->resc.current_mac_addr[4];
1673 pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5] = presp->resc.current_mac_addr[5];
1674 }
1675 else
1676 {
1677 DbgMessage(pdev, WARN, "VF uses own MAC\n");
1678 }
1679 }
1680 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1681 {
1682 struct pfvf_acquire_resp_tlv * presp;
1683
1684 if (pdev->pf_vf_acquiring_resp == NULL)
1685 {
1686 pdev->pf_vf_acquiring_resp = mm_alloc_mem(pdev, sizeof(struct pfvf_acquire_resp_tlv),LM_RESOURCE_COMMON);
1687
1688 if CHK_NULL(pdev->pf_vf_acquiring_resp)
1689 {
1690 lm_vf_pf_channel_release_message(pdev, pf_mess);
1691 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
1692 return LM_STATUS_RESOURCE;
1693 }
1694 else
1695 {
1696 DbgMessage(pdev, FATAL, "VF_PF Channel: pdev->pf_vf_acquiring_resp is allocated (%db)\n",sizeof(struct pfvf_acquire_resp_tlv));
1697 }
1698 }
1699
1700 // FIXME TODO
1701 presp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;
1702
1703 presp->pfdev_info.chip_num = CHIP_NUM_5712E;
1704
1705 mm_memcpy(pdev->pf_vf_acquiring_resp, hw_resp, sizeof(struct pfvf_acquire_resp_tlv));
1706
1707 DbgMessage(pdev, FATALvf, "presp->pfdev_info.db_size = %d\n", presp->pfdev_info.db_size);
1708 DbgMessage(pdev, FATALvf, "presp->pfdev_info.indices_per_sb = %d\n", presp->pfdev_info.indices_per_sb);
1709 DbgMessage(pdev, FATALvf, "presp->pfdev_info.pf_cap = %d\n", presp->pfdev_info.pf_cap);
1710 DbgMessage(pdev, FATALvf, "presp->pfdev_info.chip_num = %d\n", presp->pfdev_info.chip_num);
1711 DbgMessage(pdev, FATALvf, "presp->resc.hw_qid[0] = %d\n", presp->resc.hw_qid[0]);
1712 DbgMessage(pdev, FATALvf, "presp->resc.hw_sbs[0].hw_sb_id = %d\n", presp->resc.hw_sbs[0].hw_sb_id);
1713 DbgMessage(pdev, FATALvf, "presp->resc.hw_sbs[0].sb_qid = %d\n", presp->resc.hw_sbs[0].sb_qid);
1714 DbgMessage(pdev, FATALvf, "presp->resc.num_sbs = %d\n", presp->resc.num_sbs);
1715 DbgMessage(pdev, FATALvf, "presp->resc.num_rxqs = %d\n", presp->resc.num_rxqs);
1716 DbgMessage(pdev, FATALvf, "presp->resc.num_txqs = %d\n", presp->resc.num_txqs);
1717 DbgMessage(pdev, FATALvf, "presp->resc.num_mac_filters = %d\n", presp->resc.num_mac_filters);
1718 DbgMessage(pdev, FATALvf, "presp->resc.num_mc_filters = %d\n", presp->resc.num_mc_filters);
1719 DbgMessage(pdev, FATALvf, "presp->resc.num_vlan_filters = %d\n", presp->resc.num_vlan_filters);
1720
1721
1722 if (presp->pfdev_info.db_size)
1723 {
1724 max_dq = VF_BAR0_DB_SIZE / presp->pfdev_info.db_size;
1725 if (!max_dq)
1726 {
1727 max_dq = 1;
1728 }
1729 }
1730 else
1731 {
1732 lm_vf_pf_channel_release_message(pdev, pf_mess);
1733 DbgBreakIf(!DBG_BREAK_ON(UNDER_TEST));
1734 return LM_STATUS_INVALID_PARAMETER;
1735 }
1736 pdev->params.fw_base_qzone_cnt = pdev->params.sb_cnt = min(presp->resc.num_sbs, max_dq);
1737 pdev->params.max_rss_chains = pdev->params.rss_chain_cnt = min(presp->resc.num_rxqs, max_dq);
1738 pdev->params.tss_chain_cnt = min(presp->resc.num_txqs, max_dq);
1739
1740 pdev->hw_info.chip_id = presp->pfdev_info.chip_num;
1741 pdev->hw_info.intr_blk_info.blk_type = INTR_BLK_IGU;
1742 pdev->hw_info.intr_blk_info.blk_mode = INTR_BLK_MODE_NORM;
1743 pdev->hw_info.intr_blk_info.access_type = INTR_BLK_ACCESS_IGUMEM;
1744
1745 /* IGU specific data */
1746 pdev->hw_info.intr_blk_info.igu_info.igu_base_sb = presp->resc.hw_sbs[0].hw_sb_id;
1747 pdev->hw_info.intr_blk_info.igu_info.igu_sb_cnt = presp->resc.num_sbs;
1748 /* TODO: don't assume consecutiveness... */
1749 {
1750 u8_t idx;
1751 for (idx = 0; idx < pdev->params.fw_base_qzone_cnt; idx++)
1752 {
1753 pdev->params.fw_qzone_id[idx] = presp->resc.hw_qid[idx];
1754 IGU_VF_NDSB(pdev,idx) = presp->resc.hw_sbs[idx].hw_sb_id;
1755 }
1756 }
1757
1758
1759 /* TODO: get this from presp... here for purpose of rx_mask... */
1760 //pdev->hw_info.chip_id |= CHIP_REV_EMUL;
1761 if (presp->resc.num_mc_filters == 0xFF)
1762 {
1763 presp->resc.num_mc_filters = 0;
1764 }
1765 else if (presp->resc.num_mc_filters == 0)
1766 {
1767 presp->resc.num_mc_filters = hw_mess->resc_request.num_mc_filters;
1768 }
1769 pdev->params.mc_table_size[LM_CLI_IDX_NDIS] = presp->resc.num_mc_filters;
1770 pdev->vars.pf_link_speed = presp->resc.pf_link_speed;
1771
1772 if (presp->resc.current_mac_addr[0]
1773 || presp->resc.current_mac_addr[1]
1774 || presp->resc.current_mac_addr[2]
1775 || presp->resc.current_mac_addr[3]
1776 || presp->resc.current_mac_addr[4]
1777 || presp->resc.current_mac_addr[5])
1778 {
1779
1780 DbgMessage(pdev, WARN, "VF received MAC from PF\n");
1781 pdev->params.mac_addr[0] = pdev->hw_info.mac_addr[0] = presp->resc.current_mac_addr[0];
1782 pdev->params.mac_addr[1] = pdev->hw_info.mac_addr[1] = presp->resc.current_mac_addr[1];
1783 pdev->params.mac_addr[2] = pdev->hw_info.mac_addr[2] = presp->resc.current_mac_addr[2];
1784 pdev->params.mac_addr[3] = pdev->hw_info.mac_addr[3] = presp->resc.current_mac_addr[3];
1785 pdev->params.mac_addr[4] = pdev->hw_info.mac_addr[4] = presp->resc.current_mac_addr[4];
1786 pdev->params.mac_addr[5] = pdev->hw_info.mac_addr[5] = presp->resc.current_mac_addr[5];
1787 pdev->vars.is_pf_provides_mac = TRUE;
1788 pdev->vars.is_pf_restricts_lamac = lm_vf_check_mac_restriction(pdev, presp);
1789 }
1790 else
1791 {
1792 DbgMessage(pdev, WARN, "VF uses own MAC\n");
1793 pdev->vars.is_pf_provides_mac = FALSE;
1794 pdev->vars.is_pf_restricts_lamac = FALSE;
1795 }
1796 }
1797 else
1798 {
1799 DbgBreak();
1800 lm_status = LM_STATUS_FAILURE;
1801 }
1802 }
1803
1804 lm_vf_pf_channel_release_message(pdev, pf_mess);
1805 return lm_status;
1806 }
1807
lm_vf_pf_init_vf(struct _lm_device_t * pdev)1808 lm_status_t lm_vf_pf_init_vf(struct _lm_device_t * pdev)
1809 {
1810 lm_status_t lm_status = LM_STATUS_SUCCESS;
1811 lm_vf_pf_message_t * pf_mess = NULL;
1812 lm_address_t q_stats;
1813 u8_t sb_id;
1814
1815 DbgMessage(pdev, WARNvf, "lm_vf_pf_init_vf\n");
1816
1817 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && (LM_SB_CNT(pdev) <= PFVF_MAX_SBS_PER_VF)));
1818 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_INIT_VF);
1819 if (!pf_mess) {
1820 lm_status = LM_STATUS_RESOURCE;
1821 DbgBreak();
1822 return lm_status;
1823 }
1824 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1825 {
1826 struct vf_pf_msg_init_vf * mess = NULL;
1827 mess = (struct vf_pf_msg_init_vf*)pf_mess->message_virt_addr;
1828
1829 q_stats = pdev->vars.stats.stats_collect.stats_fw.fw_stats_data_mapping;
1830 LM_INC64(&q_stats, OFFSETOF(lm_stats_fw_stats_data_t, queue_stats));
1831 mess->stats_addr = q_stats.as_u64;
1832
1833 LM_FOREACH_SB_ID(pdev,sb_id) {
1834 mess->sb_addr[sb_id] = pdev->vars.status_blocks_arr[sb_id].hc_status_block_data.vf_sb_phy_address.as_u64;
1835 }
1836 }
1837 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1838 {
1839 struct vfpf_init_tlv * mess = NULL;
1840 mess = (struct vfpf_init_tlv*)pf_mess->message_virt_addr;
1841
1842 q_stats = pdev->vars.stats.stats_collect.stats_fw.fw_stats_data_mapping;
1843 LM_INC64(&q_stats, OFFSETOF(lm_stats_fw_stats_data_t, queue_stats));
1844 mess->stats_addr = q_stats.as_u64;
1845 mess->flags = VFPF_INIT_FLG_STATS_COALESCE;
1846
1847 LM_FOREACH_SB_ID(pdev,sb_id) {
1848 mess->sb_addr[sb_id] = pdev->vars.status_blocks_arr[sb_id].hc_status_block_data.vf_sb_phy_address.as_u64;
1849 }
1850 }
1851 else
1852 {
1853 DbgBreak();
1854 lm_vf_pf_channel_release_message(pdev,pf_mess);
1855 return LM_STATUS_FAILURE;
1856 }
1857
1858 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
1859 if (lm_status != LM_STATUS_SUCCESS) {
1860 lm_vf_pf_channel_release_message(pdev,pf_mess);
1861 }
1862 DbgMessage(pdev, WARNvf, "lm_vf_pf_init_vf return lm_status = %d\n", lm_status);
1863
1864 return lm_status;
1865 }
1866
lm_vf_pf_setup_q(struct _lm_device_t * pdev,u8 vf_qid,u8_t validation_flag)1867 lm_status_t lm_vf_pf_setup_q(struct _lm_device_t * pdev, u8 vf_qid, u8_t validation_flag)
1868 {
1869 lm_status_t lm_status = LM_STATUS_SUCCESS;
1870 lm_vf_pf_message_t * pf_mess = NULL;
1871
1872 DbgMessage(pdev, WARNvf, "lm_vf_pf_setup_q\n");
1873
1874 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)
1875 && (validation_flag & (RX_Q_VALIDATE | TX_Q_VALIDATE))
1876 && (vf_qid < LM_SB_CNT(pdev))
1877 && pdev->pf_vf_acquiring_resp));
1878
1879 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_SETUP_Q);
1880 if (!pf_mess) {
1881 lm_status = LM_STATUS_RESOURCE;
1882 DbgBreak();
1883 return lm_status;
1884 }
1885 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
1886 {
1887 struct vf_pf_msg_setup_q * mess = NULL;
1888 struct pf_vf_msg_acquire_resp * presp = NULL;
1889
1890 mess = (struct vf_pf_msg_setup_q*)pf_mess->message_virt_addr;
1891 presp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
1892 mess->vf_qid = vf_qid;
1893 if (validation_flag & RX_Q_VALIDATE) {
1894 SET_FLAGS(mess->param_valid, VFPF_RXQ_VALID);
1895 mess->rxq.rcq_addr = lm_bd_chain_phys_addr(&(LM_RCQ(pdev,vf_qid).bd_chain), 0).as_u64;
1896 mess->rxq.rcq_np_addr = lm_bd_chain_phys_addr(&(LM_RCQ(pdev,vf_qid).bd_chain), 1).as_u64;
1897 mess->rxq.rxq_addr = lm_bd_chain_phys_addr(&(LM_RXQ_CHAIN(pdev,vf_qid,0)), 0).as_u64;
1898 if (presp->pfdev_info.pf_cap & PFVF_CAP_TPA) {
1899 mess->rxq.sge_addr = LM_TPA_CHAIN_BD(pdev, vf_qid).bd_chain_phy.as_u64;
1900 if (mess->rxq.sge_addr) {
1901 mess->rxq.flags |= SW_VFPF_QUEUE_FLG_TPA;
1902 }
1903 } else {
1904 mess->rxq.sge_addr = 0;
1905 }
1906
1907 /* sb + hc info */
1908 mess->rxq.vf_sb = vf_qid; /* relative to vf */
1909 mess->rxq.flags |= SW_VFPF_QUEUE_FLG_CACHE_ALIGN;
1910 mess->rxq.sb_index = LM_RCQ(pdev, vf_qid).hc_sb_info.hc_index_value;
1911 if ((pdev->params.int_coalesing_mode == LM_INT_COAL_PERIODIC_SYNC)/* && !pdev->params.int_coalesing_mode_disabled_by_ndis*/) {
1912 mess->rxq.hc_rate = (u16_t)pdev->params.int_per_sec_rx[HC_PARAMS_ETH_INDEX]; /* desired interrupts per sec. *//* valid iff VFPF_QUEUE_FLG_HC */
1913 mess->rxq.flags |= SW_VFPF_QUEUE_FLG_HC;
1914 if (pdev->params.enable_dynamic_hc[HC_PARAMS_ETH_INDEX] && (presp->pfdev_info.pf_cap & PFVF_CAP_DHC)) {
1915 mess->rxq.flags |= SW_VFPF_QUEUE_FLG_DHC;
1916 }
1917 }
1918
1919 /* rx buffer info */
1920 mess->rxq.mtu = (u16_t)pdev->params.l2_cli_con_params[vf_qid].mtu;
1921 mess->rxq.buf_sz = MAX_L2_CLI_BUFFER_SIZE(pdev, vf_qid);
1922 mess->rxq.drop_flags = 0; //(u8_t)pdev->params.rx_err_filter;
1923 }
1924
1925 if (validation_flag & TX_Q_VALIDATE) {
1926 SET_FLAGS(mess->param_valid, VFPF_TXQ_VALID);
1927 mess->txq.txq_addr = lm_bd_chain_phys_addr(&(LM_TXQ(pdev,vf_qid).bd_chain), 0).as_u64;
1928 mess->txq.vf_sb = vf_qid;
1929 mess->txq.sb_index = LM_TXQ(pdev, vf_qid).hc_sb_info.hc_index_value;
1930 if ((pdev->params.int_coalesing_mode == LM_INT_COAL_PERIODIC_SYNC)/* && pdev->params.int_coalesing_mode_disabled_by_ndis*/) {
1931 mess->txq.hc_rate = (u16_t)pdev->params.int_per_sec_tx[HC_PARAMS_ETH_INDEX]; /* desired interrupts per sec. *//* valid iff VFPF_QUEUE_FLG_HC */
1932 mess->txq.flags |= SW_VFPF_QUEUE_FLG_HC;
1933 }
1934 }
1935 }
1936 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
1937 {
1938 struct vfpf_setup_q_tlv * mess = NULL;
1939 struct pfvf_acquire_resp_tlv * presp = NULL;
1940
1941 mess = (struct vfpf_setup_q_tlv*)pf_mess->message_virt_addr;
1942 presp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;
1943 mess->vf_qid = vf_qid;
1944 if (validation_flag & RX_Q_VALIDATE) {
1945 SET_FLAGS(mess->param_valid, VFPF_RXQ_VALID);
1946 mess->rxq.rcq_addr = lm_bd_chain_phys_addr(&(LM_RCQ(pdev,vf_qid).bd_chain), 0).as_u64;
1947 mess->rxq.rcq_np_addr = lm_bd_chain_phys_addr(&(LM_RCQ(pdev,vf_qid).bd_chain), 1).as_u64;
1948 mess->rxq.rxq_addr = lm_bd_chain_phys_addr(&(LM_RXQ_CHAIN(pdev,vf_qid,0)), 0).as_u64;
1949 #if 0
1950 if (presp->pfdev_info.pf_cap & PFVF_CAP_TPA) {
1951 mess->rxq.sge_addr = LM_TPA_CHAIN_BD(pdev, vf_qid).bd_chain_phy.as_u64;
1952 if (mess->rxq.sge_addr) {
1953 mess->rxq.flags |= VFPF_QUEUE_FLG_TPA;
1954 }
1955 }
1956 else
1957 #endif
1958 {
1959 mess->rxq.sge_addr = 0;
1960 }
1961
1962 /* sb + hc info */
1963 mess->rxq.vf_sb = vf_qid; /* relative to vf */
1964 mess->rxq.flags |= VFPF_QUEUE_FLG_CACHE_ALIGN;
1965 mess->rxq.flags |= VFPF_QUEUE_FLG_STATS;
1966 mess->rxq.flags |= VFPF_QUEUE_FLG_VLAN;
1967 mess->rxq.sb_index = LM_RCQ(pdev, vf_qid).hc_sb_info.hc_index_value;
1968 if ((pdev->params.int_coalesing_mode == LM_INT_COAL_PERIODIC_SYNC)/* && !pdev->params.int_coalesing_mode_disabled_by_ndis*/) {
1969 mess->rxq.hc_rate = (u16_t)pdev->params.int_per_sec_rx[HC_PARAMS_ETH_INDEX]; /* desired interrupts per sec. *//* valid iff VFPF_QUEUE_FLG_HC */
1970 mess->rxq.flags |= VFPF_QUEUE_FLG_HC;
1971 if (pdev->params.enable_dynamic_hc[HC_PARAMS_ETH_INDEX] && (presp->pfdev_info.pf_cap & PFVF_CAP_DHC)) {
1972 mess->rxq.flags |= VFPF_QUEUE_FLG_DHC;
1973 }
1974 }
1975 if (!vf_qid)
1976 {
1977 mess->rxq.flags |= VFPF_QUEUE_FLG_LEADING_RSS;
1978 }
1979 /* rx buffer info */
1980 mess->rxq.mtu = (u16_t)pdev->params.l2_cli_con_params[vf_qid].mtu;
1981 mess->rxq.buf_sz = MAX_L2_CLI_BUFFER_SIZE(pdev, vf_qid);
1982 mess->rxq.drop_flags = 0; //(u8_t)pdev->params.rx_err_filter;
1983 }
1984
1985 if (validation_flag & TX_Q_VALIDATE) {
1986 SET_FLAGS(mess->param_valid, VFPF_TXQ_VALID);
1987 mess->txq.txq_addr = lm_bd_chain_phys_addr(&(LM_TXQ(pdev,vf_qid).bd_chain), 0).as_u64;
1988 mess->txq.vf_sb = vf_qid;
1989 mess->txq.sb_index = LM_TXQ(pdev, vf_qid).hc_sb_info.hc_index_value;
1990 if ((pdev->params.int_coalesing_mode == LM_INT_COAL_PERIODIC_SYNC)/* && pdev->params.int_coalesing_mode_disabled_by_ndis*/) {
1991 mess->txq.hc_rate = (u16_t)pdev->params.int_per_sec_tx[HC_PARAMS_ETH_INDEX]; /* desired interrupts per sec. *//* valid iff VFPF_QUEUE_FLG_HC */
1992 mess->txq.flags |= VFPF_QUEUE_FLG_HC;
1993 }
1994 }
1995 }
1996 else
1997 {
1998 DbgBreak();
1999 lm_vf_pf_channel_release_message(pdev,pf_mess);
2000 return LM_STATUS_FAILURE;
2001 }
2002 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2003 if (lm_status != LM_STATUS_SUCCESS) {
2004 lm_vf_pf_channel_release_message(pdev,pf_mess);
2005 }
2006
2007 DbgMessage(pdev, WARNvf, "lm_vf_pf_setup_q lm_status = %d\n", lm_status);
2008 return lm_status;
2009 }
2010
2011
2012
lm_vf_pf_tear_q_down(struct _lm_device_t * pdev,u8 vf_qid)2013 lm_status_t lm_vf_pf_tear_q_down(struct _lm_device_t * pdev, u8 vf_qid)
2014 {
2015 lm_status_t lm_status = LM_STATUS_SUCCESS;
2016 lm_vf_pf_message_t * pf_mess = NULL;
2017
2018 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)
2019 && (vf_qid < LM_SB_CNT(pdev))));
2020
2021 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_TEARDOWN_Q);
2022 if (!pf_mess) {
2023 lm_status = LM_STATUS_RESOURCE;
2024 DbgBreak();
2025 return lm_status;
2026 }
2027 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2028 {
2029 struct vf_pf_msg_q_op * mess = NULL;
2030 mess = (struct vf_pf_msg_q_op*)pf_mess->message_virt_addr;
2031 mess->vf_qid = vf_qid;
2032 }
2033 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2034 {
2035 struct vfpf_q_op_tlv * mess = NULL;
2036 mess = (struct vfpf_q_op_tlv*)pf_mess->message_virt_addr;
2037 mess->vf_qid = vf_qid;
2038 }
2039 else
2040 {
2041 DbgBreak();
2042 lm_vf_pf_channel_release_message(pdev,pf_mess);
2043 return LM_STATUS_FAILURE;
2044 }
2045 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2046 if (lm_status != LM_STATUS_SUCCESS) {
2047 lm_vf_pf_channel_release_message(pdev,pf_mess);
2048 }
2049
2050 return lm_status;
2051 }
2052
lm_vf_pf_set_q_filters(struct _lm_device_t * pdev,u8 vf_qid,void * cookie,q_filter_type filter_type,u8_t * pbuf,u32_t buf_len,u16_t vlan_tag,u8_t set_mac)2053 lm_status_t lm_vf_pf_set_q_filters(struct _lm_device_t * pdev, u8 vf_qid, void * cookie, q_filter_type filter_type, u8_t * pbuf, u32_t buf_len,
2054 u16_t vlan_tag, u8_t set_mac)
2055 {
2056 lm_status_t lm_status = LM_STATUS_SUCCESS;
2057 lm_vf_pf_message_t * pf_mess = NULL;
2058 u8_t num_entries, idx_entries;
2059 u8_t is_clear;
2060 lm_rx_mask_t * rx_mask;
2061 u8_t send_it = FALSE;
2062
2063 DbgMessage(pdev, WARNvf, "lm_vf_pf_set_q_filters\n");
2064
2065 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && (vf_qid < LM_SB_CNT(pdev)) && pdev->pf_vf_acquiring_resp));
2066
2067 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_SET_Q_FILTERS);
2068 if (!pf_mess) {
2069 lm_status = LM_STATUS_RESOURCE;
2070 DbgBreak();
2071 return lm_status;
2072 }
2073 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2074 {
2075 struct vf_pf_msg_set_q_filters * mess = NULL;
2076 struct pf_vf_msg_acquire_resp * resp = NULL;
2077 mess = (struct vf_pf_msg_set_q_filters*)pf_mess->message_virt_addr;
2078 resp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
2079 mess->vf_qid = vf_qid;
2080 pf_mess->cookie = cookie;
2081 is_clear = ((pbuf == NULL) || (buf_len == 0));
2082
2083 switch (filter_type) {
2084 case Q_FILTER_MAC:
2085 num_entries = resp->resc.num_mac_filters;
2086 is_clear = !set_mac;
2087 if (!is_clear) {
2088 num_entries = min((u32_t)num_entries, buf_len/ETHERNET_ADDRESS_SIZE);
2089 }
2090 mess->n_mac_vlan_filters = num_entries;
2091 for (idx_entries = 0; idx_entries < num_entries; idx_entries++) {
2092 mess->filters[idx_entries].flags = VFPF_Q_FILTER_DEST_MAC_PRESENT;
2093 if (is_clear) {
2094 mess->filters[idx_entries].flags &= ~VFPF_Q_FILTER_SET_MAC;
2095 } else {
2096 mess->filters[idx_entries].flags |= VFPF_Q_FILTER_SET_MAC;
2097 }
2098 mm_memcpy(mess->filters[idx_entries].dest_mac, pbuf + idx_entries*ETHERNET_ADDRESS_SIZE, ETHERNET_ADDRESS_SIZE);
2099 if (vlan_tag != LM_SET_CAM_NO_VLAN_FILTER) {
2100 mess->filters[idx_entries].vlan_tag = vlan_tag;
2101 mess->filters[idx_entries].flags |= VFPF_Q_FILTER_VLAN_TAG_PRESENT;
2102 }
2103 }
2104 if (mess->n_mac_vlan_filters) {
2105 mess->flags = VFPF_SET_Q_FILTERS_MAC_VLAN_CHANGED;
2106 }
2107 break;
2108 case Q_FILTER_VLAN:
2109 DbgMessage(pdev, FATAL, "VLAN filter is not supported yet\n");
2110 DbgBreak();
2111 break;
2112 case Q_FILTER_MC:
2113 num_entries = resp->resc.num_mc_filters;
2114 if (!is_clear) {
2115 num_entries = min((u32_t)num_entries, buf_len/ETHERNET_ADDRESS_SIZE);
2116 }
2117 DbgMessage(pdev, FATAL, "Q_FILTER_MC: %d entries\n", num_entries);
2118 mess->n_multicast = num_entries;
2119 for (idx_entries = 0; idx_entries < num_entries; idx_entries++) {
2120 if (is_clear) {
2121 mm_mem_zero(&mess->multicast[idx_entries][0], ETHERNET_ADDRESS_SIZE);
2122 } else {
2123 mm_memcpy(&mess->multicast[idx_entries][0], pbuf + idx_entries*ETHERNET_ADDRESS_SIZE, ETHERNET_ADDRESS_SIZE);
2124 }
2125 }
2126 if (mess->n_multicast) {
2127 mess->flags = VFPF_SET_Q_FILTERS_MULTICAST_CHANGED;
2128 }
2129 break;
2130 case Q_FILTER_RX_MASK:
2131 DbgBreakIf(is_clear || (buf_len != sizeof(lm_rx_mask_t)));
2132 mess->rx_mask = 0;
2133 rx_mask = (lm_rx_mask_t*)pbuf;
2134 if (GET_FLAGS(*rx_mask, LM_RX_MASK_PROMISCUOUS_MODE)) {
2135 mess->rx_mask |= (VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST | VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST |
2136 VFPF_RX_MASK_ACCEPT_ALL_MULTICAST | VFPF_RX_MASK_ACCEPT_ALL_UNICAST | VFPF_RX_MASK_ACCEPT_BROADCAST);
2137 }
2138 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_UNICAST)) {
2139 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
2140 }
2141 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_MULTICAST)) {
2142 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
2143 }
2144 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_ALL_MULTICAST)) {
2145 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
2146 }
2147 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_BROADCAST)) {
2148 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
2149 }
2150 mess->flags = VFPF_SET_Q_FILTERS_RX_MASK_CHANGED;
2151
2152 DbgMessage(pdev, FATAL, "Q_FILTER_RX_MASK: mess->rx_mask=%x mess->flags=%x\n", mess->rx_mask, mess->flags);
2153 break;
2154 default:
2155 break;
2156 }
2157 if (mess->flags)
2158 {
2159 send_it = TRUE;
2160 }
2161 }
2162 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2163 {
2164 struct vfpf_set_q_filters_tlv * mess = NULL;
2165 struct pfvf_acquire_resp_tlv * resp = NULL;
2166 mess = (struct vfpf_set_q_filters_tlv*)pf_mess->message_virt_addr;
2167 resp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;
2168 mess->vf_qid = vf_qid;
2169 pf_mess->cookie = cookie;
2170 is_clear = ((pbuf == NULL) || (buf_len == 0));
2171
2172 switch (filter_type) {
2173 case Q_FILTER_MAC:
2174 num_entries = resp->resc.num_mac_filters;
2175 is_clear = !set_mac;
2176 if (!is_clear) {
2177 num_entries = min((u32_t)num_entries, buf_len/ETHERNET_ADDRESS_SIZE);
2178 }
2179 mess->n_mac_vlan_filters = num_entries;
2180 for (idx_entries = 0; idx_entries < num_entries; idx_entries++) {
2181 mess->filters[idx_entries].flags = VFPF_Q_FILTER_DEST_MAC_PRESENT;
2182 if (is_clear) {
2183 mess->filters[idx_entries].flags &= ~VFPF_Q_FILTER_SET_MAC;
2184 } else {
2185 mess->filters[idx_entries].flags |= VFPF_Q_FILTER_SET_MAC;
2186 }
2187 mm_memcpy(mess->filters[idx_entries].mac, pbuf + idx_entries*ETHERNET_ADDRESS_SIZE, ETHERNET_ADDRESS_SIZE);
2188 if (vlan_tag != LM_SET_CAM_NO_VLAN_FILTER) {
2189 mess->filters[idx_entries].vlan_tag = vlan_tag;
2190 mess->filters[idx_entries].flags |= VFPF_Q_FILTER_VLAN_TAG_PRESENT;
2191 }
2192 }
2193 if (mess->n_mac_vlan_filters) {
2194 mess->flags = VFPF_SET_Q_FILTERS_MAC_VLAN_CHANGED;
2195 }
2196 break;
2197 case Q_FILTER_VLAN:
2198 DbgMessage(pdev,FATAL,"VLAN filter is not supported yet\n");
2199 DbgBreak();
2200 break;
2201 case Q_FILTER_MC:
2202 num_entries = resp->resc.num_mc_filters;
2203 if (!is_clear) {
2204 num_entries = min((u32_t)num_entries, buf_len/ETHERNET_ADDRESS_SIZE);
2205 }
2206 DbgMessage(pdev, FATAL, "Q_FILTER_MC: %d entries\n", num_entries);
2207 mess->n_multicast = num_entries;
2208 for (idx_entries = 0; idx_entries < num_entries; idx_entries++) {
2209 if (is_clear) {
2210 mm_mem_zero(&mess->multicast[idx_entries][0], ETHERNET_ADDRESS_SIZE);
2211 } else {
2212 mm_memcpy(&mess->multicast[idx_entries][0], pbuf + idx_entries*ETHERNET_ADDRESS_SIZE, ETHERNET_ADDRESS_SIZE);
2213 }
2214 }
2215 if (mess->n_multicast) {
2216 mess->flags = VFPF_SET_Q_FILTERS_MULTICAST_CHANGED;
2217 }
2218 break;
2219 case Q_FILTER_RX_MASK:
2220 DbgBreakIf(is_clear || (buf_len != sizeof(lm_rx_mask_t)));
2221 mess->rx_mask = 0;
2222 rx_mask = (lm_rx_mask_t*)pbuf;
2223 if (GET_FLAGS(*rx_mask, LM_RX_MASK_PROMISCUOUS_MODE)) {
2224 mess->rx_mask |= (VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST | VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST |
2225 VFPF_RX_MASK_ACCEPT_ALL_MULTICAST | VFPF_RX_MASK_ACCEPT_ALL_UNICAST | VFPF_RX_MASK_ACCEPT_BROADCAST);
2226 }
2227 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_UNICAST)) {
2228 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
2229 }
2230 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_MULTICAST)) {
2231 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
2232 }
2233 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_ALL_MULTICAST)) {
2234 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
2235 }
2236 if (GET_FLAGS(*rx_mask, LM_RX_MASK_ACCEPT_BROADCAST)) {
2237 mess->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
2238 }
2239 mess->flags = VFPF_SET_Q_FILTERS_RX_MASK_CHANGED;
2240
2241 DbgMessage(pdev, FATAL, "Q_FILTER_RX_MASK: mess->rx_mask=%x mess->flags=%x\n", mess->rx_mask, mess->flags);
2242 break;
2243 default:
2244 break;
2245 }
2246 if (mess->flags)
2247 {
2248 send_it = TRUE;
2249 }
2250 }
2251 else
2252 {
2253 DbgBreak();
2254 lm_vf_pf_channel_release_message(pdev,pf_mess);
2255 return LM_STATUS_FAILURE;
2256 }
2257
2258 if (send_it) {
2259 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2260 if (lm_status != LM_STATUS_SUCCESS) {
2261 lm_vf_pf_channel_release_message(pdev,pf_mess);
2262 }
2263 } else {
2264 DbgMessage(pdev, FATAL, "lm_vf_pf_set_q_filters: flag is not set. Use bypass\n");
2265 *pf_mess->done = SW_PFVF_STATUS_SUCCESS;
2266 DbgBreakIf(filter_type != Q_FILTER_MC);
2267 }
2268
2269 return lm_status;
2270 }
2271
lm_vf_pf_set_q_filters_list(struct _lm_device_t * pdev,u8 vf_qid,void * cookie,q_filter_type filter_type,d_list_t * pbuf,u16_t vlan_tag,u8_t set_mac)2272 lm_status_t lm_vf_pf_set_q_filters_list(struct _lm_device_t * pdev, u8 vf_qid, void * cookie, q_filter_type filter_type, d_list_t * pbuf,
2273 u16_t vlan_tag, u8_t set_mac)
2274
2275 {
2276 DbgMessage(NULL, FATAL, "lm_vf_pf_set_q_filters_list is not used in channel VF\n");
2277 DbgBreak();
2278 return LM_STATUS_FAILURE;
2279 }
2280
lm_vf_pf_update_rss(struct _lm_device_t * pdev,void * cookie,u32_t rss_flags,u8_t rss_result_mask,u8_t * ind_table,u32_t * rss_key)2281 lm_status_t lm_vf_pf_update_rss(struct _lm_device_t *pdev, void * cookie, u32_t rss_flags, u8_t rss_result_mask, u8_t * ind_table, u32_t * rss_key)
2282 {
2283 lm_status_t lm_status = LM_STATUS_SUCCESS;
2284 lm_vf_pf_message_t * pf_mess = NULL;
2285 u8_t ind_table_idx;
2286
2287 DbgMessage(pdev, WARNvf, "lm_vf_pf_update_rss\n");
2288
2289 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && pdev->pf_vf_acquiring_resp));
2290
2291 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_UPDATE_RSS);
2292 if (!pf_mess) {
2293 lm_status = LM_STATUS_RESOURCE;
2294 DbgBreak();
2295 return lm_status;
2296 }
2297 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2298 {
2299 struct vf_pf_msg_rss * mess = NULL;
2300 mess = (struct vf_pf_msg_rss*)pf_mess->message_virt_addr;
2301 pf_mess->cookie = cookie;
2302 mess->rss_flags = rss_flags;
2303 mess->rss_result_mask = rss_result_mask;
2304 mm_memcpy(mess->ind_table, ind_table, T_ETH_INDIRECTION_TABLE_SIZE);
2305 mess->ind_table_size = T_ETH_INDIRECTION_TABLE_SIZE;
2306 mm_memcpy(mess->rss_key, rss_key, sizeof(u32_t)*T_ETH_RSS_KEY);
2307 mess->rss_key_size = T_ETH_RSS_KEY;
2308 }
2309 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2310 {
2311 struct vfpf_rss_tlv * mess = NULL;
2312 mess = (struct vfpf_rss_tlv*)pf_mess->message_virt_addr;
2313 pf_mess->cookie = cookie;
2314 mess->rss_flags = rss_flags;
2315 mess->rss_result_mask = rss_result_mask;
2316 for (ind_table_idx = 0; ind_table_idx < T_ETH_INDIRECTION_TABLE_SIZE; ind_table_idx++) {
2317 mess->ind_table[ind_table_idx] = IGU_VF_NDSB(pdev,ind_table[ind_table_idx]);
2318 }
2319 mess->ind_table_size = T_ETH_INDIRECTION_TABLE_SIZE;
2320 mm_memcpy(mess->rss_key, rss_key, sizeof(u32_t)*T_ETH_RSS_KEY);
2321 mess->rss_key_size = T_ETH_RSS_KEY;
2322 }
2323 else
2324 {
2325 DbgBreak();
2326 lm_vf_pf_channel_release_message(pdev,pf_mess);
2327 return LM_STATUS_FAILURE;
2328 }
2329
2330 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2331 if (lm_status != LM_STATUS_SUCCESS) {
2332 lm_vf_pf_channel_release_message(pdev,pf_mess);
2333 }
2334
2335 return lm_status;
2336 }
2337
lm_vf_pf_update_rsc(struct _lm_device_t * pdev)2338 lm_status_t lm_vf_pf_update_rsc(struct _lm_device_t *pdev)
2339 {
2340 lm_status_t lm_status = LM_STATUS_SUCCESS;
2341 lm_vf_pf_message_t * pf_mess = NULL;
2342 u8_t rss_idx = 0;
2343
2344 DbgMessage(pdev, WARNvf, "lm_vf_pf_update_rsc\n");
2345
2346 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && pdev->pf_vf_acquiring_resp));
2347
2348 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_UPDATE_RSC);
2349 if (!pf_mess) {
2350 lm_status = LM_STATUS_RESOURCE;
2351 DbgBreak();
2352 return lm_status;
2353 }
2354 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2355 {
2356 struct vf_pf_msg_rsc * mess = (struct vf_pf_msg_rsc *)pf_mess->message_virt_addr;
2357 mess->rsc_ipv4_state = lm_tpa_ramrod_update_ipvx(pdev, 0, TPA_IPV4_ENABLED);
2358 mess->rsc_ipv6_state = lm_tpa_ramrod_update_ipvx(pdev, 0, TPA_IPV6_ENABLED);
2359 }
2360 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2361 {
2362 struct vfpf_tpa_tlv * mess = (struct vfpf_tpa_tlv*)pf_mess->message_virt_addr;
2363
2364 LM_FOREACH_RSS_IDX(pdev, rss_idx)
2365 {
2366 mess->tpa_client_info.sge_addr[rss_idx] = LM_TPA_CHAIN_BD(pdev, rss_idx).bd_chain_phy.as_u64;
2367 }
2368
2369 mess->tpa_client_info.complete_on_both_clients = 1;
2370 mess->tpa_client_info.max_tpa_queues = LM_TPA_MAX_AGGS;
2371 mess->tpa_client_info.max_sges_for_packet = DIV_ROUND_UP_BITS((u16_t)pdev->params.l2_cli_con_params[0].mtu, LM_TPA_PAGE_BITS);
2372 mess->tpa_client_info.sge_buff_size = LM_TPA_PAGE_SIZE;
2373 mess->tpa_client_info.max_agg_size = LM_TPA_MAX_AGG_SIZE * LM_TPA_PAGE_SIZE;
2374 mess->tpa_client_info.sge_pause_thr_low = LM_TPA_SGE_PAUSE_THR_LOW;
2375 mess->tpa_client_info.sge_pause_thr_high = LM_TPA_SGE_PAUSE_THR_HIGH;
2376 mess->tpa_client_info.complete_on_both_clients = TRUE;
2377 mess->tpa_client_info.dont_verify_thr = 0;
2378 mess->tpa_client_info.tpa_mode = TPA_LRO;
2379 mess->tpa_client_info.update_ipv4 = lm_tpa_ramrod_update_ipvx(pdev, 0, TPA_IPV4_ENABLED);
2380 mess->tpa_client_info.update_ipv6 = lm_tpa_ramrod_update_ipvx(pdev, 0, TPA_IPV6_ENABLED);
2381
2382 }
2383 else
2384 {
2385 DbgBreak();
2386 lm_vf_pf_channel_release_message(pdev,pf_mess);
2387 return LM_STATUS_FAILURE;
2388 }
2389
2390 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2391 if (lm_status != LM_STATUS_SUCCESS) {
2392 lm_vf_pf_channel_release_message(pdev,pf_mess);
2393 }
2394
2395 return lm_status;
2396 }
2397
lm_vf_pf_close_vf(struct _lm_device_t * pdev)2398 lm_status_t lm_vf_pf_close_vf(struct _lm_device_t * pdev)
2399 {
2400 lm_status_t lm_status = LM_STATUS_SUCCESS;
2401 lm_vf_pf_message_t * pf_mess = NULL;
2402
2403 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)));
2404 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_CLOSE_VF);
2405 if (!pf_mess) {
2406 lm_status = LM_STATUS_RESOURCE;
2407 DbgBreak();
2408 return lm_status;
2409 }
2410 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2411 {
2412 struct vf_pf_msg_close_vf * mess = NULL;
2413 mess = (struct vf_pf_msg_close_vf*)pf_mess->message_virt_addr;
2414 mess->vf_id = ABS_VFID(pdev);
2415 }
2416 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2417 {
2418 struct vfpf_close_tlv * mess = NULL;
2419 mess = (struct vfpf_close_tlv*)pf_mess->message_virt_addr;
2420 mess->vf_id = ABS_VFID(pdev);
2421 }
2422 else
2423 {
2424 DbgBreak();
2425 lm_vf_pf_channel_release_message(pdev,pf_mess);
2426 return LM_STATUS_FAILURE;
2427 }
2428
2429 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2430 if (lm_status != LM_STATUS_SUCCESS) {
2431 lm_vf_pf_channel_release_message(pdev,pf_mess);
2432 }
2433
2434 return lm_status;
2435
2436 }
2437
lm_vf_pf_release_vf(struct _lm_device_t * pdev)2438 lm_status_t lm_vf_pf_release_vf(struct _lm_device_t * pdev)
2439 {
2440 lm_status_t lm_status = LM_STATUS_SUCCESS;
2441 lm_vf_pf_message_t * pf_mess = NULL;
2442 void* vresp = NULL;
2443
2444 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev)));
2445
2446 pf_mess = lm_vf_pf_channel_get_message_to_send(pdev, PFVF_OP_RELEASE_VF);
2447 if (!pf_mess) {
2448 lm_status = LM_STATUS_RESOURCE;
2449 DbgBreak();
2450 return lm_status;
2451 }
2452 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2453 {
2454 struct vf_pf_msg_release_vf * mess = NULL;
2455 mess = (struct vf_pf_msg_release_vf*)pf_mess->message_virt_addr;
2456 mess->vf_id = ABS_VFID(pdev); /* ME register value */
2457 vresp = (u8_t*)mess + mess->hdr.resp_msg_offset;
2458 }
2459 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2460 {
2461 struct vfpf_release_tlv * mess = NULL;
2462 mess = (struct vfpf_release_tlv*)pf_mess->message_virt_addr;
2463 mess->vf_id = ABS_VFID(pdev);
2464 }
2465 else
2466 {
2467 DbgBreak();
2468 lm_vf_pf_channel_release_message(pdev,pf_mess);
2469 return LM_STATUS_FAILURE;
2470 }
2471 pf_mess->do_not_arm_trigger = TRUE;
2472 lm_status = lm_vf_pf_channel_send(pdev,pf_mess);
2473 if (lm_status != LM_STATUS_SUCCESS) {
2474 lm_vf_pf_channel_release_message(pdev,pf_mess);
2475 return lm_status;
2476 }
2477 lm_status = lm_vf_pf_channel_wait_response(pdev, pf_mess);
2478 // FIXME TODO
2479 if (lm_status == LM_STATUS_SUCCESS) {
2480 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2481 {
2482 struct pf_vf_msg_resp * resp = NULL;
2483 resp = (struct pf_vf_msg_resp *)vresp;
2484 if (resp->hdr.opcode != PFVF_OP_RELEASE_VF) {
2485 lm_status = LM_STATUS_FAILURE;
2486 } else {
2487 switch (resp->hdr.status) {
2488 case SW_PFVF_STATUS_SUCCESS:
2489 lm_status = LM_STATUS_SUCCESS;
2490 break;
2491 case SW_PFVF_STATUS_FAILURE:
2492 case SW_PFVF_STATUS_MISMATCH_PF_VF_VERSION:
2493 case SW_PFVF_STATUS_MISMATCH_FW_HSI:
2494 case SW_PFVF_STATUS_NO_RESOURCE:
2495 DbgMessage(pdev, FATAL, "VF_PF Channel: Status %d is not supported yet\n", resp->hdr.status);
2496 lm_status = LM_STATUS_FAILURE;
2497 break;
2498 default:
2499 DbgMessage(pdev, FATAL, "VF_PF Channel: Unknown status %d\n", resp->hdr.status);
2500 lm_status = LM_STATUS_FAILURE;
2501 break;
2502 }
2503 }
2504 }
2505 }
2506
2507
2508 lm_vf_pf_channel_release_message(pdev, pf_mess);
2509 return lm_status;
2510 }
2511
lm_vf_fl_reset_set_inprogress(struct _lm_device_t * pdev)2512 void lm_vf_fl_reset_set_inprogress(struct _lm_device_t * pdev)
2513 {
2514 DbgMessage(pdev, WARN, "Set FLR flag is not implemented yet\n");
2515 }
2516
lm_vf_fl_reset_clear_inprogress(struct _lm_device_t * pdev)2517 void lm_vf_fl_reset_clear_inprogress(struct _lm_device_t *pdev)
2518 {
2519 DbgMessage(pdev, WARN, "Clear FLR flag is not implemented yet\n");
2520 }
2521
lm_vf_fl_reset_is_inprogress(struct _lm_device_t * pdev)2522 u8_t lm_vf_fl_reset_is_inprogress(struct _lm_device_t *pdev)
2523 {
2524 DbgMessage(pdev, WARN, "Get FLR flag is not implemented yet\n");
2525 return FALSE;
2526 }
2527
lm_vf_get_vf_id(struct _lm_device_t * pdev)2528 lm_status_t lm_vf_get_vf_id(struct _lm_device_t * pdev)
2529 {
2530 pdev->params.debug_me_register = _vf_reg_rd(pdev,VF_BAR0_DB_OFFSET);;
2531
2532 DbgMessage(pdev, WARN, "vf ME-REG value: 0x%x\n", pdev->params.debug_me_register);
2533
2534 if (!(pdev->params.debug_me_register & ME_REG_VF_VALID)) {
2535 DbgBreakIf(!(pdev->params.debug_me_register & ME_REG_VF_VALID));
2536 return LM_STATUS_FAILURE;
2537 }
2538 pdev->params.vf_num_in_path = (pdev->params.debug_me_register & ME_REG_VF_NUM_MASK) >> ME_REG_VF_NUM_SHIFT;
2539 DbgMessage(pdev, WARN, "vf_num_in_path=%d\n", pdev->params.vf_num_in_path);
2540 return LM_STATUS_SUCCESS;
2541 }
2542
lm_vf_setup_alloc_resc(struct _lm_device_t * pdev,u8_t b_is_alloc)2543 lm_status_t lm_vf_setup_alloc_resc(struct _lm_device_t *pdev, u8_t b_is_alloc )
2544 {
2545 lm_variables_t* vars = NULL ;
2546 u32_t mem_size = 0 ;
2547 //u32_t alloc_size = 0 ;
2548 u8_t mm_cli_idx = 0 ;
2549 u8_t sb_id = 0 ;
2550 lm_address_t sb_phy_address;
2551 void * p_sb;
2552 DbgBreakIf(!(pdev && IS_CHANNEL_VFDEV(pdev) && pdev->pf_vf_acquiring_resp));
2553 //DbgBreakIf(!(presp && (sb_id < presp->pfdev_info.indices_per_sb)));
2554
2555 if CHK_NULL( pdev )
2556 {
2557 return LM_STATUS_INVALID_PARAMETER ;
2558 }
2559
2560 DbgMessage(pdev, FATAL, "### VF lm_common_setup_alloc_resc b_is_alloc=%s\n", b_is_alloc ? "TRUE" : "FALSE" );
2561
2562 vars = &(pdev->vars) ;
2563
2564 // Status blocks allocation. We allocate mem both for the default and non-default status blocks
2565 // there is 1 def sb and 16 non-def sb per port.
2566 // non-default sb: index 0-15, default sb: index 16.
2567 if (IS_CHANNEL_VFDEV(pdev)) {
2568 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2569 {
2570 struct pf_vf_msg_acquire_resp * presp;
2571 presp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
2572 mem_size = (sizeof(u16_t) * (presp->pfdev_info.indices_per_sb + 2) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
2573 }
2574 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2575 {
2576 struct pfvf_acquire_resp_tlv * presp;
2577 presp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;
2578 mem_size = (sizeof(u16_t) * (presp->pfdev_info.indices_per_sb + 2) + CACHE_LINE_SIZE_MASK) & ~CACHE_LINE_SIZE_MASK;
2579 }
2580 else
2581 {
2582 DbgBreak();
2583 return LM_STATUS_FAILURE;
2584 }
2585 } else {
2586 mem_size = E2_STATUS_BLOCK_BUFFER_SIZE;
2587 }
2588
2589 mm_cli_idx = LM_RESOURCE_COMMON;//!!DP mm_cli_idx_to_um_idx(LM_CLI_IDX_MAX);
2590
2591 LM_FOREACH_SB_ID(pdev, sb_id)
2592 {
2593 if( b_is_alloc )
2594 {
2595 if (IS_CHANNEL_VFDEV(pdev)) {
2596 pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.vf_sb = p_sb = mm_alloc_phys_mem(pdev, mem_size, &sb_phy_address, 0, mm_cli_idx);
2597 pdev->vars.status_blocks_arr[sb_id].hc_status_block_data.vf_sb_phy_address.as_u32.low = sb_phy_address.as_u32.low;
2598 pdev->vars.status_blocks_arr[sb_id].hc_status_block_data.vf_sb_phy_address.as_u32.high = sb_phy_address.as_u32.high;
2599 } else {
2600 pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.e2_sb = p_sb = mm_alloc_phys_mem(pdev, mem_size, &sb_phy_address, 0, mm_cli_idx);
2601 pdev->vars.status_blocks_arr[sb_id].hc_status_block_data.e2_sb_data.common.host_sb_addr.lo = sb_phy_address.as_u32.low;
2602 pdev->vars.status_blocks_arr[sb_id].hc_status_block_data.e2_sb_data.common.host_sb_addr.hi = sb_phy_address.as_u32.high;
2603 }
2604 }
2605 else
2606 {
2607 if (IS_CHANNEL_VFDEV(pdev)) {
2608 p_sb = (void *)pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.vf_sb;
2609 } else {
2610 p_sb = (void *)pdev->vars.status_blocks_arr[sb_id].host_hc_status_block.e2_sb;
2611 }
2612 }
2613
2614 if CHK_NULL(p_sb)
2615 {
2616 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
2617 return LM_STATUS_RESOURCE ;
2618 }
2619 mm_mem_zero(p_sb, mem_size);
2620 }
2621 lm_reset_sb_ack_values(pdev);
2622
2623 mm_mem_zero(pdev->debug_info.ack_dis, sizeof(pdev->debug_info.ack_dis));
2624 mm_mem_zero(pdev->debug_info.ack_en, sizeof(pdev->debug_info.ack_en));
2625 mm_mem_zero(pdev->debug_info.rx_only_int, sizeof(pdev->debug_info.rx_only_int));
2626 mm_mem_zero(pdev->debug_info.tx_only_int, sizeof(pdev->debug_info.tx_only_int));
2627 mm_mem_zero(pdev->debug_info.both_int, sizeof(pdev->debug_info.both_int));
2628 mm_mem_zero(pdev->debug_info.empty_int, sizeof(pdev->debug_info.empty_int));
2629 mm_mem_zero(pdev->debug_info.false_int, sizeof(pdev->debug_info.false_int));
2630
2631 #if 0
2632 //CAM
2633 alloc_size = sizeof(struct mac_configuration_cmd) ;
2634
2635 if( b_is_alloc )
2636 {
2637 pdev->params.mac_config[LM_CLI_IDX_NDIS] = mm_alloc_phys_mem(pdev,
2638 alloc_size,
2639 &pdev->params.mac_config_phy[LM_CLI_IDX_NDIS],
2640 0,
2641 mm_cli_idx);
2642 }
2643 if CHK_NULL( pdev->params.mac_config[LM_CLI_IDX_NDIS] )
2644 {
2645 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
2646 return LM_STATUS_RESOURCE ;
2647 }
2648
2649 mm_mem_zero((void *) (pdev->params.mac_config[LM_CLI_IDX_NDIS]), alloc_size );
2650
2651 if( b_is_alloc )
2652 {
2653 pdev->params.mcast_config = mm_alloc_phys_mem(pdev,
2654 alloc_size,
2655 &pdev->params.mcast_config_phy,
2656 0,
2657 mm_cli_idx);
2658 }
2659
2660 if CHK_NULL( pdev->params.mcast_config )
2661 {
2662 DbgBreakIf(DBG_BREAK_ON(MEMORY_ALLOCATION_FAILURE));
2663 return LM_STATUS_RESOURCE ;
2664 }
2665 mm_mem_zero((void *) (pdev->params.mcast_config), alloc_size);
2666 #endif
2667 return LM_STATUS_SUCCESS;
2668 }
2669
2670
lm_vf_chip_init(struct _lm_device_t * pdev)2671 lm_status_t lm_vf_chip_init(struct _lm_device_t *pdev)
2672 {
2673 lm_status_t lm_status;
2674
2675 DbgMessage(pdev, WARNvf, "lm_vf_chip_init\n");
2676
2677 lm_status = lm_vf_pf_init_vf(pdev);
2678 if (lm_status == LM_STATUS_SUCCESS) {
2679 lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
2680 #if 0
2681 "ACK_enable" (even "ACK_disable/ACK_enable") does not help when IGU block is stuck from previous VM shutdown/reboot (not ACKed sunbitted interrupt interrupt).
2682 Windows8 PF executes clear IGU block on VM initialization. Must be checked for Linux PF.
2683 if (lm_status == LM_STATUS_SUCCESS)
2684 {
2685 u8_t sb_id;
2686 u8_t igu_sb_cnt;
2687
2688 igu_sb_cnt = LM_IGU_SB_CNT(pdev);
2689 for (sb_id = 0; sb_id < igu_sb_cnt; sb_id++)
2690 {
2691 /* Give Consumer updates with value '0' */
2692 lm_int_igu_ack_sb(pdev, IGU_VF_NDSB(pdev,sb_id), IGU_SEG_ACCESS_NORM, 0, IGU_INT_DISABLE, 0);
2693 lm_int_igu_ack_sb(pdev, IGU_VF_NDSB(pdev,sb_id), IGU_SEG_ACCESS_NORM, 0, IGU_INT_ENABLE, 1);
2694 }
2695 }
2696 #endif
2697 }
2698
2699
2700 /* Temporary FIXME TODO: is this the right location??? */
2701 pdev->vars.cable_is_attached = TRUE;
2702 pdev->vars.link_status = LM_STATUS_LINK_ACTIVE;
2703 if (IS_HW_CHANNEL_VIRT_MODE(pdev) && pdev->vars.pf_link_speed)
2704 {
2705 switch(pdev->vars.pf_link_speed)
2706 {
2707 case 10:
2708 SET_MEDIUM_SPEED(pdev->vars.medium, LM_MEDIUM_SPEED_10MBPS);
2709 break;
2710
2711 case 100:
2712 SET_MEDIUM_SPEED(pdev->vars.medium, LM_MEDIUM_SPEED_100MBPS);
2713 break;
2714
2715 case 1000:
2716 SET_MEDIUM_SPEED(pdev->vars.medium, LM_MEDIUM_SPEED_1000MBPS);
2717 break;
2718
2719 case 2500:
2720 SET_MEDIUM_SPEED(pdev->vars.medium, LM_MEDIUM_SPEED_2500MBPS);
2721 break;
2722
2723 case 20000:
2724 SET_MEDIUM_SPEED(pdev->vars.medium, LM_MEDIUM_SPEED_20GBPS);
2725 break;
2726
2727 case 10000:
2728 default:
2729 SET_MEDIUM_SPEED(pdev->vars.medium, LM_MEDIUM_SPEED_10GBPS);
2730 break;
2731 }
2732 }
2733 else
2734 {
2735 SET_MEDIUM_SPEED(pdev->vars.medium,LM_MEDIUM_SPEED_10GBPS);
2736 }
2737
2738
2739 DbgMessage(pdev, WARNvf, "lm_vf_chip_init lm_status = %d\n", lm_status);
2740 return lm_status;
2741 }
2742
lm_vf_queue_init(struct _lm_device_t * pdev,u8_t cid)2743 lm_status_t lm_vf_queue_init(struct _lm_device_t *pdev, u8_t cid)
2744 {
2745 lm_status_t lm_status;
2746 u8_t validation_flag = 0;
2747 u8_t q_index = LM_SW_CID_TO_SW_QID(pdev,cid);
2748
2749 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
2750 {
2751 struct pf_vf_msg_acquire_resp * presp;
2752 presp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
2753
2754 if (q_index < presp->resc.num_rxqs) {
2755 validation_flag |= RX_Q_VALIDATE;
2756 }
2757
2758 if (q_index < presp->resc.num_txqs) {
2759 validation_flag |= TX_Q_VALIDATE;
2760 }
2761 }
2762 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
2763 {
2764 struct pfvf_acquire_resp_tlv * presp;
2765 presp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;
2766 if (q_index < presp->resc.num_rxqs) {
2767 validation_flag |= RX_Q_VALIDATE;
2768 }
2769
2770 if (q_index < presp->resc.num_txqs) {
2771 validation_flag |= TX_Q_VALIDATE;
2772 }
2773 }
2774 else
2775 {
2776 DbgBreak();
2777 return LM_STATUS_FAILURE;
2778 }
2779
2780 DbgMessage(pdev, WARNvf, "validation_flag = %d\n", validation_flag);
2781
2782 lm_status = lm_vf_pf_setup_q(pdev, q_index, validation_flag);
2783 if (lm_status == LM_STATUS_SUCCESS) {
2784 lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
2785 }
2786 if (lm_status == LM_STATUS_SUCCESS) {
2787 lm_set_con_state(pdev, cid, LM_CON_STATE_OPEN);
2788 }
2789 return lm_status;
2790
2791 }
2792
lm_vf_queue_close(struct _lm_device_t * pdev,u8_t cid)2793 lm_status_t lm_vf_queue_close(struct _lm_device_t *pdev, u8_t cid)
2794 {
2795 lm_status_t lm_status = LM_STATUS_SUCCESS;
2796 u8_t q_index = LM_SW_CID_TO_SW_QID(pdev,cid);
2797
2798 if (lm_reset_is_inprogress(pdev)) {
2799 lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
2800 return LM_STATUS_SUCCESS;
2801 }
2802
2803 if (lm_get_con_state(pdev, cid) == LM_CON_STATE_OPEN) {
2804 lm_status = lm_vf_pf_tear_q_down(pdev, q_index);
2805 if (lm_status == LM_STATUS_SUCCESS) {
2806 lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
2807 } else {
2808 if (lm_status == LM_STATUS_REQUEST_NOT_ACCEPTED) {
2809 lm_status = LM_STATUS_SUCCESS;
2810 }
2811 }
2812 if (lm_status == LM_STATUS_SUCCESS) {
2813 lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
2814 }
2815 }
2816 return lm_status;
2817 }
2818
lm_vf_chip_reset(struct _lm_device_t * pdev,lm_reason_t reason)2819 lm_status_t lm_vf_chip_reset(struct _lm_device_t *pdev, lm_reason_t reason)
2820 {
2821 lm_status_t lm_status = LM_STATUS_SUCCESS;
2822
2823 if (lm_reset_is_inprogress(pdev)) {
2824 return LM_STATUS_SUCCESS;
2825 }
2826
2827 lm_status = lm_vf_pf_close_vf(pdev);
2828 if (lm_status == LM_STATUS_SUCCESS) {
2829 lm_status = lm_vf_pf_wait_no_messages_pending(pdev);
2830 }
2831
2832 return lm_status;
2833 }
2834
lm_vf_is_function_after_flr(struct _lm_device_t * pdev)2835 u8_t lm_vf_is_function_after_flr(struct _lm_device_t * pdev)
2836 {
2837 return FALSE;
2838 }
2839
lm_vf_init_dev_info(struct _lm_device_t * pdev)2840 lm_status_t lm_vf_init_dev_info(struct _lm_device_t *pdev)
2841 {
2842 DbgMessage(pdev, WARN, "lm_vf_init_dev_info>>\n");
2843 // Cleaning after driver unload
2844 pdev->context_info = NULL;
2845 mm_mem_zero((void *) &pdev->cid_recycled_callbacks, sizeof(pdev->cid_recycled_callbacks));
2846 mm_mem_zero((void *) &pdev->toe_info, sizeof(pdev->toe_info));
2847
2848 return LM_STATUS_SUCCESS;
2849 }
2850
2851
lm_vf_recycle_resc_in_pf(struct _lm_device_t * pdev)2852 lm_status_t lm_vf_recycle_resc_in_pf(struct _lm_device_t *pdev)
2853 {
2854 DbgMessage(NULL, WARN, "lm_vf_recycle_resc_in_pf is used only in basic VF\n");
2855 return LM_STATUS_SUCCESS;
2856 }
2857
2858
lm_vf_enable_vf(struct _lm_device_t * pdev)2859 lm_status_t lm_vf_enable_vf(struct _lm_device_t *pdev)
2860 {
2861 DbgMessage(NULL, WARN, "lm_vf_enable_vf is used only in basic VF\n");
2862 return LM_STATUS_SUCCESS;
2863 }
2864
lm_vf_enable_igu_int(struct _lm_device_t * pdev)2865 lm_status_t lm_vf_enable_igu_int(struct _lm_device_t * pdev)
2866 {
2867 return LM_STATUS_SUCCESS;
2868 }
2869
2870
lm_vf_disable_igu_int(struct _lm_device_t * pdev)2871 lm_status_t lm_vf_disable_igu_int(struct _lm_device_t * pdev)
2872 {
2873 /* TODO?? */
2874 return LM_STATUS_SUCCESS;
2875 }
2876
lm_vf_check_hw_back_channel(struct _lm_device_t * pdev)2877 pfvf_bb_event_type lm_vf_check_hw_back_channel(struct _lm_device_t * pdev)
2878 {
2879 struct pf_vf_bulletin_content volatile *bulletin = (struct pf_vf_bulletin_content *)pdev->vars.vf_pf_mess.bulletin_virt_addr;
2880 u32_t attempts;
2881
2882 if (bulletin == NULL)
2883 {
2884 DbgMessage(pdev, FATAL, "PF to VF channel is not active\n");
2885 return PFVF_BB_CHANNEL_IS_NOT_ACTIVE;
2886 }
2887 if (pdev->vars.vf_pf_mess.old_version != bulletin->version)
2888 {
2889 for (attempts = 0; attempts < BULLETIN_ATTEMPTS; attempts++)
2890 {
2891 if ((bulletin->length >= sizeof(bulletin->crc)) && (bulletin->length <= sizeof(union pf_vf_bulletin))
2892 && (bulletin->crc == mm_crc32((u8_t*)bulletin + sizeof(bulletin->crc), bulletin->length - sizeof(bulletin->crc), BULLETIN_CRC_SEED)))
2893 break;
2894 }
2895 if (attempts == BULLETIN_ATTEMPTS)
2896 {
2897 DbgMessage(pdev, FATAL, "PF to VF channel: CRC error\n");
2898 return PFVF_BB_CHANNEL_CRC_ERR;
2899 }
2900 pdev->vars.vf_pf_mess.old_version = bulletin->version;
2901 if (bulletin->valid_bitmap & (1 << VLAN_VALID))
2902 {
2903 DbgMessage(pdev, FATAL, "PF to VF channel: PF provides VLAN\n");
2904 }
2905 if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID))
2906 {
2907 if ((bulletin->mac[0] != pdev->params.mac_addr[0])
2908 || (bulletin->mac[1] != pdev->params.mac_addr[1])
2909 || (bulletin->mac[2] != pdev->params.mac_addr[2])
2910 || (bulletin->mac[3] != pdev->params.mac_addr[3])
2911 || (bulletin->mac[4] != pdev->params.mac_addr[4])
2912 || (bulletin->mac[5] != pdev->params.mac_addr[5]))
2913 {
2914 DbgMessage(pdev, FATAL, "PF to VF channel: PF provides new MAC\n");
2915 return PFVF_BB_VALID_MAC;
2916 }
2917 }
2918 }
2919 return PFVF_BB_NO_UPDATE;
2920 }
lm_pf_enable_vf_igu_int(struct _lm_device_t * pdev,u8_t abs_vf_id)2921 lm_status_t lm_pf_enable_vf_igu_int(struct _lm_device_t * pdev, u8_t abs_vf_id)
2922 {
2923 lm_status_t lm_status = LM_STATUS_SUCCESS;
2924 u32_t val;
2925 u16_t pretend_val;
2926 u8_t num_segs;
2927 u8_t prod_idx;
2928 u8_t sb_id;
2929 u8_t i;
2930 u8_t igu_sb_cnt;
2931
2932 lm_vf_info_t * vf_info = lm_pf_find_vf_info_by_abs_id(pdev, abs_vf_id);
2933
2934
2935 /* Need to use pretend for VF */
2936 pretend_val = ABS_FUNC_ID(pdev) | (1<<3) | (abs_vf_id << 4);
2937 lm_pretend_func(PFDEV(pdev), pretend_val);
2938
2939 REG_WR(PFDEV(pdev), IGU_REG_SB_INT_BEFORE_MASK_LSB, 0);
2940 REG_WR(PFDEV(pdev), IGU_REG_SB_INT_BEFORE_MASK_MSB, 0);
2941 REG_WR(PFDEV(pdev), IGU_REG_SB_MASK_LSB, 0);
2942 REG_WR(PFDEV(pdev), IGU_REG_SB_MASK_MSB, 0);
2943 REG_WR(PFDEV(pdev), IGU_REG_PBA_STATUS_LSB, 0);
2944 REG_WR(PFDEV(pdev), IGU_REG_PBA_STATUS_MSB, 0);
2945
2946
2947 val=REG_RD(PFDEV(pdev), IGU_REG_VF_CONFIGURATION);
2948
2949 SET_FLAGS(val, IGU_VF_CONF_FUNC_EN);
2950 SET_FLAGS(val, IGU_VF_CONF_MSI_MSIX_EN);
2951
2952 if (pdev->params.interrupt_mode == LM_INT_MODE_SIMD) {
2953 SET_FLAGS(val,IGU_VF_CONF_SINGLE_ISR_EN);
2954 }
2955
2956 /* set Parent PF */
2957 val |= ((FUNC_ID(pdev) << IGU_VF_CONF_PARENT_SHIFT) & IGU_VF_CONF_PARENT_MASK);
2958
2959 REG_WR(PFDEV(pdev), IGU_REG_VF_CONFIGURATION, val);
2960
2961 igu_sb_cnt = vf_info->num_allocated_chains; // pdev->hw_info.intr_blk_info.igu_info.vf_igu_info[abs_vf_id].igu_sb_cnt;
2962 num_segs = IGU_NORM_NDSB_NUM_SEGS;
2963 for (sb_id = 0; sb_id < igu_sb_cnt; sb_id++) {
2964 prod_idx = LM_VF_IGU_SB_ID(vf_info,sb_id)*num_segs; /* bc-assumption consecutive pfs, norm-no assumption */
2965 for (i = 0; i < num_segs;i++) {
2966 REG_WR(PFDEV(pdev), IGU_REG_PROD_CONS_MEMORY + (prod_idx + i)*4, 0);
2967 }
2968 SB_RX_INDEX(pdev,LM_VF_IGU_SB_ID(vf_info,sb_id)) = 0;
2969 lm_int_ack_sb_enable(pdev, LM_VF_IGU_SB_ID(vf_info,sb_id));
2970 lm_pf_int_vf_igu_sb_cleanup(pdev, vf_info, sb_id);
2971 }
2972
2973 lm_status = lm_pretend_func(PFDEV(pdev), ABS_FUNC_ID(pdev));
2974 return lm_status;
2975 }
2976
lm_pf_disable_vf_igu_int(struct _lm_device_t * pdev,u8_t abs_vf_id)2977 lm_status_t lm_pf_disable_vf_igu_int(struct _lm_device_t * pdev, u8_t abs_vf_id)
2978 {
2979 lm_status_t lm_status = LM_STATUS_SUCCESS;
2980 u32_t val;
2981 u16_t pretend_val;
2982
2983 /* Need to use pretend for VF */
2984 if (lm_fl_reset_is_inprogress(PFDEV(pdev))) {
2985 DbgMessage(pdev, FATAL, "PF[%d] of VF[%d] is under FLR\n", FUNC_ID(pdev), abs_vf_id);
2986 return LM_STATUS_SUCCESS;
2987 }
2988 pretend_val = ABS_FUNC_ID(pdev) | (1<<3) | (abs_vf_id << 4);
2989 lm_pretend_func(PFDEV(pdev), pretend_val);
2990
2991 val = REG_RD(PFDEV(pdev), IGU_REG_VF_CONFIGURATION);
2992
2993 /* disable both bits, for INTA, MSI and MSI-X. */
2994 RESET_FLAGS(val, (IGU_VF_CONF_MSI_MSIX_EN | IGU_VF_CONF_SINGLE_ISR_EN | IGU_VF_CONF_FUNC_EN | IGU_VF_CONF_PARENT_MASK));
2995
2996 REG_WR(PFDEV(pdev), IGU_REG_VF_CONFIGURATION, val);
2997
2998 lm_status = lm_pretend_func(PFDEV(pdev), ABS_FUNC_ID(pdev));
2999 return lm_status;
3000 }
3001
3002 lm_status_t
lm_pf_enable_vf(struct _lm_device_t * pdev,u8_t abs_vf_id)3003 lm_pf_enable_vf(struct _lm_device_t *pdev, u8_t abs_vf_id)
3004 {
3005 lm_status_t lm_status = LM_STATUS_SUCCESS;
3006 u16_t pretend_val;
3007 u32_t prod_idx;
3008 u8_t igu_sb_id;
3009 u32_t was_err_num;
3010 u32_t was_err_value;
3011 u32_t was_err_reg;
3012 u8_t igu_sb_cnt;
3013
3014 lm_vf_info_t * vf_info = lm_pf_find_vf_info_by_abs_id(pdev, abs_vf_id);
3015
3016 /* Enable the VF in PXP - this will enable read/write from VF bar.
3017 * Need to use Pretend in order to do this. Note: once we do pretend
3018 * all accesses to SPLIT-68 will be done as if-vf...
3019 * Bits. Bits [13:10] - Reserved. Bits [9:4] - VFID. Bits [3] - VF valid. Bits [2:0] - PFID.
3020 */
3021
3022 pretend_val = ABS_FUNC_ID(pdev) | (1<<3) | (abs_vf_id << 4);
3023 lm_status = lm_pretend_func(PFDEV(pdev), pretend_val);
3024 if (lm_status == LM_STATUS_SUCCESS) {
3025 REG_WR(PFDEV(pdev), PBF_REG_DISABLE_VF,0);
3026 REG_WR(PFDEV(pdev), PGLUE_B_REG_INTERNAL_VFID_ENABLE, 1);
3027 lm_pretend_func(PFDEV(pdev), ABS_FUNC_ID(pdev) );
3028 DbgMessage(pdev, FATAL, "vf[%d] is enabled\n", abs_vf_id);
3029
3030 was_err_num = 2 * PATH_ID(pdev) + abs_vf_id / 32;
3031 switch (was_err_num) {
3032 case 0:
3033 was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_31_0_CLR;
3034 break;
3035 case 1:
3036 was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_63_32_CLR;
3037 break;
3038 case 2:
3039 was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_95_64_CLR;
3040 break;
3041 case 3:
3042 was_err_reg = PGLUE_B_REG_WAS_ERROR_VF_127_96_CLR;
3043 break;
3044 default:
3045 was_err_reg = 0;
3046 DbgMessage(pdev, FATAL,"Wrong Path[%d], VF[%d]\n",PATH_ID(pdev),abs_vf_id);
3047 DbgBreak();
3048 }
3049
3050 was_err_value = 1 << (abs_vf_id % 32);
3051 if (was_err_reg) {
3052 REG_WR(PFDEV(pdev), was_err_reg, was_err_value); /* PglueB - Clear the was_error indication of the relevant function*/
3053 }
3054
3055 /* IGU Initializations */
3056 igu_sb_cnt = vf_info->num_allocated_chains;
3057 for (igu_sb_id = 0; igu_sb_id < igu_sb_cnt; igu_sb_id++) {
3058 prod_idx = LM_VF_IGU_SB_ID(vf_info, igu_sb_id);
3059 REG_WR(PFDEV(pdev), IGU_REG_PROD_CONS_MEMORY + prod_idx*4, 0);
3060 DbgMessage(pdev, FATAL, "IGU[%d] is inialized\n", prod_idx);
3061 }
3062 REG_WR(PFDEV(pdev),TSEM_REG_VFPF_ERR_NUM, abs_vf_id);
3063 REG_WR(PFDEV(pdev),USEM_REG_VFPF_ERR_NUM, abs_vf_id);
3064 REG_WR(PFDEV(pdev),CSEM_REG_VFPF_ERR_NUM, abs_vf_id);
3065 REG_WR(PFDEV(pdev),XSEM_REG_VFPF_ERR_NUM, abs_vf_id);
3066 } else {
3067 DbgMessage(pdev, FATAL, "lm_pretend_func(%x) returns %d\n",pretend_val,lm_status);
3068 DbgMessage(pdev, FATAL, "vf[%d] is not enabled\n", abs_vf_id);
3069 DbgBreak();
3070 }
3071
3072 return lm_status;
3073 }
3074
3075 lm_status_t
lm_pf_disable_vf(struct _lm_device_t * pdev,u8_t abs_vf_id)3076 lm_pf_disable_vf(struct _lm_device_t *pdev, u8_t abs_vf_id)
3077 {
3078 lm_status_t lm_status = LM_STATUS_SUCCESS;
3079 u16_t pretend_val;
3080
3081 if (lm_pf_fl_vf_reset_is_inprogress(pdev,abs_vf_id)) {
3082 DbgMessage(pdev, FATAL, "vf disable called on a flred function - not much we can do here... \n");
3083 return LM_STATUS_SUCCESS;
3084 }
3085 pretend_val = ABS_FUNC_ID(pdev) | (1<<3) | (abs_vf_id << 4);
3086 lm_status = lm_pretend_func(PFDEV(pdev), pretend_val);
3087 if (lm_status == LM_STATUS_SUCCESS) {
3088 REG_WR(PFDEV(pdev), PBF_REG_DISABLE_VF,1);
3089 REG_WR(PFDEV(pdev), PGLUE_B_REG_INTERNAL_VFID_ENABLE, 0);
3090 lm_pretend_func(PFDEV(pdev), ABS_FUNC_ID(pdev) );
3091 DbgMessage(pdev, FATAL, "vf[%d] is disbled\n", abs_vf_id);
3092 } else {
3093 DbgMessage(pdev, FATAL, "lm_pretend_func(%x) returns %d\n",pretend_val,lm_status);
3094 DbgMessage(pdev, FATAL, "vf[%d] is not enabled\n", abs_vf_id);
3095 }
3096
3097 return lm_status;
3098 }
3099
3100 /*Master Channel Virt*/
3101
lm_pf_create_vf(struct _lm_device_t * pdev,u16_t abs_vf_id,void * ctx)3102 lm_status_t lm_pf_create_vf(struct _lm_device_t *pdev, u16_t abs_vf_id, void* ctx)
3103 {
3104 lm_status_t lm_status = LM_STATUS_SUCCESS;
3105 u8_t chains_resource_acquired;
3106 u8_t base_fw_stat_id;
3107 lm_vf_info_t * vf_info;
3108 u32_t num_of_vf_avaiable_chains;
3109 u8_t num_rxqs,num_txqs;
3110
3111 DbgMessage(pdev, WARN, "lm_pf_create_vf(%d)\n",abs_vf_id);
3112 vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3113 if (!vf_info) {
3114 DbgBreakMsg("lm_pf_create_vf: vf_info is not found\n");
3115 return LM_STATUS_FAILURE;
3116 }
3117 lm_status = lm_pf_set_vf_ctx(pdev, vf_info->relative_vf_id, ctx);
3118 DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
3119
3120 DbgBreakIf(!vf_info);
3121
3122 lm_pf_get_queues_number(pdev, vf_info, &num_rxqs, &num_txqs);
3123 num_of_vf_avaiable_chains = lm_pf_allocate_vf_igu_sbs(pdev, vf_info, num_rxqs);
3124
3125 if (num_of_vf_avaiable_chains == 0)
3126 {
3127 return LM_STATUS_RESOURCE;
3128 }
3129
3130 chains_resource_acquired = lm_pf_acquire_vf_chains_resources(pdev, vf_info->relative_vf_id, num_of_vf_avaiable_chains);
3131
3132 if (!chains_resource_acquired) {
3133 DbgBreak();
3134 return LM_STATUS_RESOURCE;
3135 }
3136
3137
3138 if (vf_info != NULL) {
3139 base_fw_stat_id = 8 + vf_info->abs_vf_id;
3140 lm_status = lm_pf_set_vf_stat_id(pdev, vf_info->relative_vf_id, base_fw_stat_id);
3141 lm_pf_init_vf_slow_path(pdev, vf_info);
3142 lm_pf_init_vf_client(pdev, vf_info, 0);
3143 #if 0
3144 lm_status = lm_set_rx_mask(pdev, vf_info->vf_chains[0].sw_client_id, LM_RX_MASK_ACCEPT_NONE, NULL);
3145
3146 if (lm_status == LM_STATUS_PENDING)
3147 {
3148 /* Synchrounous complete */
3149 lm_status = lm_wait_set_rx_mask_done(pdev, vf_info->vf_chains[0].sw_client_id);
3150 }
3151 #endif
3152 lm_status = lm_pf_enable_vf(pdev, vf_info->abs_vf_id);
3153 } else {
3154 lm_status = LM_STATUS_FAILURE;
3155 }
3156
3157 return lm_status;
3158 }
3159
lm_pf_remove_vf(struct _lm_device_t * pdev,u16_t abs_vf_id)3160 lm_status_t lm_pf_remove_vf(struct _lm_device_t *pdev, u16_t abs_vf_id)
3161 {
3162 lm_status_t lm_status = LM_STATUS_SUCCESS;
3163 u8_t q_idx;
3164 u32_t cid,client_info_idx, con_state;
3165 lm_vf_info_t * vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3166
3167 DbgMessage(pdev, WARN, "lm_pf_remove_vf(%d)\n",abs_vf_id);
3168 if (!vf_info) {
3169 DbgBreakMsg("lm_pf_remove_vf: vf_info is not found\n");
3170 return LM_STATUS_FAILURE;
3171 }
3172 if (lm_pf_fl_vf_reset_is_inprogress(pdev, (u8_t)abs_vf_id)) {
3173 MM_ACQUIRE_VFS_STATS_LOCK(pdev);
3174 if (vf_info->vf_stats.vf_stats_state != VF_STATS_REQ_IN_PROCESSING) {
3175 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY;
3176 }
3177 vf_info->vf_stats.stop_collect_stats = TRUE;
3178 vf_info->vf_stats.vf_stats_flag = 0;
3179 MM_RELEASE_VFS_STATS_LOCK(pdev);
3180 lm_status = lm_pf_vf_wait_for_stats_ready(pdev, vf_info);
3181 if (lm_status != LM_STATUS_SUCCESS) {
3182 DbgBreak();
3183 } else {
3184 vf_info->vf_stats.vf_stats_state = VF_STATS_NONE;
3185 }
3186
3187 for (q_idx = 0; q_idx < vf_info->vf_si_num_of_active_q; q_idx++) {
3188 cid = LM_VF_Q_ID_TO_PF_CID(pdev, vf_info, q_idx);
3189 client_info_idx = LM_SW_VF_CLI_ID(vf_info, q_idx);
3190 con_state = lm_get_con_state(pdev, cid);
3191 if (con_state != LM_CON_STATE_CLOSE)
3192 {
3193 if (con_state != LM_CON_STATE_OPEN) {
3194 DbgMessage(pdev, FATAL, "State of CID %d of VF[%d(rel)] is %d)\n",cid, vf_info->relative_vf_id,
3195 con_state);
3196 DbgBreak();
3197 } else {
3198 lm_set_con_state(pdev, cid, LM_CON_STATE_HALT);
3199 lm_status = lm_terminate_eth_con(pdev, cid);
3200 DbgMessage(pdev, WARN, "lm_pf_remove_vf(%d): terminate CID %d (0x%x)\n",abs_vf_id,cid,lm_status);
3201 if (lm_status != LM_STATUS_SUCCESS)
3202 {
3203 DbgBreak();
3204 return lm_status;
3205 }
3206 lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
3207 }
3208 }
3209 }
3210 vf_info->vf_si_num_of_active_q = 0;
3211 lm_status = lm_pf_cleanup_vf_after_flr(pdev, vf_info);
3212 } else {
3213 lm_status = lm_pf_disable_vf(pdev,vf_info->abs_vf_id);
3214 }
3215
3216 lm_pf_release_vf_chains_resources(pdev, vf_info->relative_vf_id);
3217 lm_status = lm_pf_set_vf_ctx(pdev, vf_info->relative_vf_id, NULL);
3218 DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
3219
3220
3221 return lm_status;
3222 }
3223
lm_pf_cleanup_vf_after_flr(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)3224 lm_status_t lm_pf_cleanup_vf_after_flr(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
3225 {
3226 lm_status_t lm_status = LM_STATUS_SUCCESS;
3227 u32_t wait_ms = 10000;
3228 u16_t pretend_value = 0;
3229 u32_t factor = 0;
3230 u32_t cleanup_complete = 0;
3231
3232 u8_t function_for_clean_up = 0;
3233 u8_t idx = 0;
3234
3235 struct sdm_op_gen final_cleanup;
3236
3237 // TODO - use here pdev->vars.clk_factor
3238 if (CHIP_REV_IS_EMUL(pdev))
3239 {
3240 factor = LM_EMUL_FACTOR;
3241 }
3242 else if (CHIP_REV_IS_FPGA(pdev))
3243 {
3244 factor = LM_FPGA_FACTOR;
3245 }
3246 else
3247 {
3248 factor = 1;
3249 }
3250
3251 wait_ms *= factor;
3252 pdev->flr_stats.default_wait_interval_ms = DEFAULT_WAIT_INTERVAL_MICSEC;
3253 DbgMessage(pdev, FATAL, "lm_cleanup_after_flr VF[%d] >>>\n",vf_info->abs_vf_id);
3254
3255 /*
3256 VF FLR only part
3257 a. Wait until there are no pending ramrods for this VFid in the PF DB. - No pending VF's pending ramrod. It's based on "FLR not during driver load/unload".
3258 What about set MAC?
3259
3260 b. Send the new "L2 connection terminate" ramrod for each L2 CID that was used by the VF,
3261 including sending the doorbell with the "terminate" flag. - Will be implemented in FW later
3262
3263 c. Send CFC delete ramrod on all L2 connections of that VF (set the CDU-validation field to "invalid"). - part of FW cleanup. VF_TO_PF_CID must initialized in
3264 PF CID array*/
3265
3266 /* 3. Poll on the DQ per-function usage-counter until it's 0. */
3267 pretend_value = ABS_FUNC_ID(pdev) | (1<<3) | (vf_info->abs_vf_id << 4);
3268 lm_status = lm_pretend_func(PFDEV(pdev), pretend_value);
3269 if (lm_status == LM_STATUS_SUCCESS) {
3270 pdev->flr_stats.dq_usage_counter = REG_WAIT_VERIFY_VAL(PFDEV(pdev), DORQ_REG_VF_USAGE_CNT, 0, wait_ms);
3271 lm_pretend_func(PFDEV(pdev), ABS_FUNC_ID(pdev));
3272 DbgMessage(pdev, FATAL, "%d*%dms waiting for DQ per vf usage counter\n", pdev->flr_stats.dq_usage_counter, DEFAULT_WAIT_INTERVAL_MICSEC);
3273 } else {
3274 DbgMessage(pdev, FATAL,"lm_pretend_func(%x) returns %d\n",pretend_value,lm_status);
3275 DbgMessage(pdev, FATAL, "VF[%d]: could not read DORQ_REG_VF_USAGE_CNT\n", ABS_VFID(pdev));
3276 return lm_status;
3277 }
3278
3279 /* 4. Activate the FW cleanup process by activating AggInt in the FW with GRC. Set the bit of the relevant function in the AggInt bitmask,
3280 to indicate to the FW which function is being cleaned. Wait for the per-function completion indication in the Cstorm RAM
3281 */
3282 function_for_clean_up = 8 + vf_info->abs_vf_id;
3283 cleanup_complete = 0xFFFFFFFF;
3284 LM_INTMEM_READ32(PFDEV(pdev),CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(function_for_clean_up),&cleanup_complete, BAR_CSTRORM_INTMEM);
3285 if (cleanup_complete) {
3286 DbgMessage(pdev, FATAL, "CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET is %x",cleanup_complete);
3287 DbgBreak();
3288 }
3289
3290 final_cleanup.command = (XSTORM_AGG_INT_FINAL_CLEANUP_INDEX << SDM_OP_GEN_COMP_PARAM_SHIFT) & SDM_OP_GEN_COMP_PARAM;
3291 final_cleanup.command |= (XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE << SDM_OP_GEN_COMP_TYPE_SHIFT) & SDM_OP_GEN_COMP_TYPE;
3292 final_cleanup.command |= 1 << SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT;
3293 final_cleanup.command |= (function_for_clean_up << SDM_OP_GEN_AGG_VECT_IDX_SHIFT) & SDM_OP_GEN_AGG_VECT_IDX;
3294
3295 DbgMessage(pdev, FATAL, "Final cleanup\n");
3296 REG_WR(PFDEV(pdev),XSDM_REG_OPERATION_GEN, final_cleanup.command);
3297 pdev->flr_stats.final_cleanup_complete = REG_WAIT_VERIFY_VAL(PFDEV(pdev), BAR_CSTRORM_INTMEM + CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(function_for_clean_up), 1, wait_ms);
3298 DbgMessage(pdev, FATAL, "%d*%dms waiting for final cleanup compete\n", pdev->flr_stats.final_cleanup_complete, DEFAULT_WAIT_INTERVAL_MICSEC);
3299 /* Lets cleanup for next FLR final-cleanup... */
3300 LM_INTMEM_WRITE32(PFDEV(pdev),CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(function_for_clean_up),0, BAR_CSTRORM_INTMEM);
3301
3302
3303 /* 5. ATC cleanup. This process will include the following steps (note that ATC will not be available for phase2 of the
3304 integration and the following should be added only in phase3):
3305 a. Optionally, wait 2 ms. This is not a must. The driver can start polling (next steps) immediately,
3306 but take into account that it may take time till the done indications will be set.
3307 b. Wait until INVALIDATION_DONE[function] = 1
3308 c. Write-clear INVALIDATION_DONE[function] */
3309
3310
3311 /* 6. Verify PBF cleanup. Do the following for all PBF queues (queues 0,1,4, that will be indicated below with N):
3312 a. Make sure PBF command-queue is flushed: Read pN_tq_occupancy. Let's say that the value is X.
3313 This number indicates the number of occupied transmission-queue lines.
3314 Poll on pN_tq_occupancy and pN_tq_lines_freed_cnt until one of the following:
3315 i. pN_tq_occupancy is 0 (queue is empty). OR
3316 ii. pN_tq_lines_freed_cnt equals has advanced (cyclically) by X (all lines that were in the queue were processed). */
3317
3318 for (idx = 0; idx < 3; idx++) {
3319 u32_t tq_to_free;
3320 u32_t tq_freed_cnt_start;
3321 u32_t tq_occ;
3322 u32_t tq_freed_cnt_last;
3323 u32_t pbf_reg_pN_tq_occupancy = 0;
3324 u32_t pbf_reg_pN_tq_lines_freed_cnt = 0;
3325
3326 switch (idx) {
3327 case 0:
3328 pbf_reg_pN_tq_occupancy = (CHIP_IS_E3B0(pdev))? PBF_REG_TQ_OCCUPANCY_Q0 : PBF_REG_P0_TQ_OCCUPANCY;
3329 pbf_reg_pN_tq_lines_freed_cnt = (CHIP_IS_E3B0(pdev)) ? PBF_REG_TQ_LINES_FREED_CNT_Q0 : PBF_REG_P0_TQ_LINES_FREED_CNT;
3330 break;
3331 case 1:
3332 pbf_reg_pN_tq_occupancy = (CHIP_IS_E3B0(pdev)) ? PBF_REG_TQ_OCCUPANCY_Q1 : PBF_REG_P1_TQ_OCCUPANCY;
3333 pbf_reg_pN_tq_lines_freed_cnt = (CHIP_IS_E3B0(pdev)) ? PBF_REG_TQ_LINES_FREED_CNT_Q1 : PBF_REG_P1_TQ_LINES_FREED_CNT;
3334 break;
3335 case 2:
3336 pbf_reg_pN_tq_occupancy = (CHIP_IS_E3B0(pdev)) ? PBF_REG_TQ_OCCUPANCY_LB_Q : PBF_REG_P4_TQ_OCCUPANCY;
3337 pbf_reg_pN_tq_lines_freed_cnt = (CHIP_IS_E3B0(pdev)) ? PBF_REG_TQ_LINES_FREED_CNT_LB_Q : PBF_REG_P4_TQ_LINES_FREED_CNT;
3338 break;
3339 }
3340 pdev->flr_stats.pbf_queue[idx] = 0;
3341 tq_freed_cnt_last = tq_freed_cnt_start = REG_RD(PFDEV(pdev), pbf_reg_pN_tq_lines_freed_cnt);
3342 tq_occ = tq_to_free = REG_RD(PFDEV(pdev), pbf_reg_pN_tq_occupancy);
3343 DbgMessage(pdev, FATAL, "TQ_OCCUPANCY[%d] : s:%x\n", (idx == 2) ? 4 : idx, tq_to_free);
3344 DbgMessage(pdev, FATAL, "TQ_LINES_FREED_CNT[%d]: s:%x\n", (idx == 2) ? 4 : idx, tq_freed_cnt_start);
3345 while(tq_occ && ((u32_t)S32_SUB(tq_freed_cnt_last, tq_freed_cnt_start) < tq_to_free)) {
3346 if (pdev->flr_stats.pbf_queue[idx]++ < wait_ms/DEFAULT_WAIT_INTERVAL_MICSEC) {
3347 mm_wait(PFDEV(pdev), DEFAULT_WAIT_INTERVAL_MICSEC);
3348 tq_occ = REG_RD(PFDEV(pdev), pbf_reg_pN_tq_occupancy);
3349 tq_freed_cnt_last = REG_RD(PFDEV(pdev), pbf_reg_pN_tq_lines_freed_cnt);
3350 } else {
3351 DbgMessage(pdev, FATAL, "TQ_OCCUPANCY[%d] : c:%x\n", (idx == 2) ? 4 : idx, tq_occ);
3352 DbgMessage(pdev, FATAL, "TQ_LINES_FREED_CNT[%d]: c:%x\n", (idx == 2) ? 4 : idx, tq_freed_cnt_last);
3353 DbgBreak();
3354 break;
3355 }
3356 }
3357 DbgMessage(pdev, FATAL, "%d*%dms waiting for PBF command queue[%d] is flushed\n",
3358 pdev->flr_stats.pbf_queue[idx], DEFAULT_WAIT_INTERVAL_MICSEC, (idx == 2) ? 4 : idx);
3359 }
3360
3361 /* b. Make sure PBF transmission buffer is flushed: read pN_init_crd once and keep it in variable Y.
3362 Read pN_credit and keep it in X. Poll on pN_credit and pN_internal_crd_freed until one of the following:
3363 i. (Y - pN_credit) is 0 (transmission buffer is empty). OR
3364 ii. pN_internal_crd_freed_cnt has advanced (cyclically) by Y-X (all transmission buffer lines that were occupied were freed).*/
3365
3366 for (idx = 0; idx < 3; idx++) {
3367 u32_t init_crd;
3368 u32_t credit_last,credit_start;
3369 u32_t inernal_freed_crd_start;
3370 u32_t inernal_freed_crd_last = 0;
3371 u32_t pbf_reg_pN_init_crd = 0;
3372 u32_t pbf_reg_pN_credit = 0;
3373 u32_t pbf_reg_pN_internal_crd_freed = 0;
3374 switch (idx) {
3375 case 0:
3376 pbf_reg_pN_init_crd = (CHIP_IS_E3B0(pdev)) ? PBF_REG_INIT_CRD_Q0 : PBF_REG_P0_INIT_CRD;
3377 pbf_reg_pN_credit = (CHIP_IS_E3B0(pdev)) ? PBF_REG_CREDIT_Q0 : PBF_REG_P0_CREDIT;
3378 pbf_reg_pN_internal_crd_freed = (CHIP_IS_E3B0(pdev)) ? PBF_REG_INTERNAL_CRD_FREED_CNT_Q0 : PBF_REG_P0_INTERNAL_CRD_FREED_CNT;
3379 break;
3380 case 1:
3381 pbf_reg_pN_init_crd = (CHIP_IS_E3B0(pdev)) ? PBF_REG_INIT_CRD_Q1: PBF_REG_P1_INIT_CRD;
3382 pbf_reg_pN_credit = (CHIP_IS_E3B0(pdev)) ? PBF_REG_CREDIT_Q1 : PBF_REG_P1_CREDIT;
3383 pbf_reg_pN_internal_crd_freed = (CHIP_IS_E3B0(pdev)) ? PBF_REG_INTERNAL_CRD_FREED_CNT_Q1 : PBF_REG_P1_INTERNAL_CRD_FREED_CNT;
3384 break;
3385 case 2:
3386 pbf_reg_pN_init_crd = (CHIP_IS_E3B0(pdev)) ? PBF_REG_INIT_CRD_LB_Q : PBF_REG_P4_INIT_CRD;
3387 pbf_reg_pN_credit = (CHIP_IS_E3B0(pdev)) ? PBF_REG_CREDIT_LB_Q : PBF_REG_P4_CREDIT;
3388 pbf_reg_pN_internal_crd_freed = (CHIP_IS_E3B0(pdev)) ? PBF_REG_INTERNAL_CRD_FREED_CNT_LB_Q : PBF_REG_P4_INTERNAL_CRD_FREED_CNT;
3389 break;
3390 }
3391 pdev->flr_stats.pbf_transmit_buffer[idx] = 0;
3392 inernal_freed_crd_last = inernal_freed_crd_start = REG_RD(PFDEV(pdev), pbf_reg_pN_internal_crd_freed);
3393 credit_last = credit_start = REG_RD(PFDEV(pdev), pbf_reg_pN_credit);
3394 init_crd = REG_RD(PFDEV(pdev), pbf_reg_pN_init_crd);
3395 DbgMessage(pdev, FATAL, "INIT CREDIT[%d] : %x\n", (idx == 2) ? 4 : idx, init_crd);
3396 DbgMessage(pdev, FATAL, "CREDIT[%d] : s:%x\n", (idx == 2) ? 4 : idx, credit_start);
3397 DbgMessage(pdev, FATAL, "INTERNAL_CRD_FREED[%d]: s:%x\n", (idx == 2) ? 4 : idx, inernal_freed_crd_start);
3398 while ((credit_last != init_crd)
3399 && (u32_t)S32_SUB(inernal_freed_crd_last, inernal_freed_crd_start) < (init_crd - credit_start)) {
3400 if (pdev->flr_stats.pbf_transmit_buffer[idx]++ < wait_ms/DEFAULT_WAIT_INTERVAL_MICSEC) {
3401 mm_wait(PFDEV(pdev), DEFAULT_WAIT_INTERVAL_MICSEC);
3402 credit_last = REG_RD(PFDEV(pdev), pbf_reg_pN_credit);
3403 inernal_freed_crd_last = REG_RD(PFDEV(pdev), pbf_reg_pN_internal_crd_freed);
3404 } else {
3405 DbgMessage(pdev, FATAL, "CREDIT[%d] : c:%x\n", (idx == 2) ? 4 : idx, credit_last);
3406 DbgMessage(pdev, FATAL, "INTERNAL_CRD_FREED[%d]: c:%x\n", (idx == 2) ? 4 : idx, inernal_freed_crd_last);
3407 DbgBreak();
3408 break;
3409 }
3410 }
3411 DbgMessage(pdev, FATAL, "%d*%dms waiting for PBF transmission buffer[%d] is flushed\n",
3412 pdev->flr_stats.pbf_transmit_buffer[idx], DEFAULT_WAIT_INTERVAL_MICSEC, (idx == 2) ? 4 : idx);
3413 }
3414
3415 /* 7. Wait for 100ms in order to make sure that the chip is clean, including all PCI related paths
3416 (in Emulation the driver can wait for 10ms*EmulationFactor, i.e.: 20s). This is especially required if FW doesn't implement
3417 the flows in Optional Operations (future enhancements).) */
3418 mm_wait(pdev, 10000*factor);
3419
3420 /* 9. Initialize the function as usual this should include also re-enabling the function in all the HW blocks and Storms that
3421 were disabled by the MCP and cleaning relevant per-function information in the chip (internal RAM related information, IGU memory etc.).
3422 a. In case of VF, PF resources that were allocated for previous VF can be re-used by the new VF. If there are resources
3423 that are not needed by the new VF then they should be cleared.
3424 b. Note that as long as slow-path prod/cons update to Xstorm is not atomic, they must be cleared by the driver before setting
3425 the function to "enable" in the Xstorm.
3426 c. Don't forget to enable the VF in the PXP or the DMA operation for PF in the PXP. */
3427
3428
3429 if (IS_VFDEV(pdev))
3430 {
3431 #ifdef VF_INVOLVED
3432 lm_set_con_state(pdev, LM_VF_Q_ID_TO_PF_CID(pdev, vf_info,0), LM_CON_STATE_CLOSE);
3433 #endif
3434 }
3435
3436 vf_info->was_flred = FALSE;
3437
3438 return lm_status;
3439 }
3440
lm_pf_fl_vf_reset_set_inprogress(struct _lm_device_t * pdev,u8_t abs_vf_id)3441 void lm_pf_fl_vf_reset_set_inprogress(struct _lm_device_t * pdev, u8_t abs_vf_id)
3442 {
3443 lm_vf_info_t * vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3444
3445 DbgMessage(pdev, WARN, "lm_pf_fl_vf_reset_set_inprogress(%d)\n",abs_vf_id);
3446 if (!vf_info) {
3447 DbgBreakMsg("lm_pf_fl_vf_reset_set_inprogress: vf_info is not found\n");
3448 return;
3449 } else {
3450 vf_info->was_flred = TRUE;
3451 }
3452 }
3453
lm_pf_fl_vf_reset_clear_inprogress(struct _lm_device_t * pdev,u8_t abs_vf_id)3454 void lm_pf_fl_vf_reset_clear_inprogress(struct _lm_device_t *pdev, u8_t abs_vf_id)
3455 {
3456 lm_vf_info_t * vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3457
3458 DbgMessage(pdev, WARN, "lm_pf_fl_vf_reset_clear_inprogress(%d)\n",abs_vf_id);
3459 if (!vf_info) {
3460 DbgBreakMsg("lm_pf_fl_vf_reset_clear_inprogress: vf_info is not found\n");
3461 return;
3462 } else {
3463 vf_info->was_flred = FALSE;
3464 }
3465 }
3466
lm_pf_fl_vf_reset_is_inprogress(struct _lm_device_t * pdev,u8_t abs_vf_id)3467 u8_t lm_pf_fl_vf_reset_is_inprogress(struct _lm_device_t *pdev, u8_t abs_vf_id)
3468 {
3469 lm_vf_info_t * vf_info = lm_pf_find_vf_info_by_abs_id(pdev, (u8_t)abs_vf_id);
3470
3471 DbgMessage(pdev, WARN, "lm_pf_fl_vf_reset_clear_inprogress(%d)\n",abs_vf_id);
3472 if (!vf_info) {
3473 DbgBreakMsg("lm_pf_fl_vf_reset_is_inprogress: vf_info is not found\n");
3474 return FALSE;
3475 } else {
3476 return vf_info->was_flred;
3477 }
3478 }
3479
lm_pf_finally_release_vf(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)3480 lm_status_t lm_pf_finally_release_vf(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
3481 {
3482 lm_status_t lm_status = LM_STATUS_SUCCESS;
3483 u8_t function_fw_id;
3484 u8_t sb_idx;
3485 u8_t q_idx;
3486 u32_t cid;
3487
3488 DbgBreakIf(!(pdev && vf_info));
3489 if (vf_info->vf_si_state == PF_SI_VF_INITIALIZED) {
3490 DbgMessage(pdev, WARN, "VF[%d%d)] is not closed yet\n", vf_info->relative_vf_id, vf_info->abs_vf_id);
3491 MM_ACQUIRE_VFS_STATS_LOCK(pdev);
3492 if (vf_info->vf_stats.vf_stats_state != VF_STATS_REQ_IN_PROCESSING) {
3493 vf_info->vf_stats.vf_stats_state = VF_STATS_REQ_READY;
3494 }
3495 vf_info->vf_stats.stop_collect_stats = TRUE;
3496 vf_info->vf_stats.vf_stats_flag = 0;
3497 MM_RELEASE_VFS_STATS_LOCK(pdev);
3498
3499 lm_status = lm_pf_vf_wait_for_stats_ready(pdev, vf_info);
3500 if (lm_status != LM_STATUS_SUCCESS) {
3501 DbgBreak();
3502 } else {
3503 vf_info->vf_stats.vf_stats_state = VF_STATS_NONE;
3504 }
3505
3506 for (q_idx = 0; q_idx < vf_info->vf_si_num_of_active_q; q_idx++) {
3507 cid = LM_VF_Q_ID_TO_PF_CID(pdev, vf_info, q_idx);
3508 if (vf_info->was_malicious || vf_info->was_flred)
3509 {
3510 lm_set_con_state(pdev, cid, LM_CON_STATE_CLOSE);
3511 }
3512 else
3513 {
3514 lm_status = lm_close_eth_con(pdev, cid, TRUE);
3515 }
3516 }
3517 vf_info->vf_si_num_of_active_q = 0;
3518
3519 // if (!(vf_info->was_malicious || vf_info->was_flred))
3520 {
3521 lm_pf_disable_vf_igu_int(pdev, vf_info->abs_vf_id);
3522 /*
3523 Disable the function in STORMs
3524 */
3525 function_fw_id = 8 + vf_info->abs_vf_id;
3526
3527 LM_INTMEM_WRITE8(PFDEV(pdev), XSTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_XSTRORM_INTMEM);
3528 LM_INTMEM_WRITE8(PFDEV(pdev), CSTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_CSTRORM_INTMEM);
3529 LM_INTMEM_WRITE8(PFDEV(pdev), TSTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_TSTRORM_INTMEM);
3530 LM_INTMEM_WRITE8(PFDEV(pdev), USTORM_FUNC_EN_OFFSET(function_fw_id), 0, BAR_USTRORM_INTMEM);
3531
3532 for (sb_idx = 0; sb_idx < vf_info->num_sbs; sb_idx++) {
3533 lm_clear_non_def_status_block(pdev, LM_FW_VF_SB_ID(vf_info, sb_idx));
3534 }
3535
3536 for (q_idx = 0; q_idx < vf_info->num_rxqs; q_idx++) {
3537 u32_t reg = PXP_REG_HST_ZONE_PERMISSION_TABLE + LM_FW_VF_QZONE_ID(vf_info,q_idx) * 4;
3538 u32_t val = 0;
3539 REG_WR(PFDEV(pdev), reg, val);
3540 }
3541 }
3542 vf_info->vf_si_state = PF_SI_ACQUIRED;
3543 }
3544
3545 if (vf_info->vf_si_state == PF_SI_ACQUIRED) {
3546 DbgMessage(pdev, WARN, "VF[%d%d)] is not released yet\n", vf_info->relative_vf_id, vf_info->abs_vf_id);
3547 vf_info->vf_si_state = PF_SI_WAIT_FOR_ACQUIRING_REQUEST;
3548 }
3549 return lm_status;
3550 }
3551
lm_pf_tpa_send_vf_ramrod(struct _lm_device_t * pdev,lm_vf_info_t * vf_info,u32_t q_idx,u8_t update_ipv4,u8_t update_ipv6)3552 lm_status_t lm_pf_tpa_send_vf_ramrod(struct _lm_device_t *pdev, lm_vf_info_t *vf_info, u32_t q_idx, u8_t update_ipv4, u8_t update_ipv6)
3553 {
3554 // Add ramrod send code
3555 lm_vf_chain_info_t* tpa_chain = &vf_info->vf_chains[q_idx];
3556 lm_status_t lm_status = LM_STATUS_SUCCESS;
3557 lm_address_t q_addr;
3558 u32_t vf_cid_of_pf = 0;
3559 u16_t type = 0;
3560
3561 if((CHK_NULL(tpa_chain->tpa_ramrod_data_virt)))
3562 {
3563 DbgBreakMsg("lm_tpa_send_ramrod : invalid paramters");
3564 return LM_STATUS_FAILURE;
3565 }
3566
3567 tpa_chain->tpa_ramrod_data_virt->update_ipv4 = update_ipv4;
3568 tpa_chain->tpa_ramrod_data_virt->update_ipv6 = update_ipv6;
3569
3570 tpa_chain->tpa_ramrod_data_virt->client_id = LM_FW_VF_CLI_ID(vf_info, q_idx);
3571 /* maximal TPA queues allowed for this client */
3572 tpa_chain->tpa_ramrod_data_virt->max_tpa_queues = LM_TPA_MAX_AGGS;
3573 /* The maximal number of SGEs that can be used for one packet. depends on MTU and SGE size. must be 0 if SGEs are disabled */
3574 tpa_chain->tpa_ramrod_data_virt->max_sges_for_packet = DIV_ROUND_UP_BITS(tpa_chain->mtu, LM_TPA_PAGE_BITS);
3575 /* Size of the buffers pointed by SGEs */
3576 ASSERT_STATIC(LM_TPA_PAGE_SIZE < MAX_VARIABLE_VALUE(tpa_chain->tpa_ramrod_data_virt->sge_buff_size));
3577 tpa_chain->tpa_ramrod_data_virt->sge_buff_size = mm_cpu_to_le16(LM_TPA_PAGE_SIZE);
3578 /* maximal size for the aggregated TPA packets, reprted by the host */
3579 ASSERT_STATIC((LM_TPA_MAX_AGG_SIZE * LM_TPA_PAGE_SIZE) < MAX_VARIABLE_VALUE(tpa_chain->tpa_ramrod_data_virt->max_agg_size));
3580 tpa_chain->tpa_ramrod_data_virt->max_agg_size = mm_cpu_to_le16(LM_TPA_MAX_AGG_SIZE * LM_TPA_PAGE_SIZE);
3581
3582 q_addr.as_u64 = tpa_chain->sge_addr;
3583 //u32_t sge_page_base_lo /* The address to fetch the next sges from (low) */;
3584 tpa_chain->tpa_ramrod_data_virt->sge_page_base_lo = mm_cpu_to_le32(q_addr.as_u32.low);
3585 //u32_t sge_page_base_hi /* The address to fetch the next sges from (high) */;
3586 tpa_chain->tpa_ramrod_data_virt->sge_page_base_hi = mm_cpu_to_le32(q_addr.as_u32.high);
3587 //u16_t sge_pause_thr_low /* number of remaining sges under which, we send pause message */;
3588 tpa_chain->tpa_ramrod_data_virt->sge_pause_thr_low = mm_cpu_to_le16(LM_TPA_SGE_PAUSE_THR_LOW);
3589 //u16_t sge_pause_thr_high /* number of remaining sges above which, we send un-pause message */;
3590 tpa_chain->tpa_ramrod_data_virt->sge_pause_thr_high = mm_cpu_to_le16(LM_TPA_SGE_PAUSE_THR_HIGH);
3591
3592 vf_cid_of_pf = LM_VF_Q_ID_TO_PF_CID(pdev, vf_info, q_idx);
3593 type = (ETH_CONNECTION_TYPE | ((8 + vf_info->abs_vf_id) << SPE_HDR_T_FUNCTION_ID_SHIFT));
3594
3595 tpa_chain->tpa_ramrod_data_virt->complete_on_both_clients = TRUE;
3596
3597 lm_status = lm_sq_post(pdev,
3598 vf_cid_of_pf,
3599 RAMROD_CMD_ID_ETH_TPA_UPDATE,
3600 CMD_PRIORITY_MEDIUM,
3601 type,
3602 *(u64_t *)&(tpa_chain->tpa_ramrod_data_phys));
3603
3604 DbgBreakIf(lm_status != LM_STATUS_SUCCESS);
3605
3606 return lm_status;
3607 }
3608
lm_is_vf_rsc_supported(struct _lm_device_t * pdev)3609 u8_t lm_is_vf_rsc_supported(struct _lm_device_t *pdev)
3610 {
3611 u8_t is_rsc_supported = TRUE;
3612 if (IS_VFDEV(pdev)) {
3613 if (IS_SW_CHANNEL_VIRT_MODE(pdev))
3614 {
3615 struct pf_vf_msg_acquire_resp * presp = (struct pf_vf_msg_acquire_resp *)pdev->pf_vf_acquiring_resp;
3616 if (!(presp->pfdev_info.pf_cap & PFVF_CAP_TPA)) {
3617 is_rsc_supported = FALSE;
3618 }
3619 }
3620 else if (IS_HW_CHANNEL_VIRT_MODE(pdev))
3621 {
3622 struct pfvf_acquire_resp_tlv * presp;
3623 presp = (struct pfvf_acquire_resp_tlv *)pdev->pf_vf_acquiring_resp;
3624 if (!(presp->pfdev_info.pf_cap & PFVF_CAP_TPA_UPDATE)) {
3625 is_rsc_supported = FALSE;
3626 }
3627 }
3628 else
3629 {
3630 DbgBreak();
3631 }
3632 }
3633 return is_rsc_supported;
3634 }
3635
lm_pf_init_vf_filters(struct _lm_device_t * pdev,lm_vf_info_t * vf_info)3636 void lm_pf_init_vf_filters(struct _lm_device_t *pdev, lm_vf_info_t *vf_info)
3637 {
3638 if ((vf_info == NULL) || (pdev == NULL))
3639 {
3640 DbgBreakMsg("lm_pf_init_vf_filters : invalid paramters");
3641 }
3642 else
3643 {
3644 vf_info->is_promiscuous_mode_restricted = (pdev->params.vf_promiscuous_mode_restricted != 0);
3645 }
3646 return;
3647 }
3648
lm_pf_allow_vf_promiscuous_mode(lm_vf_info_t * vf_info,u8_t is_allowed)3649 void lm_pf_allow_vf_promiscuous_mode(lm_vf_info_t *vf_info, u8_t is_allowed)
3650 {
3651 if (vf_info == NULL)
3652 {
3653 DbgBreakMsg("lm_pf_allow_vf_promiscuous_mode : invalid paramters");
3654 }
3655 else
3656 {
3657 vf_info->is_promiscuous_mode_restricted = !is_allowed;
3658 }
3659 return;
3660 }
3661
lm_pf_int_vf_igu_sb_cleanup(lm_device_t * pdev,lm_vf_info_t * vf_info,u8_t vf_chain_id)3662 void lm_pf_int_vf_igu_sb_cleanup(lm_device_t *pdev, lm_vf_info_t *vf_info, u8_t vf_chain_id)
3663 {
3664 struct igu_regular cmd_data = {0};
3665 struct igu_ctrl_reg cmd_ctrl = {0};
3666 u32_t igu_addr_ack = 0;
3667 u32_t sb_bit = 0;
3668 u32_t cnt = 100;
3669 u8_t igu_sb_id = 0;
3670 #ifdef _VBD_CMD_
3671 return;
3672 #endif
3673
3674 /* Not supported in backward compatible mode! */
3675 if (INTR_BLK_MODE(pdev) == INTR_BLK_MODE_BC)
3676 {
3677 return;
3678 }
3679
3680 if ((vf_info == NULL) || (pdev == NULL))
3681 {
3682 DbgBreakMsg("lm_pf_int_vf_igu_sb_cleanup : invalid paramters");
3683 return;
3684 }
3685
3686 if (IS_VFDEV(pdev))
3687 {
3688 DbgBreakMsg("lm_pf_int_vf_igu_sb_cleanup : only available on Host/PF side");
3689 return;
3690 }
3691
3692 igu_sb_id = LM_VF_IGU_SB_ID(vf_info,vf_chain_id);
3693 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (igu_sb_id/32)*4;
3694 sb_bit = 1 << (igu_sb_id%32);
3695
3696 /* Cleanup can be done only via GRC access using the producer update command */
3697 cmd_data.sb_id_and_flags =
3698 ((IGU_USE_REGISTER_cstorm_type_0_sb_cleanup << IGU_REGULAR_CLEANUP_TYPE_SHIFT) |
3699 IGU_REGULAR_CLEANUP_SET |
3700 IGU_REGULAR_BCLEANUP);
3701
3702 cmd_ctrl.ctrl_data =
3703 (((IGU_CMD_E2_PROD_UPD_BASE + igu_sb_id) << IGU_CTRL_REG_ADDRESS_SHIFT) |
3704 (vf_info->abs_vf_id << IGU_CTRL_REG_FID_SHIFT) |
3705 (IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT));
3706
3707 REG_WR(pdev, IGU_REG_COMMAND_REG_32LSB_DATA, cmd_data.sb_id_and_flags);
3708 REG_WR(pdev, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl.ctrl_data);
3709
3710 /* wait for clean up to finish */
3711 while (!(REG_RD(pdev, igu_addr_ack) & sb_bit) && --cnt)
3712 {
3713 mm_wait(pdev, 10);
3714 }
3715
3716 if (!(REG_RD(pdev, igu_addr_ack) & sb_bit))
3717 {
3718 DbgMessage(pdev, FATAL, "Unable to finish IGU cleanup - set: igu_sb_id %d offset %d bit %d (cnt %d)\n",
3719 igu_sb_id, igu_sb_id/32, igu_sb_id%32, cnt);
3720 }
3721
3722 /* Now we clear the cleanup-bit... same command without cleanup_set... */
3723 cmd_data.sb_id_and_flags =
3724 ((IGU_USE_REGISTER_cstorm_type_0_sb_cleanup << IGU_REGULAR_CLEANUP_TYPE_SHIFT) |
3725 IGU_REGULAR_BCLEANUP);
3726
3727
3728 REG_WR(pdev, IGU_REG_COMMAND_REG_32LSB_DATA, cmd_data.sb_id_and_flags);
3729 REG_WR(pdev, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl.ctrl_data);
3730
3731 /* wait for clean up to finish */
3732 while ((REG_RD(pdev, igu_addr_ack) & sb_bit) && --cnt)
3733 {
3734 mm_wait(pdev, 10);
3735 }
3736
3737 if ((REG_RD(pdev, igu_addr_ack) & sb_bit))
3738 {
3739 DbgMessage(pdev, FATAL, "Unable to finish IGU cleanup - clear: igu_sb_id %d offset %d bit %d (cnt %d)\n",
3740 igu_sb_id, igu_sb_id/32, igu_sb_id%32, cnt);
3741 }
3742 }
3743
3744 #endif
3745 /* */
3746