net/sfc: implement EF10 native Tx datapath
[dpdk.git] / drivers / net / bnx2x / bnx2x_vfpf.c
1 /*
2  * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
3  *
4  * Copyright (c) 2015 QLogic Corporation.
5  * All rights reserved.
6  * www.qlogic.com
7  *
8  * See LICENSE.bnx2x_pmd for copyright and licensing details.
9  */
10
11 #include "bnx2x.h"
12
13 /* calculate the crc in the bulletin board */
14 static inline uint32_t
15 bnx2x_vf_crc(struct bnx2x_vf_bulletin *bull)
16 {
17         uint32_t crc_sz = sizeof(bull->crc), length = bull->length - crc_sz;
18
19         return ECORE_CRC32_LE(0, (uint8_t *)bull + crc_sz, length);
20 }
21
22 /* Checks are there mac/channel updates for VF
23  * returns TRUE if something was updated
24 */
25 int
26 bnx2x_check_bull(struct bnx2x_softc *sc)
27 {
28         struct bnx2x_vf_bulletin *bull;
29         uint8_t tries = 0;
30         uint16_t old_version = sc->old_bulletin.version;
31         uint64_t valid_bitmap;
32
33         bull = sc->pf2vf_bulletin;
34         if (old_version == bull->version) {
35                 return FALSE;
36         } else {
37                 /* Check the crc until we get the correct data */
38                 while (tries < BNX2X_VF_BULLETIN_TRIES) {
39                         bull = sc->pf2vf_bulletin;
40                         if (bull->crc == bnx2x_vf_crc(bull))
41                                 break;
42
43                         PMD_DRV_LOG(ERR, "bad crc on bulletin board. contained %x computed %x",
44                                         bull->crc, bnx2x_vf_crc(bull));
45                         ++tries;
46                 }
47                 if (tries == BNX2X_VF_BULLETIN_TRIES) {
48                         PMD_DRV_LOG(ERR, "pf to vf bulletin board crc was wrong %d consecutive times. Aborting",
49                                         tries);
50                         return FALSE;
51                 }
52         }
53
54         valid_bitmap = bull->valid_bitmap;
55
56         /* check the mac address and VLAN and allocate memory if valid */
57         if (valid_bitmap & (1 << MAC_ADDR_VALID) && memcmp(bull->mac, sc->old_bulletin.mac, ETH_ALEN))
58                 rte_memcpy(&sc->link_params.mac_addr, bull->mac, ETH_ALEN);
59         if (valid_bitmap & (1 << VLAN_VALID))
60                 rte_memcpy(&bull->vlan, &sc->old_bulletin.vlan, VLAN_HLEN);
61
62         sc->old_bulletin = *bull;
63
64         return TRUE;
65 }
66
67 /* place a given tlv on the tlv buffer at a given offset */
68 static void
69 bnx2x_add_tlv(__rte_unused struct bnx2x_softc *sc, void *tlvs_list,
70               uint16_t offset, uint16_t type, uint16_t length)
71 {
72         struct channel_tlv *tl = (struct channel_tlv *)
73                                         ((unsigned long)tlvs_list + offset);
74
75         tl->type = type;
76         tl->length = length;
77 }
78
79 /* Initiliaze header of the first tlv and clear mailbox*/
80 static void
81 bnx2x_vf_prep(struct bnx2x_softc *sc, struct vf_first_tlv *first_tlv,
82               uint16_t type, uint16_t length)
83 {
84         struct bnx2x_vf_mbx_msg *mbox = sc->vf2pf_mbox;
85
86         rte_spinlock_lock(&sc->vf2pf_lock);
87
88         PMD_DRV_LOG(DEBUG, "Preparing %d tlv for sending", type);
89
90         memset(mbox, 0, sizeof(struct bnx2x_vf_mbx_msg));
91
92         bnx2x_add_tlv(sc, &first_tlv->tl, 0, type, length);
93
94         /* Initialize header of the first tlv */
95         first_tlv->reply_offset = sizeof(mbox->query);
96 }
97
98 /* releases the mailbox */
99 static void
100 bnx2x_vf_finalize(struct bnx2x_softc *sc,
101                   __rte_unused struct vf_first_tlv *first_tlv)
102 {
103         PMD_DRV_LOG(DEBUG, "done sending [%d] tlv over vf pf channel",
104                     first_tlv->tl.type);
105
106         rte_spinlock_unlock(&sc->vf2pf_lock);
107 }
108
109 #define BNX2X_VF_CMD_ADDR_LO PXP_VF_ADDR_CSDM_GLOBAL_START
110 #define BNX2X_VF_CMD_ADDR_HI BNX2X_VF_CMD_ADDR_LO + 4
111 #define BNX2X_VF_CMD_TRIGGER BNX2X_VF_CMD_ADDR_HI + 4
112 #define BNX2X_VF_CHANNEL_DELAY 100
113 #define BNX2X_VF_CHANNEL_TRIES 100
114
115 static int
116 bnx2x_do_req4pf(struct bnx2x_softc *sc, phys_addr_t phys_addr)
117 {
118         uint8_t *status = &sc->vf2pf_mbox->resp.common_reply.status;
119         uint8_t i;
120
121         if (*status) {
122                 PMD_DRV_LOG(ERR, "status should be zero before message"
123                                  " to pf was sent");
124                 return -EINVAL;
125         }
126
127         bnx2x_check_bull(sc);
128         if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
129                 PMD_DRV_LOG(ERR, "channel is down. Aborting message sending");
130                 return -EINVAL;
131         }
132
133         REG_WR(sc, BNX2X_VF_CMD_ADDR_LO, U64_LO(phys_addr));
134         REG_WR(sc, BNX2X_VF_CMD_ADDR_HI, U64_HI(phys_addr));
135
136         /* memory barrier to ensure that FW can read phys_addr */
137         wmb();
138
139         REG_WR8(sc, BNX2X_VF_CMD_TRIGGER, 1);
140
141         /* Do several attempts until PF completes */
142         for (i = 0; i < BNX2X_VF_CHANNEL_TRIES; i++) {
143                 DELAY_MS(BNX2X_VF_CHANNEL_DELAY);
144                 if (*status)
145                         break;
146         }
147
148         if (!*status) {
149                 PMD_DRV_LOG(ERR, "Response from PF timed out");
150                 return -EAGAIN;
151         }
152
153         PMD_DRV_LOG(DEBUG, "Response from PF was received");
154         return 0;
155 }
156
157 static inline uint16_t bnx2x_check_me_flags(uint32_t val)
158 {
159         if (((val) & ME_REG_VF_VALID) && (!((val) & ME_REG_VF_ERR)))
160                 return ME_REG_VF_VALID;
161         else
162                 return 0;
163 }
164
165 #define BNX2X_ME_ANSWER_DELAY 100
166 #define BNX2X_ME_ANSWER_TRIES 10
167
168 static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc)
169 {
170         uint32_t val;
171         uint8_t i = 0;
172
173         while (i <= BNX2X_ME_ANSWER_TRIES) {
174                 val = BNX2X_DB_READ(DOORBELL_ADDR(sc, 0));
175                 if (bnx2x_check_me_flags(val))
176                         return VF_ID(val);
177
178                 DELAY_MS(BNX2X_ME_ANSWER_DELAY);
179                 i++;
180         }
181
182         return -EINVAL;
183 }
184
185 #define BNX2X_VF_OBTAIN_MAX_TRIES 3
186 #define BNX2X_VF_OBTAIN_MAC_FILTERS 1
187 #define BNX2X_VF_OBTAIN_MC_FILTERS 10
188
189 static
190 int bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
191 {
192         struct vf_acquire_resp_tlv *resp = &sc->vf2pf_mbox->resp.acquire_resp,
193                                    *sc_resp = &sc->acquire_resp;
194         struct vf_resource_query   *res_query;
195         struct vf_resc             *resc;
196         int res_obtained = false;
197         int tries = 0;
198         int rc;
199
200         do {
201                 PMD_DRV_LOG(DEBUG, "trying to get resources");
202
203                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
204                 if (rc)
205                         return rc;
206
207                 memcpy(sc_resp, resp, sizeof(sc->acquire_resp));
208
209                 tries++;
210
211                 /* check PF to request acceptance */
212                 if (sc_resp->status == BNX2X_VF_STATUS_SUCCESS) {
213                         PMD_DRV_LOG(DEBUG, "resources obtained successfully");
214                         res_obtained = true;
215                 } else if (sc_resp->status == BNX2X_VF_STATUS_NO_RESOURCES &&
216                            tries < BNX2X_VF_OBTAIN_MAX_TRIES) {
217                         PMD_DRV_LOG(DEBUG,
218                            "PF cannot allocate requested amount of resources");
219
220                         res_query = &sc->vf2pf_mbox->query[0].acquire.res_query;
221                         resc      = &sc_resp->resc;
222
223                         /* PF refused our request. Try to decrease request params */
224                         res_query->num_txqs         = min(res_query->num_txqs, resc->num_txqs);
225                         res_query->num_rxqs         = min(res_query->num_rxqs, resc->num_rxqs);
226                         res_query->num_sbs          = min(res_query->num_sbs, resc->num_sbs);
227                         res_query->num_mac_filters  = min(res_query->num_mac_filters, resc->num_mac_filters);
228                         res_query->num_vlan_filters = min(res_query->num_vlan_filters, resc->num_vlan_filters);
229                         res_query->num_mc_filters   = min(res_query->num_mc_filters, resc->num_mc_filters);
230
231                         memset(&sc->vf2pf_mbox->resp, 0, sizeof(union resp_tlvs));
232                 } else {
233                         PMD_DRV_LOG(ERR, "Failed to get the requested "
234                                          "amount of resources: %d.",
235                                          sc_resp->status);
236                         return -EINVAL;
237                 }
238         } while (!res_obtained);
239
240         return 0;
241 }
242
243 int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count)
244 {
245         struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
246         int vf_id;
247         int rc;
248
249         bnx2x_vf_close(sc);
250         bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
251
252         vf_id = bnx2x_read_vf_id(sc);
253         if (vf_id < 0) {
254                 rc = -EAGAIN;
255                 goto out;
256         }
257
258         acq->vf_id = vf_id;
259
260         acq->res_query.num_rxqs = rx_count;
261         acq->res_query.num_txqs = tx_count;
262         acq->res_query.num_sbs = sc->igu_sb_cnt;
263         acq->res_query.num_mac_filters = BNX2X_VF_OBTAIN_MAC_FILTERS;
264         acq->res_query.num_mc_filters = BNX2X_VF_OBTAIN_MC_FILTERS;
265
266         acq->bulletin_addr = sc->pf2vf_bulletin_mapping.paddr;
267
268         /* Request physical port identifier */
269         bnx2x_add_tlv(sc, acq, acq->first_tlv.tl.length,
270                       BNX2X_VF_TLV_PHYS_PORT_ID,
271                       sizeof(struct channel_tlv));
272
273         bnx2x_add_tlv(sc, acq,
274                       (acq->first_tlv.tl.length + sizeof(struct channel_tlv)),
275                       BNX2X_VF_TLV_LIST_END,
276                       sizeof(struct channel_list_end_tlv));
277
278         /* requesting the resources in loop */
279         rc = bnx2x_loop_obtain_resources(sc);
280         if (rc)
281                 goto out;
282
283         struct vf_acquire_resp_tlv sc_resp = sc->acquire_resp;
284
285         sc->devinfo.chip_id        |= (sc_resp.chip_num & 0xFFFF);
286         sc->devinfo.int_block       = INT_BLOCK_IGU;
287         sc->devinfo.chip_port_mode  = CHIP_2_PORT_MODE;
288         sc->devinfo.mf_info.mf_ov   = 0;
289         sc->devinfo.mf_info.mf_mode = 0;
290         sc->devinfo.flash_size      = 0;
291
292         sc->igu_sb_cnt  = sc_resp.resc.num_sbs;
293         sc->igu_base_sb = sc_resp.resc.hw_sbs[0] & 0xFF;
294         sc->igu_dsb_id  = -1;
295         sc->max_tx_queues = sc_resp.resc.num_txqs;
296         sc->max_rx_queues = sc_resp.resc.num_rxqs;
297
298         sc->link_params.chip_id = sc->devinfo.chip_id;
299         sc->doorbell_size = sc_resp.db_size;
300         sc->flags |= BNX2X_NO_WOL_FLAG | BNX2X_NO_ISCSI_OOO_FLAG | BNX2X_NO_ISCSI_FLAG | BNX2X_NO_FCOE_FLAG;
301
302         PMD_DRV_LOG(DEBUG, "status block count = %d, base status block = %x",
303                 sc->igu_sb_cnt, sc->igu_base_sb);
304         strncpy(sc->fw_ver, sc_resp.fw_ver, sizeof(sc->fw_ver));
305
306         if (is_valid_assigned_ether_addr(&sc_resp.resc.current_mac_addr))
307                 ether_addr_copy(&sc_resp.resc.current_mac_addr,
308                                 (struct ether_addr *)sc->link_params.mac_addr);
309         else
310                 eth_random_addr(sc->link_params.mac_addr);
311
312 out:
313         bnx2x_vf_finalize(sc, &acq->first_tlv);
314
315         return rc;
316 }
317
318 /* Ask PF to release VF's resources */
319 void
320 bnx2x_vf_close(struct bnx2x_softc *sc)
321 {
322         struct vf_release_tlv *query;
323         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
324         int vf_id = bnx2x_read_vf_id(sc);
325         int rc;
326
327         if (vf_id >= 0) {
328                 query = &sc->vf2pf_mbox->query[0].release;
329                 bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
330                               sizeof(*query));
331
332                 query->vf_id = vf_id;
333                 bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
334                               BNX2X_VF_TLV_LIST_END,
335                               sizeof(struct channel_list_end_tlv));
336
337                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
338                 if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
339                         PMD_DRV_LOG(ERR, "Failed to release VF");
340
341                 bnx2x_vf_finalize(sc, &query->first_tlv);
342         }
343 }
344
345 /* Let PF know the VF status blocks phys_addrs */
346 int
347 bnx2x_vf_init(struct bnx2x_softc *sc)
348 {
349         struct vf_init_tlv *query;
350         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
351         int i, rc;
352
353         query = &sc->vf2pf_mbox->query[0].init;
354         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
355                       sizeof(*query));
356
357         FOR_EACH_QUEUE(sc, i) {
358                 query->sb_addr[i] = (unsigned long)(sc->fp[i].sb_dma.paddr);
359         }
360
361         query->stats_step = sizeof(struct per_queue_stats);
362         query->stats_addr = sc->fw_stats_data_mapping +
363                 offsetof(struct bnx2x_fw_stats_data, queue_stats);
364
365         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
366                       BNX2X_VF_TLV_LIST_END,
367                       sizeof(struct channel_list_end_tlv));
368
369         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
370         if (rc)
371                 goto out;
372         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
373                 PMD_DRV_LOG(ERR, "Failed to init VF");
374                 rc = -EINVAL;
375                 goto out;
376         }
377
378         PMD_DRV_LOG(DEBUG, "VF was initialized");
379 out:
380         bnx2x_vf_finalize(sc, &query->first_tlv);
381         return rc;
382 }
383
384 void
385 bnx2x_vf_unload(struct bnx2x_softc *sc)
386 {
387         struct vf_close_tlv *query;
388         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
389         struct vf_q_op_tlv *query_op;
390         int i, vf_id, rc;
391
392         vf_id = bnx2x_read_vf_id(sc);
393         if (vf_id > 0) {
394                 FOR_EACH_QUEUE(sc, i) {
395                         query_op = &sc->vf2pf_mbox->query[0].q_op;
396                         bnx2x_vf_prep(sc, &query_op->first_tlv,
397                                       BNX2X_VF_TLV_TEARDOWN_Q,
398                                       sizeof(*query_op));
399
400                         query_op->vf_qid = i;
401
402                         bnx2x_add_tlv(sc, query_op,
403                                       query_op->first_tlv.tl.length,
404                                       BNX2X_VF_TLV_LIST_END,
405                                       sizeof(struct channel_list_end_tlv));
406
407                         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
408                         if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
409                                 PMD_DRV_LOG(ERR,
410                                             "Bad reply for vf_q %d teardown", i);
411
412                         bnx2x_vf_finalize(sc, &query_op->first_tlv);
413                 }
414
415                 bnx2x_vf_set_mac(sc, false);
416
417                 query = &sc->vf2pf_mbox->query[0].close;
418                 bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
419                               sizeof(*query));
420
421                 query->vf_id = vf_id;
422
423                 bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
424                               BNX2X_VF_TLV_LIST_END,
425                               sizeof(struct channel_list_end_tlv));
426
427                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
428                 if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
429                         PMD_DRV_LOG(ERR,
430                                     "Bad reply from PF for close message");
431
432                 bnx2x_vf_finalize(sc, &query->first_tlv);
433         }
434 }
435
436 static inline uint16_t
437 bnx2x_vf_q_flags(uint8_t leading)
438 {
439         uint16_t flags = leading ? BNX2X_VF_Q_FLAG_LEADING_RSS : 0;
440
441         flags |= BNX2X_VF_Q_FLAG_CACHE_ALIGN;
442         flags |= BNX2X_VF_Q_FLAG_STATS;
443         flags |= BNX2X_VF_Q_FLAG_VLAN;
444
445         return flags;
446 }
447
448 static void
449 bnx2x_vf_rx_q_prep(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp,
450                 struct vf_rxq_params *rxq_init, uint16_t flags)
451 {
452         struct bnx2x_rx_queue *rxq;
453
454         rxq = sc->rx_queues[fp->index];
455         if (!rxq) {
456                 PMD_DRV_LOG(ERR, "RX queue %d is NULL", fp->index);
457                 return;
458         }
459
460         rxq_init->rcq_addr = rxq->cq_ring_phys_addr;
461         rxq_init->rcq_np_addr = rxq->cq_ring_phys_addr + BNX2X_PAGE_SIZE;
462         rxq_init->rxq_addr = rxq->rx_ring_phys_addr;
463         rxq_init->vf_sb_id = fp->index;
464         rxq_init->sb_cq_index = HC_INDEX_ETH_RX_CQ_CONS;
465         rxq_init->mtu = sc->mtu;
466         rxq_init->buf_sz = fp->rx_buf_size;
467         rxq_init->flags = flags;
468         rxq_init->stat_id = -1;
469         rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT;
470 }
471
472 static void
473 bnx2x_vf_tx_q_prep(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp,
474                 struct vf_txq_params *txq_init, uint16_t flags)
475 {
476         struct bnx2x_tx_queue *txq;
477
478         txq = sc->tx_queues[fp->index];
479         if (!txq) {
480                 PMD_DRV_LOG(ERR, "TX queue %d is NULL", fp->index);
481                 return;
482         }
483
484         txq_init->txq_addr = txq->tx_ring_phys_addr;
485         txq_init->sb_index = HC_INDEX_ETH_TX_CQ_CONS_COS0;
486         txq_init->flags = flags;
487         txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW;
488         txq_init->vf_sb_id = fp->index;
489 }
490
491 int
492 bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int leading)
493 {
494         struct vf_setup_q_tlv *query;
495         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
496         uint16_t flags = bnx2x_vf_q_flags(leading);
497         int rc;
498
499         query = &sc->vf2pf_mbox->query[0].setup_q;
500         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SETUP_Q,
501                       sizeof(*query));
502
503         query->vf_qid = fp->index;
504         query->param_valid = VF_RXQ_VALID | VF_TXQ_VALID;
505
506         bnx2x_vf_rx_q_prep(sc, fp, &query->rxq, flags);
507         bnx2x_vf_tx_q_prep(sc, fp, &query->txq, flags);
508
509         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
510                       BNX2X_VF_TLV_LIST_END,
511                       sizeof(struct channel_list_end_tlv));
512
513         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
514         if (rc)
515                 goto out;
516         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
517                 PMD_DRV_LOG(ERR, "Failed to setup VF queue[%d]",
518                                  fp->index);
519                 rc = -EINVAL;
520         }
521 out:
522         bnx2x_vf_finalize(sc, &query->first_tlv);
523
524         return rc;
525 }
526
527 int
528 bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
529 {
530         struct vf_set_q_filters_tlv *query;
531         struct vf_common_reply_tlv *reply;
532         int rc;
533
534         query = &sc->vf2pf_mbox->query[0].set_q_filters;
535         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
536                         sizeof(*query));
537
538         query->vf_qid = sc->fp->index;
539         query->mac_filters_cnt = 1;
540         query->flags = BNX2X_VF_MAC_VLAN_CHANGED;
541
542         query->filters[0].flags = (set ? BNX2X_VF_Q_FILTER_SET_MAC : 0) |
543                 BNX2X_VF_Q_FILTER_DEST_MAC_VALID;
544
545         bnx2x_check_bull(sc);
546
547         rte_memcpy(query->filters[0].mac, sc->link_params.mac_addr, ETH_ALEN);
548
549         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
550                       BNX2X_VF_TLV_LIST_END,
551                       sizeof(struct channel_list_end_tlv));
552
553         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
554         if (rc)
555                 goto out;
556         reply = &sc->vf2pf_mbox->resp.common_reply;
557
558         while (BNX2X_VF_STATUS_FAILURE == reply->status &&
559                         bnx2x_check_bull(sc)) {
560                 /* A new mac was configured by PF for us */
561                 rte_memcpy(sc->link_params.mac_addr, sc->pf2vf_bulletin->mac,
562                                 ETH_ALEN);
563                 rte_memcpy(query->filters[0].mac, sc->pf2vf_bulletin->mac,
564                                 ETH_ALEN);
565
566                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
567                 if (rc)
568                         goto out;
569         }
570
571         if (BNX2X_VF_STATUS_SUCCESS != reply->status) {
572                 PMD_DRV_LOG(ERR, "Bad reply from PF for SET MAC message: %d",
573                                 reply->status);
574                 rc = -EINVAL;
575         }
576 out:
577         bnx2x_vf_finalize(sc, &query->first_tlv);
578
579         return rc;
580 }
581
582 int
583 bnx2x_vf_config_rss(struct bnx2x_softc *sc,
584                           struct ecore_config_rss_params *params)
585 {
586         struct vf_rss_tlv *query;
587         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
588         int rc;
589
590         query = &sc->vf2pf_mbox->query[0].update_rss;
591
592         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_UPDATE_RSS,
593                         sizeof(*query));
594
595         /* add list termination tlv */
596         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
597                       BNX2X_VF_TLV_LIST_END,
598                       sizeof(struct channel_list_end_tlv));
599
600         rte_memcpy(query->rss_key, params->rss_key, sizeof(params->rss_key));
601         query->rss_key_size = T_ETH_RSS_KEY;
602
603         rte_memcpy(query->ind_table, params->ind_table, T_ETH_INDIRECTION_TABLE_SIZE);
604         query->ind_table_size = T_ETH_INDIRECTION_TABLE_SIZE;
605
606         query->rss_result_mask = params->rss_result_mask;
607         query->rss_flags = params->rss_flags;
608
609         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
610         if (rc)
611                 goto out;
612
613         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
614                 PMD_DRV_LOG(ERR, "Failed to configure RSS");
615                 rc = -EINVAL;
616         }
617 out:
618         bnx2x_vf_finalize(sc, &query->first_tlv);
619
620         return rc;
621 }
622
623 int
624 bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
625 {
626         struct vf_set_q_filters_tlv *query;
627         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
628         int rc;
629
630         query = &sc->vf2pf_mbox->query[0].set_q_filters;
631         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
632                         sizeof(*query));
633
634         query->vf_qid = 0;
635         query->flags = BNX2X_VF_RX_MASK_CHANGED;
636
637         switch (sc->rx_mode) {
638         case BNX2X_RX_MODE_NONE: /* no Rx */
639                 query->rx_mask = VFPF_RX_MASK_ACCEPT_NONE;
640                 break;
641         case BNX2X_RX_MODE_NORMAL:
642                 query->rx_mask = VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
643                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
644                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
645                 break;
646         case BNX2X_RX_MODE_ALLMULTI:
647                 query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
648                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
649                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
650                 break;
651         case BNX2X_RX_MODE_ALLMULTI_PROMISC:
652         case BNX2X_RX_MODE_PROMISC:
653                 query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_UNICAST;
654                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
655                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
656                 break;
657         default:
658                 PMD_DRV_LOG(ERR, "BAD rx mode (%d)", sc->rx_mode);
659                 rc = -EINVAL;
660                 goto out;
661         }
662
663         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
664                       BNX2X_VF_TLV_LIST_END,
665                       sizeof(struct channel_list_end_tlv));
666
667         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
668         if (rc)
669                 goto out;
670
671         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
672                 PMD_DRV_LOG(ERR, "Failed to set RX mode");
673                 rc = -EINVAL;
674         }
675
676 out:
677         bnx2x_vf_finalize(sc, &query->first_tlv);
678
679         return rc;
680 }