net/bnx2x: check return codes during VF mailbox operation
[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 struct bnx2x_obtain_status {
190         int success;
191         int err_code;
192 };
193
194 static
195 struct bnx2x_obtain_status bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
196 {
197         int tries = 0;
198         struct vf_acquire_resp_tlv *resp = &sc->vf2pf_mbox->resp.acquire_resp,
199                                                                  *sc_resp = &sc->acquire_resp;
200         struct vf_resource_query    *res_query;
201         struct vf_resc            *resc;
202         struct bnx2x_obtain_status     status;
203         int res_obtained = false;
204
205         do {
206                 PMD_DRV_LOG(DEBUG, "trying to get resources");
207
208                 if (bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr)) {
209                         /* timeout */
210                         status.success = 0;
211                         status.err_code = -EAGAIN;
212                         return status;
213                 }
214
215                 memcpy(sc_resp, resp, sizeof(sc->acquire_resp));
216
217                 tries++;
218
219                 /* check PF to request acceptance */
220                 if (sc_resp->status == BNX2X_VF_STATUS_SUCCESS) {
221                         PMD_DRV_LOG(DEBUG, "resources obtained successfully");
222                         res_obtained = true;
223                 } else if (sc_resp->status == BNX2X_VF_STATUS_NO_RESOURCES &&
224                         tries < BNX2X_VF_OBTAIN_MAX_TRIES) {
225                         PMD_DRV_LOG(DEBUG,
226                            "PF cannot allocate requested amount of resources");
227
228                         res_query = &sc->vf2pf_mbox->query[0].acquire.res_query;
229                         resc     = &sc_resp->resc;
230
231                         /* PF refused our request. Try to decrease request params */
232                         res_query->num_txqs         = min(res_query->num_txqs, resc->num_txqs);
233                         res_query->num_rxqs         = min(res_query->num_rxqs, resc->num_rxqs);
234                         res_query->num_sbs          = min(res_query->num_sbs, resc->num_sbs);
235                         res_query->num_mac_filters  = min(res_query->num_mac_filters, resc->num_mac_filters);
236                         res_query->num_vlan_filters = min(res_query->num_vlan_filters, resc->num_vlan_filters);
237                         res_query->num_mc_filters   = min(res_query->num_mc_filters, resc->num_mc_filters);
238
239                         memset(&sc->vf2pf_mbox->resp, 0, sizeof(union resp_tlvs));
240                 } else {
241                         PMD_DRV_LOG(ERR, "Resources cannot be obtained. Status of handling: %d. Aborting",
242                                         sc_resp->status);
243                         status.success = 0;
244                         status.err_code = -EAGAIN;
245                         return status;
246                 }
247         } while (!res_obtained);
248
249         status.success = 1;
250         return status;
251 }
252
253 int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count)
254 {
255         struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
256         int vf_id;
257         struct bnx2x_obtain_status obtain_status;
258         int rc = 0;
259
260         bnx2x_vf_close(sc);
261         bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
262
263         vf_id = bnx2x_read_vf_id(sc);
264         if (vf_id < 0) {
265                 rc = -EAGAIN;
266                 goto out;
267         }
268
269         acq->vf_id = vf_id;
270
271         acq->res_query.num_rxqs = rx_count;
272         acq->res_query.num_txqs = tx_count;
273         acq->res_query.num_sbs = sc->igu_sb_cnt;
274         acq->res_query.num_mac_filters = BNX2X_VF_OBTAIN_MAC_FILTERS;
275         acq->res_query.num_mc_filters = BNX2X_VF_OBTAIN_MC_FILTERS;
276
277         acq->bulletin_addr = sc->pf2vf_bulletin_mapping.paddr;
278
279         /* Request physical port identifier */
280         bnx2x_add_tlv(sc, acq, acq->first_tlv.tl.length,
281                       BNX2X_VF_TLV_PHYS_PORT_ID,
282                       sizeof(struct channel_tlv));
283
284         bnx2x_add_tlv(sc, acq,
285                       (acq->first_tlv.tl.length + sizeof(struct channel_tlv)),
286                       BNX2X_VF_TLV_LIST_END,
287                       sizeof(struct channel_list_end_tlv));
288
289         /* requesting the resources in loop */
290         obtain_status = bnx2x_loop_obtain_resources(sc);
291         if (!obtain_status.success) {
292                 rc = obtain_status.err_code;
293                 goto out;
294         }
295
296         struct vf_acquire_resp_tlv sc_resp = sc->acquire_resp;
297
298         sc->devinfo.chip_id        |= (sc_resp.chip_num & 0xFFFF);
299         sc->devinfo.int_block       = INT_BLOCK_IGU;
300         sc->devinfo.chip_port_mode  = CHIP_2_PORT_MODE;
301         sc->devinfo.mf_info.mf_ov   = 0;
302         sc->devinfo.mf_info.mf_mode = 0;
303         sc->devinfo.flash_size      = 0;
304
305         sc->igu_sb_cnt  = sc_resp.resc.num_sbs;
306         sc->igu_base_sb = sc_resp.resc.hw_sbs[0] & 0xFF;
307         sc->igu_dsb_id  = -1;
308         sc->max_tx_queues = sc_resp.resc.num_txqs;
309         sc->max_rx_queues = sc_resp.resc.num_rxqs;
310
311         sc->link_params.chip_id = sc->devinfo.chip_id;
312         sc->doorbell_size = sc_resp.db_size;
313         sc->flags |= BNX2X_NO_WOL_FLAG | BNX2X_NO_ISCSI_OOO_FLAG | BNX2X_NO_ISCSI_FLAG | BNX2X_NO_FCOE_FLAG;
314
315         PMD_DRV_LOG(DEBUG, "status block count = %d, base status block = %x",
316                 sc->igu_sb_cnt, sc->igu_base_sb);
317         strncpy(sc->fw_ver, sc_resp.fw_ver, sizeof(sc->fw_ver));
318
319         if (is_valid_assigned_ether_addr(&sc_resp.resc.current_mac_addr))
320                 ether_addr_copy(&sc_resp.resc.current_mac_addr,
321                                 (struct ether_addr *)sc->link_params.mac_addr);
322         else
323                 eth_random_addr(sc->link_params.mac_addr);
324
325 out:
326         bnx2x_vf_finalize(sc, &acq->first_tlv);
327
328         return rc;
329 }
330
331 /* Ask PF to release VF's resources */
332 void
333 bnx2x_vf_close(struct bnx2x_softc *sc)
334 {
335         struct vf_release_tlv *query;
336         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
337         int vf_id = bnx2x_read_vf_id(sc);
338         int rc;
339
340         if (vf_id >= 0) {
341                 query = &sc->vf2pf_mbox->query[0].release;
342                 bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
343                               sizeof(*query));
344
345                 query->vf_id = vf_id;
346                 bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
347                               BNX2X_VF_TLV_LIST_END,
348                               sizeof(struct channel_list_end_tlv));
349
350                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
351                 if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
352                         PMD_DRV_LOG(ERR, "Failed to release VF");
353
354                 bnx2x_vf_finalize(sc, &query->first_tlv);
355         }
356 }
357
358 /* Let PF know the VF status blocks phys_addrs */
359 int
360 bnx2x_vf_init(struct bnx2x_softc *sc)
361 {
362         struct vf_init_tlv *query;
363         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
364         int i, rc;
365
366         query = &sc->vf2pf_mbox->query[0].init;
367         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
368                       sizeof(*query));
369
370         FOR_EACH_QUEUE(sc, i) {
371                 query->sb_addr[i] = (unsigned long)(sc->fp[i].sb_dma.paddr);
372         }
373
374         query->stats_step = sizeof(struct per_queue_stats);
375         query->stats_addr = sc->fw_stats_data_mapping +
376                 offsetof(struct bnx2x_fw_stats_data, queue_stats);
377
378         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
379                       BNX2X_VF_TLV_LIST_END,
380                       sizeof(struct channel_list_end_tlv));
381
382         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
383         if (rc)
384                 goto out;
385         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
386                 PMD_DRV_LOG(ERR, "Failed to init VF");
387                 rc = -EINVAL;
388                 goto out;
389         }
390
391         PMD_DRV_LOG(DEBUG, "VF was initialized");
392 out:
393         bnx2x_vf_finalize(sc, &query->first_tlv);
394         return rc;
395 }
396
397 void
398 bnx2x_vf_unload(struct bnx2x_softc *sc)
399 {
400         struct vf_close_tlv *query;
401         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
402         struct vf_q_op_tlv *query_op;
403         int i, vf_id, rc;
404
405         vf_id = bnx2x_read_vf_id(sc);
406         if (vf_id > 0) {
407                 FOR_EACH_QUEUE(sc, i) {
408                         query_op = &sc->vf2pf_mbox->query[0].q_op;
409                         bnx2x_vf_prep(sc, &query_op->first_tlv,
410                                       BNX2X_VF_TLV_TEARDOWN_Q,
411                                       sizeof(*query_op));
412
413                         query_op->vf_qid = i;
414
415                         bnx2x_add_tlv(sc, query_op,
416                                       query_op->first_tlv.tl.length,
417                                       BNX2X_VF_TLV_LIST_END,
418                                       sizeof(struct channel_list_end_tlv));
419
420                         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
421                         if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
422                                 PMD_DRV_LOG(ERR,
423                                             "Bad reply for vf_q %d teardown", i);
424
425                         bnx2x_vf_finalize(sc, &query_op->first_tlv);
426                 }
427
428                 bnx2x_vf_set_mac(sc, false);
429
430                 query = &sc->vf2pf_mbox->query[0].close;
431                 bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_CLOSE,
432                               sizeof(*query));
433
434                 query->vf_id = vf_id;
435
436                 bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
437                               BNX2X_VF_TLV_LIST_END,
438                               sizeof(struct channel_list_end_tlv));
439
440                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
441                 if (rc || reply->status != BNX2X_VF_STATUS_SUCCESS)
442                         PMD_DRV_LOG(ERR,
443                                     "Bad reply from PF for close message");
444
445                 bnx2x_vf_finalize(sc, &query->first_tlv);
446         }
447 }
448
449 static inline uint16_t
450 bnx2x_vf_q_flags(uint8_t leading)
451 {
452         uint16_t flags = leading ? BNX2X_VF_Q_FLAG_LEADING_RSS : 0;
453
454         flags |= BNX2X_VF_Q_FLAG_CACHE_ALIGN;
455         flags |= BNX2X_VF_Q_FLAG_STATS;
456         flags |= BNX2X_VF_Q_FLAG_VLAN;
457
458         return flags;
459 }
460
461 static void
462 bnx2x_vf_rx_q_prep(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp,
463                 struct vf_rxq_params *rxq_init, uint16_t flags)
464 {
465         struct bnx2x_rx_queue *rxq;
466
467         rxq = sc->rx_queues[fp->index];
468         if (!rxq) {
469                 PMD_DRV_LOG(ERR, "RX queue %d is NULL", fp->index);
470                 return;
471         }
472
473         rxq_init->rcq_addr = rxq->cq_ring_phys_addr;
474         rxq_init->rcq_np_addr = rxq->cq_ring_phys_addr + BNX2X_PAGE_SIZE;
475         rxq_init->rxq_addr = rxq->rx_ring_phys_addr;
476         rxq_init->vf_sb_id = fp->index;
477         rxq_init->sb_cq_index = HC_INDEX_ETH_RX_CQ_CONS;
478         rxq_init->mtu = sc->mtu;
479         rxq_init->buf_sz = fp->rx_buf_size;
480         rxq_init->flags = flags;
481         rxq_init->stat_id = -1;
482         rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT;
483 }
484
485 static void
486 bnx2x_vf_tx_q_prep(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp,
487                 struct vf_txq_params *txq_init, uint16_t flags)
488 {
489         struct bnx2x_tx_queue *txq;
490
491         txq = sc->tx_queues[fp->index];
492         if (!txq) {
493                 PMD_DRV_LOG(ERR, "TX queue %d is NULL", fp->index);
494                 return;
495         }
496
497         txq_init->txq_addr = txq->tx_ring_phys_addr;
498         txq_init->sb_index = HC_INDEX_ETH_TX_CQ_CONS_COS0;
499         txq_init->flags = flags;
500         txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW;
501         txq_init->vf_sb_id = fp->index;
502 }
503
504 int
505 bnx2x_vf_setup_queue(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp, int leading)
506 {
507         struct vf_setup_q_tlv *query;
508         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
509         uint16_t flags = bnx2x_vf_q_flags(leading);
510         int rc;
511
512         query = &sc->vf2pf_mbox->query[0].setup_q;
513         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SETUP_Q,
514                       sizeof(*query));
515
516         query->vf_qid = fp->index;
517         query->param_valid = VF_RXQ_VALID | VF_TXQ_VALID;
518
519         bnx2x_vf_rx_q_prep(sc, fp, &query->rxq, flags);
520         bnx2x_vf_tx_q_prep(sc, fp, &query->txq, flags);
521
522         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
523                       BNX2X_VF_TLV_LIST_END,
524                       sizeof(struct channel_list_end_tlv));
525
526         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
527         if (rc)
528                 goto out;
529         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
530                 PMD_DRV_LOG(ERR, "Failed to setup VF queue[%d]",
531                                  fp->index);
532                 rc = -EINVAL;
533         }
534 out:
535         bnx2x_vf_finalize(sc, &query->first_tlv);
536
537         return rc;
538 }
539
540 int
541 bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
542 {
543         struct vf_set_q_filters_tlv *query;
544         struct vf_common_reply_tlv *reply;
545         int rc;
546
547         query = &sc->vf2pf_mbox->query[0].set_q_filters;
548         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
549                         sizeof(*query));
550
551         query->vf_qid = sc->fp->index;
552         query->mac_filters_cnt = 1;
553         query->flags = BNX2X_VF_MAC_VLAN_CHANGED;
554
555         query->filters[0].flags = (set ? BNX2X_VF_Q_FILTER_SET_MAC : 0) |
556                 BNX2X_VF_Q_FILTER_DEST_MAC_VALID;
557
558         bnx2x_check_bull(sc);
559
560         rte_memcpy(query->filters[0].mac, sc->link_params.mac_addr, ETH_ALEN);
561
562         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
563                       BNX2X_VF_TLV_LIST_END,
564                       sizeof(struct channel_list_end_tlv));
565
566         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
567         if (rc)
568                 goto out;
569         reply = &sc->vf2pf_mbox->resp.common_reply;
570
571         while (BNX2X_VF_STATUS_FAILURE == reply->status &&
572                         bnx2x_check_bull(sc)) {
573                 /* A new mac was configured by PF for us */
574                 rte_memcpy(sc->link_params.mac_addr, sc->pf2vf_bulletin->mac,
575                                 ETH_ALEN);
576                 rte_memcpy(query->filters[0].mac, sc->pf2vf_bulletin->mac,
577                                 ETH_ALEN);
578
579                 rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
580                 if (rc)
581                         goto out;
582         }
583
584         if (BNX2X_VF_STATUS_SUCCESS != reply->status) {
585                 PMD_DRV_LOG(ERR, "Bad reply from PF for SET MAC message: %d",
586                                 reply->status);
587                 rc = -EINVAL;
588         }
589 out:
590         bnx2x_vf_finalize(sc, &query->first_tlv);
591
592         return rc;
593 }
594
595 int
596 bnx2x_vf_config_rss(struct bnx2x_softc *sc,
597                           struct ecore_config_rss_params *params)
598 {
599         struct vf_rss_tlv *query;
600         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
601         int rc;
602
603         query = &sc->vf2pf_mbox->query[0].update_rss;
604
605         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_UPDATE_RSS,
606                         sizeof(*query));
607
608         /* add list termination tlv */
609         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
610                       BNX2X_VF_TLV_LIST_END,
611                       sizeof(struct channel_list_end_tlv));
612
613         rte_memcpy(query->rss_key, params->rss_key, sizeof(params->rss_key));
614         query->rss_key_size = T_ETH_RSS_KEY;
615
616         rte_memcpy(query->ind_table, params->ind_table, T_ETH_INDIRECTION_TABLE_SIZE);
617         query->ind_table_size = T_ETH_INDIRECTION_TABLE_SIZE;
618
619         query->rss_result_mask = params->rss_result_mask;
620         query->rss_flags = params->rss_flags;
621
622         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
623         if (rc)
624                 goto out;
625
626         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
627                 PMD_DRV_LOG(ERR, "Failed to configure RSS");
628                 rc = -EINVAL;
629         }
630 out:
631         bnx2x_vf_finalize(sc, &query->first_tlv);
632
633         return rc;
634 }
635
636 int
637 bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
638 {
639         struct vf_set_q_filters_tlv *query;
640         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
641         int rc;
642
643         query = &sc->vf2pf_mbox->query[0].set_q_filters;
644         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
645                         sizeof(*query));
646
647         query->vf_qid = 0;
648         query->flags = BNX2X_VF_RX_MASK_CHANGED;
649
650         switch (sc->rx_mode) {
651         case BNX2X_RX_MODE_NONE: /* no Rx */
652                 query->rx_mask = VFPF_RX_MASK_ACCEPT_NONE;
653                 break;
654         case BNX2X_RX_MODE_NORMAL:
655                 query->rx_mask = VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
656                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
657                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
658                 break;
659         case BNX2X_RX_MODE_ALLMULTI:
660                 query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
661                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
662                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
663                 break;
664         case BNX2X_RX_MODE_PROMISC:
665                 query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_UNICAST;
666                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
667                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
668                 break;
669         default:
670                 PMD_DRV_LOG(ERR, "BAD rx mode (%d)", sc->rx_mode);
671                 rc = -EINVAL;
672                 goto out;
673         }
674
675         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
676                       BNX2X_VF_TLV_LIST_END,
677                       sizeof(struct channel_list_end_tlv));
678
679         rc = bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
680         if (rc)
681                 goto out;
682
683         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
684                 PMD_DRV_LOG(ERR, "Failed to set RX mode");
685                 rc = -EINVAL;
686         }
687
688 out:
689         bnx2x_vf_finalize(sc, &query->first_tlv);
690
691         return rc;
692 }