net/bnx2x: serialize access to VF mailbox
[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                 bnx2x_check_bull(sc);
123                 if (sc->old_bulletin.valid_bitmap & (1 << CHANNEL_DOWN)) {
124                         PMD_DRV_LOG(ERR, "channel is down. Aborting message sending");
125                         *status = BNX2X_VF_STATUS_SUCCESS;
126                         return 0;
127                 }
128
129                 REG_WR(sc, BNX2X_VF_CMD_ADDR_LO, U64_LO(phys_addr));
130                 REG_WR(sc, BNX2X_VF_CMD_ADDR_HI, U64_HI(phys_addr));
131
132                 /* memory barrier to ensure that FW can read phys_addr */
133                 wmb();
134
135                 REG_WR8(sc, BNX2X_VF_CMD_TRIGGER, 1);
136
137                 /* Do several attempts until PF completes
138                  * "." is used to show progress
139                  */
140                 for (i = 0; i < BNX2X_VF_CHANNEL_TRIES; i++) {
141                         DELAY_MS(BNX2X_VF_CHANNEL_DELAY);
142                         if (*status)
143                                 break;
144                 }
145
146                 if (!*status) {
147                         PMD_DRV_LOG(ERR, "Response from PF timed out");
148                         return -EAGAIN;
149                 }
150         } else {
151                 PMD_DRV_LOG(ERR, "status should be zero before message"
152                                 "to pf was sent");
153                 return -EINVAL;
154         }
155
156         PMD_DRV_LOG(DEBUG, "Response from PF was received");
157         return 0;
158 }
159
160 static inline uint16_t bnx2x_check_me_flags(uint32_t val)
161 {
162         if (((val) & ME_REG_VF_VALID) && (!((val) & ME_REG_VF_ERR)))
163                 return ME_REG_VF_VALID;
164         else
165                 return 0;
166 }
167
168 #define BNX2X_ME_ANSWER_DELAY 100
169 #define BNX2X_ME_ANSWER_TRIES 10
170
171 static inline int bnx2x_read_vf_id(struct bnx2x_softc *sc)
172 {
173         uint32_t val;
174         uint8_t i = 0;
175
176         while (i <= BNX2X_ME_ANSWER_TRIES) {
177                 val = BNX2X_DB_READ(DOORBELL_ADDR(sc, 0));
178                 if (bnx2x_check_me_flags(val))
179                         return VF_ID(val);
180
181                 DELAY_MS(BNX2X_ME_ANSWER_DELAY);
182                 i++;
183         }
184
185         return -EINVAL;
186 }
187
188 #define BNX2X_VF_OBTAIN_MAX_TRIES 3
189 #define BNX2X_VF_OBTAIN_MAC_FILTERS 1
190 #define BNX2X_VF_OBTAIN_MC_FILTERS 10
191
192 struct bnx2x_obtain_status {
193         int success;
194         int err_code;
195 };
196
197 static
198 struct bnx2x_obtain_status bnx2x_loop_obtain_resources(struct bnx2x_softc *sc)
199 {
200         int tries = 0;
201         struct vf_acquire_resp_tlv *resp = &sc->vf2pf_mbox->resp.acquire_resp,
202                                                                  *sc_resp = &sc->acquire_resp;
203         struct vf_resource_query    *res_query;
204         struct vf_resc            *resc;
205         struct bnx2x_obtain_status     status;
206         int res_obtained = false;
207
208         do {
209                 PMD_DRV_LOG(DEBUG, "trying to get resources");
210
211                 if (bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr)) {
212                         /* timeout */
213                         status.success = 0;
214                         status.err_code = -EAGAIN;
215                         return status;
216                 }
217
218                 memcpy(sc_resp, resp, sizeof(sc->acquire_resp));
219
220                 tries++;
221
222                 /* check PF to request acceptance */
223                 if (sc_resp->status == BNX2X_VF_STATUS_SUCCESS) {
224                         PMD_DRV_LOG(DEBUG, "resources obtained successfully");
225                         res_obtained = true;
226                 } else if (sc_resp->status == BNX2X_VF_STATUS_NO_RESOURCES &&
227                         tries < BNX2X_VF_OBTAIN_MAX_TRIES) {
228                         PMD_DRV_LOG(DEBUG,
229                            "PF cannot allocate requested amount of resources");
230
231                         res_query = &sc->vf2pf_mbox->query[0].acquire.res_query;
232                         resc     = &sc_resp->resc;
233
234                         /* PF refused our request. Try to decrease request params */
235                         res_query->num_txqs         = min(res_query->num_txqs, resc->num_txqs);
236                         res_query->num_rxqs         = min(res_query->num_rxqs, resc->num_rxqs);
237                         res_query->num_sbs          = min(res_query->num_sbs, resc->num_sbs);
238                         res_query->num_mac_filters  = min(res_query->num_mac_filters, resc->num_mac_filters);
239                         res_query->num_vlan_filters = min(res_query->num_vlan_filters, resc->num_vlan_filters);
240                         res_query->num_mc_filters   = min(res_query->num_mc_filters, resc->num_mc_filters);
241
242                         memset(&sc->vf2pf_mbox->resp, 0, sizeof(union resp_tlvs));
243                 } else {
244                         PMD_DRV_LOG(ERR, "Resources cannot be obtained. Status of handling: %d. Aborting",
245                                         sc_resp->status);
246                         status.success = 0;
247                         status.err_code = -EAGAIN;
248                         return status;
249                 }
250         } while (!res_obtained);
251
252         status.success = 1;
253         return status;
254 }
255
256 int bnx2x_vf_get_resources(struct bnx2x_softc *sc, uint8_t tx_count, uint8_t rx_count)
257 {
258         struct vf_acquire_tlv *acq = &sc->vf2pf_mbox->query[0].acquire;
259         int vf_id;
260         struct bnx2x_obtain_status obtain_status;
261         int rc = 0;
262
263         bnx2x_vf_close(sc);
264         bnx2x_vf_prep(sc, &acq->first_tlv, BNX2X_VF_TLV_ACQUIRE, sizeof(*acq));
265
266         vf_id = bnx2x_read_vf_id(sc);
267         if (vf_id < 0) {
268                 rc = -EAGAIN;
269                 goto out;
270         }
271
272         acq->vf_id = vf_id;
273
274         acq->res_query.num_rxqs = rx_count;
275         acq->res_query.num_txqs = tx_count;
276         acq->res_query.num_sbs = sc->igu_sb_cnt;
277         acq->res_query.num_mac_filters = BNX2X_VF_OBTAIN_MAC_FILTERS;
278         acq->res_query.num_mc_filters = BNX2X_VF_OBTAIN_MC_FILTERS;
279
280         acq->bulletin_addr = sc->pf2vf_bulletin_mapping.paddr;
281
282         /* Request physical port identifier */
283         bnx2x_add_tlv(sc, acq, acq->first_tlv.tl.length,
284                       BNX2X_VF_TLV_PHYS_PORT_ID,
285                       sizeof(struct channel_tlv));
286
287         bnx2x_add_tlv(sc, acq,
288                       (acq->first_tlv.tl.length + sizeof(struct channel_tlv)),
289                       BNX2X_VF_TLV_LIST_END,
290                       sizeof(struct channel_list_end_tlv));
291
292         /* requesting the resources in loop */
293         obtain_status = bnx2x_loop_obtain_resources(sc);
294         if (!obtain_status.success) {
295                 rc = obtain_status.err_code;
296                 goto out;
297         }
298
299         struct vf_acquire_resp_tlv sc_resp = sc->acquire_resp;
300
301         sc->devinfo.chip_id        |= (sc_resp.chip_num & 0xFFFF);
302         sc->devinfo.int_block       = INT_BLOCK_IGU;
303         sc->devinfo.chip_port_mode  = CHIP_2_PORT_MODE;
304         sc->devinfo.mf_info.mf_ov   = 0;
305         sc->devinfo.mf_info.mf_mode = 0;
306         sc->devinfo.flash_size      = 0;
307
308         sc->igu_sb_cnt  = sc_resp.resc.num_sbs;
309         sc->igu_base_sb = sc_resp.resc.hw_sbs[0] & 0xFF;
310         sc->igu_dsb_id  = -1;
311         sc->max_tx_queues = sc_resp.resc.num_txqs;
312         sc->max_rx_queues = sc_resp.resc.num_rxqs;
313
314         sc->link_params.chip_id = sc->devinfo.chip_id;
315         sc->doorbell_size = sc_resp.db_size;
316         sc->flags |= BNX2X_NO_WOL_FLAG | BNX2X_NO_ISCSI_OOO_FLAG | BNX2X_NO_ISCSI_FLAG | BNX2X_NO_FCOE_FLAG;
317
318         PMD_DRV_LOG(DEBUG, "status block count = %d, base status block = %x",
319                 sc->igu_sb_cnt, sc->igu_base_sb);
320         strncpy(sc->fw_ver, sc_resp.fw_ver, sizeof(sc->fw_ver));
321
322         if (is_valid_assigned_ether_addr(&sc_resp.resc.current_mac_addr))
323                 ether_addr_copy(&sc_resp.resc.current_mac_addr,
324                                 (struct ether_addr *)sc->link_params.mac_addr);
325         else
326                 eth_random_addr(sc->link_params.mac_addr);
327
328 out:
329         bnx2x_vf_finalize(sc, &acq->first_tlv);
330
331         return rc;
332 }
333
334 /* Ask PF to release VF's resources */
335 void
336 bnx2x_vf_close(struct bnx2x_softc *sc)
337 {
338         struct vf_release_tlv *query;
339         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
340         int vf_id = bnx2x_read_vf_id(sc);
341
342         if (vf_id >= 0) {
343                 query = &sc->vf2pf_mbox->query[0].release;
344                 bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_RELEASE,
345                               sizeof(*query));
346
347                 query->vf_id = vf_id;
348                 bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
349                               BNX2X_VF_TLV_LIST_END,
350                               sizeof(struct channel_list_end_tlv));
351
352                 bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
353                 if (reply->status != BNX2X_VF_STATUS_SUCCESS)
354                         PMD_DRV_LOG(ERR, "Failed to release VF");
355
356                 bnx2x_vf_finalize(sc, &query->first_tlv);
357         }
358 }
359
360 /* Let PF know the VF status blocks phys_addrs */
361 int
362 bnx2x_vf_init(struct bnx2x_softc *sc)
363 {
364         struct vf_init_tlv *query;
365         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
366         int i, rc = 0;
367
368         query = &sc->vf2pf_mbox->query[0].init;
369         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_INIT,
370                       sizeof(*query));
371
372         FOR_EACH_QUEUE(sc, i) {
373                 query->sb_addr[i] = (unsigned long)(sc->fp[i].sb_dma.paddr);
374         }
375
376         query->stats_step = sizeof(struct per_queue_stats);
377         query->stats_addr = sc->fw_stats_data_mapping +
378                 offsetof(struct bnx2x_fw_stats_data, queue_stats);
379
380         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
381                       BNX2X_VF_TLV_LIST_END,
382                       sizeof(struct channel_list_end_tlv));
383
384         bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
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;
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                         bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
421                         if (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                 bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
441                 if (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 = 0;
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         bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
527         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
528                 PMD_DRV_LOG(ERR, "Failed to setup VF queue[%d]",
529                                  fp->index);
530                 rc = -EINVAL;
531         }
532
533         bnx2x_vf_finalize(sc, &query->first_tlv);
534
535         return rc;
536 }
537
538 int
539 bnx2x_vf_set_mac(struct bnx2x_softc *sc, int set)
540 {
541         struct vf_set_q_filters_tlv *query;
542         struct vf_common_reply_tlv *reply;
543         int rc = 0;
544
545         query = &sc->vf2pf_mbox->query[0].set_q_filters;
546         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
547                         sizeof(*query));
548
549         query->vf_qid = sc->fp->index;
550         query->mac_filters_cnt = 1;
551         query->flags = BNX2X_VF_MAC_VLAN_CHANGED;
552
553         query->filters[0].flags = (set ? BNX2X_VF_Q_FILTER_SET_MAC : 0) |
554                 BNX2X_VF_Q_FILTER_DEST_MAC_VALID;
555
556         bnx2x_check_bull(sc);
557
558         rte_memcpy(query->filters[0].mac, sc->link_params.mac_addr, ETH_ALEN);
559
560         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
561                       BNX2X_VF_TLV_LIST_END,
562                       sizeof(struct channel_list_end_tlv));
563
564         bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
565         reply = &sc->vf2pf_mbox->resp.common_reply;
566
567         while (BNX2X_VF_STATUS_FAILURE == reply->status &&
568                         bnx2x_check_bull(sc)) {
569                 /* A new mac was configured by PF for us */
570                 rte_memcpy(sc->link_params.mac_addr, sc->pf2vf_bulletin->mac,
571                                 ETH_ALEN);
572                 rte_memcpy(query->filters[0].mac, sc->pf2vf_bulletin->mac,
573                                 ETH_ALEN);
574
575                 bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
576         }
577
578         if (BNX2X_VF_STATUS_SUCCESS != reply->status) {
579                 PMD_DRV_LOG(ERR, "Bad reply from PF for SET MAC message: %d",
580                                 reply->status);
581                 rc = -EINVAL;
582         }
583
584         bnx2x_vf_finalize(sc, &query->first_tlv);
585
586         return rc;
587 }
588
589 int
590 bnx2x_vf_config_rss(struct bnx2x_softc *sc,
591                           struct ecore_config_rss_params *params)
592 {
593         struct vf_rss_tlv *query;
594         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
595         int rc = 0;
596
597         query = &sc->vf2pf_mbox->query[0].update_rss;
598
599         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_UPDATE_RSS,
600                         sizeof(*query));
601
602         /* add list termination tlv */
603         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
604                       BNX2X_VF_TLV_LIST_END,
605                       sizeof(struct channel_list_end_tlv));
606
607         rte_memcpy(query->rss_key, params->rss_key, sizeof(params->rss_key));
608         query->rss_key_size = T_ETH_RSS_KEY;
609
610         rte_memcpy(query->ind_table, params->ind_table, T_ETH_INDIRECTION_TABLE_SIZE);
611         query->ind_table_size = T_ETH_INDIRECTION_TABLE_SIZE;
612
613         query->rss_result_mask = params->rss_result_mask;
614         query->rss_flags = params->rss_flags;
615
616         bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
617         if (reply->status != BNX2X_VF_STATUS_SUCCESS) {
618                 PMD_DRV_LOG(ERR, "Failed to configure RSS");
619                 rc = -EINVAL;
620         }
621
622         bnx2x_vf_finalize(sc, &query->first_tlv);
623
624         return rc;
625 }
626
627 int
628 bnx2x_vf_set_rx_mode(struct bnx2x_softc *sc)
629 {
630         struct vf_set_q_filters_tlv *query;
631         struct vf_common_reply_tlv *reply = &sc->vf2pf_mbox->resp.common_reply;
632         int rc = 0;
633
634         query = &sc->vf2pf_mbox->query[0].set_q_filters;
635         bnx2x_vf_prep(sc, &query->first_tlv, BNX2X_VF_TLV_SET_Q_FILTERS,
636                         sizeof(*query));
637
638         query->vf_qid = 0;
639         query->flags = BNX2X_VF_RX_MASK_CHANGED;
640
641         switch (sc->rx_mode) {
642         case BNX2X_RX_MODE_NONE: /* no Rx */
643                 query->rx_mask = VFPF_RX_MASK_ACCEPT_NONE;
644                 break;
645         case BNX2X_RX_MODE_NORMAL:
646                 query->rx_mask = VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
647                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
648                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
649                 break;
650         case BNX2X_RX_MODE_ALLMULTI:
651                 query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
652                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
653                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
654                 break;
655         case BNX2X_RX_MODE_PROMISC:
656                 query->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_UNICAST;
657                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
658                 query->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
659                 break;
660         default:
661                 PMD_DRV_LOG(ERR, "BAD rx mode (%d)", sc->rx_mode);
662                 rc = -EINVAL;
663                 goto out;
664         }
665
666         bnx2x_add_tlv(sc, query, query->first_tlv.tl.length,
667                       BNX2X_VF_TLV_LIST_END,
668                       sizeof(struct channel_list_end_tlv));
669
670         bnx2x_do_req4pf(sc, sc->vf2pf_mbox_mapping.paddr);
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 }