Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2001-2020 Intel Corporation
3 : : */
4 : :
5 : : #include "i40e_adminq.h"
6 : : #include "i40e_prototype.h"
7 : : #include "i40e_dcb.h"
8 : :
9 : : /**
10 : : * i40e_get_dcbx_status
11 : : * @hw: pointer to the hw struct
12 : : * @status: Embedded DCBX Engine Status
13 : : *
14 : : * Get the DCBX status from the Firmware
15 : : **/
16 : 0 : enum i40e_status_code i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
17 : : {
18 : : u32 reg;
19 : :
20 [ # # ]: 0 : if (!status)
21 : : return I40E_ERR_PARAM;
22 : :
23 : 0 : reg = rd32(hw, I40E_PRTDCB_GENS);
24 : 0 : *status = (u16)((reg & I40E_PRTDCB_GENS_DCBX_STATUS_MASK) >>
25 : : I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT);
26 : :
27 : 0 : return I40E_SUCCESS;
28 : : }
29 : :
30 : : /**
31 : : * i40e_parse_ieee_etscfg_tlv
32 : : * @tlv: IEEE 802.1Qaz ETS CFG TLV
33 : : * @dcbcfg: Local store to update ETS CFG data
34 : : *
35 : : * Parses IEEE 802.1Qaz ETS CFG TLV
36 : : **/
37 : 0 : static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv,
38 : : struct i40e_dcbx_config *dcbcfg)
39 : : {
40 : : struct i40e_dcb_ets_config *etscfg;
41 : 0 : u8 *buf = tlv->tlvinfo;
42 : : u16 offset = 0;
43 : : u8 priority;
44 : : int i;
45 : :
46 : : /* First Octet post subtype
47 : : * --------------------------
48 : : * |will-|CBS | Re- | Max |
49 : : * |ing | |served| TCs |
50 : : * --------------------------
51 : : * |1bit | 1bit|3 bits|3bits|
52 : : */
53 : : etscfg = &dcbcfg->etscfg;
54 : 0 : etscfg->willing = (u8)((buf[offset] & I40E_IEEE_ETS_WILLING_MASK) >>
55 : : I40E_IEEE_ETS_WILLING_SHIFT);
56 : 0 : etscfg->cbs = (u8)((buf[offset] & I40E_IEEE_ETS_CBS_MASK) >>
57 : : I40E_IEEE_ETS_CBS_SHIFT);
58 : 0 : etscfg->maxtcs = (u8)((buf[offset] & I40E_IEEE_ETS_MAXTC_MASK) >>
59 : : I40E_IEEE_ETS_MAXTC_SHIFT);
60 : :
61 : : /* Move offset to Priority Assignment Table */
62 : : offset++;
63 : :
64 : : /* Priority Assignment Table (4 octets)
65 : : * Octets:| 1 | 2 | 3 | 4 |
66 : : * -----------------------------------------
67 : : * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
68 : : * -----------------------------------------
69 : : * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
70 : : * -----------------------------------------
71 : : */
72 [ # # ]: 0 : for (i = 0; i < 4; i++) {
73 : 0 : priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
74 : : I40E_IEEE_ETS_PRIO_1_SHIFT);
75 : 0 : etscfg->prioritytable[i * 2] = priority;
76 : 0 : priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
77 : : I40E_IEEE_ETS_PRIO_0_SHIFT);
78 : 0 : etscfg->prioritytable[i * 2 + 1] = priority;
79 : 0 : offset++;
80 : : }
81 : :
82 : : /* TC Bandwidth Table (8 octets)
83 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
84 : : * ---------------------------------
85 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
86 : : * ---------------------------------
87 : : */
88 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
89 : 0 : etscfg->tcbwtable[i] = buf[offset++];
90 : :
91 : : /* TSA Assignment Table (8 octets)
92 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
93 : : * ---------------------------------
94 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
95 : : * ---------------------------------
96 : : */
97 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
98 : 0 : etscfg->tsatable[i] = buf[offset++];
99 : 0 : }
100 : :
101 : : /**
102 : : * i40e_parse_ieee_etsrec_tlv
103 : : * @tlv: IEEE 802.1Qaz ETS REC TLV
104 : : * @dcbcfg: Local store to update ETS REC data
105 : : *
106 : : * Parses IEEE 802.1Qaz ETS REC TLV
107 : : **/
108 : 0 : static void i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
109 : : struct i40e_dcbx_config *dcbcfg)
110 : : {
111 : 0 : u8 *buf = tlv->tlvinfo;
112 : : u16 offset = 0;
113 : : u8 priority;
114 : : int i;
115 : :
116 : : /* Move offset to priority table */
117 : : offset++;
118 : :
119 : : /* Priority Assignment Table (4 octets)
120 : : * Octets:| 1 | 2 | 3 | 4 |
121 : : * -----------------------------------------
122 : : * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
123 : : * -----------------------------------------
124 : : * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
125 : : * -----------------------------------------
126 : : */
127 [ # # ]: 0 : for (i = 0; i < 4; i++) {
128 : 0 : priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
129 : : I40E_IEEE_ETS_PRIO_1_SHIFT);
130 : 0 : dcbcfg->etsrec.prioritytable[i*2] = priority;
131 : 0 : priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
132 : : I40E_IEEE_ETS_PRIO_0_SHIFT);
133 : 0 : dcbcfg->etsrec.prioritytable[i*2 + 1] = priority;
134 : 0 : offset++;
135 : : }
136 : :
137 : : /* TC Bandwidth Table (8 octets)
138 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
139 : : * ---------------------------------
140 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
141 : : * ---------------------------------
142 : : */
143 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
144 : 0 : dcbcfg->etsrec.tcbwtable[i] = buf[offset++];
145 : :
146 : : /* TSA Assignment Table (8 octets)
147 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
148 : : * ---------------------------------
149 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
150 : : * ---------------------------------
151 : : */
152 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
153 : 0 : dcbcfg->etsrec.tsatable[i] = buf[offset++];
154 : 0 : }
155 : :
156 : : /**
157 : : * i40e_parse_ieee_pfccfg_tlv
158 : : * @tlv: IEEE 802.1Qaz PFC CFG TLV
159 : : * @dcbcfg: Local store to update PFC CFG data
160 : : *
161 : : * Parses IEEE 802.1Qaz PFC CFG TLV
162 : : **/
163 : : static void i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv *tlv,
164 : : struct i40e_dcbx_config *dcbcfg)
165 : : {
166 : : u8 *buf = tlv->tlvinfo;
167 : :
168 : : /* ----------------------------------------
169 : : * |will-|MBC | Re- | PFC | PFC Enable |
170 : : * |ing | |served| cap | |
171 : : * -----------------------------------------
172 : : * |1bit | 1bit|2 bits|4bits| 1 octet |
173 : : */
174 : 0 : dcbcfg->pfc.willing = (u8)((buf[0] & I40E_IEEE_PFC_WILLING_MASK) >>
175 : : I40E_IEEE_PFC_WILLING_SHIFT);
176 : 0 : dcbcfg->pfc.mbc = (u8)((buf[0] & I40E_IEEE_PFC_MBC_MASK) >>
177 : : I40E_IEEE_PFC_MBC_SHIFT);
178 : 0 : dcbcfg->pfc.pfccap = (u8)((buf[0] & I40E_IEEE_PFC_CAP_MASK) >>
179 : : I40E_IEEE_PFC_CAP_SHIFT);
180 : 0 : dcbcfg->pfc.pfcenable = buf[1];
181 : 0 : }
182 : :
183 : : /**
184 : : * i40e_parse_ieee_app_tlv
185 : : * @tlv: IEEE 802.1Qaz APP TLV
186 : : * @dcbcfg: Local store to update APP PRIO data
187 : : *
188 : : * Parses IEEE 802.1Qaz APP PRIO TLV
189 : : **/
190 : 0 : static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv,
191 : : struct i40e_dcbx_config *dcbcfg)
192 : : {
193 : : u16 typelength;
194 : : u16 offset = 0;
195 : : u16 length;
196 : : int i = 0;
197 : : u8 *buf;
198 : :
199 [ # # ]: 0 : typelength = I40E_NTOHS(tlv->typelength);
200 : 0 : length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
201 : : I40E_LLDP_TLV_LEN_SHIFT);
202 : 0 : buf = tlv->tlvinfo;
203 : :
204 : : /* The App priority table starts 5 octets after TLV header */
205 : 0 : length -= (sizeof(tlv->ouisubtype) + 1);
206 : :
207 : : /* Move offset to App Priority Table */
208 : : offset++;
209 : :
210 : : /* Application Priority Table (3 octets)
211 : : * Octets:| 1 | 2 | 3 |
212 : : * -----------------------------------------
213 : : * |Priority|Rsrvd| Sel | Protocol ID |
214 : : * -----------------------------------------
215 : : * Bits:|23 21|20 19|18 16|15 0|
216 : : * -----------------------------------------
217 : : */
218 [ # # ]: 0 : while (offset < length) {
219 : 0 : dcbcfg->app[i].priority = (u8)((buf[offset] &
220 : 0 : I40E_IEEE_APP_PRIO_MASK) >>
221 : : I40E_IEEE_APP_PRIO_SHIFT);
222 : 0 : dcbcfg->app[i].selector = (u8)((buf[offset] &
223 : : I40E_IEEE_APP_SEL_MASK) >>
224 : : I40E_IEEE_APP_SEL_SHIFT);
225 : 0 : dcbcfg->app[i].protocolid = (buf[offset + 1] << 0x8) |
226 : 0 : buf[offset + 2];
227 : : /* Move to next app */
228 : 0 : offset += 3;
229 : 0 : i++;
230 [ # # ]: 0 : if (i >= I40E_DCBX_MAX_APPS)
231 : : break;
232 : : }
233 : :
234 : 0 : dcbcfg->numapps = i;
235 : 0 : }
236 : :
237 : : /**
238 : : * i40e_parse_ieee_tlv
239 : : * @tlv: IEEE 802.1Qaz TLV
240 : : * @dcbcfg: Local store to update ETS REC data
241 : : *
242 : : * Get the TLV subtype and send it to parsing function
243 : : * based on the subtype value
244 : : **/
245 : 0 : static void i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv *tlv,
246 : : struct i40e_dcbx_config *dcbcfg)
247 : : {
248 : : u32 ouisubtype;
249 : : u8 subtype;
250 : :
251 [ # # ]: 0 : ouisubtype = I40E_NTOHL(tlv->ouisubtype);
252 : : subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
253 : : I40E_LLDP_TLV_SUBTYPE_SHIFT);
254 [ # # # # : 0 : switch (subtype) {
# ]
255 : 0 : case I40E_IEEE_SUBTYPE_ETS_CFG:
256 : 0 : i40e_parse_ieee_etscfg_tlv(tlv, dcbcfg);
257 : 0 : break;
258 : 0 : case I40E_IEEE_SUBTYPE_ETS_REC:
259 : 0 : i40e_parse_ieee_etsrec_tlv(tlv, dcbcfg);
260 : 0 : break;
261 : : case I40E_IEEE_SUBTYPE_PFC_CFG:
262 : : i40e_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
263 : : break;
264 : 0 : case I40E_IEEE_SUBTYPE_APP_PRI:
265 : 0 : i40e_parse_ieee_app_tlv(tlv, dcbcfg);
266 : 0 : break;
267 : : default:
268 : : break;
269 : : }
270 : 0 : }
271 : :
272 : : /**
273 : : * i40e_parse_cee_pgcfg_tlv
274 : : * @tlv: CEE DCBX PG CFG TLV
275 : : * @dcbcfg: Local store to update ETS CFG data
276 : : *
277 : : * Parses CEE DCBX PG CFG TLV
278 : : **/
279 : 0 : static void i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv *tlv,
280 : : struct i40e_dcbx_config *dcbcfg)
281 : : {
282 : : struct i40e_dcb_ets_config *etscfg;
283 : 0 : u8 *buf = tlv->tlvinfo;
284 : : u16 offset = 0;
285 : : u8 priority;
286 : : int i;
287 : :
288 : : etscfg = &dcbcfg->etscfg;
289 : :
290 [ # # ]: 0 : if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
291 : 0 : etscfg->willing = 1;
292 : :
293 : 0 : etscfg->cbs = 0;
294 : : /* Priority Group Table (4 octets)
295 : : * Octets:| 1 | 2 | 3 | 4 |
296 : : * -----------------------------------------
297 : : * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
298 : : * -----------------------------------------
299 : : * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
300 : : * -----------------------------------------
301 : : */
302 [ # # ]: 0 : for (i = 0; i < 4; i++) {
303 : 0 : priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_1_MASK) >>
304 : : I40E_CEE_PGID_PRIO_1_SHIFT);
305 : 0 : etscfg->prioritytable[i * 2] = priority;
306 : 0 : priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_0_MASK) >>
307 : : I40E_CEE_PGID_PRIO_0_SHIFT);
308 : 0 : etscfg->prioritytable[i * 2 + 1] = priority;
309 : 0 : offset++;
310 : : }
311 : :
312 : : /* PG Percentage Table (8 octets)
313 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
314 : : * ---------------------------------
315 : : * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|
316 : : * ---------------------------------
317 : : */
318 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
319 : 0 : etscfg->tcbwtable[i] = buf[offset++];
320 : :
321 [ # # ]: 0 : if (etscfg->prioritytable[i] == I40E_CEE_PGID_STRICT)
322 : 0 : dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
323 : : else
324 : 0 : dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
325 : : }
326 : :
327 : : /* Number of TCs supported (1 octet) */
328 : 0 : etscfg->maxtcs = buf[offset];
329 : 0 : }
330 : :
331 : : /**
332 : : * i40e_parse_cee_pfccfg_tlv
333 : : * @tlv: CEE DCBX PFC CFG TLV
334 : : * @dcbcfg: Local store to update PFC CFG data
335 : : *
336 : : * Parses CEE DCBX PFC CFG TLV
337 : : **/
338 : : static void i40e_parse_cee_pfccfg_tlv(struct i40e_cee_feat_tlv *tlv,
339 : : struct i40e_dcbx_config *dcbcfg)
340 : : {
341 : : u8 *buf = tlv->tlvinfo;
342 : :
343 [ # # ]: 0 : if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
344 : 0 : dcbcfg->pfc.willing = 1;
345 : :
346 : : /* ------------------------
347 : : * | PFC Enable | PFC TCs |
348 : : * ------------------------
349 : : * | 1 octet | 1 octet |
350 : : */
351 : 0 : dcbcfg->pfc.pfcenable = buf[0];
352 : 0 : dcbcfg->pfc.pfccap = buf[1];
353 : 0 : }
354 : :
355 : : /**
356 : : * i40e_parse_cee_app_tlv
357 : : * @tlv: CEE DCBX APP TLV
358 : : * @dcbcfg: Local store to update APP PRIO data
359 : : *
360 : : * Parses CEE DCBX APP PRIO TLV
361 : : **/
362 : 0 : static void i40e_parse_cee_app_tlv(struct i40e_cee_feat_tlv *tlv,
363 : : struct i40e_dcbx_config *dcbcfg)
364 : : {
365 : : u16 length, typelength, offset = 0;
366 : : struct i40e_cee_app_prio *app;
367 : : u8 i;
368 : :
369 [ # # ]: 0 : typelength = I40E_NTOHS(tlv->hdr.typelen);
370 : 0 : length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
371 : : I40E_LLDP_TLV_LEN_SHIFT);
372 : :
373 : 0 : dcbcfg->numapps = length / sizeof(*app);
374 [ # # ]: 0 : if (!dcbcfg->numapps)
375 : : return;
376 [ # # ]: 0 : if (dcbcfg->numapps > I40E_DCBX_MAX_APPS)
377 : 0 : dcbcfg->numapps = I40E_DCBX_MAX_APPS;
378 : :
379 [ # # ]: 0 : for (i = 0; i < dcbcfg->numapps; i++) {
380 : : u8 up, selector;
381 : :
382 : 0 : app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
383 [ # # ]: 0 : for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
384 [ # # ]: 0 : if (app->prio_map & BIT(up))
385 : : break;
386 : : }
387 : 0 : dcbcfg->app[i].priority = up;
388 : :
389 : : /* Get Selector from lower 2 bits, and convert to IEEE */
390 : 0 : selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
391 [ # # # ]: 0 : switch (selector) {
392 : 0 : case I40E_CEE_APP_SEL_ETHTYPE:
393 : 0 : dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
394 : 0 : break;
395 : 0 : case I40E_CEE_APP_SEL_TCPIP:
396 : 0 : dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
397 : 0 : break;
398 : 0 : default:
399 : : /* Keep selector as it is for unknown types */
400 : 0 : dcbcfg->app[i].selector = selector;
401 : : }
402 : :
403 [ # # ]: 0 : dcbcfg->app[i].protocolid = I40E_NTOHS(app->protocol);
404 : : /* Move to next app */
405 : 0 : offset += sizeof(*app);
406 : : }
407 : : }
408 : :
409 : : /**
410 : : * i40e_parse_cee_tlv
411 : : * @tlv: CEE DCBX TLV
412 : : * @dcbcfg: Local store to update DCBX config data
413 : : *
414 : : * Get the TLV subtype and send it to parsing function
415 : : * based on the subtype value
416 : : **/
417 : 0 : static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
418 : : struct i40e_dcbx_config *dcbcfg)
419 : : {
420 : : u16 len, tlvlen, sublen, typelength;
421 : : struct i40e_cee_feat_tlv *sub_tlv;
422 : : u8 subtype, feat_tlv_count = 0;
423 : : u32 ouisubtype;
424 : :
425 [ # # ]: 0 : ouisubtype = I40E_NTOHL(tlv->ouisubtype);
426 : 0 : subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
427 : : I40E_LLDP_TLV_SUBTYPE_SHIFT);
428 : : /* Return if not CEE DCBX */
429 [ # # ]: 0 : if (subtype != I40E_CEE_DCBX_TYPE)
430 : : return;
431 : :
432 [ # # ]: 0 : typelength = I40E_NTOHS(tlv->typelength);
433 : 0 : tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
434 : : I40E_LLDP_TLV_LEN_SHIFT);
435 : : len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
436 : : sizeof(struct i40e_cee_ctrl_tlv);
437 : : /* Return if no CEE DCBX Feature TLVs */
438 [ # # ]: 0 : if (tlvlen <= len)
439 : : return;
440 : :
441 : 0 : sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
442 [ # # ]: 0 : while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
443 [ # # ]: 0 : typelength = I40E_NTOHS(sub_tlv->hdr.typelen);
444 : 0 : sublen = (u16)((typelength &
445 : : I40E_LLDP_TLV_LEN_MASK) >>
446 : : I40E_LLDP_TLV_LEN_SHIFT);
447 : 0 : subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
448 : : I40E_LLDP_TLV_TYPE_SHIFT);
449 [ # # # # ]: 0 : switch (subtype) {
450 : 0 : case I40E_CEE_SUBTYPE_PG_CFG:
451 : 0 : i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
452 : 0 : break;
453 : : case I40E_CEE_SUBTYPE_PFC_CFG:
454 : : i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
455 : : break;
456 : 0 : case I40E_CEE_SUBTYPE_APP_PRI:
457 : 0 : i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
458 : 0 : break;
459 : : default:
460 : : return; /* Invalid Sub-type return */
461 : : }
462 : 0 : feat_tlv_count++;
463 : : /* Move to next sub TLV */
464 : 0 : sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
465 : 0 : sizeof(sub_tlv->hdr.typelen) +
466 : : sublen);
467 : : }
468 : : }
469 : :
470 : : /**
471 : : * i40e_parse_org_tlv
472 : : * @tlv: Organization specific TLV
473 : : * @dcbcfg: Local store to update ETS REC data
474 : : *
475 : : * Currently only IEEE 802.1Qaz TLV is supported, all others
476 : : * will be returned
477 : : **/
478 : 0 : static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
479 : : struct i40e_dcbx_config *dcbcfg)
480 : : {
481 : : u32 ouisubtype;
482 : : u32 oui;
483 : :
484 [ # # ]: 0 : ouisubtype = I40E_NTOHL(tlv->ouisubtype);
485 : 0 : oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
486 : : I40E_LLDP_TLV_OUI_SHIFT);
487 [ # # # ]: 0 : switch (oui) {
488 : 0 : case I40E_IEEE_8021QAZ_OUI:
489 : 0 : i40e_parse_ieee_tlv(tlv, dcbcfg);
490 : 0 : break;
491 : 0 : case I40E_CEE_DCBX_OUI:
492 : 0 : i40e_parse_cee_tlv(tlv, dcbcfg);
493 : 0 : break;
494 : : default:
495 : : break;
496 : : }
497 : 0 : }
498 : :
499 : : /**
500 : : * i40e_lldp_to_dcb_config
501 : : * @lldpmib: LLDPDU to be parsed
502 : : * @dcbcfg: store for LLDPDU data
503 : : *
504 : : * Parse DCB configuration from the LLDPDU
505 : : **/
506 : 0 : enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
507 : : struct i40e_dcbx_config *dcbcfg)
508 : : {
509 : : enum i40e_status_code ret = I40E_SUCCESS;
510 : : struct i40e_lldp_org_tlv *tlv;
511 : : u16 type;
512 : : u16 length;
513 : : u16 typelength;
514 : : u16 offset = 0;
515 : :
516 [ # # ]: 0 : if (!lldpmib || !dcbcfg)
517 : : return I40E_ERR_PARAM;
518 : :
519 : : /* set to the start of LLDPDU */
520 : 0 : lldpmib += I40E_LLDP_MIB_HLEN;
521 : : tlv = (struct i40e_lldp_org_tlv *)lldpmib;
522 : : while (1) {
523 [ # # ]: 0 : typelength = I40E_NTOHS(tlv->typelength);
524 : 0 : type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
525 : : I40E_LLDP_TLV_TYPE_SHIFT);
526 : 0 : length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
527 : : I40E_LLDP_TLV_LEN_SHIFT);
528 : 0 : offset += sizeof(typelength) + length;
529 : :
530 : : /* END TLV or beyond LLDPDU size */
531 [ # # ]: 0 : if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
532 : : break;
533 : :
534 [ # # ]: 0 : switch (type) {
535 : 0 : case I40E_TLV_TYPE_ORG:
536 : 0 : i40e_parse_org_tlv(tlv, dcbcfg);
537 : 0 : break;
538 : : default:
539 : : break;
540 : : }
541 : :
542 : : /* Move to next TLV */
543 : 0 : tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
544 : 0 : sizeof(tlv->typelength) +
545 : : length);
546 : : }
547 : :
548 : : return ret;
549 : : }
550 : :
551 : : /**
552 : : * i40e_aq_get_dcb_config
553 : : * @hw: pointer to the hw struct
554 : : * @mib_type: mib type for the query
555 : : * @bridgetype: bridge type for the query (remote)
556 : : * @dcbcfg: store for LLDPDU data
557 : : *
558 : : * Query DCB configuration from the Firmware
559 : : **/
560 : 0 : enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
561 : : u8 bridgetype,
562 : : struct i40e_dcbx_config *dcbcfg)
563 : : {
564 : : enum i40e_status_code ret = I40E_SUCCESS;
565 : : struct i40e_virt_mem mem;
566 : : u8 *lldpmib;
567 : :
568 : : /* Allocate the LLDPDU */
569 : 0 : ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
570 [ # # ]: 0 : if (ret)
571 : : return ret;
572 : :
573 : 0 : lldpmib = (u8 *)mem.va;
574 : 0 : ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
575 : : (void *)lldpmib, I40E_LLDPDU_SIZE,
576 : : NULL, NULL, NULL);
577 [ # # ]: 0 : if (ret)
578 : 0 : goto free_mem;
579 : :
580 : : /* Parse LLDP MIB to get dcb configuration */
581 : 0 : ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
582 : :
583 : 0 : free_mem:
584 : 0 : i40e_free_virt_mem(hw, &mem);
585 : 0 : return ret;
586 : : }
587 : :
588 : : /**
589 : : * i40e_cee_to_dcb_v1_config
590 : : * @cee_cfg: pointer to CEE v1 response configuration struct
591 : : * @dcbcfg: DCB configuration struct
592 : : *
593 : : * Convert CEE v1 configuration from firmware to DCB configuration
594 : : **/
595 : 0 : static void i40e_cee_to_dcb_v1_config(
596 : : struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
597 : : struct i40e_dcbx_config *dcbcfg)
598 : : {
599 : 0 : u16 status, tlv_status = LE16_TO_CPU(cee_cfg->tlv_status);
600 : 0 : u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
601 : : u8 i, tc, err;
602 : :
603 : : /* CEE PG data to ETS config */
604 : 0 : dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
605 : :
606 : : /* Note that the FW creates the oper_prio_tc nibbles reversed
607 : : * from those in the CEE Priority Group sub-TLV.
608 : : */
609 [ # # ]: 0 : for (i = 0; i < 4; i++) {
610 : 0 : tc = (u8)((cee_cfg->oper_prio_tc[i] &
611 : : I40E_CEE_PGID_PRIO_0_MASK) >>
612 : : I40E_CEE_PGID_PRIO_0_SHIFT);
613 : 0 : dcbcfg->etscfg.prioritytable[i*2] = tc;
614 : 0 : tc = (u8)((cee_cfg->oper_prio_tc[i] &
615 : : I40E_CEE_PGID_PRIO_1_MASK) >>
616 : : I40E_CEE_PGID_PRIO_1_SHIFT);
617 : 0 : dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
618 : : }
619 : :
620 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
621 : 0 : dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
622 : :
623 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
624 [ # # ]: 0 : if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
625 : : /* Map it to next empty TC */
626 : 0 : dcbcfg->etscfg.prioritytable[i] =
627 : 0 : cee_cfg->oper_num_tc - 1;
628 : 0 : dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
629 : : } else {
630 : 0 : dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
631 : : }
632 : : }
633 : :
634 : : /* CEE PFC data to ETS config */
635 : 0 : dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
636 : 0 : dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
637 : :
638 : 0 : status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
639 : : I40E_AQC_CEE_APP_STATUS_SHIFT;
640 : 0 : err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
641 : : /* Add APPs if Error is False */
642 [ # # ]: 0 : if (!err) {
643 : : /* CEE operating configuration supports FCoE/iSCSI/FIP only */
644 : 0 : dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
645 : :
646 : : /* FCoE APP */
647 : 0 : dcbcfg->app[0].priority =
648 : 0 : (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
649 : : I40E_AQC_CEE_APP_FCOE_SHIFT;
650 : 0 : dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
651 : 0 : dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
652 : :
653 : : /* iSCSI APP */
654 : 0 : dcbcfg->app[1].priority =
655 : 0 : (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
656 : : I40E_AQC_CEE_APP_ISCSI_SHIFT;
657 : 0 : dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
658 : 0 : dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
659 : :
660 : : /* FIP APP */
661 : 0 : dcbcfg->app[2].priority =
662 : 0 : (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
663 : : I40E_AQC_CEE_APP_FIP_SHIFT;
664 : 0 : dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
665 : 0 : dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
666 : : }
667 : 0 : }
668 : :
669 : : /**
670 : : * i40e_cee_to_dcb_config
671 : : * @cee_cfg: pointer to CEE configuration struct
672 : : * @dcbcfg: DCB configuration struct
673 : : *
674 : : * Convert CEE configuration from firmware to DCB configuration
675 : : **/
676 : 0 : static void i40e_cee_to_dcb_config(
677 : : struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
678 : : struct i40e_dcbx_config *dcbcfg)
679 : : {
680 : 0 : u32 status, tlv_status = LE32_TO_CPU(cee_cfg->tlv_status);
681 : 0 : u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
682 : : u8 i, tc, err, sync, oper;
683 : :
684 : : /* CEE PG data to ETS config */
685 : 0 : dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
686 : :
687 : : /* Note that the FW creates the oper_prio_tc nibbles reversed
688 : : * from those in the CEE Priority Group sub-TLV.
689 : : */
690 [ # # ]: 0 : for (i = 0; i < 4; i++) {
691 : 0 : tc = (u8)((cee_cfg->oper_prio_tc[i] &
692 : : I40E_CEE_PGID_PRIO_0_MASK) >>
693 : : I40E_CEE_PGID_PRIO_0_SHIFT);
694 : 0 : dcbcfg->etscfg.prioritytable[i*2] = tc;
695 : 0 : tc = (u8)((cee_cfg->oper_prio_tc[i] &
696 : : I40E_CEE_PGID_PRIO_1_MASK) >>
697 : : I40E_CEE_PGID_PRIO_1_SHIFT);
698 : 0 : dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
699 : : }
700 : :
701 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
702 : 0 : dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
703 : :
704 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
705 [ # # ]: 0 : if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
706 : : /* Map it to next empty TC */
707 : 0 : dcbcfg->etscfg.prioritytable[i] =
708 : 0 : cee_cfg->oper_num_tc - 1;
709 : 0 : dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
710 : : } else {
711 : 0 : dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
712 : : }
713 : : }
714 : :
715 : : /* CEE PFC data to ETS config */
716 : 0 : dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
717 : 0 : dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
718 : :
719 : : i = 0;
720 : 0 : status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
721 : : I40E_AQC_CEE_FCOE_STATUS_SHIFT;
722 : 0 : err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
723 : 0 : sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
724 : 0 : oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
725 : : /* Add FCoE APP if Error is False and Oper/Sync is True */
726 [ # # # # ]: 0 : if (!err && sync && oper) {
727 : : /* FCoE APP */
728 : 0 : dcbcfg->app[i].priority =
729 : 0 : (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
730 : : I40E_AQC_CEE_APP_FCOE_SHIFT;
731 : 0 : dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
732 : 0 : dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
733 : : i++;
734 : : }
735 : :
736 : 0 : status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
737 : : I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
738 : 0 : err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
739 : 0 : sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
740 : 0 : oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
741 : : /* Add iSCSI APP if Error is False and Oper/Sync is True */
742 [ # # # # ]: 0 : if (!err && sync && oper) {
743 : : /* iSCSI APP */
744 : 0 : dcbcfg->app[i].priority =
745 : 0 : (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
746 : : I40E_AQC_CEE_APP_ISCSI_SHIFT;
747 : 0 : dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
748 : 0 : dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
749 : 0 : i++;
750 : : }
751 : :
752 : 0 : status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
753 : : I40E_AQC_CEE_FIP_STATUS_SHIFT;
754 : 0 : err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
755 : 0 : sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
756 : 0 : oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
757 : : /* Add FIP APP if Error is False and Oper/Sync is True */
758 [ # # # # ]: 0 : if (!err && sync && oper) {
759 : : /* FIP APP */
760 : 0 : dcbcfg->app[i].priority =
761 : 0 : (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
762 : : I40E_AQC_CEE_APP_FIP_SHIFT;
763 : 0 : dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
764 : 0 : dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
765 : 0 : i++;
766 : : }
767 : 0 : dcbcfg->numapps = i;
768 : 0 : }
769 : :
770 : : /**
771 : : * i40e_get_ieee_dcb_config
772 : : * @hw: pointer to the hw struct
773 : : *
774 : : * Get IEEE mode DCB configuration from the Firmware
775 : : **/
776 : 0 : STATIC enum i40e_status_code i40e_get_ieee_dcb_config(struct i40e_hw *hw)
777 : : {
778 : : enum i40e_status_code ret = I40E_SUCCESS;
779 : :
780 : : /* IEEE mode */
781 : 0 : hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
782 : : /* Get Local DCB Config */
783 : 0 : ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
784 : : &hw->local_dcbx_config);
785 [ # # ]: 0 : if (ret)
786 : 0 : goto out;
787 : :
788 : : /* Get Remote DCB Config */
789 : 0 : ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
790 : : I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
791 : : &hw->remote_dcbx_config);
792 : : /* Don't treat ENOENT as an error for Remote MIBs */
793 [ # # ]: 0 : if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
794 : : ret = I40E_SUCCESS;
795 : :
796 : 0 : out:
797 : 0 : return ret;
798 : : }
799 : :
800 : : /**
801 : : * i40e_get_dcb_config
802 : : * @hw: pointer to the hw struct
803 : : *
804 : : * Get DCB configuration from the Firmware
805 : : **/
806 : 0 : enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
807 : : {
808 : : enum i40e_status_code ret = I40E_SUCCESS;
809 : : struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
810 : : struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
811 : :
812 : : /* If Firmware version < v4.33 on X710/XL710, IEEE only */
813 [ # # ]: 0 : if ((hw->mac.type == I40E_MAC_XL710) &&
814 [ # # # # : 0 : (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
# # ]
815 : : (hw->aq.fw_maj_ver < 4)))
816 : 0 : return i40e_get_ieee_dcb_config(hw);
817 : :
818 : : /* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
819 [ # # ]: 0 : if ((hw->mac.type == I40E_MAC_XL710) &&
820 [ # # ]: 0 : ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
821 : 0 : ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
822 : : sizeof(cee_v1_cfg), NULL);
823 [ # # ]: 0 : if (ret == I40E_SUCCESS) {
824 : : /* CEE mode */
825 : 0 : hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
826 : 0 : hw->local_dcbx_config.tlv_status =
827 : 0 : LE16_TO_CPU(cee_v1_cfg.tlv_status);
828 : 0 : i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
829 : : &hw->local_dcbx_config);
830 : : }
831 : : } else {
832 : 0 : ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
833 : : sizeof(cee_cfg), NULL);
834 [ # # ]: 0 : if (ret == I40E_SUCCESS) {
835 : : /* CEE mode */
836 : 0 : hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
837 : 0 : hw->local_dcbx_config.tlv_status =
838 : 0 : LE32_TO_CPU(cee_cfg.tlv_status);
839 : 0 : i40e_cee_to_dcb_config(&cee_cfg,
840 : : &hw->local_dcbx_config);
841 : : }
842 : : }
843 : :
844 : : /* CEE mode not enabled try querying IEEE data */
845 [ # # ]: 0 : if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
846 : 0 : return i40e_get_ieee_dcb_config(hw);
847 : :
848 [ # # ]: 0 : if (ret != I40E_SUCCESS)
849 : 0 : goto out;
850 : :
851 : : /* Get CEE DCB Desired Config */
852 : 0 : ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
853 : : &hw->desired_dcbx_config);
854 [ # # ]: 0 : if (ret)
855 : 0 : goto out;
856 : :
857 : : /* Get Remote DCB Config */
858 : 0 : ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
859 : : I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
860 : : &hw->remote_dcbx_config);
861 : : /* Don't treat ENOENT as an error for Remote MIBs */
862 [ # # ]: 0 : if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
863 : : ret = I40E_SUCCESS;
864 : :
865 : 0 : out:
866 : : return ret;
867 : : }
868 : :
869 : : /**
870 : : * i40e_init_dcb
871 : : * @hw: pointer to the hw struct
872 : : * @enable_mib_change: enable mib change event
873 : : *
874 : : * Update DCB configuration from the Firmware
875 : : **/
876 : 0 : enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
877 : : {
878 : : enum i40e_status_code ret = I40E_SUCCESS;
879 : : struct i40e_lldp_variables lldp_cfg;
880 : : u8 adminstatus = 0;
881 : :
882 [ # # ]: 0 : if (!hw->func_caps.dcb)
883 : : return I40E_NOT_SUPPORTED;
884 : :
885 : : /* Read LLDP NVM area */
886 [ # # ]: 0 : if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) {
887 : : u8 offset = 0;
888 : :
889 [ # # ]: 0 : if (hw->mac.type == I40E_MAC_XL710)
890 : : offset = I40E_LLDP_CURRENT_STATUS_XL710_OFFSET;
891 [ # # ]: 0 : else if (hw->mac.type == I40E_MAC_X722)
892 : : offset = I40E_LLDP_CURRENT_STATUS_X722_OFFSET;
893 : : else
894 : : return I40E_NOT_SUPPORTED;
895 : :
896 : 0 : ret = i40e_read_nvm_module_data(hw,
897 : : I40E_SR_EMP_SR_SETTINGS_PTR,
898 : : offset,
899 : : I40E_LLDP_CURRENT_STATUS_OFFSET,
900 : : I40E_LLDP_CURRENT_STATUS_SIZE,
901 : : &lldp_cfg.adminstatus);
902 : : } else {
903 : 0 : ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
904 : : }
905 [ # # ]: 0 : if (ret)
906 : : return I40E_ERR_NOT_READY;
907 : :
908 : : /* Get the LLDP AdminStatus for the current port */
909 : 0 : adminstatus = (u8)(lldp_cfg.adminstatus >> (hw->port * 4));
910 : 0 : adminstatus &= 0xF;
911 : :
912 : : /* LLDP agent disabled */
913 [ # # ]: 0 : if (!adminstatus) {
914 : 0 : hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
915 : 0 : return I40E_ERR_NOT_READY;
916 : : }
917 : :
918 : : /* Get DCBX status */
919 : 0 : ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
920 [ # # ]: 0 : if (ret)
921 : : return ret;
922 : :
923 : : /* Check the DCBX Status */
924 [ # # ]: 0 : if (hw->dcbx_status == I40E_DCBX_STATUS_DONE ||
925 : : hw->dcbx_status == I40E_DCBX_STATUS_IN_PROGRESS) {
926 : : /* Get current DCBX configuration */
927 : 0 : ret = i40e_get_dcb_config(hw);
928 [ # # ]: 0 : if (ret)
929 : : return ret;
930 [ # # ]: 0 : } else if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) {
931 : : return I40E_ERR_NOT_READY;
932 : : }
933 : :
934 : : /* Configure the LLDP MIB change event */
935 [ # # ]: 0 : if (enable_mib_change)
936 : 0 : ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
937 : :
938 : : return ret;
939 : : }
940 : :
941 : : /**
942 : : * i40e_get_fw_lldp_status
943 : : * @hw: pointer to the hw struct
944 : : * @lldp_status: pointer to the status enum
945 : : *
946 : : * Get status of FW Link Layer Discovery Protocol (LLDP) Agent.
947 : : * Status of agent is reported via @lldp_status parameter.
948 : : **/
949 : : enum i40e_status_code
950 : 0 : i40e_get_fw_lldp_status(struct i40e_hw *hw,
951 : : enum i40e_get_fw_lldp_status_resp *lldp_status)
952 : : {
953 : : enum i40e_status_code ret;
954 : : struct i40e_virt_mem mem;
955 : : u8 *lldpmib;
956 : :
957 [ # # ]: 0 : if (!lldp_status)
958 : : return I40E_ERR_PARAM;
959 : :
960 : : /* Allocate buffer for the LLDPDU */
961 : 0 : ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
962 [ # # ]: 0 : if (ret)
963 : : return ret;
964 : :
965 : 0 : lldpmib = (u8 *)mem.va;
966 : 0 : ret = i40e_aq_get_lldp_mib(hw, 0, 0, (void *)lldpmib,
967 : : I40E_LLDPDU_SIZE, NULL, NULL, NULL);
968 : :
969 [ # # ]: 0 : if (ret == I40E_SUCCESS) {
970 : 0 : *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED;
971 [ # # ]: 0 : } else if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT) {
972 : : /* MIB is not available yet but the agent is running */
973 : 0 : *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED;
974 : : ret = I40E_SUCCESS;
975 [ # # ]: 0 : } else if (hw->aq.asq_last_status == I40E_AQ_RC_EPERM) {
976 : 0 : *lldp_status = I40E_GET_FW_LLDP_STATUS_DISABLED;
977 : : ret = I40E_SUCCESS;
978 : : }
979 : :
980 : 0 : i40e_free_virt_mem(hw, &mem);
981 : 0 : return ret;
982 : : }
983 : :
984 : : /**
985 : : * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
986 : : * @tlv: Fill the ETS config data in IEEE format
987 : : * @dcbcfg: Local store which holds the DCB Config
988 : : *
989 : : * Prepare IEEE 802.1Qaz ETS CFG TLV
990 : : **/
991 : 0 : static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
992 : : struct i40e_dcbx_config *dcbcfg)
993 : : {
994 : : u8 priority0, priority1, maxtcwilling = 0;
995 : : struct i40e_dcb_ets_config *etscfg;
996 : : u16 offset = 0, typelength, i;
997 : 0 : u8 *buf = tlv->tlvinfo;
998 : : u32 ouisubtype;
999 : :
1000 : : typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1001 : : I40E_IEEE_ETS_TLV_LENGTH);
1002 : 0 : tlv->typelength = I40E_HTONS(typelength);
1003 : :
1004 : : ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1005 : : I40E_IEEE_SUBTYPE_ETS_CFG);
1006 : 0 : tlv->ouisubtype = I40E_HTONL(ouisubtype);
1007 : :
1008 : : /* First Octet post subtype
1009 : : * --------------------------
1010 : : * |will-|CBS | Re- | Max |
1011 : : * |ing | |served| TCs |
1012 : : * --------------------------
1013 : : * |1bit | 1bit|3 bits|3bits|
1014 : : */
1015 : : etscfg = &dcbcfg->etscfg;
1016 [ # # ]: 0 : if (etscfg->willing)
1017 : : maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
1018 : 0 : maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
1019 : 0 : buf[offset] = maxtcwilling;
1020 : :
1021 : : /* Move offset to Priority Assignment Table */
1022 : : offset++;
1023 : :
1024 : : /* Priority Assignment Table (4 octets)
1025 : : * Octets:| 1 | 2 | 3 | 4 |
1026 : : * -----------------------------------------
1027 : : * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
1028 : : * -----------------------------------------
1029 : : * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
1030 : : * -----------------------------------------
1031 : : */
1032 [ # # ]: 0 : for (i = 0; i < 4; i++) {
1033 : 0 : priority0 = etscfg->prioritytable[i * 2] & 0xF;
1034 : 0 : priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
1035 : 0 : buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1036 : : priority1;
1037 : 0 : offset++;
1038 : : }
1039 : :
1040 : : /* TC Bandwidth Table (8 octets)
1041 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1042 : : * ---------------------------------
1043 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1044 : : * ---------------------------------
1045 : : */
1046 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1047 : 0 : buf[offset++] = etscfg->tcbwtable[i];
1048 : :
1049 : : /* TSA Assignment Table (8 octets)
1050 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1051 : : * ---------------------------------
1052 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1053 : : * ---------------------------------
1054 : : */
1055 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1056 : 0 : buf[offset++] = etscfg->tsatable[i];
1057 : 0 : }
1058 : :
1059 : : /**
1060 : : * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
1061 : : * @tlv: Fill ETS Recommended TLV in IEEE format
1062 : : * @dcbcfg: Local store which holds the DCB Config
1063 : : *
1064 : : * Prepare IEEE 802.1Qaz ETS REC TLV
1065 : : **/
1066 : 0 : static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
1067 : : struct i40e_dcbx_config *dcbcfg)
1068 : : {
1069 : : struct i40e_dcb_ets_config *etsrec;
1070 : : u16 offset = 0, typelength, i;
1071 : : u8 priority0, priority1;
1072 : 0 : u8 *buf = tlv->tlvinfo;
1073 : : u32 ouisubtype;
1074 : :
1075 : : typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1076 : : I40E_IEEE_ETS_TLV_LENGTH);
1077 : 0 : tlv->typelength = I40E_HTONS(typelength);
1078 : :
1079 : : ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1080 : : I40E_IEEE_SUBTYPE_ETS_REC);
1081 : 0 : tlv->ouisubtype = I40E_HTONL(ouisubtype);
1082 : :
1083 : : etsrec = &dcbcfg->etsrec;
1084 : : /* First Octet is reserved */
1085 : : /* Move offset to Priority Assignment Table */
1086 : : offset++;
1087 : :
1088 : : /* Priority Assignment Table (4 octets)
1089 : : * Octets:| 1 | 2 | 3 | 4 |
1090 : : * -----------------------------------------
1091 : : * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
1092 : : * -----------------------------------------
1093 : : * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
1094 : : * -----------------------------------------
1095 : : */
1096 [ # # ]: 0 : for (i = 0; i < 4; i++) {
1097 : 0 : priority0 = etsrec->prioritytable[i * 2] & 0xF;
1098 : 0 : priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
1099 : 0 : buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1100 : : priority1;
1101 : 0 : offset++;
1102 : : }
1103 : :
1104 : : /* TC Bandwidth Table (8 octets)
1105 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1106 : : * ---------------------------------
1107 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1108 : : * ---------------------------------
1109 : : */
1110 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1111 : 0 : buf[offset++] = etsrec->tcbwtable[i];
1112 : :
1113 : : /* TSA Assignment Table (8 octets)
1114 : : * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1115 : : * ---------------------------------
1116 : : * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1117 : : * ---------------------------------
1118 : : */
1119 [ # # ]: 0 : for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1120 : 0 : buf[offset++] = etsrec->tsatable[i];
1121 : 0 : }
1122 : :
1123 : : /**
1124 : : * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
1125 : : * @tlv: Fill PFC TLV in IEEE format
1126 : : * @dcbcfg: Local store to get PFC CFG data
1127 : : *
1128 : : * Prepare IEEE 802.1Qaz PFC CFG TLV
1129 : : **/
1130 : : static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
1131 : : struct i40e_dcbx_config *dcbcfg)
1132 : : {
1133 : : u8 *buf = tlv->tlvinfo;
1134 : : u32 ouisubtype;
1135 : : u16 typelength;
1136 : :
1137 : : typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1138 : : I40E_IEEE_PFC_TLV_LENGTH);
1139 : 0 : tlv->typelength = I40E_HTONS(typelength);
1140 : :
1141 : : ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1142 : : I40E_IEEE_SUBTYPE_PFC_CFG);
1143 : 0 : tlv->ouisubtype = I40E_HTONL(ouisubtype);
1144 : :
1145 : : /* ----------------------------------------
1146 : : * |will-|MBC | Re- | PFC | PFC Enable |
1147 : : * |ing | |served| cap | |
1148 : : * -----------------------------------------
1149 : : * |1bit | 1bit|2 bits|4bits| 1 octet |
1150 : : */
1151 [ # # ]: 0 : if (dcbcfg->pfc.willing)
1152 : 0 : buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
1153 : :
1154 [ # # ]: 0 : if (dcbcfg->pfc.mbc)
1155 : 0 : buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
1156 : :
1157 : 0 : buf[0] |= dcbcfg->pfc.pfccap & 0xF;
1158 : 0 : buf[1] = dcbcfg->pfc.pfcenable;
1159 : 0 : }
1160 : :
1161 : : /**
1162 : : * i40e_add_ieee_app_pri_tlv - Prepare APP TLV in IEEE format
1163 : : * @tlv: Fill APP TLV in IEEE format
1164 : : * @dcbcfg: Local store to get APP CFG data
1165 : : *
1166 : : * Prepare IEEE 802.1Qaz APP CFG TLV
1167 : : **/
1168 : 0 : static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
1169 : : struct i40e_dcbx_config *dcbcfg)
1170 : : {
1171 : : u16 typelength, length, offset = 0;
1172 : : u8 priority, selector, i = 0;
1173 : 0 : u8 *buf = tlv->tlvinfo;
1174 : : u32 ouisubtype;
1175 : :
1176 : : /* No APP TLVs then just return */
1177 [ # # ]: 0 : if (dcbcfg->numapps == 0)
1178 : : return;
1179 : : ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1180 : : I40E_IEEE_SUBTYPE_APP_PRI);
1181 : 0 : tlv->ouisubtype = I40E_HTONL(ouisubtype);
1182 : :
1183 : : /* Move offset to App Priority Table */
1184 : : offset++;
1185 : : /* Application Priority Table (3 octets)
1186 : : * Octets:| 1 | 2 | 3 |
1187 : : * -----------------------------------------
1188 : : * |Priority|Rsrvd| Sel | Protocol ID |
1189 : : * -----------------------------------------
1190 : : * Bits:|23 21|20 19|18 16|15 0|
1191 : : * -----------------------------------------
1192 : : */
1193 [ # # ]: 0 : while (i < dcbcfg->numapps) {
1194 : 0 : priority = dcbcfg->app[i].priority & 0x7;
1195 : 0 : selector = dcbcfg->app[i].selector & 0x7;
1196 : 0 : buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
1197 : 0 : buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
1198 : 0 : buf[offset + 2] = dcbcfg->app[i].protocolid & 0xFF;
1199 : : /* Move to next app */
1200 : 0 : offset += 3;
1201 : 0 : i++;
1202 [ # # ]: 0 : if (i >= I40E_DCBX_MAX_APPS)
1203 : : break;
1204 : : }
1205 : : /* length includes size of ouisubtype + 1 reserved + 3*numapps */
1206 : 0 : length = sizeof(tlv->ouisubtype) + 1 + (i*3);
1207 : 0 : typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1208 : : (length & 0x1FF));
1209 [ # # ]: 0 : tlv->typelength = I40E_HTONS(typelength);
1210 : : }
1211 : :
1212 : : /**
1213 : : * i40e_add_dcb_tlv - Add all IEEE TLVs
1214 : : * @tlv: pointer to org tlv
1215 : : *
1216 : : * add tlv information
1217 : : **/
1218 : 0 : static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
1219 : : struct i40e_dcbx_config *dcbcfg,
1220 : : u16 tlvid)
1221 : : {
1222 [ # # # # : 0 : switch (tlvid) {
# ]
1223 : 0 : case I40E_IEEE_TLV_ID_ETS_CFG:
1224 : 0 : i40e_add_ieee_ets_tlv(tlv, dcbcfg);
1225 : 0 : break;
1226 : 0 : case I40E_IEEE_TLV_ID_ETS_REC:
1227 : 0 : i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
1228 : 0 : break;
1229 : : case I40E_IEEE_TLV_ID_PFC_CFG:
1230 : : i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
1231 : : break;
1232 : 0 : case I40E_IEEE_TLV_ID_APP_PRI:
1233 : 0 : i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
1234 : 0 : break;
1235 : : default:
1236 : : break;
1237 : : }
1238 : 0 : }
1239 : :
1240 : : /**
1241 : : * i40e_set_dcb_config - Set the local LLDP MIB to FW
1242 : : * @hw: pointer to the hw struct
1243 : : *
1244 : : * Set DCB configuration to the Firmware
1245 : : **/
1246 : 0 : enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw)
1247 : : {
1248 : : enum i40e_status_code ret = I40E_SUCCESS;
1249 : : struct i40e_dcbx_config *dcbcfg;
1250 : : struct i40e_virt_mem mem;
1251 : : u8 mib_type, *lldpmib;
1252 : : u16 miblen;
1253 : :
1254 : : /* update the hw local config */
1255 : 0 : dcbcfg = &hw->local_dcbx_config;
1256 : : /* Allocate the LLDPDU */
1257 : 0 : ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
1258 [ # # ]: 0 : if (ret)
1259 : : return ret;
1260 : :
1261 : : mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
1262 [ # # ]: 0 : if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
1263 : : mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
1264 : : SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
1265 : : }
1266 : 0 : lldpmib = (u8 *)mem.va;
1267 : 0 : ret = i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
1268 : 0 : ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
1269 : :
1270 : 0 : i40e_free_virt_mem(hw, &mem);
1271 : 0 : return ret;
1272 : : }
1273 : :
1274 : : /**
1275 : : * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
1276 : : * @lldpmib: pointer to mib to be output
1277 : : * @miblen: pointer to u16 for length of lldpmib
1278 : : * @dcbcfg: store for LLDPDU data
1279 : : *
1280 : : * send DCB configuration to FW
1281 : : **/
1282 : 0 : enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
1283 : : struct i40e_dcbx_config *dcbcfg)
1284 : : {
1285 : : u16 length, offset = 0, tlvid = I40E_TLV_ID_START;
1286 : : enum i40e_status_code ret = I40E_SUCCESS;
1287 : : struct i40e_lldp_org_tlv *tlv;
1288 : : u16 typelength;
1289 : :
1290 : : tlv = (struct i40e_lldp_org_tlv *)lldpmib;
1291 : : while (1) {
1292 : 0 : i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
1293 [ # # ]: 0 : typelength = I40E_NTOHS(tlv->typelength);
1294 : 0 : length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
1295 : : I40E_LLDP_TLV_LEN_SHIFT);
1296 [ # # ]: 0 : if (length)
1297 : 0 : offset += length + 2;
1298 : : /* END TLV or beyond LLDPDU size */
1299 : 0 : if ((tlvid >= I40E_TLV_ID_END_OF_LLDPPDU) ||
1300 [ # # ]: 0 : (offset > I40E_LLDPDU_SIZE))
1301 : : break;
1302 : : /* Move to next TLV */
1303 [ # # ]: 0 : if (length)
1304 : 0 : tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
1305 : 0 : sizeof(tlv->typelength) + length);
1306 : : }
1307 : 0 : *miblen = offset;
1308 : 0 : return ret;
1309 : : }
1310 : :
1311 : : /**
1312 : : * _i40e_read_lldp_cfg - generic read of LLDP Configuration data from NVM
1313 : : * @hw: pointer to the HW structure
1314 : : * @lldp_cfg: pointer to hold lldp configuration variables
1315 : : * @module: address of the module pointer
1316 : : * @word_offset: offset of LLDP configuration
1317 : : *
1318 : : * Reads the LLDP configuration data from NVM using passed addresses
1319 : : **/
1320 : 0 : static enum i40e_status_code _i40e_read_lldp_cfg(struct i40e_hw *hw,
1321 : : struct i40e_lldp_variables *lldp_cfg,
1322 : : u8 module, u32 word_offset)
1323 : : {
1324 : 0 : u32 address, offset = (2 * word_offset);
1325 : : enum i40e_status_code ret;
1326 : : __le16 raw_mem;
1327 : : u16 mem;
1328 : :
1329 : 0 : ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1330 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1331 : : return ret;
1332 : :
1333 : 0 : ret = i40e_aq_read_nvm(hw, 0x0, module * 2, sizeof(raw_mem), &raw_mem,
1334 : : true, NULL);
1335 : 0 : i40e_release_nvm(hw);
1336 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1337 : : return ret;
1338 : :
1339 : 0 : mem = LE16_TO_CPU(raw_mem);
1340 : : /* Check if this pointer needs to be read in word size or 4K sector
1341 : : * units.
1342 : : */
1343 [ # # ]: 0 : if (mem & I40E_PTR_TYPE)
1344 : 0 : address = (0x7FFF & mem) * 4096;
1345 : : else
1346 : 0 : address = (0x7FFF & mem) * 2;
1347 : :
1348 : 0 : ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1349 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1350 : 0 : goto err_lldp_cfg;
1351 : :
1352 : 0 : ret = i40e_aq_read_nvm(hw, module, offset, sizeof(raw_mem), &raw_mem,
1353 : : true, NULL);
1354 : 0 : i40e_release_nvm(hw);
1355 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1356 : : return ret;
1357 : :
1358 : 0 : mem = LE16_TO_CPU(raw_mem);
1359 : 0 : offset = mem + word_offset;
1360 : 0 : offset *= 2;
1361 : :
1362 : 0 : ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1363 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1364 : 0 : goto err_lldp_cfg;
1365 : :
1366 : 0 : ret = i40e_aq_read_nvm(hw, 0, address + offset,
1367 : : sizeof(struct i40e_lldp_variables), lldp_cfg,
1368 : : true, NULL);
1369 : 0 : i40e_release_nvm(hw);
1370 : :
1371 : : err_lldp_cfg:
1372 : : return ret;
1373 : : }
1374 : :
1375 : : /**
1376 : : * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1377 : : * @hw: pointer to the HW structure
1378 : : * @lldp_cfg: pointer to hold lldp configuration variables
1379 : : *
1380 : : * Reads the LLDP configuration data from NVM
1381 : : **/
1382 : 0 : enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
1383 : : struct i40e_lldp_variables *lldp_cfg)
1384 : : {
1385 : : enum i40e_status_code ret = I40E_SUCCESS;
1386 : : u32 mem;
1387 : :
1388 [ # # ]: 0 : if (!lldp_cfg)
1389 : : return I40E_ERR_PARAM;
1390 : :
1391 : 0 : ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1392 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1393 : : return ret;
1394 : :
1395 : 0 : ret = i40e_aq_read_nvm(hw, I40E_SR_NVM_CONTROL_WORD, 0, sizeof(mem),
1396 : : &mem, true, NULL);
1397 : 0 : i40e_release_nvm(hw);
1398 [ # # ]: 0 : if (ret != I40E_SUCCESS)
1399 : : return ret;
1400 : :
1401 : : /* Read a bit that holds information whether we are running flat or
1402 : : * structured NVM image. Flat image has LLDP configuration in shadow
1403 : : * ram, so there is a need to pass different addresses for both cases.
1404 : : */
1405 [ # # ]: 0 : if (mem & I40E_SR_NVM_MAP_STRUCTURE_TYPE) {
1406 : : /* Flat NVM case */
1407 : 0 : ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_SR_EMP_MODULE_PTR,
1408 : : I40E_SR_LLDP_CFG_PTR);
1409 : : } else {
1410 : : /* Good old structured NVM image */
1411 : 0 : ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_EMP_MODULE_PTR,
1412 : : I40E_NVM_LLDP_CFG_PTR);
1413 : : }
1414 : :
1415 : : return ret;
1416 : : }
|