1
2
3
4
5
6#include <ethdev_driver.h>
7#include <rte_ether.h>
8
9#include "common.h"
10#include "t4_regs.h"
11
12
13
14
15
16
17
18
19static int t4vf_wait_dev_ready(struct adapter *adapter)
20{
21 const u32 whoami = T4VF_PL_BASE_ADDR + A_PL_VF_WHOAMI;
22 const u32 notready1 = 0xffffffff;
23 const u32 notready2 = 0xeeeeeeee;
24 u32 val;
25
26 val = t4_read_reg(adapter, whoami);
27 if (val != notready1 && val != notready2)
28 return 0;
29
30 msleep(500);
31 val = t4_read_reg(adapter, whoami);
32 if (val != notready1 && val != notready2)
33 return 0;
34
35 dev_err(adapter, "Device didn't become ready for access, whoami = %#x\n",
36 val);
37 return -EIO;
38}
39
40
41
42
43static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
44 u32 mbox_addr)
45{
46 for ( ; nflit; nflit--, mbox_addr += 8)
47 *rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr));
48}
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70int t4vf_wr_mbox_core(struct adapter *adapter,
71 const void __attribute__((__may_alias__)) *cmd,
72 int size, void *rpl, bool sleep_ok)
73{
74
75
76
77
78
79 static const int delay[] = {
80 1, 1, 3, 5, 10, 10, 20, 50, 100
81 };
82
83
84 u32 mbox_ctl = T4VF_CIM_BASE_ADDR + A_CIM_VF_EXT_MAILBOX_CTRL;
85 __be64 cmd_rpl[MBOX_LEN / 8];
86 struct mbox_entry entry;
87 unsigned int delay_idx;
88 u32 v, mbox_data;
89 const __be64 *p;
90 int i, ret;
91 int ms;
92
93
94
95
96 if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
97 mbox_data = T4VF_MBDATA_BASE_ADDR;
98 else
99 mbox_data = T6VF_MBDATA_BASE_ADDR;
100
101
102
103
104
105 if ((size % 16) != 0 ||
106 size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4)
107 return -EINVAL;
108
109
110
111
112
113
114
115 t4_os_atomic_add_tail(&entry, &adapter->mbox_list, &adapter->mbox_lock);
116
117 delay_idx = 0;
118 ms = delay[0];
119
120 for (i = 0; ; i += ms) {
121
122
123
124
125
126
127 if (i > (2 * FW_CMD_MAX_TIMEOUT)) {
128 t4_os_atomic_list_del(&entry, &adapter->mbox_list,
129 &adapter->mbox_lock);
130 ret = -EBUSY;
131 return ret;
132 }
133
134
135
136
137
138 if (t4_os_list_first_entry(&adapter->mbox_list) == &entry)
139 break;
140
141
142
143
144 if (sleep_ok) {
145 ms = delay[delay_idx];
146 if (delay_idx < ARRAY_SIZE(delay) - 1)
147 delay_idx++;
148 msleep(ms);
149 } else {
150 rte_delay_ms(ms);
151 }
152 }
153
154
155
156
157
158 v = G_MBOWNER(t4_read_reg(adapter, mbox_ctl));
159 for (i = 0; v == X_MBOWNER_NONE && i < 3; i++)
160 v = G_MBOWNER(t4_read_reg(adapter, mbox_ctl));
161
162 if (v != X_MBOWNER_PL) {
163 t4_os_atomic_list_del(&entry, &adapter->mbox_list,
164 &adapter->mbox_lock);
165 ret = (v == X_MBOWNER_FW) ? -EBUSY : -ETIMEDOUT;
166 return ret;
167 }
168
169
170
171
172
173 for (i = 0, p = cmd; i < size; i += 8)
174 t4_write_reg64(adapter, mbox_data + i, be64_to_cpu(*p++));
175
176 t4_read_reg(adapter, mbox_data);
177 t4_write_reg(adapter, mbox_ctl,
178 F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW));
179 t4_read_reg(adapter, mbox_ctl);
180 delay_idx = 0;
181 ms = delay[0];
182
183
184
185
186 for (i = 0; i < FW_CMD_MAX_TIMEOUT; i++) {
187 if (sleep_ok) {
188 ms = delay[delay_idx];
189 if (delay_idx < ARRAY_SIZE(delay) - 1)
190 delay_idx++;
191 msleep(ms);
192 } else {
193 rte_delay_ms(ms);
194 }
195
196
197
198
199 v = t4_read_reg(adapter, mbox_ctl);
200 if (G_MBOWNER(v) == X_MBOWNER_PL) {
201
202
203
204
205 if ((v & F_MBMSGVALID) == 0) {
206 t4_write_reg(adapter, mbox_ctl,
207 V_MBOWNER(X_MBOWNER_NONE));
208 continue;
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 get_mbox_rpl(adapter, cmd_rpl, size / 8, mbox_data);
225 t4_write_reg(adapter, mbox_ctl,
226 V_MBOWNER(X_MBOWNER_NONE));
227 t4_os_atomic_list_del(&entry, &adapter->mbox_list,
228 &adapter->mbox_lock);
229
230
231 v = be64_to_cpu(cmd_rpl[0]);
232
233 if (rpl) {
234
235 WARN_ON((be32_to_cpu(*(const u32 *)cmd)
236 & F_FW_CMD_REQUEST) == 0);
237 memcpy(rpl, cmd_rpl, size);
238 }
239 return -((int)G_FW_CMD_RETVAL(v));
240 }
241 }
242
243
244
245
246 dev_err(adapter, "command %#x timed out\n",
247 *(const u8 *)cmd);
248 dev_err(adapter, " Control = %#x\n", t4_read_reg(adapter, mbox_ctl));
249 t4_os_atomic_list_del(&entry, &adapter->mbox_list, &adapter->mbox_lock);
250 ret = -ETIMEDOUT;
251 return ret;
252}
253
254
255
256
257
258
259
260
261
262int t4vf_fw_reset(struct adapter *adapter)
263{
264 struct fw_reset_cmd cmd;
265
266 memset(&cmd, 0, sizeof(cmd));
267 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RESET_CMD) |
268 F_FW_CMD_WRITE);
269 cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(FW_LEN16(cmd)));
270 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
271}
272
273
274
275
276
277
278
279
280
281int t4vf_prep_adapter(struct adapter *adapter)
282{
283 u32 pl_vf_rev;
284 int ret, ver;
285
286 ret = t4vf_wait_dev_ready(adapter);
287 if (ret < 0)
288 return ret;
289
290
291
292
293
294 adapter->params.nports = 1;
295 adapter->params.vfres.pmask = 1;
296 adapter->params.vpd.cclk = 50000;
297
298 pl_vf_rev = G_REV(t4_read_reg(adapter, A_PL_VF_REV));
299 adapter->params.pci.device_id = adapter->pdev->id.device_id;
300 adapter->params.pci.vendor_id = adapter->pdev->id.vendor_id;
301
302
303
304
305
306 ver = CHELSIO_PCI_ID_VER(adapter->params.pci.device_id);
307 adapter->params.chip = 0;
308 switch (ver) {
309 case CHELSIO_T5:
310 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5,
311 pl_vf_rev);
312 adapter->params.arch.sge_fl_db = F_DBPRIO | F_DBTYPE;
313 adapter->params.arch.mps_tcam_size =
314 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
315 break;
316 case CHELSIO_T6:
317 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6,
318 pl_vf_rev);
319 adapter->params.arch.sge_fl_db = 0;
320 adapter->params.arch.mps_tcam_size =
321 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
322 break;
323 default:
324 dev_err(adapter, "%s: Device %d is not supported\n",
325 __func__, adapter->params.pci.device_id);
326 return -EINVAL;
327 }
328 return 0;
329}
330
331
332
333
334
335
336
337
338
339
340
341int t4vf_query_params(struct adapter *adapter, unsigned int nparams,
342 const u32 *params, u32 *vals)
343{
344 struct fw_params_cmd cmd, rpl;
345 struct fw_params_param *p;
346 unsigned int i;
347 size_t len16;
348 int ret;
349
350 if (nparams > 7)
351 return -EINVAL;
352
353 memset(&cmd, 0, sizeof(cmd));
354 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) |
355 F_FW_CMD_REQUEST |
356 F_FW_CMD_READ);
357 len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
358 param[nparams]), 16);
359 cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(len16));
360 for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++)
361 p->mnem = cpu_to_be32(*params++);
362 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
363 if (ret == 0)
364 for (i = 0, p = &rpl.param[0]; i < nparams; i++, p++)
365 *vals++ = be32_to_cpu(p->val);
366 return ret;
367}
368
369
370
371
372
373
374
375
376int t4vf_get_vpd_params(struct adapter *adapter)
377{
378 struct vpd_params *vpd_params = &adapter->params.vpd;
379 u32 params[7], vals[7];
380 int v;
381
382 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
383 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK));
384 v = t4vf_query_params(adapter, 1, params, vals);
385 if (v != FW_SUCCESS)
386 return v;
387 vpd_params->cclk = vals[0];
388 dev_debug(adapter, "%s: vpd_params->cclk = %u\n",
389 __func__, vpd_params->cclk);
390 return 0;
391}
392
393
394
395
396
397
398
399int t4vf_get_dev_params(struct adapter *adapter)
400{
401 u32 params[7], vals[7];
402 int v;
403
404 params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
405 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FWREV));
406 params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
407 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_TPREV));
408 v = t4vf_query_params(adapter, 2, params, vals);
409 if (v != FW_SUCCESS)
410 return v;
411 adapter->params.fw_vers = vals[0];
412 adapter->params.tp_vers = vals[1];
413
414 dev_info(adapter, "Firmware version: %u.%u.%u.%u\n",
415 G_FW_HDR_FW_VER_MAJOR(adapter->params.fw_vers),
416 G_FW_HDR_FW_VER_MINOR(adapter->params.fw_vers),
417 G_FW_HDR_FW_VER_MICRO(adapter->params.fw_vers),
418 G_FW_HDR_FW_VER_BUILD(adapter->params.fw_vers));
419
420 dev_info(adapter, "TP Microcode version: %u.%u.%u.%u\n",
421 G_FW_HDR_FW_VER_MAJOR(adapter->params.tp_vers),
422 G_FW_HDR_FW_VER_MINOR(adapter->params.tp_vers),
423 G_FW_HDR_FW_VER_MICRO(adapter->params.tp_vers),
424 G_FW_HDR_FW_VER_BUILD(adapter->params.tp_vers));
425 return 0;
426}
427
428
429
430
431
432
433
434
435
436
437
438int t4vf_set_params(struct adapter *adapter, unsigned int nparams,
439 const u32 *params, const u32 *vals)
440{
441 struct fw_params_param *p;
442 struct fw_params_cmd cmd;
443 unsigned int i;
444 size_t len16;
445
446 if (nparams > 7)
447 return -EINVAL;
448
449 memset(&cmd, 0, sizeof(cmd));
450 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PARAMS_CMD) |
451 F_FW_CMD_REQUEST |
452 F_FW_CMD_WRITE);
453 len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
454 param[nparams]), 16);
455 cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(len16));
456 for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) {
457 p->mnem = cpu_to_be32(*params++);
458 p->val = cpu_to_be32(*vals++);
459 }
460 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
461}
462
463
464
465
466
467
468
469
470
471int t4vf_fl_pkt_align(struct adapter *adapter, u32 sge_control,
472 u32 sge_control2)
473{
474 unsigned int ingpadboundary, ingpackboundary, fl_align, ingpad_shift;
475
476
477
478
479
480
481
482 if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
483 ingpad_shift = X_INGPADBOUNDARY_SHIFT;
484 else
485 ingpad_shift = X_T6_INGPADBOUNDARY_SHIFT;
486
487 ingpadboundary = 1 << (G_INGPADBOUNDARY(sge_control) + ingpad_shift);
488
489 fl_align = ingpadboundary;
490 if (!is_t4(adapter->params.chip)) {
491 ingpackboundary = G_INGPACKBOUNDARY(sge_control2);
492 if (ingpackboundary == X_INGPACKBOUNDARY_16B)
493 ingpackboundary = 16;
494 else
495 ingpackboundary = 1 << (ingpackboundary +
496 X_INGPACKBOUNDARY_SHIFT);
497
498 fl_align = max(ingpadboundary, ingpackboundary);
499 }
500 return fl_align;
501}
502
503unsigned int t4vf_get_pf_from_vf(struct adapter *adapter)
504{
505 u32 whoami;
506
507 whoami = t4_read_reg(adapter, T4VF_PL_BASE_ADDR + A_PL_VF_WHOAMI);
508 return (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
509 G_SOURCEPF(whoami) : G_T6_SOURCEPF(whoami));
510}
511
512
513
514
515
516
517
518
519int t4vf_get_rss_glb_config(struct adapter *adapter)
520{
521 struct rss_params *rss = &adapter->params.rss;
522 struct fw_rss_glb_config_cmd cmd, rpl;
523 int v;
524
525
526
527
528
529 memset(&cmd, 0, sizeof(cmd));
530 cmd.op_to_write = cpu_to_be32(V_FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
531 F_FW_CMD_REQUEST |
532 F_FW_CMD_READ);
533 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
534 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
535 if (v != FW_SUCCESS)
536 return v;
537
538
539
540
541
542
543
544 rss->mode = G_FW_RSS_GLB_CONFIG_CMD_MODE
545 (be32_to_cpu(rpl.u.manual.mode_pkd));
546 switch (rss->mode) {
547 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
548 u32 word = be32_to_cpu
549 (rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
550
551 rss->u.basicvirtual.synmapen =
552 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0);
553 rss->u.basicvirtual.syn4tupenipv6 =
554 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0);
555 rss->u.basicvirtual.syn2tupenipv6 =
556 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0);
557 rss->u.basicvirtual.syn4tupenipv4 =
558 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0);
559 rss->u.basicvirtual.syn2tupenipv4 =
560 ((word & F_FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0);
561 rss->u.basicvirtual.ofdmapen =
562 ((word & F_FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0);
563 rss->u.basicvirtual.tnlmapen =
564 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0);
565 rss->u.basicvirtual.tnlalllookup =
566 ((word & F_FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
567 rss->u.basicvirtual.hashtoeplitz =
568 ((word & F_FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0);
569
570
571 if (!rss->u.basicvirtual.tnlmapen)
572 return -EINVAL;
573 break;
574 }
575
576 default:
577
578 return -EINVAL;
579 }
580 return 0;
581}
582
583
584
585
586
587
588
589
590int t4vf_get_vfres(struct adapter *adapter)
591{
592 struct vf_resources *vfres = &adapter->params.vfres;
593 struct fw_pfvf_cmd cmd, rpl;
594 u32 word;
595 int v;
596
597
598
599
600
601 memset(&cmd, 0, sizeof(cmd));
602 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) |
603 F_FW_CMD_REQUEST |
604 F_FW_CMD_READ);
605 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
606 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
607 if (v != FW_SUCCESS)
608 return v;
609
610
611
612
613 word = be32_to_cpu(rpl.niqflint_niq);
614 vfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word);
615 vfres->niq = G_FW_PFVF_CMD_NIQ(word);
616
617 word = be32_to_cpu(rpl.type_to_neq);
618 vfres->neq = G_FW_PFVF_CMD_NEQ(word);
619 vfres->pmask = G_FW_PFVF_CMD_PMASK(word);
620
621 word = be32_to_cpu(rpl.tc_to_nexactf);
622 vfres->tc = G_FW_PFVF_CMD_TC(word);
623 vfres->nvi = G_FW_PFVF_CMD_NVI(word);
624 vfres->nexactf = G_FW_PFVF_CMD_NEXACTF(word);
625
626 word = be32_to_cpu(rpl.r_caps_to_nethctrl);
627 vfres->r_caps = G_FW_PFVF_CMD_R_CAPS(word);
628 vfres->wx_caps = G_FW_PFVF_CMD_WX_CAPS(word);
629 vfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word);
630 return 0;
631}
632
633
634
635
636
637
638
639
640
641
642static int t4vf_get_port_stats_fw(struct adapter *adapter, int pidx,
643 struct port_stats *p)
644{
645 struct port_info *pi = adap2pinfo(adapter, pidx);
646 unsigned int rem = VI_VF_NUM_STATS;
647 struct fw_vi_stats_vf fwstats;
648 __be64 *fwsp = (__be64 *)&fwstats;
649
650
651
652
653
654
655 while (rem) {
656 unsigned int ix = VI_VF_NUM_STATS - rem;
657 unsigned int nstats = min(6U, rem);
658 struct fw_vi_stats_cmd cmd, rpl;
659 size_t len = (offsetof(struct fw_vi_stats_cmd, u) +
660 sizeof(struct fw_vi_stats_ctl));
661 size_t len16 = DIV_ROUND_UP(len, 16);
662 int ret;
663
664 memset(&cmd, 0, sizeof(cmd));
665 cmd.op_to_viid = cpu_to_be32(V_FW_CMD_OP(FW_VI_STATS_CMD) |
666 V_FW_VI_STATS_CMD_VIID(pi->viid) |
667 F_FW_CMD_REQUEST |
668 F_FW_CMD_READ);
669 cmd.retval_len16 = cpu_to_be32(V_FW_CMD_LEN16(len16));
670 cmd.u.ctl.nstats_ix =
671 cpu_to_be16(V_FW_VI_STATS_CMD_IX(ix) |
672 V_FW_VI_STATS_CMD_NSTATS(nstats));
673 ret = t4vf_wr_mbox_ns(adapter, &cmd, len, &rpl);
674 if (ret != FW_SUCCESS)
675 return ret;
676
677 memcpy(fwsp, &rpl.u.ctl.stat0, sizeof(__be64) * nstats);
678
679 rem -= nstats;
680 fwsp += nstats;
681 }
682
683
684
685
686 p->tx_octets = be64_to_cpu(fwstats.tx_bcast_bytes) +
687 be64_to_cpu(fwstats.tx_mcast_bytes) +
688 be64_to_cpu(fwstats.tx_ucast_bytes);
689 p->tx_bcast_frames = be64_to_cpu(fwstats.tx_bcast_frames);
690 p->tx_mcast_frames = be64_to_cpu(fwstats.tx_mcast_frames);
691 p->tx_ucast_frames = be64_to_cpu(fwstats.tx_ucast_frames);
692 p->tx_drop = be64_to_cpu(fwstats.tx_drop_frames);
693
694 p->rx_bcast_frames = be64_to_cpu(fwstats.rx_bcast_frames);
695 p->rx_mcast_frames = be64_to_cpu(fwstats.rx_mcast_frames);
696 p->rx_ucast_frames = be64_to_cpu(fwstats.rx_ucast_frames);
697 p->rx_len_err = be64_to_cpu(fwstats.rx_err_frames);
698
699 return 0;
700}
701
702
703
704
705
706
707
708
709
710void t4vf_get_port_stats(struct adapter *adapter, int pidx,
711 struct port_stats *p)
712{
713
714
715
716
717
718 if (pidx != 0)
719 t4vf_get_port_stats_fw(adapter, pidx, p);
720
721
722
723
724
725#define GET_STAT(name) \
726 t4_read_reg64(adapter, \
727 T4VF_MPS_BASE_ADDR + A_MPS_VF_STAT_##name##_L)
728 p->tx_octets = GET_STAT(TX_VF_BCAST_BYTES) +
729 GET_STAT(TX_VF_MCAST_BYTES) +
730 GET_STAT(TX_VF_UCAST_BYTES);
731 p->tx_bcast_frames = GET_STAT(TX_VF_BCAST_FRAMES);
732 p->tx_mcast_frames = GET_STAT(TX_VF_MCAST_FRAMES);
733 p->tx_ucast_frames = GET_STAT(TX_VF_UCAST_FRAMES);
734 p->tx_drop = GET_STAT(TX_VF_DROP_FRAMES);
735
736 p->rx_bcast_frames = GET_STAT(RX_VF_BCAST_FRAMES);
737 p->rx_mcast_frames = GET_STAT(RX_VF_MCAST_FRAMES);
738 p->rx_ucast_frames = GET_STAT(RX_VF_UCAST_FRAMES);
739
740 p->rx_len_err = GET_STAT(RX_VF_ERR_FRAMES);
741#undef GET_STAT
742}
743
744static int t4vf_alloc_vi(struct adapter *adapter, int port_id)
745{
746 struct fw_vi_cmd cmd, rpl;
747 int v;
748
749
750
751
752
753 memset(&cmd, 0, sizeof(cmd));
754 cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) |
755 F_FW_CMD_REQUEST |
756 F_FW_CMD_WRITE |
757 F_FW_CMD_EXEC);
758 cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
759 F_FW_VI_CMD_ALLOC);
760 cmd.portid_pkd = V_FW_VI_CMD_PORTID(port_id);
761 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
762 if (v != FW_SUCCESS)
763 return v;
764 return G_FW_VI_CMD_VIID(be16_to_cpu(rpl.type_to_viid));
765}
766
767int t4vf_port_init(struct adapter *adapter)
768{
769 struct fw_port_cmd port_cmd, port_rpl, rpl;
770 struct fw_vi_cmd vi_cmd, vi_rpl;
771 u32 param, val, pcaps, acaps;
772 enum fw_port_type port_type;
773 int mdio_addr;
774 int ret, i;
775
776 param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_PFVF) |
777 V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
778 val = 1;
779 ret = t4vf_set_params(adapter, 1, ¶m, &val);
780 if (ret < 0)
781 return ret;
782
783 for_each_port(adapter, i) {
784 struct port_info *p = adap2pinfo(adapter, i);
785 u32 lstatus32;
786
787 ret = t4vf_alloc_vi(adapter, p->port_id);
788 if (ret < 0) {
789 dev_err(&pdev->dev, "cannot allocate VI for port %d:"
790 " err=%d\n", p->port_id, ret);
791 return ret;
792 }
793 p->viid = ret;
794
795
796
797
798
799 memset(&vi_cmd, 0, sizeof(vi_cmd));
800 vi_cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_VI_CMD) |
801 F_FW_CMD_REQUEST |
802 F_FW_CMD_READ);
803 vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd));
804 vi_cmd.type_to_viid = cpu_to_be16(V_FW_VI_CMD_VIID(p->viid));
805 ret = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl);
806 if (ret != FW_SUCCESS)
807 return ret;
808
809 p->rss_size = G_FW_VI_CMD_RSSSIZE
810 (be16_to_cpu(vi_rpl.norss_rsssize));
811 t4_os_set_hw_addr(adapter, i, vi_rpl.mac);
812
813
814
815
816
817 if (!(adapter->params.vfres.r_caps & FW_CMD_CAP_PORT))
818 return 0;
819
820 memset(&port_cmd, 0, sizeof(port_cmd));
821 port_cmd.op_to_portid =
822 cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) |
823 F_FW_CMD_REQUEST | F_FW_CMD_READ |
824 V_FW_PORT_CMD_PORTID(p->port_id));
825 val = FW_PORT_ACTION_GET_PORT_INFO32;
826 port_cmd.action_to_len16 =
827 cpu_to_be32(V_FW_PORT_CMD_ACTION(val) |
828 FW_LEN16(port_cmd));
829 ret = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd),
830 &port_rpl);
831 if (ret != FW_SUCCESS)
832 return ret;
833
834
835
836
837 rpl = port_rpl;
838 lstatus32 = be32_to_cpu(rpl.u.info32.lstatus32_to_cbllen32);
839
840 port_type = G_FW_PORT_CMD_PORTTYPE32(lstatus32);
841 mdio_addr = (lstatus32 & F_FW_PORT_CMD_MDIOCAP32) ?
842 (int)G_FW_PORT_CMD_MDIOADDR32(lstatus32) : -1;
843 pcaps = be32_to_cpu(port_rpl.u.info32.pcaps32);
844 acaps = be32_to_cpu(port_rpl.u.info32.acaps32);
845
846 t4_init_link_config(p, pcaps, acaps, mdio_addr, port_type,
847 FW_PORT_MOD_TYPE_NA);
848 }
849 return 0;
850}
851