blob: db14e230c9a496134b414451576392d8e626b99a [file] [log] [blame]
Yuval Mintz1408cc1f2016-05-11 16:36:14 +03001/* QLogic qed NIC Driver
2 * Copyright (c) 2015 QLogic Corporation
3 *
4 * This software is available under the terms of the GNU General Public License
5 * (GPL) Version 2, available from the file COPYING in the main directory of
6 * this source tree.
7 */
8
Yuval Mintz36558c32016-05-11 16:36:17 +03009#include <linux/crc32.h>
Yuval Mintzeff16962016-05-11 16:36:21 +030010#include <linux/etherdevice.h>
Yuval Mintz1408cc1f2016-05-11 16:36:14 +030011#include "qed.h"
12#include "qed_sriov.h"
13#include "qed_vf.h"
14
15static void *qed_vf_pf_prep(struct qed_hwfn *p_hwfn, u16 type, u16 length)
16{
17 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
18 void *p_tlv;
19
20 /* This lock is released when we receive PF's response
21 * in qed_send_msg2pf().
22 * So, qed_vf_pf_prep() and qed_send_msg2pf()
23 * must come in sequence.
24 */
25 mutex_lock(&(p_iov->mutex));
26
27 DP_VERBOSE(p_hwfn,
28 QED_MSG_IOV,
29 "preparing to send 0x%04x tlv over vf pf channel\n",
30 type);
31
32 /* Reset Requst offset */
33 p_iov->offset = (u8 *)p_iov->vf2pf_request;
34
35 /* Clear mailbox - both request and reply */
36 memset(p_iov->vf2pf_request, 0, sizeof(union vfpf_tlvs));
37 memset(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs));
38
39 /* Init type and length */
40 p_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, type, length);
41
42 /* Init first tlv header */
43 ((struct vfpf_first_tlv *)p_tlv)->reply_address =
44 (u64)p_iov->pf2vf_reply_phys;
45
46 return p_tlv;
47}
48
49static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size)
50{
51 union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request;
52 struct ustorm_trigger_vf_zone trigger;
53 struct ustorm_vf_zone *zone_data;
54 int rc = 0, time = 100;
55
56 zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B;
57
58 /* output tlvs list */
59 qed_dp_tlv_list(p_hwfn, p_req);
60
61 /* need to add the END TLV to the message size */
62 resp_size += sizeof(struct channel_list_end_tlv);
63
64 /* Send TLVs over HW channel */
65 memset(&trigger, 0, sizeof(struct ustorm_trigger_vf_zone));
66 trigger.vf_pf_msg_valid = 1;
67
68 DP_VERBOSE(p_hwfn,
69 QED_MSG_IOV,
70 "VF -> PF [%02x] message: [%08x, %08x] --> %p, %08x --> %p\n",
71 GET_FIELD(p_hwfn->hw_info.concrete_fid,
72 PXP_CONCRETE_FID_PFID),
73 upper_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys),
74 lower_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys),
75 &zone_data->non_trigger.vf_pf_msg_addr,
76 *((u32 *)&trigger), &zone_data->trigger);
77
78 REG_WR(p_hwfn,
79 (uintptr_t)&zone_data->non_trigger.vf_pf_msg_addr.lo,
80 lower_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys));
81
82 REG_WR(p_hwfn,
83 (uintptr_t)&zone_data->non_trigger.vf_pf_msg_addr.hi,
84 upper_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys));
85
86 /* The message data must be written first, to prevent trigger before
87 * data is written.
88 */
89 wmb();
90
91 REG_WR(p_hwfn, (uintptr_t)&zone_data->trigger, *((u32 *)&trigger));
92
93 /* When PF would be done with the response, it would write back to the
94 * `done' address. Poll until then.
95 */
96 while ((!*done) && time) {
97 msleep(25);
98 time--;
99 }
100
101 if (!*done) {
102 DP_VERBOSE(p_hwfn, QED_MSG_IOV,
103 "VF <-- PF Timeout [Type %d]\n",
104 p_req->first_tlv.tl.type);
105 rc = -EBUSY;
106 goto exit;
107 } else {
108 DP_VERBOSE(p_hwfn, QED_MSG_IOV,
109 "PF response: %d [Type %d]\n",
110 *done, p_req->first_tlv.tl.type);
111 }
112
113exit:
114 mutex_unlock(&(p_hwfn->vf_iov_info->mutex));
115
116 return rc;
117}
118
119#define VF_ACQUIRE_THRESH 3
120#define VF_ACQUIRE_MAC_FILTERS 1
121
122static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn)
123{
124 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
125 struct pfvf_acquire_resp_tlv *resp = &p_iov->pf2vf_reply->acquire_resp;
126 struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info;
127 u8 rx_count = 1, tx_count = 1, num_sbs = 1;
128 u8 num_mac = VF_ACQUIRE_MAC_FILTERS;
129 bool resources_acquired = false;
130 struct vfpf_acquire_tlv *req;
131 int rc = 0, attempts = 0;
132
133 /* clear mailbox and prep first tlv */
134 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_ACQUIRE, sizeof(*req));
135
136 /* starting filling the request */
137 req->vfdev_info.opaque_fid = p_hwfn->hw_info.opaque_fid;
138
139 req->resc_request.num_rxqs = rx_count;
140 req->resc_request.num_txqs = tx_count;
141 req->resc_request.num_sbs = num_sbs;
142 req->resc_request.num_mac_filters = num_mac;
143 req->resc_request.num_vlan_filters = QED_ETH_VF_NUM_VLAN_FILTERS;
144
145 req->vfdev_info.os_type = VFPF_ACQUIRE_OS_LINUX;
146 req->vfdev_info.fw_major = FW_MAJOR_VERSION;
147 req->vfdev_info.fw_minor = FW_MINOR_VERSION;
148 req->vfdev_info.fw_revision = FW_REVISION_VERSION;
149 req->vfdev_info.fw_engineering = FW_ENGINEERING_VERSION;
150
151 /* Fill capability field with any non-deprecated config we support */
152 req->vfdev_info.capabilities |= VFPF_ACQUIRE_CAP_100G;
153
154 /* pf 2 vf bulletin board address */
155 req->bulletin_addr = p_iov->bulletin.phys;
156 req->bulletin_size = p_iov->bulletin.size;
157
158 /* add list termination tlv */
159 qed_add_tlv(p_hwfn, &p_iov->offset,
160 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
161
162 while (!resources_acquired) {
163 DP_VERBOSE(p_hwfn,
164 QED_MSG_IOV, "attempting to acquire resources\n");
165
166 /* send acquire request */
167 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
168 if (rc)
169 return rc;
170
171 /* copy acquire response from buffer to p_hwfn */
172 memcpy(&p_iov->acquire_resp, resp, sizeof(p_iov->acquire_resp));
173
174 attempts++;
175
176 if (resp->hdr.status == PFVF_STATUS_SUCCESS) {
177 /* PF agrees to allocate our resources */
178 if (!(resp->pfdev_info.capabilities &
179 PFVF_ACQUIRE_CAP_POST_FW_OVERRIDE)) {
180 DP_INFO(p_hwfn,
181 "PF is using old incompatible driver; Either downgrade driver or request provider to update hypervisor version\n");
182 return -EINVAL;
183 }
184 DP_VERBOSE(p_hwfn, QED_MSG_IOV, "resources acquired\n");
185 resources_acquired = true;
186 } else if (resp->hdr.status == PFVF_STATUS_NO_RESOURCE &&
187 attempts < VF_ACQUIRE_THRESH) {
188 DP_VERBOSE(p_hwfn,
189 QED_MSG_IOV,
190 "PF unwilling to fullfill resource request. Try PF recommended amount\n");
191
192 /* humble our request */
193 req->resc_request.num_txqs = resp->resc.num_txqs;
194 req->resc_request.num_rxqs = resp->resc.num_rxqs;
195 req->resc_request.num_sbs = resp->resc.num_sbs;
196 req->resc_request.num_mac_filters =
197 resp->resc.num_mac_filters;
198 req->resc_request.num_vlan_filters =
199 resp->resc.num_vlan_filters;
200
201 /* Clear response buffer */
202 memset(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs));
203 } else {
204 DP_ERR(p_hwfn,
205 "PF returned error %d to VF acquisition request\n",
206 resp->hdr.status);
207 return -EAGAIN;
208 }
209 }
210
211 /* Update bulletin board size with response from PF */
212 p_iov->bulletin.size = resp->bulletin_size;
213
214 /* get HW info */
215 p_hwfn->cdev->type = resp->pfdev_info.dev_type;
216 p_hwfn->cdev->chip_rev = resp->pfdev_info.chip_rev;
217
218 p_hwfn->cdev->chip_num = pfdev_info->chip_num & 0xffff;
219
220 /* Learn of the possibility of CMT */
221 if (IS_LEAD_HWFN(p_hwfn)) {
222 if (resp->pfdev_info.capabilities & PFVF_ACQUIRE_CAP_100G) {
223 DP_NOTICE(p_hwfn, "100g VF\n");
224 p_hwfn->cdev->num_hwfns = 2;
225 }
226 }
227
228 return 0;
229}
230
231int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn)
232{
233 struct qed_vf_iov *p_iov;
234 u32 reg;
235
236 /* Set number of hwfns - might be overriden once leading hwfn learns
237 * actual configuration from PF.
238 */
239 if (IS_LEAD_HWFN(p_hwfn))
240 p_hwfn->cdev->num_hwfns = 1;
241
242 /* Set the doorbell bar. Assumption: regview is set */
243 p_hwfn->doorbells = (u8 __iomem *)p_hwfn->regview +
244 PXP_VF_BAR0_START_DQ;
245
246 reg = PXP_VF_BAR0_ME_OPAQUE_ADDRESS;
247 p_hwfn->hw_info.opaque_fid = (u16)REG_RD(p_hwfn, reg);
248
249 reg = PXP_VF_BAR0_ME_CONCRETE_ADDRESS;
250 p_hwfn->hw_info.concrete_fid = REG_RD(p_hwfn, reg);
251
252 /* Allocate vf sriov info */
253 p_iov = kzalloc(sizeof(*p_iov), GFP_KERNEL);
254 if (!p_iov) {
255 DP_NOTICE(p_hwfn, "Failed to allocate `struct qed_sriov'\n");
256 return -ENOMEM;
257 }
258
259 /* Allocate vf2pf msg */
260 p_iov->vf2pf_request = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
261 sizeof(union vfpf_tlvs),
262 &p_iov->vf2pf_request_phys,
263 GFP_KERNEL);
264 if (!p_iov->vf2pf_request) {
265 DP_NOTICE(p_hwfn,
266 "Failed to allocate `vf2pf_request' DMA memory\n");
267 goto free_p_iov;
268 }
269
270 p_iov->pf2vf_reply = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
271 sizeof(union pfvf_tlvs),
272 &p_iov->pf2vf_reply_phys,
273 GFP_KERNEL);
274 if (!p_iov->pf2vf_reply) {
275 DP_NOTICE(p_hwfn,
276 "Failed to allocate `pf2vf_reply' DMA memory\n");
277 goto free_vf2pf_request;
278 }
279
280 DP_VERBOSE(p_hwfn,
281 QED_MSG_IOV,
282 "VF's Request mailbox [%p virt 0x%llx phys], Response mailbox [%p virt 0x%llx phys]\n",
283 p_iov->vf2pf_request,
284 (u64) p_iov->vf2pf_request_phys,
285 p_iov->pf2vf_reply, (u64)p_iov->pf2vf_reply_phys);
286
287 /* Allocate Bulletin board */
288 p_iov->bulletin.size = sizeof(struct qed_bulletin_content);
289 p_iov->bulletin.p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
290 p_iov->bulletin.size,
291 &p_iov->bulletin.phys,
292 GFP_KERNEL);
293 DP_VERBOSE(p_hwfn, QED_MSG_IOV,
294 "VF's bulletin Board [%p virt 0x%llx phys 0x%08x bytes]\n",
295 p_iov->bulletin.p_virt,
296 (u64)p_iov->bulletin.phys, p_iov->bulletin.size);
297
298 mutex_init(&p_iov->mutex);
299
300 p_hwfn->vf_iov_info = p_iov;
301
302 p_hwfn->hw_info.personality = QED_PCI_ETH;
303
304 return qed_vf_pf_acquire(p_hwfn);
305
306free_vf2pf_request:
307 dma_free_coherent(&p_hwfn->cdev->pdev->dev,
308 sizeof(union vfpf_tlvs),
309 p_iov->vf2pf_request, p_iov->vf2pf_request_phys);
310free_p_iov:
311 kfree(p_iov);
312
313 return -ENOMEM;
314}
315
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300316int qed_vf_pf_rxq_start(struct qed_hwfn *p_hwfn,
317 u8 rx_qid,
318 u16 sb,
319 u8 sb_index,
320 u16 bd_max_bytes,
321 dma_addr_t bd_chain_phys_addr,
322 dma_addr_t cqe_pbl_addr,
323 u16 cqe_pbl_size, void __iomem **pp_prod)
324{
325 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
326 struct pfvf_start_queue_resp_tlv *resp;
327 struct vfpf_start_rxq_tlv *req;
328 int rc;
329
330 /* clear mailbox and prep first tlv */
331 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_START_RXQ, sizeof(*req));
332
333 req->rx_qid = rx_qid;
334 req->cqe_pbl_addr = cqe_pbl_addr;
335 req->cqe_pbl_size = cqe_pbl_size;
336 req->rxq_addr = bd_chain_phys_addr;
337 req->hw_sb = sb;
338 req->sb_index = sb_index;
339 req->bd_max_bytes = bd_max_bytes;
340 req->stat_id = -1;
341
342 /* add list termination tlv */
343 qed_add_tlv(p_hwfn, &p_iov->offset,
344 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
345
346 resp = &p_iov->pf2vf_reply->queue_start;
347 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
348 if (rc)
349 return rc;
350
351 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
352 return -EINVAL;
353
354 /* Learn the address of the producer from the response */
355 if (pp_prod) {
356 u64 init_prod_val = 0;
357
358 *pp_prod = (u8 __iomem *)p_hwfn->regview + resp->offset;
359 DP_VERBOSE(p_hwfn, QED_MSG_IOV,
360 "Rxq[0x%02x]: producer at %p [offset 0x%08x]\n",
361 rx_qid, *pp_prod, resp->offset);
362
363 /* Init the rcq, rx bd and rx sge (if valid) producers to 0 */
364 __internal_ram_wr(p_hwfn, *pp_prod, sizeof(u64),
365 (u32 *)&init_prod_val);
366 }
367
368 return rc;
369}
370
371int qed_vf_pf_rxq_stop(struct qed_hwfn *p_hwfn, u16 rx_qid, bool cqe_completion)
372{
373 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
374 struct vfpf_stop_rxqs_tlv *req;
375 struct pfvf_def_resp_tlv *resp;
376 int rc;
377
378 /* clear mailbox and prep first tlv */
379 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_STOP_RXQS, sizeof(*req));
380
381 req->rx_qid = rx_qid;
382 req->num_rxqs = 1;
383 req->cqe_completion = cqe_completion;
384
385 /* add list termination tlv */
386 qed_add_tlv(p_hwfn, &p_iov->offset,
387 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
388
389 resp = &p_iov->pf2vf_reply->default_resp;
390 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
391 if (rc)
392 return rc;
393
394 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
395 return -EINVAL;
396
397 return rc;
398}
399
400int qed_vf_pf_txq_start(struct qed_hwfn *p_hwfn,
401 u16 tx_queue_id,
402 u16 sb,
403 u8 sb_index,
404 dma_addr_t pbl_addr,
405 u16 pbl_size, void __iomem **pp_doorbell)
406{
407 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
408 struct vfpf_start_txq_tlv *req;
409 struct pfvf_def_resp_tlv *resp;
410 int rc;
411
412 /* clear mailbox and prep first tlv */
413 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_START_TXQ, sizeof(*req));
414
415 req->tx_qid = tx_queue_id;
416
417 /* Tx */
418 req->pbl_addr = pbl_addr;
419 req->pbl_size = pbl_size;
420 req->hw_sb = sb;
421 req->sb_index = sb_index;
422
423 /* add list termination tlv */
424 qed_add_tlv(p_hwfn, &p_iov->offset,
425 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
426
427 resp = &p_iov->pf2vf_reply->default_resp;
428 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
429 if (rc)
430 return rc;
431
432 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
433 return -EINVAL;
434
435 if (pp_doorbell) {
436 u8 cid = p_iov->acquire_resp.resc.cid[tx_queue_id];
437
438 *pp_doorbell = (u8 __iomem *)p_hwfn->doorbells +
439 qed_db_addr(cid, DQ_DEMS_LEGACY);
440 }
441
442 return rc;
443}
444
445int qed_vf_pf_txq_stop(struct qed_hwfn *p_hwfn, u16 tx_qid)
446{
447 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
448 struct vfpf_stop_txqs_tlv *req;
449 struct pfvf_def_resp_tlv *resp;
450 int rc;
451
452 /* clear mailbox and prep first tlv */
453 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_STOP_TXQS, sizeof(*req));
454
455 req->tx_qid = tx_qid;
456 req->num_txqs = 1;
457
458 /* add list termination tlv */
459 qed_add_tlv(p_hwfn, &p_iov->offset,
460 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
461
462 resp = &p_iov->pf2vf_reply->default_resp;
463 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
464 if (rc)
465 return rc;
466
467 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
468 return -EINVAL;
469
470 return rc;
471}
472
473int qed_vf_pf_vport_start(struct qed_hwfn *p_hwfn,
474 u8 vport_id,
475 u16 mtu,
476 u8 inner_vlan_removal,
477 enum qed_tpa_mode tpa_mode,
Yuval Mintz08feecd2016-05-11 16:36:20 +0300478 u8 max_buffers_per_cqe, u8 only_untagged)
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300479{
480 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
481 struct vfpf_vport_start_tlv *req;
482 struct pfvf_def_resp_tlv *resp;
483 int rc, i;
484
485 /* clear mailbox and prep first tlv */
486 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_START, sizeof(*req));
487
488 req->mtu = mtu;
489 req->vport_id = vport_id;
490 req->inner_vlan_removal = inner_vlan_removal;
491 req->tpa_mode = tpa_mode;
492 req->max_buffers_per_cqe = max_buffers_per_cqe;
Yuval Mintz08feecd2016-05-11 16:36:20 +0300493 req->only_untagged = only_untagged;
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300494
495 /* status blocks */
496 for (i = 0; i < p_hwfn->vf_iov_info->acquire_resp.resc.num_sbs; i++)
497 if (p_hwfn->sbs_info[i])
498 req->sb_addr[i] = p_hwfn->sbs_info[i]->sb_phys;
499
500 /* add list termination tlv */
501 qed_add_tlv(p_hwfn, &p_iov->offset,
502 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
503
504 resp = &p_iov->pf2vf_reply->default_resp;
505 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
506 if (rc)
507 return rc;
508
509 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
510 return -EINVAL;
511
512 return rc;
513}
514
515int qed_vf_pf_vport_stop(struct qed_hwfn *p_hwfn)
516{
517 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
518 struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp;
519 int rc;
520
521 /* clear mailbox and prep first tlv */
522 qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_TEARDOWN,
523 sizeof(struct vfpf_first_tlv));
524
525 /* add list termination tlv */
526 qed_add_tlv(p_hwfn, &p_iov->offset,
527 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
528
529 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
530 if (rc)
531 return rc;
532
533 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
534 return -EINVAL;
535
536 return rc;
537}
538
539static bool
540qed_vf_handle_vp_update_is_needed(struct qed_hwfn *p_hwfn,
541 struct qed_sp_vport_update_params *p_data,
542 u16 tlv)
543{
544 switch (tlv) {
545 case CHANNEL_TLV_VPORT_UPDATE_ACTIVATE:
546 return !!(p_data->update_vport_active_rx_flg ||
547 p_data->update_vport_active_tx_flg);
Yuval Mintz17b235c2016-05-11 16:36:18 +0300548 case CHANNEL_TLV_VPORT_UPDATE_TX_SWITCH:
549 return !!p_data->update_tx_switching_flg;
550 case CHANNEL_TLV_VPORT_UPDATE_VLAN_STRIP:
551 return !!p_data->update_inner_vlan_removal_flg;
Yuval Mintz08feecd2016-05-11 16:36:20 +0300552 case CHANNEL_TLV_VPORT_UPDATE_ACCEPT_ANY_VLAN:
553 return !!p_data->update_accept_any_vlan_flg;
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300554 case CHANNEL_TLV_VPORT_UPDATE_MCAST:
555 return !!p_data->update_approx_mcast_flg;
556 case CHANNEL_TLV_VPORT_UPDATE_ACCEPT_PARAM:
557 return !!(p_data->accept_flags.update_rx_mode_config ||
558 p_data->accept_flags.update_tx_mode_config);
559 case CHANNEL_TLV_VPORT_UPDATE_RSS:
560 return !!p_data->rss_params;
Yuval Mintz17b235c2016-05-11 16:36:18 +0300561 case CHANNEL_TLV_VPORT_UPDATE_SGE_TPA:
562 return !!p_data->sge_tpa_params;
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300563 default:
564 DP_INFO(p_hwfn, "Unexpected vport-update TLV[%d]\n",
565 tlv);
566 return false;
567 }
568}
569
570static void
571qed_vf_handle_vp_update_tlvs_resp(struct qed_hwfn *p_hwfn,
572 struct qed_sp_vport_update_params *p_data)
573{
574 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
575 struct pfvf_def_resp_tlv *p_resp;
576 u16 tlv;
577
578 for (tlv = CHANNEL_TLV_VPORT_UPDATE_ACTIVATE;
579 tlv < CHANNEL_TLV_VPORT_UPDATE_MAX; tlv++) {
580 if (!qed_vf_handle_vp_update_is_needed(p_hwfn, p_data, tlv))
581 continue;
582
583 p_resp = (struct pfvf_def_resp_tlv *)
584 qed_iov_search_list_tlvs(p_hwfn, p_iov->pf2vf_reply,
585 tlv);
586 if (p_resp && p_resp->hdr.status)
587 DP_VERBOSE(p_hwfn, QED_MSG_IOV,
588 "TLV[%d] Configuration %s\n",
589 tlv,
590 (p_resp && p_resp->hdr.status) ? "succeeded"
591 : "failed");
592 }
593}
594
595int qed_vf_pf_vport_update(struct qed_hwfn *p_hwfn,
596 struct qed_sp_vport_update_params *p_params)
597{
598 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
599 struct vfpf_vport_update_tlv *req;
600 struct pfvf_def_resp_tlv *resp;
601 u8 update_rx, update_tx;
602 u32 resp_size = 0;
603 u16 size, tlv;
604 int rc;
605
606 resp = &p_iov->pf2vf_reply->default_resp;
607 resp_size = sizeof(*resp);
608
609 update_rx = p_params->update_vport_active_rx_flg;
610 update_tx = p_params->update_vport_active_tx_flg;
611
612 /* clear mailbox and prep header tlv */
613 qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_UPDATE, sizeof(*req));
614
615 /* Prepare extended tlvs */
616 if (update_rx || update_tx) {
617 struct vfpf_vport_update_activate_tlv *p_act_tlv;
618
619 size = sizeof(struct vfpf_vport_update_activate_tlv);
620 p_act_tlv = qed_add_tlv(p_hwfn, &p_iov->offset,
621 CHANNEL_TLV_VPORT_UPDATE_ACTIVATE,
622 size);
623 resp_size += sizeof(struct pfvf_def_resp_tlv);
624
625 if (update_rx) {
626 p_act_tlv->update_rx = update_rx;
627 p_act_tlv->active_rx = p_params->vport_active_rx_flg;
628 }
629
630 if (update_tx) {
631 p_act_tlv->update_tx = update_tx;
632 p_act_tlv->active_tx = p_params->vport_active_tx_flg;
633 }
634 }
635
636 if (p_params->update_approx_mcast_flg) {
637 struct vfpf_vport_update_mcast_bin_tlv *p_mcast_tlv;
638
639 size = sizeof(struct vfpf_vport_update_mcast_bin_tlv);
640 p_mcast_tlv = qed_add_tlv(p_hwfn, &p_iov->offset,
641 CHANNEL_TLV_VPORT_UPDATE_MCAST, size);
642 resp_size += sizeof(struct pfvf_def_resp_tlv);
643
644 memcpy(p_mcast_tlv->bins, p_params->bins,
645 sizeof(unsigned long) * ETH_MULTICAST_MAC_BINS_IN_REGS);
646 }
647
648 update_rx = p_params->accept_flags.update_rx_mode_config;
649 update_tx = p_params->accept_flags.update_tx_mode_config;
650
651 if (update_rx || update_tx) {
652 struct vfpf_vport_update_accept_param_tlv *p_accept_tlv;
653
654 tlv = CHANNEL_TLV_VPORT_UPDATE_ACCEPT_PARAM;
655 size = sizeof(struct vfpf_vport_update_accept_param_tlv);
656 p_accept_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, tlv, size);
657 resp_size += sizeof(struct pfvf_def_resp_tlv);
658
659 if (update_rx) {
660 p_accept_tlv->update_rx_mode = update_rx;
661 p_accept_tlv->rx_accept_filter =
662 p_params->accept_flags.rx_accept_filter;
663 }
664
665 if (update_tx) {
666 p_accept_tlv->update_tx_mode = update_tx;
667 p_accept_tlv->tx_accept_filter =
668 p_params->accept_flags.tx_accept_filter;
669 }
670 }
671
672 if (p_params->rss_params) {
673 struct qed_rss_params *rss_params = p_params->rss_params;
674 struct vfpf_vport_update_rss_tlv *p_rss_tlv;
675
676 size = sizeof(struct vfpf_vport_update_rss_tlv);
677 p_rss_tlv = qed_add_tlv(p_hwfn,
678 &p_iov->offset,
679 CHANNEL_TLV_VPORT_UPDATE_RSS, size);
680 resp_size += sizeof(struct pfvf_def_resp_tlv);
681
682 if (rss_params->update_rss_config)
683 p_rss_tlv->update_rss_flags |=
684 VFPF_UPDATE_RSS_CONFIG_FLAG;
685 if (rss_params->update_rss_capabilities)
686 p_rss_tlv->update_rss_flags |=
687 VFPF_UPDATE_RSS_CAPS_FLAG;
688 if (rss_params->update_rss_ind_table)
689 p_rss_tlv->update_rss_flags |=
690 VFPF_UPDATE_RSS_IND_TABLE_FLAG;
691 if (rss_params->update_rss_key)
692 p_rss_tlv->update_rss_flags |= VFPF_UPDATE_RSS_KEY_FLAG;
693
694 p_rss_tlv->rss_enable = rss_params->rss_enable;
695 p_rss_tlv->rss_caps = rss_params->rss_caps;
696 p_rss_tlv->rss_table_size_log = rss_params->rss_table_size_log;
697 memcpy(p_rss_tlv->rss_ind_table, rss_params->rss_ind_table,
698 sizeof(rss_params->rss_ind_table));
699 memcpy(p_rss_tlv->rss_key, rss_params->rss_key,
700 sizeof(rss_params->rss_key));
701 }
702
Yuval Mintz08feecd2016-05-11 16:36:20 +0300703 if (p_params->update_accept_any_vlan_flg) {
704 struct vfpf_vport_update_accept_any_vlan_tlv *p_any_vlan_tlv;
705
706 size = sizeof(struct vfpf_vport_update_accept_any_vlan_tlv);
707 tlv = CHANNEL_TLV_VPORT_UPDATE_ACCEPT_ANY_VLAN;
708 p_any_vlan_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, tlv, size);
709
710 resp_size += sizeof(struct pfvf_def_resp_tlv);
711 p_any_vlan_tlv->accept_any_vlan = p_params->accept_any_vlan;
712 p_any_vlan_tlv->update_accept_any_vlan_flg =
713 p_params->update_accept_any_vlan_flg;
714 }
715
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300716 /* add list termination tlv */
717 qed_add_tlv(p_hwfn, &p_iov->offset,
718 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
719
720 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, resp_size);
721 if (rc)
722 return rc;
723
724 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
725 return -EINVAL;
726
727 qed_vf_handle_vp_update_tlvs_resp(p_hwfn, p_params);
728
729 return rc;
730}
731
Yuval Mintz0b55e272016-05-11 16:36:15 +0300732int qed_vf_pf_reset(struct qed_hwfn *p_hwfn)
733{
734 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
735 struct pfvf_def_resp_tlv *resp;
736 struct vfpf_first_tlv *req;
737 int rc;
738
739 /* clear mailbox and prep first tlv */
740 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_CLOSE, sizeof(*req));
741
742 /* add list termination tlv */
743 qed_add_tlv(p_hwfn, &p_iov->offset,
744 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
745
746 resp = &p_iov->pf2vf_reply->default_resp;
747 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
748 if (rc)
749 return rc;
750
751 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
752 return -EAGAIN;
753
754 p_hwfn->b_int_enabled = 0;
755
756 return 0;
757}
758
759int qed_vf_pf_release(struct qed_hwfn *p_hwfn)
760{
761 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
762 struct pfvf_def_resp_tlv *resp;
763 struct vfpf_first_tlv *req;
764 u32 size;
765 int rc;
766
767 /* clear mailbox and prep first tlv */
768 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_RELEASE, sizeof(*req));
769
770 /* add list termination tlv */
771 qed_add_tlv(p_hwfn, &p_iov->offset,
772 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
773
774 resp = &p_iov->pf2vf_reply->default_resp;
775 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
776
777 if (!rc && resp->hdr.status != PFVF_STATUS_SUCCESS)
778 rc = -EAGAIN;
779
780 p_hwfn->b_int_enabled = 0;
781
782 if (p_iov->vf2pf_request)
783 dma_free_coherent(&p_hwfn->cdev->pdev->dev,
784 sizeof(union vfpf_tlvs),
785 p_iov->vf2pf_request,
786 p_iov->vf2pf_request_phys);
787 if (p_iov->pf2vf_reply)
788 dma_free_coherent(&p_hwfn->cdev->pdev->dev,
789 sizeof(union pfvf_tlvs),
790 p_iov->pf2vf_reply, p_iov->pf2vf_reply_phys);
791
792 if (p_iov->bulletin.p_virt) {
793 size = sizeof(struct qed_bulletin_content);
794 dma_free_coherent(&p_hwfn->cdev->pdev->dev,
795 size,
796 p_iov->bulletin.p_virt, p_iov->bulletin.phys);
797 }
798
799 kfree(p_hwfn->vf_iov_info);
800 p_hwfn->vf_iov_info = NULL;
801
802 return rc;
803}
804
Yuval Mintzdacd88d2016-05-11 16:36:16 +0300805void qed_vf_pf_filter_mcast(struct qed_hwfn *p_hwfn,
806 struct qed_filter_mcast *p_filter_cmd)
807{
808 struct qed_sp_vport_update_params sp_params;
809 int i;
810
811 memset(&sp_params, 0, sizeof(sp_params));
812 sp_params.update_approx_mcast_flg = 1;
813
814 if (p_filter_cmd->opcode == QED_FILTER_ADD) {
815 for (i = 0; i < p_filter_cmd->num_mc_addrs; i++) {
816 u32 bit;
817
818 bit = qed_mcast_bin_from_mac(p_filter_cmd->mac[i]);
819 __set_bit(bit, sp_params.bins);
820 }
821 }
822
823 qed_vf_pf_vport_update(p_hwfn, &sp_params);
824}
825
826int qed_vf_pf_filter_ucast(struct qed_hwfn *p_hwfn,
827 struct qed_filter_ucast *p_ucast)
828{
829 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
830 struct vfpf_ucast_filter_tlv *req;
831 struct pfvf_def_resp_tlv *resp;
832 int rc;
833
834 /* clear mailbox and prep first tlv */
835 req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_UCAST_FILTER, sizeof(*req));
836 req->opcode = (u8) p_ucast->opcode;
837 req->type = (u8) p_ucast->type;
838 memcpy(req->mac, p_ucast->mac, ETH_ALEN);
839 req->vlan = p_ucast->vlan;
840
841 /* add list termination tlv */
842 qed_add_tlv(p_hwfn, &p_iov->offset,
843 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
844
845 resp = &p_iov->pf2vf_reply->default_resp;
846 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
847 if (rc)
848 return rc;
849
850 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
851 return -EAGAIN;
852
853 return 0;
854}
855
Yuval Mintz0b55e272016-05-11 16:36:15 +0300856int qed_vf_pf_int_cleanup(struct qed_hwfn *p_hwfn)
857{
858 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
859 struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp;
860 int rc;
861
862 /* clear mailbox and prep first tlv */
863 qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_INT_CLEANUP,
864 sizeof(struct vfpf_first_tlv));
865
866 /* add list termination tlv */
867 qed_add_tlv(p_hwfn, &p_iov->offset,
868 CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv));
869
870 rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
871 if (rc)
872 return rc;
873
874 if (resp->hdr.status != PFVF_STATUS_SUCCESS)
875 return -EINVAL;
876
877 return 0;
878}
879
Yuval Mintz1408cc1f2016-05-11 16:36:14 +0300880u16 qed_vf_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id)
881{
882 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
883
884 if (!p_iov) {
885 DP_NOTICE(p_hwfn, "vf_sriov_info isn't initialized\n");
886 return 0;
887 }
888
889 return p_iov->acquire_resp.resc.hw_sbs[sb_id].hw_sb_id;
890}
891
Yuval Mintz36558c32016-05-11 16:36:17 +0300892int qed_vf_read_bulletin(struct qed_hwfn *p_hwfn, u8 *p_change)
893{
894 struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info;
895 struct qed_bulletin_content shadow;
896 u32 crc, crc_size;
897
898 crc_size = sizeof(p_iov->bulletin.p_virt->crc);
899 *p_change = 0;
900
901 /* Need to guarantee PF is not in the middle of writing it */
902 memcpy(&shadow, p_iov->bulletin.p_virt, p_iov->bulletin.size);
903
904 /* If version did not update, no need to do anything */
905 if (shadow.version == p_iov->bulletin_shadow.version)
906 return 0;
907
908 /* Verify the bulletin we see is valid */
909 crc = crc32(0, (u8 *)&shadow + crc_size,
910 p_iov->bulletin.size - crc_size);
911 if (crc != shadow.crc)
912 return -EAGAIN;
913
914 /* Set the shadow bulletin and process it */
915 memcpy(&p_iov->bulletin_shadow, &shadow, p_iov->bulletin.size);
916
917 DP_VERBOSE(p_hwfn, QED_MSG_IOV,
918 "Read a bulletin update %08x\n", shadow.version);
919
920 *p_change = 1;
921
922 return 0;
923}
924
925void __qed_vf_get_link_params(struct qed_hwfn *p_hwfn,
926 struct qed_mcp_link_params *p_params,
927 struct qed_bulletin_content *p_bulletin)
928{
929 memset(p_params, 0, sizeof(*p_params));
930
931 p_params->speed.autoneg = p_bulletin->req_autoneg;
932 p_params->speed.advertised_speeds = p_bulletin->req_adv_speed;
933 p_params->speed.forced_speed = p_bulletin->req_forced_speed;
934 p_params->pause.autoneg = p_bulletin->req_autoneg_pause;
935 p_params->pause.forced_rx = p_bulletin->req_forced_rx;
936 p_params->pause.forced_tx = p_bulletin->req_forced_tx;
937 p_params->loopback_mode = p_bulletin->req_loopback;
938}
939
940void qed_vf_get_link_params(struct qed_hwfn *p_hwfn,
941 struct qed_mcp_link_params *params)
942{
943 __qed_vf_get_link_params(p_hwfn, params,
944 &(p_hwfn->vf_iov_info->bulletin_shadow));
945}
946
947void __qed_vf_get_link_state(struct qed_hwfn *p_hwfn,
948 struct qed_mcp_link_state *p_link,
949 struct qed_bulletin_content *p_bulletin)
950{
951 memset(p_link, 0, sizeof(*p_link));
952
953 p_link->link_up = p_bulletin->link_up;
954 p_link->speed = p_bulletin->speed;
955 p_link->full_duplex = p_bulletin->full_duplex;
956 p_link->an = p_bulletin->autoneg;
957 p_link->an_complete = p_bulletin->autoneg_complete;
958 p_link->parallel_detection = p_bulletin->parallel_detection;
959 p_link->pfc_enabled = p_bulletin->pfc_enabled;
960 p_link->partner_adv_speed = p_bulletin->partner_adv_speed;
961 p_link->partner_tx_flow_ctrl_en = p_bulletin->partner_tx_flow_ctrl_en;
962 p_link->partner_rx_flow_ctrl_en = p_bulletin->partner_rx_flow_ctrl_en;
963 p_link->partner_adv_pause = p_bulletin->partner_adv_pause;
964 p_link->sfp_tx_fault = p_bulletin->sfp_tx_fault;
965}
966
967void qed_vf_get_link_state(struct qed_hwfn *p_hwfn,
968 struct qed_mcp_link_state *link)
969{
970 __qed_vf_get_link_state(p_hwfn, link,
971 &(p_hwfn->vf_iov_info->bulletin_shadow));
972}
973
974void __qed_vf_get_link_caps(struct qed_hwfn *p_hwfn,
975 struct qed_mcp_link_capabilities *p_link_caps,
976 struct qed_bulletin_content *p_bulletin)
977{
978 memset(p_link_caps, 0, sizeof(*p_link_caps));
979 p_link_caps->speed_capabilities = p_bulletin->capability_speed;
980}
981
982void qed_vf_get_link_caps(struct qed_hwfn *p_hwfn,
983 struct qed_mcp_link_capabilities *p_link_caps)
984{
985 __qed_vf_get_link_caps(p_hwfn, p_link_caps,
986 &(p_hwfn->vf_iov_info->bulletin_shadow));
987}
988
Yuval Mintz1408cc1f2016-05-11 16:36:14 +0300989void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs)
990{
991 *num_rxqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_rxqs;
992}
993
994void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac)
995{
996 memcpy(port_mac,
997 p_hwfn->vf_iov_info->acquire_resp.pfdev_info.port_mac, ETH_ALEN);
998}
999
1000void qed_vf_get_num_vlan_filters(struct qed_hwfn *p_hwfn, u8 *num_vlan_filters)
1001{
1002 struct qed_vf_iov *p_vf;
1003
1004 p_vf = p_hwfn->vf_iov_info;
1005 *num_vlan_filters = p_vf->acquire_resp.resc.num_vlan_filters;
1006}
1007
Yuval Mintzeff16962016-05-11 16:36:21 +03001008bool qed_vf_check_mac(struct qed_hwfn *p_hwfn, u8 *mac)
1009{
1010 struct qed_bulletin_content *bulletin;
1011
1012 bulletin = &p_hwfn->vf_iov_info->bulletin_shadow;
1013 if (!(bulletin->valid_bitmap & (1 << MAC_ADDR_FORCED)))
1014 return true;
1015
1016 /* Forbid VF from changing a MAC enforced by PF */
1017 if (ether_addr_equal(bulletin->mac, mac))
1018 return false;
1019
1020 return false;
1021}
1022
1023bool qed_vf_bulletin_get_forced_mac(struct qed_hwfn *hwfn,
1024 u8 *dst_mac, u8 *p_is_forced)
1025{
1026 struct qed_bulletin_content *bulletin;
1027
1028 bulletin = &hwfn->vf_iov_info->bulletin_shadow;
1029
1030 if (bulletin->valid_bitmap & (1 << MAC_ADDR_FORCED)) {
1031 if (p_is_forced)
1032 *p_is_forced = 1;
1033 } else if (bulletin->valid_bitmap & (1 << VFPF_BULLETIN_MAC_ADDR)) {
1034 if (p_is_forced)
1035 *p_is_forced = 0;
1036 } else {
1037 return false;
1038 }
1039
1040 ether_addr_copy(dst_mac, bulletin->mac);
1041
1042 return true;
1043}
1044
Yuval Mintz1408cc1f2016-05-11 16:36:14 +03001045void qed_vf_get_fw_version(struct qed_hwfn *p_hwfn,
1046 u16 *fw_major, u16 *fw_minor,
1047 u16 *fw_rev, u16 *fw_eng)
1048{
1049 struct pf_vf_pfdev_info *info;
1050
1051 info = &p_hwfn->vf_iov_info->acquire_resp.pfdev_info;
1052
1053 *fw_major = info->fw_major;
1054 *fw_minor = info->fw_minor;
1055 *fw_rev = info->fw_rev;
1056 *fw_eng = info->fw_eng;
1057}
Yuval Mintz36558c32016-05-11 16:36:17 +03001058
1059static void qed_handle_bulletin_change(struct qed_hwfn *hwfn)
1060{
Yuval Mintzeff16962016-05-11 16:36:21 +03001061 struct qed_eth_cb_ops *ops = hwfn->cdev->protocol_ops.eth;
1062 u8 mac[ETH_ALEN], is_mac_exist, is_mac_forced;
1063 void *cookie = hwfn->cdev->ops_cookie;
1064
1065 is_mac_exist = qed_vf_bulletin_get_forced_mac(hwfn, mac,
1066 &is_mac_forced);
1067 if (is_mac_exist && is_mac_forced && cookie)
1068 ops->force_mac(cookie, mac);
1069
Yuval Mintz36558c32016-05-11 16:36:17 +03001070 /* Always update link configuration according to bulletin */
1071 qed_link_update(hwfn);
1072}
1073
1074void qed_iov_vf_task(struct work_struct *work)
1075{
1076 struct qed_hwfn *hwfn = container_of(work, struct qed_hwfn,
1077 iov_task.work);
1078 u8 change = 0;
1079
1080 if (test_and_clear_bit(QED_IOV_WQ_STOP_WQ_FLAG, &hwfn->iov_task_flags))
1081 return;
1082
1083 /* Handle bulletin board changes */
1084 qed_vf_read_bulletin(hwfn, &change);
1085 if (change)
1086 qed_handle_bulletin_change(hwfn);
1087
1088 /* As VF is polling bulletin board, need to constantly re-schedule */
1089 queue_delayed_work(hwfn->iov_wq, &hwfn->iov_task, HZ);
1090}