1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/pci.h>
37
38#include "t4vf_common.h"
39#include "t4vf_defs.h"
40
41#include "../cxgb4/t4_regs.h"
42#include "../cxgb4/t4fw_api.h"
43
44
45
46
47
48
49int t4vf_wait_dev_ready(struct adapter *adapter)
50{
51 const u32 whoami = T4VF_PL_BASE_ADDR + PL_VF_WHOAMI;
52 const u32 notready1 = 0xffffffff;
53 const u32 notready2 = 0xeeeeeeee;
54 u32 val;
55
56 val = t4_read_reg(adapter, whoami);
57 if (val != notready1 && val != notready2)
58 return 0;
59 msleep(500);
60 val = t4_read_reg(adapter, whoami);
61 if (val != notready1 && val != notready2)
62 return 0;
63 else
64 return -EIO;
65}
66
67
68
69
70
71static void get_mbox_rpl(struct adapter *adapter, __be64 *rpl, int size,
72 u32 mbox_data)
73{
74 for ( ; size; size -= 8, mbox_data += 8)
75 *rpl++ = cpu_to_be64(t4_read_reg64(adapter, mbox_data));
76}
77
78
79
80
81static void dump_mbox(struct adapter *adapter, const char *tag, u32 mbox_data)
82{
83 dev_err(adapter->pdev_dev,
84 "mbox %s: %llx %llx %llx %llx %llx %llx %llx %llx\n", tag,
85 (unsigned long long)t4_read_reg64(adapter, mbox_data + 0),
86 (unsigned long long)t4_read_reg64(adapter, mbox_data + 8),
87 (unsigned long long)t4_read_reg64(adapter, mbox_data + 16),
88 (unsigned long long)t4_read_reg64(adapter, mbox_data + 24),
89 (unsigned long long)t4_read_reg64(adapter, mbox_data + 32),
90 (unsigned long long)t4_read_reg64(adapter, mbox_data + 40),
91 (unsigned long long)t4_read_reg64(adapter, mbox_data + 48),
92 (unsigned long long)t4_read_reg64(adapter, mbox_data + 56));
93}
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115int t4vf_wr_mbox_core(struct adapter *adapter, const void *cmd, int size,
116 void *rpl, bool sleep_ok)
117{
118 static const int delay[] = {
119 1, 1, 3, 5, 10, 10, 20, 50, 100
120 };
121
122 u32 v;
123 int i, ms, delay_idx;
124 const __be64 *p;
125 u32 mbox_data = T4VF_MBDATA_BASE_ADDR;
126 u32 mbox_ctl = T4VF_CIM_BASE_ADDR + CIM_VF_EXT_MAILBOX_CTRL;
127
128
129
130
131
132 if ((size % 16) != 0 ||
133 size > NUM_CIM_VF_MAILBOX_DATA_INSTANCES * 4)
134 return -EINVAL;
135
136
137
138
139
140 v = MBOWNER_GET(t4_read_reg(adapter, mbox_ctl));
141 for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
142 v = MBOWNER_GET(t4_read_reg(adapter, mbox_ctl));
143 if (v != MBOX_OWNER_DRV)
144 return v == MBOX_OWNER_FW ? -EBUSY : -ETIMEDOUT;
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 for (i = 0, p = cmd; i < size; i += 8)
160 t4_write_reg64(adapter, mbox_data + i, be64_to_cpu(*p++));
161 t4_read_reg(adapter, mbox_data);
162
163 t4_write_reg(adapter, mbox_ctl,
164 MBMSGVALID | MBOWNER(MBOX_OWNER_FW));
165 t4_read_reg(adapter, mbox_ctl);
166
167
168
169
170 delay_idx = 0;
171 ms = delay[0];
172
173 for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
174 if (sleep_ok) {
175 ms = delay[delay_idx];
176 if (delay_idx < ARRAY_SIZE(delay) - 1)
177 delay_idx++;
178 msleep(ms);
179 } else
180 mdelay(ms);
181
182
183
184
185 v = t4_read_reg(adapter, mbox_ctl);
186 if (MBOWNER_GET(v) == MBOX_OWNER_DRV) {
187
188
189
190
191 if ((v & MBMSGVALID) == 0) {
192 t4_write_reg(adapter, mbox_ctl,
193 MBOWNER(MBOX_OWNER_NONE));
194 continue;
195 }
196
197
198
199
200
201
202
203
204
205
206 v = t4_read_reg(adapter, mbox_data);
207 if (FW_CMD_RETVAL_GET(v))
208 dump_mbox(adapter, "FW Error", mbox_data);
209
210 if (rpl) {
211
212 WARN_ON((be32_to_cpu(*(const u32 *)cmd)
213 & FW_CMD_REQUEST) == 0);
214 get_mbox_rpl(adapter, rpl, size, mbox_data);
215 WARN_ON((be32_to_cpu(*(u32 *)rpl)
216 & FW_CMD_REQUEST) != 0);
217 }
218 t4_write_reg(adapter, mbox_ctl,
219 MBOWNER(MBOX_OWNER_NONE));
220 return -FW_CMD_RETVAL_GET(v);
221 }
222 }
223
224
225
226
227 dump_mbox(adapter, "FW Timeout", mbox_data);
228 return -ETIMEDOUT;
229}
230
231
232
233
234
235
236
237
238static int hash_mac_addr(const u8 *addr)
239{
240 u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2];
241 u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5];
242 a ^= b;
243 a ^= (a >> 12);
244 a ^= (a >> 6);
245 return a & 0x3f;
246}
247
248
249
250
251
252
253
254
255
256static void init_link_config(struct link_config *lc, unsigned int caps)
257{
258 lc->supported = caps;
259 lc->requested_speed = 0;
260 lc->speed = 0;
261 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
262 if (lc->supported & SUPPORTED_Autoneg) {
263 lc->advertising = lc->supported;
264 lc->autoneg = AUTONEG_ENABLE;
265 lc->requested_fc |= PAUSE_AUTONEG;
266 } else {
267 lc->advertising = 0;
268 lc->autoneg = AUTONEG_DISABLE;
269 }
270}
271
272
273
274
275
276
277int t4vf_port_init(struct adapter *adapter, int pidx)
278{
279 struct port_info *pi = adap2pinfo(adapter, pidx);
280 struct fw_vi_cmd vi_cmd, vi_rpl;
281 struct fw_port_cmd port_cmd, port_rpl;
282 int v;
283 u32 word;
284
285
286
287
288
289 memset(&vi_cmd, 0, sizeof(vi_cmd));
290 vi_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) |
291 FW_CMD_REQUEST |
292 FW_CMD_READ);
293 vi_cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(vi_cmd));
294 vi_cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(pi->viid));
295 v = t4vf_wr_mbox(adapter, &vi_cmd, sizeof(vi_cmd), &vi_rpl);
296 if (v)
297 return v;
298
299 BUG_ON(pi->port_id != FW_VI_CMD_PORTID_GET(vi_rpl.portid_pkd));
300 pi->rss_size = FW_VI_CMD_RSSSIZE_GET(be16_to_cpu(vi_rpl.rsssize_pkd));
301 t4_os_set_hw_addr(adapter, pidx, vi_rpl.mac);
302
303
304
305
306
307 if (!(adapter->params.vfres.r_caps & FW_CMD_CAP_PORT))
308 return 0;
309
310 memset(&port_cmd, 0, sizeof(port_cmd));
311 port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP(FW_PORT_CMD) |
312 FW_CMD_REQUEST |
313 FW_CMD_READ |
314 FW_PORT_CMD_PORTID(pi->port_id));
315 port_cmd.action_to_len16 =
316 cpu_to_be32(FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) |
317 FW_LEN16(port_cmd));
318 v = t4vf_wr_mbox(adapter, &port_cmd, sizeof(port_cmd), &port_rpl);
319 if (v)
320 return v;
321
322 v = 0;
323 word = be16_to_cpu(port_rpl.u.info.pcap);
324 if (word & FW_PORT_CAP_SPEED_100M)
325 v |= SUPPORTED_100baseT_Full;
326 if (word & FW_PORT_CAP_SPEED_1G)
327 v |= SUPPORTED_1000baseT_Full;
328 if (word & FW_PORT_CAP_SPEED_10G)
329 v |= SUPPORTED_10000baseT_Full;
330 if (word & FW_PORT_CAP_ANEG)
331 v |= SUPPORTED_Autoneg;
332 init_link_config(&pi->link_cfg, v);
333
334 return 0;
335}
336
337
338
339
340
341
342
343
344
345int t4vf_fw_reset(struct adapter *adapter)
346{
347 struct fw_reset_cmd cmd;
348
349 memset(&cmd, 0, sizeof(cmd));
350 cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) |
351 FW_CMD_WRITE);
352 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
353 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
354}
355
356
357
358
359
360
361
362
363
364
365
366int t4vf_query_params(struct adapter *adapter, unsigned int nparams,
367 const u32 *params, u32 *vals)
368{
369 int i, ret;
370 struct fw_params_cmd cmd, rpl;
371 struct fw_params_param *p;
372 size_t len16;
373
374 if (nparams > 7)
375 return -EINVAL;
376
377 memset(&cmd, 0, sizeof(cmd));
378 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) |
379 FW_CMD_REQUEST |
380 FW_CMD_READ);
381 len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
382 param[nparams].mnem), 16);
383 cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
384 for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++)
385 p->mnem = htonl(*params++);
386
387 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
388 if (ret == 0)
389 for (i = 0, p = &rpl.param[0]; i < nparams; i++, p++)
390 *vals++ = be32_to_cpu(p->val);
391 return ret;
392}
393
394
395
396
397
398
399
400
401
402
403
404int t4vf_set_params(struct adapter *adapter, unsigned int nparams,
405 const u32 *params, const u32 *vals)
406{
407 int i;
408 struct fw_params_cmd cmd;
409 struct fw_params_param *p;
410 size_t len16;
411
412 if (nparams > 7)
413 return -EINVAL;
414
415 memset(&cmd, 0, sizeof(cmd));
416 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PARAMS_CMD) |
417 FW_CMD_REQUEST |
418 FW_CMD_WRITE);
419 len16 = DIV_ROUND_UP(offsetof(struct fw_params_cmd,
420 param[nparams]), 16);
421 cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
422 for (i = 0, p = &cmd.param[0]; i < nparams; i++, p++) {
423 p->mnem = cpu_to_be32(*params++);
424 p->val = cpu_to_be32(*vals++);
425 }
426
427 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
428}
429
430
431
432
433
434
435
436
437
438int t4vf_get_sge_params(struct adapter *adapter)
439{
440 struct sge_params *sge_params = &adapter->params.sge;
441 u32 params[7], vals[7];
442 int v;
443
444 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
445 FW_PARAMS_PARAM_XYZ(SGE_CONTROL));
446 params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
447 FW_PARAMS_PARAM_XYZ(SGE_HOST_PAGE_SIZE));
448 params[2] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
449 FW_PARAMS_PARAM_XYZ(SGE_FL_BUFFER_SIZE0));
450 params[3] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
451 FW_PARAMS_PARAM_XYZ(SGE_FL_BUFFER_SIZE1));
452 params[4] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
453 FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_0_AND_1));
454 params[5] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
455 FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_2_AND_3));
456 params[6] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
457 FW_PARAMS_PARAM_XYZ(SGE_TIMER_VALUE_4_AND_5));
458 v = t4vf_query_params(adapter, 7, params, vals);
459 if (v)
460 return v;
461 sge_params->sge_control = vals[0];
462 sge_params->sge_host_page_size = vals[1];
463 sge_params->sge_fl_buffer_size[0] = vals[2];
464 sge_params->sge_fl_buffer_size[1] = vals[3];
465 sge_params->sge_timer_value_0_and_1 = vals[4];
466 sge_params->sge_timer_value_2_and_3 = vals[5];
467 sge_params->sge_timer_value_4_and_5 = vals[6];
468
469 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
470 FW_PARAMS_PARAM_XYZ(SGE_INGRESS_RX_THRESHOLD));
471 v = t4vf_query_params(adapter, 1, params, vals);
472 if (v)
473 return v;
474 sge_params->sge_ingress_rx_threshold = vals[0];
475
476 return 0;
477}
478
479
480
481
482
483
484
485
486int t4vf_get_vpd_params(struct adapter *adapter)
487{
488 struct vpd_params *vpd_params = &adapter->params.vpd;
489 u32 params[7], vals[7];
490 int v;
491
492 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
493 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_CCLK));
494 v = t4vf_query_params(adapter, 1, params, vals);
495 if (v)
496 return v;
497 vpd_params->cclk = vals[0];
498
499 return 0;
500}
501
502
503
504
505
506
507
508
509int t4vf_get_dev_params(struct adapter *adapter)
510{
511 struct dev_params *dev_params = &adapter->params.dev;
512 u32 params[7], vals[7];
513 int v;
514
515 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
516 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_FWREV));
517 params[1] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) |
518 FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_TPREV));
519 v = t4vf_query_params(adapter, 2, params, vals);
520 if (v)
521 return v;
522 dev_params->fwrev = vals[0];
523 dev_params->tprev = vals[1];
524
525 return 0;
526}
527
528
529
530
531
532
533
534
535int t4vf_get_rss_glb_config(struct adapter *adapter)
536{
537 struct rss_params *rss = &adapter->params.rss;
538 struct fw_rss_glb_config_cmd cmd, rpl;
539 int v;
540
541
542
543
544
545 memset(&cmd, 0, sizeof(cmd));
546 cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RSS_GLB_CONFIG_CMD) |
547 FW_CMD_REQUEST |
548 FW_CMD_READ);
549 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
550 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
551 if (v)
552 return v;
553
554
555
556
557
558
559
560 rss->mode = FW_RSS_GLB_CONFIG_CMD_MODE_GET(
561 be32_to_cpu(rpl.u.manual.mode_pkd));
562 switch (rss->mode) {
563 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
564 u32 word = be32_to_cpu(
565 rpl.u.basicvirtual.synmapen_to_hashtoeplitz);
566
567 rss->u.basicvirtual.synmapen =
568 ((word & FW_RSS_GLB_CONFIG_CMD_SYNMAPEN) != 0);
569 rss->u.basicvirtual.syn4tupenipv6 =
570 ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV6) != 0);
571 rss->u.basicvirtual.syn2tupenipv6 =
572 ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV6) != 0);
573 rss->u.basicvirtual.syn4tupenipv4 =
574 ((word & FW_RSS_GLB_CONFIG_CMD_SYN4TUPENIPV4) != 0);
575 rss->u.basicvirtual.syn2tupenipv4 =
576 ((word & FW_RSS_GLB_CONFIG_CMD_SYN2TUPENIPV4) != 0);
577
578 rss->u.basicvirtual.ofdmapen =
579 ((word & FW_RSS_GLB_CONFIG_CMD_OFDMAPEN) != 0);
580
581 rss->u.basicvirtual.tnlmapen =
582 ((word & FW_RSS_GLB_CONFIG_CMD_TNLMAPEN) != 0);
583 rss->u.basicvirtual.tnlalllookup =
584 ((word & FW_RSS_GLB_CONFIG_CMD_TNLALLLKP) != 0);
585
586 rss->u.basicvirtual.hashtoeplitz =
587 ((word & FW_RSS_GLB_CONFIG_CMD_HASHTOEPLITZ) != 0);
588
589
590 if (!rss->u.basicvirtual.tnlmapen)
591 return -EINVAL;
592 break;
593 }
594
595 default:
596
597 return -EINVAL;
598 }
599
600 return 0;
601}
602
603
604
605
606
607
608
609
610int t4vf_get_vfres(struct adapter *adapter)
611{
612 struct vf_resources *vfres = &adapter->params.vfres;
613 struct fw_pfvf_cmd cmd, rpl;
614 int v;
615 u32 word;
616
617
618
619
620
621 memset(&cmd, 0, sizeof(cmd));
622 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_PFVF_CMD) |
623 FW_CMD_REQUEST |
624 FW_CMD_READ);
625 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
626 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
627 if (v)
628 return v;
629
630
631
632
633 word = be32_to_cpu(rpl.niqflint_niq);
634 vfres->niqflint = FW_PFVF_CMD_NIQFLINT_GET(word);
635 vfres->niq = FW_PFVF_CMD_NIQ_GET(word);
636
637 word = be32_to_cpu(rpl.type_to_neq);
638 vfres->neq = FW_PFVF_CMD_NEQ_GET(word);
639 vfres->pmask = FW_PFVF_CMD_PMASK_GET(word);
640
641 word = be32_to_cpu(rpl.tc_to_nexactf);
642 vfres->tc = FW_PFVF_CMD_TC_GET(word);
643 vfres->nvi = FW_PFVF_CMD_NVI_GET(word);
644 vfres->nexactf = FW_PFVF_CMD_NEXACTF_GET(word);
645
646 word = be32_to_cpu(rpl.r_caps_to_nethctrl);
647 vfres->r_caps = FW_PFVF_CMD_R_CAPS_GET(word);
648 vfres->wx_caps = FW_PFVF_CMD_WX_CAPS_GET(word);
649 vfres->nethctrl = FW_PFVF_CMD_NETHCTRL_GET(word);
650
651 return 0;
652}
653
654
655
656
657
658
659
660
661
662
663int t4vf_read_rss_vi_config(struct adapter *adapter, unsigned int viid,
664 union rss_vi_config *config)
665{
666 struct fw_rss_vi_config_cmd cmd, rpl;
667 int v;
668
669 memset(&cmd, 0, sizeof(cmd));
670 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) |
671 FW_CMD_REQUEST |
672 FW_CMD_READ |
673 FW_RSS_VI_CONFIG_CMD_VIID(viid));
674 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
675 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
676 if (v)
677 return v;
678
679 switch (adapter->params.rss.mode) {
680 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
681 u32 word = be32_to_cpu(rpl.u.basicvirtual.defaultq_to_udpen);
682
683 config->basicvirtual.ip6fourtupen =
684 ((word & FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN) != 0);
685 config->basicvirtual.ip6twotupen =
686 ((word & FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN) != 0);
687 config->basicvirtual.ip4fourtupen =
688 ((word & FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN) != 0);
689 config->basicvirtual.ip4twotupen =
690 ((word & FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN) != 0);
691 config->basicvirtual.udpen =
692 ((word & FW_RSS_VI_CONFIG_CMD_UDPEN) != 0);
693 config->basicvirtual.defaultq =
694 FW_RSS_VI_CONFIG_CMD_DEFAULTQ_GET(word);
695 break;
696 }
697
698 default:
699 return -EINVAL;
700 }
701
702 return 0;
703}
704
705
706
707
708
709
710
711
712
713
714int t4vf_write_rss_vi_config(struct adapter *adapter, unsigned int viid,
715 union rss_vi_config *config)
716{
717 struct fw_rss_vi_config_cmd cmd, rpl;
718
719 memset(&cmd, 0, sizeof(cmd));
720 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_VI_CONFIG_CMD) |
721 FW_CMD_REQUEST |
722 FW_CMD_WRITE |
723 FW_RSS_VI_CONFIG_CMD_VIID(viid));
724 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
725 switch (adapter->params.rss.mode) {
726 case FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL: {
727 u32 word = 0;
728
729 if (config->basicvirtual.ip6fourtupen)
730 word |= FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN;
731 if (config->basicvirtual.ip6twotupen)
732 word |= FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN;
733 if (config->basicvirtual.ip4fourtupen)
734 word |= FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN;
735 if (config->basicvirtual.ip4twotupen)
736 word |= FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN;
737 if (config->basicvirtual.udpen)
738 word |= FW_RSS_VI_CONFIG_CMD_UDPEN;
739 word |= FW_RSS_VI_CONFIG_CMD_DEFAULTQ(
740 config->basicvirtual.defaultq);
741 cmd.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(word);
742 break;
743 }
744
745 default:
746 return -EINVAL;
747 }
748
749 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
750}
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767int t4vf_config_rss_range(struct adapter *adapter, unsigned int viid,
768 int start, int n, const u16 *rspq, int nrspq)
769{
770 const u16 *rsp = rspq;
771 const u16 *rsp_end = rspq+nrspq;
772 struct fw_rss_ind_tbl_cmd cmd;
773
774
775
776
777 memset(&cmd, 0, sizeof(cmd));
778 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_RSS_IND_TBL_CMD) |
779 FW_CMD_REQUEST |
780 FW_CMD_WRITE |
781 FW_RSS_IND_TBL_CMD_VIID(viid));
782 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
783
784
785
786
787
788
789
790 while (n > 0) {
791 __be32 *qp = &cmd.iq0_to_iq2;
792 int nq = min(n, 32);
793 int ret;
794
795
796
797
798
799 cmd.niqid = cpu_to_be16(nq);
800 cmd.startidx = cpu_to_be16(start);
801
802
803
804
805 start += nq;
806 n -= nq;
807
808
809
810
811
812
813 while (nq > 0) {
814
815
816
817
818
819
820 u16 qbuf[3];
821 u16 *qbp = qbuf;
822 int nqbuf = min(3, nq);
823
824 nq -= nqbuf;
825 qbuf[0] = qbuf[1] = qbuf[2] = 0;
826 while (nqbuf) {
827 nqbuf--;
828 *qbp++ = *rsp++;
829 if (rsp >= rsp_end)
830 rsp = rspq;
831 }
832 *qp++ = cpu_to_be32(FW_RSS_IND_TBL_CMD_IQ0(qbuf[0]) |
833 FW_RSS_IND_TBL_CMD_IQ1(qbuf[1]) |
834 FW_RSS_IND_TBL_CMD_IQ2(qbuf[2]));
835 }
836
837
838
839
840
841 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
842 if (ret)
843 return ret;
844 }
845 return 0;
846}
847
848
849
850
851
852
853
854
855
856
857int t4vf_alloc_vi(struct adapter *adapter, int port_id)
858{
859 struct fw_vi_cmd cmd, rpl;
860 int v;
861
862
863
864
865
866 memset(&cmd, 0, sizeof(cmd));
867 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) |
868 FW_CMD_REQUEST |
869 FW_CMD_WRITE |
870 FW_CMD_EXEC);
871 cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
872 FW_VI_CMD_ALLOC);
873 cmd.portid_pkd = FW_VI_CMD_PORTID(port_id);
874 v = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
875 if (v)
876 return v;
877
878 return FW_VI_CMD_VIID_GET(be16_to_cpu(rpl.type_viid));
879}
880
881
882
883
884
885
886
887
888
889int t4vf_free_vi(struct adapter *adapter, int viid)
890{
891 struct fw_vi_cmd cmd;
892
893
894
895
896 memset(&cmd, 0, sizeof(cmd));
897 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_VI_CMD) |
898 FW_CMD_REQUEST |
899 FW_CMD_EXEC);
900 cmd.alloc_to_len16 = cpu_to_be32(FW_LEN16(cmd) |
901 FW_VI_CMD_FREE);
902 cmd.type_viid = cpu_to_be16(FW_VI_CMD_VIID(viid));
903 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
904}
905
906
907
908
909
910
911
912
913
914
915int t4vf_enable_vi(struct adapter *adapter, unsigned int viid,
916 bool rx_en, bool tx_en)
917{
918 struct fw_vi_enable_cmd cmd;
919
920 memset(&cmd, 0, sizeof(cmd));
921 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_ENABLE_CMD) |
922 FW_CMD_REQUEST |
923 FW_CMD_EXEC |
924 FW_VI_ENABLE_CMD_VIID(viid));
925 cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN(rx_en) |
926 FW_VI_ENABLE_CMD_EEN(tx_en) |
927 FW_LEN16(cmd));
928 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
929}
930
931
932
933
934
935
936
937
938
939int t4vf_identify_port(struct adapter *adapter, unsigned int viid,
940 unsigned int nblinks)
941{
942 struct fw_vi_enable_cmd cmd;
943
944 memset(&cmd, 0, sizeof(cmd));
945 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_ENABLE_CMD) |
946 FW_CMD_REQUEST |
947 FW_CMD_EXEC |
948 FW_VI_ENABLE_CMD_VIID(viid));
949 cmd.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED |
950 FW_LEN16(cmd));
951 cmd.blinkdur = cpu_to_be16(nblinks);
952 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
953}
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968int t4vf_set_rxmode(struct adapter *adapter, unsigned int viid,
969 int mtu, int promisc, int all_multi, int bcast, int vlanex,
970 bool sleep_ok)
971{
972 struct fw_vi_rxmode_cmd cmd;
973
974
975 if (mtu < 0)
976 mtu = FW_VI_RXMODE_CMD_MTU_MASK;
977 if (promisc < 0)
978 promisc = FW_VI_RXMODE_CMD_PROMISCEN_MASK;
979 if (all_multi < 0)
980 all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK;
981 if (bcast < 0)
982 bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK;
983 if (vlanex < 0)
984 vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK;
985
986 memset(&cmd, 0, sizeof(cmd));
987 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_RXMODE_CMD) |
988 FW_CMD_REQUEST |
989 FW_CMD_WRITE |
990 FW_VI_RXMODE_CMD_VIID(viid));
991 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
992 cmd.mtu_to_vlanexen =
993 cpu_to_be32(FW_VI_RXMODE_CMD_MTU(mtu) |
994 FW_VI_RXMODE_CMD_PROMISCEN(promisc) |
995 FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) |
996 FW_VI_RXMODE_CMD_BROADCASTEN(bcast) |
997 FW_VI_RXMODE_CMD_VLANEXEN(vlanex));
998 return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok);
999}
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
1023 unsigned int naddr, const u8 **addr, u16 *idx,
1024 u64 *hash, bool sleep_ok)
1025{
1026 int offset, ret = 0;
1027 unsigned nfilters = 0;
1028 unsigned int rem = naddr;
1029 struct fw_vi_mac_cmd cmd, rpl;
1030 unsigned int max_naddr = is_t4(adapter->chip) ?
1031 NUM_MPS_CLS_SRAM_L_INSTANCES :
1032 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
1033
1034 if (naddr > max_naddr)
1035 return -EINVAL;
1036
1037 for (offset = 0; offset < naddr; ) {
1038 unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
1039 ? rem
1040 : ARRAY_SIZE(cmd.u.exact));
1041 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1042 u.exact[fw_naddr]), 16);
1043 struct fw_vi_mac_exact *p;
1044 int i;
1045
1046 memset(&cmd, 0, sizeof(cmd));
1047 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1048 FW_CMD_REQUEST |
1049 FW_CMD_WRITE |
1050 (free ? FW_CMD_EXEC : 0) |
1051 FW_VI_MAC_CMD_VIID(viid));
1052 cmd.freemacs_to_len16 =
1053 cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
1054 FW_CMD_LEN16(len16));
1055
1056 for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
1057 p->valid_to_idx = cpu_to_be16(
1058 FW_VI_MAC_CMD_VALID |
1059 FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
1060 memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
1061 }
1062
1063
1064 ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
1065 sleep_ok);
1066 if (ret && ret != -ENOMEM)
1067 break;
1068
1069 for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
1070 u16 index = FW_VI_MAC_CMD_IDX_GET(
1071 be16_to_cpu(p->valid_to_idx));
1072
1073 if (idx)
1074 idx[offset+i] =
1075 (index >= max_naddr
1076 ? 0xffff
1077 : index);
1078 if (index < max_naddr)
1079 nfilters++;
1080 else if (hash)
1081 *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
1082 }
1083
1084 free = false;
1085 offset += fw_naddr;
1086 rem -= fw_naddr;
1087 }
1088
1089
1090
1091
1092
1093 if (ret == 0 || ret == -ENOMEM)
1094 ret = nfilters;
1095 return ret;
1096}
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116int t4vf_change_mac(struct adapter *adapter, unsigned int viid,
1117 int idx, const u8 *addr, bool persist)
1118{
1119 int ret;
1120 struct fw_vi_mac_cmd cmd, rpl;
1121 struct fw_vi_mac_exact *p = &cmd.u.exact[0];
1122 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1123 u.exact[1]), 16);
1124 unsigned int max_naddr = is_t4(adapter->chip) ?
1125 NUM_MPS_CLS_SRAM_L_INSTANCES :
1126 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
1127
1128
1129
1130
1131
1132 if (idx < 0)
1133 idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
1134
1135 memset(&cmd, 0, sizeof(cmd));
1136 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1137 FW_CMD_REQUEST |
1138 FW_CMD_WRITE |
1139 FW_VI_MAC_CMD_VIID(viid));
1140 cmd.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
1141 p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID |
1142 FW_VI_MAC_CMD_IDX(idx));
1143 memcpy(p->macaddr, addr, sizeof(p->macaddr));
1144
1145 ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &rpl);
1146 if (ret == 0) {
1147 p = &rpl.u.exact[0];
1148 ret = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx));
1149 if (ret >= max_naddr)
1150 ret = -ENOMEM;
1151 }
1152 return ret;
1153}
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165int t4vf_set_addr_hash(struct adapter *adapter, unsigned int viid,
1166 bool ucast, u64 vec, bool sleep_ok)
1167{
1168 struct fw_vi_mac_cmd cmd;
1169 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1170 u.exact[0]), 16);
1171
1172 memset(&cmd, 0, sizeof(cmd));
1173 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1174 FW_CMD_REQUEST |
1175 FW_CMD_WRITE |
1176 FW_VI_ENABLE_CMD_VIID(viid));
1177 cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN |
1178 FW_VI_MAC_CMD_HASHUNIEN(ucast) |
1179 FW_CMD_LEN16(len16));
1180 cmd.u.hash.hashvec = cpu_to_be64(vec);
1181 return t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), NULL, sleep_ok);
1182}
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192int t4vf_get_port_stats(struct adapter *adapter, int pidx,
1193 struct t4vf_port_stats *s)
1194{
1195 struct port_info *pi = adap2pinfo(adapter, pidx);
1196 struct fw_vi_stats_vf fwstats;
1197 unsigned int rem = VI_VF_NUM_STATS;
1198 __be64 *fwsp = (__be64 *)&fwstats;
1199
1200
1201
1202
1203
1204
1205 while (rem) {
1206 unsigned int ix = VI_VF_NUM_STATS - rem;
1207 unsigned int nstats = min(6U, rem);
1208 struct fw_vi_stats_cmd cmd, rpl;
1209 size_t len = (offsetof(struct fw_vi_stats_cmd, u) +
1210 sizeof(struct fw_vi_stats_ctl));
1211 size_t len16 = DIV_ROUND_UP(len, 16);
1212 int ret;
1213
1214 memset(&cmd, 0, sizeof(cmd));
1215 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_STATS_CMD) |
1216 FW_VI_STATS_CMD_VIID(pi->viid) |
1217 FW_CMD_REQUEST |
1218 FW_CMD_READ);
1219 cmd.retval_len16 = cpu_to_be32(FW_CMD_LEN16(len16));
1220 cmd.u.ctl.nstats_ix =
1221 cpu_to_be16(FW_VI_STATS_CMD_IX(ix) |
1222 FW_VI_STATS_CMD_NSTATS(nstats));
1223 ret = t4vf_wr_mbox_ns(adapter, &cmd, len, &rpl);
1224 if (ret)
1225 return ret;
1226
1227 memcpy(fwsp, &rpl.u.ctl.stat0, sizeof(__be64) * nstats);
1228
1229 rem -= nstats;
1230 fwsp += nstats;
1231 }
1232
1233
1234
1235
1236 s->tx_bcast_bytes = be64_to_cpu(fwstats.tx_bcast_bytes);
1237 s->tx_bcast_frames = be64_to_cpu(fwstats.tx_bcast_frames);
1238 s->tx_mcast_bytes = be64_to_cpu(fwstats.tx_mcast_bytes);
1239 s->tx_mcast_frames = be64_to_cpu(fwstats.tx_mcast_frames);
1240 s->tx_ucast_bytes = be64_to_cpu(fwstats.tx_ucast_bytes);
1241 s->tx_ucast_frames = be64_to_cpu(fwstats.tx_ucast_frames);
1242 s->tx_drop_frames = be64_to_cpu(fwstats.tx_drop_frames);
1243 s->tx_offload_bytes = be64_to_cpu(fwstats.tx_offload_bytes);
1244 s->tx_offload_frames = be64_to_cpu(fwstats.tx_offload_frames);
1245
1246 s->rx_bcast_bytes = be64_to_cpu(fwstats.rx_bcast_bytes);
1247 s->rx_bcast_frames = be64_to_cpu(fwstats.rx_bcast_frames);
1248 s->rx_mcast_bytes = be64_to_cpu(fwstats.rx_mcast_bytes);
1249 s->rx_mcast_frames = be64_to_cpu(fwstats.rx_mcast_frames);
1250 s->rx_ucast_bytes = be64_to_cpu(fwstats.rx_ucast_bytes);
1251 s->rx_ucast_frames = be64_to_cpu(fwstats.rx_ucast_frames);
1252
1253 s->rx_err_frames = be64_to_cpu(fwstats.rx_err_frames);
1254
1255 return 0;
1256}
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268int t4vf_iq_free(struct adapter *adapter, unsigned int iqtype,
1269 unsigned int iqid, unsigned int fl0id, unsigned int fl1id)
1270{
1271 struct fw_iq_cmd cmd;
1272
1273 memset(&cmd, 0, sizeof(cmd));
1274 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_IQ_CMD) |
1275 FW_CMD_REQUEST |
1276 FW_CMD_EXEC);
1277 cmd.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE |
1278 FW_LEN16(cmd));
1279 cmd.type_to_iqandstindex =
1280 cpu_to_be32(FW_IQ_CMD_TYPE(iqtype));
1281
1282 cmd.iqid = cpu_to_be16(iqid);
1283 cmd.fl0id = cpu_to_be16(fl0id);
1284 cmd.fl1id = cpu_to_be16(fl1id);
1285 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1286}
1287
1288
1289
1290
1291
1292
1293
1294
1295int t4vf_eth_eq_free(struct adapter *adapter, unsigned int eqid)
1296{
1297 struct fw_eq_eth_cmd cmd;
1298
1299 memset(&cmd, 0, sizeof(cmd));
1300 cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP(FW_EQ_ETH_CMD) |
1301 FW_CMD_REQUEST |
1302 FW_CMD_EXEC);
1303 cmd.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE |
1304 FW_LEN16(cmd));
1305 cmd.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID(eqid));
1306 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
1307}
1308
1309
1310
1311
1312
1313
1314
1315
1316int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
1317{
1318 const struct fw_cmd_hdr *cmd_hdr = (const struct fw_cmd_hdr *)rpl;
1319 u8 opcode = FW_CMD_OP_GET(be32_to_cpu(cmd_hdr->hi));
1320
1321 switch (opcode) {
1322 case FW_PORT_CMD: {
1323
1324
1325
1326 const struct fw_port_cmd *port_cmd =
1327 (const struct fw_port_cmd *)rpl;
1328 u32 word;
1329 int action, port_id, link_ok, speed, fc, pidx;
1330
1331
1332
1333
1334 action = FW_PORT_CMD_ACTION_GET(
1335 be32_to_cpu(port_cmd->action_to_len16));
1336 if (action != FW_PORT_ACTION_GET_PORT_INFO) {
1337 dev_err(adapter->pdev_dev,
1338 "Unknown firmware PORT reply action %x\n",
1339 action);
1340 break;
1341 }
1342
1343 port_id = FW_PORT_CMD_PORTID_GET(
1344 be32_to_cpu(port_cmd->op_to_portid));
1345
1346 word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype);
1347 link_ok = (word & FW_PORT_CMD_LSTATUS) != 0;
1348 speed = 0;
1349 fc = 0;
1350 if (word & FW_PORT_CMD_RXPAUSE)
1351 fc |= PAUSE_RX;
1352 if (word & FW_PORT_CMD_TXPAUSE)
1353 fc |= PAUSE_TX;
1354 if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
1355 speed = SPEED_100;
1356 else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
1357 speed = SPEED_1000;
1358 else if (word & FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
1359 speed = SPEED_10000;
1360
1361
1362
1363
1364
1365
1366
1367 for_each_port(adapter, pidx) {
1368 struct port_info *pi = adap2pinfo(adapter, pidx);
1369 struct link_config *lc;
1370
1371 if (pi->port_id != port_id)
1372 continue;
1373
1374 lc = &pi->link_cfg;
1375 if (link_ok != lc->link_ok || speed != lc->speed ||
1376 fc != lc->fc) {
1377
1378 lc->link_ok = link_ok;
1379 lc->speed = speed;
1380 lc->fc = fc;
1381 t4vf_os_link_changed(adapter, pidx, link_ok);
1382 }
1383 }
1384 break;
1385 }
1386
1387 default:
1388 dev_err(adapter->pdev_dev, "Unknown firmware reply %X\n",
1389 opcode);
1390 }
1391 return 0;
1392}
1393