1
2
3
4#include "ice_common.h"
5#include "ice_sched.h"
6#include "ice_dcb.h"
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21static enum ice_status
22ice_aq_get_lldp_mib(struct ice_hw *hw, u8 bridge_type, u8 mib_type, void *buf,
23 u16 buf_size, u16 *local_len, u16 *remote_len,
24 struct ice_sq_cd *cd)
25{
26 struct ice_aqc_lldp_get_mib *cmd;
27 struct ice_aq_desc desc;
28 enum ice_status status;
29
30 cmd = &desc.params.lldp_get_mib;
31
32 if (buf_size == 0 || !buf)
33 return ICE_ERR_PARAM;
34
35 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_get_mib);
36
37 cmd->type = mib_type & ICE_AQ_LLDP_MIB_TYPE_M;
38 cmd->type |= (bridge_type << ICE_AQ_LLDP_BRID_TYPE_S) &
39 ICE_AQ_LLDP_BRID_TYPE_M;
40
41 desc.datalen = cpu_to_le16(buf_size);
42
43 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
44 if (!status) {
45 if (local_len)
46 *local_len = le16_to_cpu(cmd->local_len);
47 if (remote_len)
48 *remote_len = le16_to_cpu(cmd->remote_len);
49 }
50
51 return status;
52}
53
54
55
56
57
58
59
60
61
62
63enum ice_status
64ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update,
65 struct ice_sq_cd *cd)
66{
67 struct ice_aqc_lldp_set_mib_change *cmd;
68 struct ice_aq_desc desc;
69
70 cmd = &desc.params.lldp_set_event;
71
72 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_mib_change);
73
74 if (!ena_update)
75 cmd->command |= ICE_AQ_LLDP_MIB_UPDATE_DIS;
76
77 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
78}
79
80
81
82
83
84
85
86
87
88
89
90
91enum ice_status
92ice_aq_stop_lldp(struct ice_hw *hw, bool shutdown_lldp_agent, bool persist,
93 struct ice_sq_cd *cd)
94{
95 struct ice_aqc_lldp_stop *cmd;
96 struct ice_aq_desc desc;
97
98 cmd = &desc.params.lldp_stop;
99
100 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_stop);
101
102 if (shutdown_lldp_agent)
103 cmd->command |= ICE_AQ_LLDP_AGENT_SHUTDOWN;
104
105 if (persist)
106 cmd->command |= ICE_AQ_LLDP_AGENT_PERSIST_DIS;
107
108 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
109}
110
111
112
113
114
115
116
117
118
119enum ice_status
120ice_aq_start_lldp(struct ice_hw *hw, bool persist, struct ice_sq_cd *cd)
121{
122 struct ice_aqc_lldp_start *cmd;
123 struct ice_aq_desc desc;
124
125 cmd = &desc.params.lldp_start;
126
127 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_start);
128
129 cmd->command = ICE_AQ_LLDP_AGENT_START;
130
131 if (persist)
132 cmd->command |= ICE_AQ_LLDP_AGENT_PERSIST_ENA;
133
134 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
135}
136
137
138
139
140
141
142
143
144
145
146
147static enum ice_status
148ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
149 struct ice_sq_cd *cd)
150{
151 struct ice_aqc_lldp_set_local_mib *cmd;
152 struct ice_aq_desc desc;
153
154 cmd = &desc.params.lldp_set_mib;
155
156 if (buf_size == 0 || !buf)
157 return ICE_ERR_PARAM;
158
159 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_local_mib);
160
161 desc.flags |= cpu_to_le16((u16)ICE_AQ_FLAG_RD);
162 desc.datalen = cpu_to_le16(buf_size);
163
164 cmd->type = mib_type;
165 cmd->length = cpu_to_le16(buf_size);
166
167 return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
168}
169
170
171
172
173
174
175
176static u8 ice_get_dcbx_status(struct ice_hw *hw)
177{
178 u32 reg;
179
180 reg = rd32(hw, PRTDCB_GENS);
181 return (u8)((reg & PRTDCB_GENS_DCBX_STATUS_M) >>
182 PRTDCB_GENS_DCBX_STATUS_S);
183}
184
185
186
187
188
189
190
191
192static void
193ice_parse_ieee_ets_common_tlv(u8 *buf, struct ice_dcb_ets_cfg *ets_cfg)
194{
195 u8 offset = 0;
196 int i;
197
198
199
200
201
202
203
204
205
206 for (i = 0; i < 4; i++) {
207 ets_cfg->prio_table[i * 2] =
208 ((buf[offset] & ICE_IEEE_ETS_PRIO_1_M) >>
209 ICE_IEEE_ETS_PRIO_1_S);
210 ets_cfg->prio_table[i * 2 + 1] =
211 ((buf[offset] & ICE_IEEE_ETS_PRIO_0_M) >>
212 ICE_IEEE_ETS_PRIO_0_S);
213 offset++;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227
228 ice_for_each_traffic_class(i) {
229 ets_cfg->tcbwtable[i] = buf[offset];
230 ets_cfg->tsatable[i] = buf[ICE_MAX_TRAFFIC_CLASS + offset++];
231 }
232}
233
234
235
236
237
238
239
240
241static void
242ice_parse_ieee_etscfg_tlv(struct ice_lldp_org_tlv *tlv,
243 struct ice_dcbx_cfg *dcbcfg)
244{
245 struct ice_dcb_ets_cfg *etscfg;
246 u8 *buf = tlv->tlvinfo;
247
248
249
250
251
252
253
254
255 etscfg = &dcbcfg->etscfg;
256 etscfg->willing = ((buf[0] & ICE_IEEE_ETS_WILLING_M) >>
257 ICE_IEEE_ETS_WILLING_S);
258 etscfg->cbs = ((buf[0] & ICE_IEEE_ETS_CBS_M) >> ICE_IEEE_ETS_CBS_S);
259 etscfg->maxtcs = ((buf[0] & ICE_IEEE_ETS_MAXTC_M) >>
260 ICE_IEEE_ETS_MAXTC_S);
261
262
263 ice_parse_ieee_ets_common_tlv(&buf[1], etscfg);
264}
265
266
267
268
269
270
271
272
273static void
274ice_parse_ieee_etsrec_tlv(struct ice_lldp_org_tlv *tlv,
275 struct ice_dcbx_cfg *dcbcfg)
276{
277 u8 *buf = tlv->tlvinfo;
278
279
280 ice_parse_ieee_ets_common_tlv(&buf[1], &dcbcfg->etsrec);
281}
282
283
284
285
286
287
288
289
290static void
291ice_parse_ieee_pfccfg_tlv(struct ice_lldp_org_tlv *tlv,
292 struct ice_dcbx_cfg *dcbcfg)
293{
294 u8 *buf = tlv->tlvinfo;
295
296
297
298
299
300
301
302 dcbcfg->pfc.willing = ((buf[0] & ICE_IEEE_PFC_WILLING_M) >>
303 ICE_IEEE_PFC_WILLING_S);
304 dcbcfg->pfc.mbc = ((buf[0] & ICE_IEEE_PFC_MBC_M) >> ICE_IEEE_PFC_MBC_S);
305 dcbcfg->pfc.pfccap = ((buf[0] & ICE_IEEE_PFC_CAP_M) >>
306 ICE_IEEE_PFC_CAP_S);
307 dcbcfg->pfc.pfcena = buf[1];
308}
309
310
311
312
313
314
315
316
317static void
318ice_parse_ieee_app_tlv(struct ice_lldp_org_tlv *tlv,
319 struct ice_dcbx_cfg *dcbcfg)
320{
321 u16 offset = 0;
322 u16 typelen;
323 int i = 0;
324 u16 len;
325 u8 *buf;
326
327 typelen = ntohs(tlv->typelen);
328 len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
329 buf = tlv->tlvinfo;
330
331
332
333
334 len -= (sizeof(tlv->ouisubtype) + 1);
335
336
337 offset++;
338
339
340
341
342
343
344
345
346
347 while (offset < len) {
348 dcbcfg->app[i].priority = ((buf[offset] &
349 ICE_IEEE_APP_PRIO_M) >>
350 ICE_IEEE_APP_PRIO_S);
351 dcbcfg->app[i].selector = ((buf[offset] &
352 ICE_IEEE_APP_SEL_M) >>
353 ICE_IEEE_APP_SEL_S);
354 dcbcfg->app[i].prot_id = (buf[offset + 1] << 0x8) |
355 buf[offset + 2];
356
357 offset += 3;
358 i++;
359 if (i >= ICE_DCBX_MAX_APPS)
360 break;
361 }
362
363 dcbcfg->numapps = i;
364}
365
366
367
368
369
370
371
372
373
374static void
375ice_parse_ieee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
376{
377 u32 ouisubtype;
378 u8 subtype;
379
380 ouisubtype = ntohl(tlv->ouisubtype);
381 subtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >>
382 ICE_LLDP_TLV_SUBTYPE_S);
383 switch (subtype) {
384 case ICE_IEEE_SUBTYPE_ETS_CFG:
385 ice_parse_ieee_etscfg_tlv(tlv, dcbcfg);
386 break;
387 case ICE_IEEE_SUBTYPE_ETS_REC:
388 ice_parse_ieee_etsrec_tlv(tlv, dcbcfg);
389 break;
390 case ICE_IEEE_SUBTYPE_PFC_CFG:
391 ice_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
392 break;
393 case ICE_IEEE_SUBTYPE_APP_PRI:
394 ice_parse_ieee_app_tlv(tlv, dcbcfg);
395 break;
396 default:
397 break;
398 }
399}
400
401
402
403
404
405
406
407
408static void
409ice_parse_cee_pgcfg_tlv(struct ice_cee_feat_tlv *tlv,
410 struct ice_dcbx_cfg *dcbcfg)
411{
412 struct ice_dcb_ets_cfg *etscfg;
413 u8 *buf = tlv->tlvinfo;
414 u16 offset = 0;
415 int i;
416
417 etscfg = &dcbcfg->etscfg;
418
419 if (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M)
420 etscfg->willing = 1;
421
422 etscfg->cbs = 0;
423
424
425
426
427
428
429
430
431 for (i = 0; i < 4; i++) {
432 etscfg->prio_table[i * 2] =
433 ((buf[offset] & ICE_CEE_PGID_PRIO_1_M) >>
434 ICE_CEE_PGID_PRIO_1_S);
435 etscfg->prio_table[i * 2 + 1] =
436 ((buf[offset] & ICE_CEE_PGID_PRIO_0_M) >>
437 ICE_CEE_PGID_PRIO_0_S);
438 offset++;
439 }
440
441
442
443
444
445
446
447 ice_for_each_traffic_class(i)
448 etscfg->tcbwtable[i] = buf[offset++];
449
450
451 etscfg->maxtcs = buf[offset];
452}
453
454
455
456
457
458
459
460
461static void
462ice_parse_cee_pfccfg_tlv(struct ice_cee_feat_tlv *tlv,
463 struct ice_dcbx_cfg *dcbcfg)
464{
465 u8 *buf = tlv->tlvinfo;
466
467 if (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M)
468 dcbcfg->pfc.willing = 1;
469
470
471
472
473
474
475 dcbcfg->pfc.pfcena = buf[0];
476 dcbcfg->pfc.pfccap = buf[1];
477}
478
479
480
481
482
483
484
485
486static void
487ice_parse_cee_app_tlv(struct ice_cee_feat_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
488{
489 u16 len, typelen, offset = 0;
490 struct ice_cee_app_prio *app;
491 u8 i;
492
493 typelen = ntohs(tlv->hdr.typelen);
494 len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
495
496 dcbcfg->numapps = len / sizeof(*app);
497 if (!dcbcfg->numapps)
498 return;
499 if (dcbcfg->numapps > ICE_DCBX_MAX_APPS)
500 dcbcfg->numapps = ICE_DCBX_MAX_APPS;
501
502 for (i = 0; i < dcbcfg->numapps; i++) {
503 u8 up, selector;
504
505 app = (struct ice_cee_app_prio *)(tlv->tlvinfo + offset);
506 for (up = 0; up < ICE_MAX_USER_PRIORITY; up++)
507 if (app->prio_map & BIT(up))
508 break;
509
510 dcbcfg->app[i].priority = up;
511
512
513 selector = (app->upper_oui_sel & ICE_CEE_APP_SELECTOR_M);
514 switch (selector) {
515 case ICE_CEE_APP_SEL_ETHTYPE:
516 dcbcfg->app[i].selector = ICE_APP_SEL_ETHTYPE;
517 break;
518 case ICE_CEE_APP_SEL_TCPIP:
519 dcbcfg->app[i].selector = ICE_APP_SEL_TCPIP;
520 break;
521 default:
522
523 dcbcfg->app[i].selector = selector;
524 }
525
526 dcbcfg->app[i].prot_id = ntohs(app->protocol);
527
528 offset += sizeof(*app);
529 }
530}
531
532
533
534
535
536
537
538
539
540static void
541ice_parse_cee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
542{
543 struct ice_cee_feat_tlv *sub_tlv;
544 u8 subtype, feat_tlv_count = 0;
545 u16 len, tlvlen, typelen;
546 u32 ouisubtype;
547
548 ouisubtype = ntohl(tlv->ouisubtype);
549 subtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >>
550 ICE_LLDP_TLV_SUBTYPE_S);
551
552 if (subtype != ICE_CEE_DCBX_TYPE)
553 return;
554
555 typelen = ntohs(tlv->typelen);
556 tlvlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
557 len = sizeof(tlv->typelen) + sizeof(ouisubtype) +
558 sizeof(struct ice_cee_ctrl_tlv);
559
560 if (tlvlen <= len)
561 return;
562
563 sub_tlv = (struct ice_cee_feat_tlv *)((char *)tlv + len);
564 while (feat_tlv_count < ICE_CEE_MAX_FEAT_TYPE) {
565 u16 sublen;
566
567 typelen = ntohs(sub_tlv->hdr.typelen);
568 sublen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
569 subtype = (u8)((typelen & ICE_LLDP_TLV_TYPE_M) >>
570 ICE_LLDP_TLV_TYPE_S);
571 switch (subtype) {
572 case ICE_CEE_SUBTYPE_PG_CFG:
573 ice_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
574 break;
575 case ICE_CEE_SUBTYPE_PFC_CFG:
576 ice_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
577 break;
578 case ICE_CEE_SUBTYPE_APP_PRI:
579 ice_parse_cee_app_tlv(sub_tlv, dcbcfg);
580 break;
581 default:
582 return;
583 }
584 feat_tlv_count++;
585
586 sub_tlv = (struct ice_cee_feat_tlv *)
587 ((char *)sub_tlv + sizeof(sub_tlv->hdr.typelen) +
588 sublen);
589 }
590}
591
592
593
594
595
596
597
598
599
600static void
601ice_parse_org_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
602{
603 u32 ouisubtype;
604 u32 oui;
605
606 ouisubtype = ntohl(tlv->ouisubtype);
607 oui = ((ouisubtype & ICE_LLDP_TLV_OUI_M) >> ICE_LLDP_TLV_OUI_S);
608 switch (oui) {
609 case ICE_IEEE_8021QAZ_OUI:
610 ice_parse_ieee_tlv(tlv, dcbcfg);
611 break;
612 case ICE_CEE_DCBX_OUI:
613 ice_parse_cee_tlv(tlv, dcbcfg);
614 break;
615 default:
616 break;
617 }
618}
619
620
621
622
623
624
625
626
627static enum ice_status
628ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg)
629{
630 struct ice_lldp_org_tlv *tlv;
631 enum ice_status ret = 0;
632 u16 offset = 0;
633 u16 typelen;
634 u16 type;
635 u16 len;
636
637 if (!lldpmib || !dcbcfg)
638 return ICE_ERR_PARAM;
639
640
641 lldpmib += ETH_HLEN;
642 tlv = (struct ice_lldp_org_tlv *)lldpmib;
643 while (1) {
644 typelen = ntohs(tlv->typelen);
645 type = ((typelen & ICE_LLDP_TLV_TYPE_M) >> ICE_LLDP_TLV_TYPE_S);
646 len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
647 offset += sizeof(typelen) + len;
648
649
650 if (type == ICE_TLV_TYPE_END || offset > ICE_LLDPDU_SIZE)
651 break;
652
653 switch (type) {
654 case ICE_TLV_TYPE_ORG:
655 ice_parse_org_tlv(tlv, dcbcfg);
656 break;
657 default:
658 break;
659 }
660
661
662 tlv = (struct ice_lldp_org_tlv *)
663 ((char *)tlv + sizeof(tlv->typelen) + len);
664 }
665
666 return ret;
667}
668
669
670
671
672
673
674
675
676
677
678enum ice_status
679ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype,
680 struct ice_dcbx_cfg *dcbcfg)
681{
682 enum ice_status ret;
683 u8 *lldpmib;
684
685
686 lldpmib = devm_kzalloc(ice_hw_to_dev(hw), ICE_LLDPDU_SIZE, GFP_KERNEL);
687 if (!lldpmib)
688 return ICE_ERR_NO_MEMORY;
689
690 ret = ice_aq_get_lldp_mib(hw, bridgetype, mib_type, (void *)lldpmib,
691 ICE_LLDPDU_SIZE, NULL, NULL, NULL);
692
693 if (!ret)
694
695 ret = ice_lldp_to_dcb_cfg(lldpmib, dcbcfg);
696
697 devm_kfree(ice_hw_to_dev(hw), lldpmib);
698
699 return ret;
700}
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716enum ice_status
717ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,
718 bool *dcbx_agent_status, struct ice_sq_cd *cd)
719{
720 struct ice_aqc_lldp_stop_start_specific_agent *cmd;
721 enum ice_status status;
722 struct ice_aq_desc desc;
723 u16 opcode;
724
725 cmd = &desc.params.lldp_agent_ctrl;
726
727 opcode = ice_aqc_opc_lldp_stop_start_specific_agent;
728
729 ice_fill_dflt_direct_cmd_desc(&desc, opcode);
730
731 if (start_dcbx_agent)
732 cmd->command = ICE_AQC_START_STOP_AGENT_START_DCBX;
733
734 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
735
736 *dcbx_agent_status = false;
737
738 if (!status &&
739 cmd->command == ICE_AQC_START_STOP_AGENT_START_DCBX)
740 *dcbx_agent_status = true;
741
742 return status;
743}
744
745
746
747
748
749
750
751
752
753static enum ice_status
754ice_aq_get_cee_dcb_cfg(struct ice_hw *hw,
755 struct ice_aqc_get_cee_dcb_cfg_resp *buff,
756 struct ice_sq_cd *cd)
757{
758 struct ice_aq_desc desc;
759
760 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_cee_dcb_cfg);
761
762 return ice_aq_send_cmd(hw, &desc, (void *)buff, sizeof(*buff), cd);
763}
764
765
766
767
768
769
770
771
772static void
773ice_cee_to_dcb_cfg(struct ice_aqc_get_cee_dcb_cfg_resp *cee_cfg,
774 struct ice_dcbx_cfg *dcbcfg)
775{
776 u32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status);
777 u32 ice_aqc_cee_status_mask, ice_aqc_cee_status_shift;
778 u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
779 u8 i, err, sync, oper, app_index, ice_app_sel_type;
780 u16 ice_aqc_cee_app_mask, ice_aqc_cee_app_shift;
781 u16 ice_app_prot_id_type;
782
783
784 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
785
786
787
788
789 for (i = 0; i < ICE_MAX_TRAFFIC_CLASS / 2; i++) {
790 dcbcfg->etscfg.prio_table[i * 2] =
791 ((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_0_M) >>
792 ICE_CEE_PGID_PRIO_0_S);
793 dcbcfg->etscfg.prio_table[i * 2 + 1] =
794 ((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_1_M) >>
795 ICE_CEE_PGID_PRIO_1_S);
796 }
797
798 ice_for_each_traffic_class(i) {
799 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
800
801 if (dcbcfg->etscfg.prio_table[i] == ICE_CEE_PGID_STRICT) {
802
803 dcbcfg->etscfg.prio_table[i] = cee_cfg->oper_num_tc - 1;
804 dcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_STRICT;
805 } else {
806 dcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;
807 }
808 }
809
810
811 dcbcfg->pfc.pfcena = cee_cfg->oper_pfc_en;
812 dcbcfg->pfc.pfccap = ICE_MAX_TRAFFIC_CLASS;
813
814 app_index = 0;
815 for (i = 0; i < 3; i++) {
816 if (i == 0) {
817
818 ice_aqc_cee_status_mask = ICE_AQC_CEE_FCOE_STATUS_M;
819 ice_aqc_cee_status_shift = ICE_AQC_CEE_FCOE_STATUS_S;
820 ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FCOE_M;
821 ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FCOE_S;
822 ice_app_sel_type = ICE_APP_SEL_ETHTYPE;
823 ice_app_prot_id_type = ICE_APP_PROT_ID_FCOE;
824 } else if (i == 1) {
825
826 ice_aqc_cee_status_mask = ICE_AQC_CEE_ISCSI_STATUS_M;
827 ice_aqc_cee_status_shift = ICE_AQC_CEE_ISCSI_STATUS_S;
828 ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_ISCSI_M;
829 ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_ISCSI_S;
830 ice_app_sel_type = ICE_APP_SEL_TCPIP;
831 ice_app_prot_id_type = ICE_APP_PROT_ID_ISCSI;
832 } else {
833
834 ice_aqc_cee_status_mask = ICE_AQC_CEE_FIP_STATUS_M;
835 ice_aqc_cee_status_shift = ICE_AQC_CEE_FIP_STATUS_S;
836 ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FIP_M;
837 ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FIP_S;
838 ice_app_sel_type = ICE_APP_SEL_ETHTYPE;
839 ice_app_prot_id_type = ICE_APP_PROT_ID_FIP;
840 }
841
842 status = (tlv_status & ice_aqc_cee_status_mask) >>
843 ice_aqc_cee_status_shift;
844 err = (status & ICE_TLV_STATUS_ERR) ? 1 : 0;
845 sync = (status & ICE_TLV_STATUS_SYNC) ? 1 : 0;
846 oper = (status & ICE_TLV_STATUS_OPER) ? 1 : 0;
847
848
849
850 if (!err && sync && oper) {
851 dcbcfg->app[app_index].priority =
852 (app_prio & ice_aqc_cee_app_mask) >>
853 ice_aqc_cee_app_shift;
854 dcbcfg->app[app_index].selector = ice_app_sel_type;
855 dcbcfg->app[app_index].prot_id = ice_app_prot_id_type;
856 app_index++;
857 }
858 }
859
860 dcbcfg->numapps = app_index;
861}
862
863
864
865
866
867
868
869
870static enum ice_status
871ice_get_ieee_or_cee_dcb_cfg(struct ice_port_info *pi, u8 dcbx_mode)
872{
873 struct ice_dcbx_cfg *dcbx_cfg = NULL;
874 enum ice_status ret;
875
876 if (!pi)
877 return ICE_ERR_PARAM;
878
879 if (dcbx_mode == ICE_DCBX_MODE_IEEE)
880 dcbx_cfg = &pi->local_dcbx_cfg;
881 else if (dcbx_mode == ICE_DCBX_MODE_CEE)
882 dcbx_cfg = &pi->desired_dcbx_cfg;
883
884
885
886
887 ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_LOCAL,
888 ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg);
889 if (ret)
890 goto out;
891
892
893 dcbx_cfg = &pi->remote_dcbx_cfg;
894 ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,
895 ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg);
896
897 if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
898 ret = 0;
899
900out:
901 return ret;
902}
903
904
905
906
907
908
909
910enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi)
911{
912 struct ice_aqc_get_cee_dcb_cfg_resp cee_cfg;
913 struct ice_dcbx_cfg *dcbx_cfg;
914 enum ice_status ret;
915
916 if (!pi)
917 return ICE_ERR_PARAM;
918
919 ret = ice_aq_get_cee_dcb_cfg(pi->hw, &cee_cfg, NULL);
920 if (!ret) {
921
922 dcbx_cfg = &pi->local_dcbx_cfg;
923 dcbx_cfg->dcbx_mode = ICE_DCBX_MODE_CEE;
924 dcbx_cfg->tlv_status = le32_to_cpu(cee_cfg.tlv_status);
925 ice_cee_to_dcb_cfg(&cee_cfg, dcbx_cfg);
926 ret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_CEE);
927 } else if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) {
928
929 dcbx_cfg = &pi->local_dcbx_cfg;
930 dcbx_cfg->dcbx_mode = ICE_DCBX_MODE_IEEE;
931 ret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_IEEE);
932 }
933
934 return ret;
935}
936
937
938
939
940
941
942
943enum ice_status ice_init_dcb(struct ice_hw *hw)
944{
945 struct ice_port_info *pi = hw->port_info;
946 enum ice_status ret = 0;
947
948 if (!hw->func_caps.common_cap.dcb)
949 return ICE_ERR_NOT_SUPPORTED;
950
951 pi->is_sw_lldp = true;
952
953
954 pi->dcbx_status = ice_get_dcbx_status(hw);
955
956 if (pi->dcbx_status == ICE_DCBX_STATUS_DONE ||
957 pi->dcbx_status == ICE_DCBX_STATUS_IN_PROGRESS) {
958
959 ret = ice_get_dcb_cfg(pi);
960 pi->is_sw_lldp = (hw->adminq.sq_last_status == ICE_AQ_RC_EPERM);
961 if (ret)
962 return ret;
963 } else if (pi->dcbx_status == ICE_DCBX_STATUS_DIS) {
964 return ICE_ERR_NOT_READY;
965 }
966
967
968 ret = ice_aq_cfg_lldp_mib_change(hw, true, NULL);
969 if (!ret)
970 pi->is_sw_lldp = false;
971
972 return ret;
973}
974
975
976
977
978
979
980
981
982static void
983ice_add_ieee_ets_common_tlv(u8 *buf, struct ice_dcb_ets_cfg *ets_cfg)
984{
985 u8 priority0, priority1;
986 u8 offset = 0;
987 int i;
988
989
990
991
992
993
994
995
996
997 for (i = 0; i < ICE_MAX_TRAFFIC_CLASS / 2; i++) {
998 priority0 = ets_cfg->prio_table[i * 2] & 0xF;
999 priority1 = ets_cfg->prio_table[i * 2 + 1] & 0xF;
1000 buf[offset] = (priority0 << ICE_IEEE_ETS_PRIO_1_S) | priority1;
1001 offset++;
1002 }
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 ice_for_each_traffic_class(i) {
1017 buf[offset] = ets_cfg->tcbwtable[i];
1018 buf[ICE_MAX_TRAFFIC_CLASS + offset] = ets_cfg->tsatable[i];
1019 offset++;
1020 }
1021}
1022
1023
1024
1025
1026
1027
1028
1029
1030static void
1031ice_add_ieee_ets_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
1032{
1033 struct ice_dcb_ets_cfg *etscfg;
1034 u8 *buf = tlv->tlvinfo;
1035 u8 maxtcwilling = 0;
1036 u32 ouisubtype;
1037 u16 typelen;
1038
1039 typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
1040 ICE_IEEE_ETS_TLV_LEN);
1041 tlv->typelen = htons(typelen);
1042
1043 ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
1044 ICE_IEEE_SUBTYPE_ETS_CFG);
1045 tlv->ouisubtype = htonl(ouisubtype);
1046
1047
1048
1049
1050
1051
1052
1053
1054 etscfg = &dcbcfg->etscfg;
1055 if (etscfg->willing)
1056 maxtcwilling = BIT(ICE_IEEE_ETS_WILLING_S);
1057 maxtcwilling |= etscfg->maxtcs & ICE_IEEE_ETS_MAXTC_M;
1058 buf[0] = maxtcwilling;
1059
1060
1061 ice_add_ieee_ets_common_tlv(&buf[1], etscfg);
1062}
1063
1064
1065
1066
1067
1068
1069
1070
1071static void
1072ice_add_ieee_etsrec_tlv(struct ice_lldp_org_tlv *tlv,
1073 struct ice_dcbx_cfg *dcbcfg)
1074{
1075 struct ice_dcb_ets_cfg *etsrec;
1076 u8 *buf = tlv->tlvinfo;
1077 u32 ouisubtype;
1078 u16 typelen;
1079
1080 typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
1081 ICE_IEEE_ETS_TLV_LEN);
1082 tlv->typelen = htons(typelen);
1083
1084 ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
1085 ICE_IEEE_SUBTYPE_ETS_REC);
1086 tlv->ouisubtype = htonl(ouisubtype);
1087
1088 etsrec = &dcbcfg->etsrec;
1089
1090
1091
1092 ice_add_ieee_ets_common_tlv(&buf[1], etsrec);
1093}
1094
1095
1096
1097
1098
1099
1100
1101
1102static void
1103ice_add_ieee_pfc_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
1104{
1105 u8 *buf = tlv->tlvinfo;
1106 u32 ouisubtype;
1107 u16 typelen;
1108
1109 typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) |
1110 ICE_IEEE_PFC_TLV_LEN);
1111 tlv->typelen = htons(typelen);
1112
1113 ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
1114 ICE_IEEE_SUBTYPE_PFC_CFG);
1115 tlv->ouisubtype = htonl(ouisubtype);
1116
1117
1118
1119
1120
1121
1122
1123 if (dcbcfg->pfc.willing)
1124 buf[0] = BIT(ICE_IEEE_PFC_WILLING_S);
1125
1126 if (dcbcfg->pfc.mbc)
1127 buf[0] |= BIT(ICE_IEEE_PFC_MBC_S);
1128
1129 buf[0] |= dcbcfg->pfc.pfccap & 0xF;
1130 buf[1] = dcbcfg->pfc.pfcena;
1131}
1132
1133
1134
1135
1136
1137
1138
1139
1140static void
1141ice_add_ieee_app_pri_tlv(struct ice_lldp_org_tlv *tlv,
1142 struct ice_dcbx_cfg *dcbcfg)
1143{
1144 u16 typelen, len, offset = 0;
1145 u8 priority, selector, i = 0;
1146 u8 *buf = tlv->tlvinfo;
1147 u32 ouisubtype;
1148
1149
1150 if (dcbcfg->numapps == 0)
1151 return;
1152 ouisubtype = ((ICE_IEEE_8021QAZ_OUI << ICE_LLDP_TLV_OUI_S) |
1153 ICE_IEEE_SUBTYPE_APP_PRI);
1154 tlv->ouisubtype = htonl(ouisubtype);
1155
1156
1157 offset++;
1158
1159
1160
1161
1162
1163
1164
1165
1166 while (i < dcbcfg->numapps) {
1167 priority = dcbcfg->app[i].priority & 0x7;
1168 selector = dcbcfg->app[i].selector & 0x7;
1169 buf[offset] = (priority << ICE_IEEE_APP_PRIO_S) | selector;
1170 buf[offset + 1] = (dcbcfg->app[i].prot_id >> 0x8) & 0xFF;
1171 buf[offset + 2] = dcbcfg->app[i].prot_id & 0xFF;
1172
1173 offset += 3;
1174 i++;
1175 if (i >= ICE_DCBX_MAX_APPS)
1176 break;
1177 }
1178
1179 len = sizeof(tlv->ouisubtype) + 1 + (i * 3);
1180 typelen = ((ICE_TLV_TYPE_ORG << ICE_LLDP_TLV_TYPE_S) | (len & 0x1FF));
1181 tlv->typelen = htons(typelen);
1182}
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192static void
1193ice_add_dcb_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg,
1194 u16 tlvid)
1195{
1196 switch (tlvid) {
1197 case ICE_IEEE_TLV_ID_ETS_CFG:
1198 ice_add_ieee_ets_tlv(tlv, dcbcfg);
1199 break;
1200 case ICE_IEEE_TLV_ID_ETS_REC:
1201 ice_add_ieee_etsrec_tlv(tlv, dcbcfg);
1202 break;
1203 case ICE_IEEE_TLV_ID_PFC_CFG:
1204 ice_add_ieee_pfc_tlv(tlv, dcbcfg);
1205 break;
1206 case ICE_IEEE_TLV_ID_APP_PRI:
1207 ice_add_ieee_app_pri_tlv(tlv, dcbcfg);
1208 break;
1209 default:
1210 break;
1211 }
1212}
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222static void
1223ice_dcb_cfg_to_lldp(u8 *lldpmib, u16 *miblen, struct ice_dcbx_cfg *dcbcfg)
1224{
1225 u16 len, offset = 0, tlvid = ICE_TLV_ID_START;
1226 struct ice_lldp_org_tlv *tlv;
1227 u16 typelen;
1228
1229 tlv = (struct ice_lldp_org_tlv *)lldpmib;
1230 while (1) {
1231 ice_add_dcb_tlv(tlv, dcbcfg, tlvid++);
1232 typelen = ntohs(tlv->typelen);
1233 len = (typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S;
1234 if (len)
1235 offset += len + 2;
1236
1237 if (tlvid >= ICE_TLV_ID_END_OF_LLDPPDU ||
1238 offset > ICE_LLDPDU_SIZE)
1239 break;
1240
1241 if (len)
1242 tlv = (struct ice_lldp_org_tlv *)
1243 ((char *)tlv + sizeof(tlv->typelen) + len);
1244 }
1245 *miblen = offset;
1246}
1247
1248
1249
1250
1251
1252
1253
1254enum ice_status ice_set_dcb_cfg(struct ice_port_info *pi)
1255{
1256 u8 mib_type, *lldpmib = NULL;
1257 struct ice_dcbx_cfg *dcbcfg;
1258 enum ice_status ret;
1259 struct ice_hw *hw;
1260 u16 miblen;
1261
1262 if (!pi)
1263 return ICE_ERR_PARAM;
1264
1265 hw = pi->hw;
1266
1267
1268 dcbcfg = &pi->local_dcbx_cfg;
1269
1270 lldpmib = devm_kzalloc(ice_hw_to_dev(hw), ICE_LLDPDU_SIZE, GFP_KERNEL);
1271 if (!lldpmib)
1272 return ICE_ERR_NO_MEMORY;
1273
1274 mib_type = SET_LOCAL_MIB_TYPE_LOCAL_MIB;
1275 if (dcbcfg->app_mode == ICE_DCBX_APPS_NON_WILLING)
1276 mib_type |= SET_LOCAL_MIB_TYPE_CEE_NON_WILLING;
1277
1278 ice_dcb_cfg_to_lldp(lldpmib, &miblen, dcbcfg);
1279 ret = ice_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen,
1280 NULL);
1281
1282 devm_kfree(ice_hw_to_dev(hw), lldpmib);
1283
1284 return ret;
1285}
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296static enum ice_status
1297ice_aq_query_port_ets(struct ice_port_info *pi,
1298 struct ice_aqc_port_ets_elem *buf, u16 buf_size,
1299 struct ice_sq_cd *cd)
1300{
1301 struct ice_aqc_query_port_ets *cmd;
1302 struct ice_aq_desc desc;
1303 enum ice_status status;
1304
1305 if (!pi)
1306 return ICE_ERR_PARAM;
1307 cmd = &desc.params.port_ets;
1308 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_query_port_ets);
1309 cmd->port_teid = pi->root->info.node_teid;
1310
1311 status = ice_aq_send_cmd(pi->hw, &desc, buf, buf_size, cd);
1312 return status;
1313}
1314
1315
1316
1317
1318
1319
1320
1321
1322static enum ice_status
1323ice_update_port_tc_tree_cfg(struct ice_port_info *pi,
1324 struct ice_aqc_port_ets_elem *buf)
1325{
1326 struct ice_sched_node *node, *tc_node;
1327 struct ice_aqc_get_elem elem;
1328 enum ice_status status = 0;
1329 u32 teid1, teid2;
1330 u8 i, j;
1331
1332 if (!pi)
1333 return ICE_ERR_PARAM;
1334
1335 for (i = 0; i < pi->root->num_children; i++) {
1336 teid1 = le32_to_cpu(pi->root->children[i]->info.node_teid);
1337 ice_for_each_traffic_class(j) {
1338 teid2 = le32_to_cpu(buf->tc_node_teid[j]);
1339 if (teid1 == teid2)
1340 break;
1341 }
1342 if (j < ICE_MAX_TRAFFIC_CLASS)
1343 continue;
1344
1345 pi->root->children[i]->in_use = false;
1346 }
1347
1348 ice_for_each_traffic_class(j) {
1349 teid2 = le32_to_cpu(buf->tc_node_teid[j]);
1350 if (teid2 == ICE_INVAL_TEID)
1351 continue;
1352
1353 for (i = 0; i < pi->root->num_children; i++) {
1354 tc_node = pi->root->children[i];
1355 if (!tc_node)
1356 continue;
1357 teid1 = le32_to_cpu(tc_node->info.node_teid);
1358 if (teid1 == teid2) {
1359 tc_node->tc_num = j;
1360 tc_node->in_use = true;
1361 break;
1362 }
1363 }
1364 if (i < pi->root->num_children)
1365 continue;
1366
1367 status = ice_sched_query_elem(pi->hw, teid2, &elem);
1368 if (!status)
1369 status = ice_sched_add_node(pi, 1, &elem.generic[0]);
1370 if (status)
1371 break;
1372
1373 node = ice_sched_find_node_by_teid(pi->root, teid2);
1374 if (node)
1375 node->tc_num = j;
1376 }
1377 return status;
1378}
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390enum ice_status
1391ice_query_port_ets(struct ice_port_info *pi,
1392 struct ice_aqc_port_ets_elem *buf, u16 buf_size,
1393 struct ice_sq_cd *cd)
1394{
1395 enum ice_status status;
1396
1397 mutex_lock(&pi->sched_lock);
1398 status = ice_aq_query_port_ets(pi, buf, buf_size, cd);
1399 if (!status)
1400 status = ice_update_port_tc_tree_cfg(pi, buf);
1401 mutex_unlock(&pi->sched_lock);
1402 return status;
1403}
1404