1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
290bc8e00SArkadiusz Kubalewski /* Copyright(c) 2013 - 2021 Intel Corporation. */
3afb3ff0dSNeerav Parikh
4*e383353bSJesse Brandeburg #include <linux/bitfield.h>
5*e383353bSJesse Brandeburg #include "i40e_adminq.h"
6e77220eeSIvan Vecera #include "i40e_alloc.h"
7afb3ff0dSNeerav Parikh #include "i40e_dcb.h"
8e77220eeSIvan Vecera #include "i40e_prototype.h"
9afb3ff0dSNeerav Parikh
10afb3ff0dSNeerav Parikh /**
11afb3ff0dSNeerav Parikh * i40e_get_dcbx_status
12afb3ff0dSNeerav Parikh * @hw: pointer to the hw struct
13afb3ff0dSNeerav Parikh * @status: Embedded DCBX Engine Status
14afb3ff0dSNeerav Parikh *
15afb3ff0dSNeerav Parikh * Get the DCBX status from the Firmware
16afb3ff0dSNeerav Parikh **/
i40e_get_dcbx_status(struct i40e_hw * hw,u16 * status)175180ff13SJan Sokolowski int i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
18afb3ff0dSNeerav Parikh {
19afb3ff0dSNeerav Parikh u32 reg;
20afb3ff0dSNeerav Parikh
21afb3ff0dSNeerav Parikh if (!status)
22230f3d53SJan Sokolowski return -EINVAL;
23afb3ff0dSNeerav Parikh
24afb3ff0dSNeerav Parikh reg = rd32(hw, I40E_PRTDCB_GENS);
25afb3ff0dSNeerav Parikh *status = (u16)((reg & I40E_PRTDCB_GENS_DCBX_STATUS_MASK) >>
26afb3ff0dSNeerav Parikh I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT);
27afb3ff0dSNeerav Parikh
28afb3ff0dSNeerav Parikh return 0;
29afb3ff0dSNeerav Parikh }
30afb3ff0dSNeerav Parikh
31afb3ff0dSNeerav Parikh /**
32afb3ff0dSNeerav Parikh * i40e_parse_ieee_etscfg_tlv
33afb3ff0dSNeerav Parikh * @tlv: IEEE 802.1Qaz ETS CFG TLV
34afb3ff0dSNeerav Parikh * @dcbcfg: Local store to update ETS CFG data
35afb3ff0dSNeerav Parikh *
36afb3ff0dSNeerav Parikh * Parses IEEE 802.1Qaz ETS CFG TLV
37afb3ff0dSNeerav Parikh **/
i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)38afb3ff0dSNeerav Parikh static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv,
39afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
40afb3ff0dSNeerav Parikh {
419fa61dd2SNeerav Parikh struct i40e_dcb_ets_config *etscfg;
42afb3ff0dSNeerav Parikh u8 *buf = tlv->tlvinfo;
43afb3ff0dSNeerav Parikh u16 offset = 0;
44afb3ff0dSNeerav Parikh u8 priority;
45afb3ff0dSNeerav Parikh int i;
46afb3ff0dSNeerav Parikh
47afb3ff0dSNeerav Parikh /* First Octet post subtype
48afb3ff0dSNeerav Parikh * --------------------------
49afb3ff0dSNeerav Parikh * |will-|CBS | Re- | Max |
50afb3ff0dSNeerav Parikh * |ing | |served| TCs |
51afb3ff0dSNeerav Parikh * --------------------------
52afb3ff0dSNeerav Parikh * |1bit | 1bit|3 bits|3bits|
53afb3ff0dSNeerav Parikh */
54afb3ff0dSNeerav Parikh etscfg = &dcbcfg->etscfg;
55afb3ff0dSNeerav Parikh etscfg->willing = (u8)((buf[offset] & I40E_IEEE_ETS_WILLING_MASK) >>
56afb3ff0dSNeerav Parikh I40E_IEEE_ETS_WILLING_SHIFT);
57afb3ff0dSNeerav Parikh etscfg->cbs = (u8)((buf[offset] & I40E_IEEE_ETS_CBS_MASK) >>
58afb3ff0dSNeerav Parikh I40E_IEEE_ETS_CBS_SHIFT);
59afb3ff0dSNeerav Parikh etscfg->maxtcs = (u8)((buf[offset] & I40E_IEEE_ETS_MAXTC_MASK) >>
60afb3ff0dSNeerav Parikh I40E_IEEE_ETS_MAXTC_SHIFT);
61afb3ff0dSNeerav Parikh
62afb3ff0dSNeerav Parikh /* Move offset to Priority Assignment Table */
63afb3ff0dSNeerav Parikh offset++;
64afb3ff0dSNeerav Parikh
65afb3ff0dSNeerav Parikh /* Priority Assignment Table (4 octets)
66afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 | 4 |
67afb3ff0dSNeerav Parikh * -----------------------------------------
68afb3ff0dSNeerav Parikh * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
69afb3ff0dSNeerav Parikh * -----------------------------------------
70afb3ff0dSNeerav Parikh * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
71afb3ff0dSNeerav Parikh * -----------------------------------------
72afb3ff0dSNeerav Parikh */
73afb3ff0dSNeerav Parikh for (i = 0; i < 4; i++) {
74afb3ff0dSNeerav Parikh priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
75afb3ff0dSNeerav Parikh I40E_IEEE_ETS_PRIO_1_SHIFT);
76afb3ff0dSNeerav Parikh etscfg->prioritytable[i * 2] = priority;
77afb3ff0dSNeerav Parikh priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
78afb3ff0dSNeerav Parikh I40E_IEEE_ETS_PRIO_0_SHIFT);
79afb3ff0dSNeerav Parikh etscfg->prioritytable[i * 2 + 1] = priority;
80afb3ff0dSNeerav Parikh offset++;
81afb3ff0dSNeerav Parikh }
82afb3ff0dSNeerav Parikh
83afb3ff0dSNeerav Parikh /* TC Bandwidth Table (8 octets)
84afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
85afb3ff0dSNeerav Parikh * ---------------------------------
86afb3ff0dSNeerav Parikh * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
87afb3ff0dSNeerav Parikh * ---------------------------------
88afb3ff0dSNeerav Parikh */
89afb3ff0dSNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
90afb3ff0dSNeerav Parikh etscfg->tcbwtable[i] = buf[offset++];
91afb3ff0dSNeerav Parikh
92afb3ff0dSNeerav Parikh /* TSA Assignment Table (8 octets)
93afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
94afb3ff0dSNeerav Parikh * ---------------------------------
95afb3ff0dSNeerav Parikh * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
96afb3ff0dSNeerav Parikh * ---------------------------------
97afb3ff0dSNeerav Parikh */
98afb3ff0dSNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
99afb3ff0dSNeerav Parikh etscfg->tsatable[i] = buf[offset++];
100afb3ff0dSNeerav Parikh }
101afb3ff0dSNeerav Parikh
102afb3ff0dSNeerav Parikh /**
103afb3ff0dSNeerav Parikh * i40e_parse_ieee_etsrec_tlv
104afb3ff0dSNeerav Parikh * @tlv: IEEE 802.1Qaz ETS REC TLV
105afb3ff0dSNeerav Parikh * @dcbcfg: Local store to update ETS REC data
106afb3ff0dSNeerav Parikh *
107afb3ff0dSNeerav Parikh * Parses IEEE 802.1Qaz ETS REC TLV
108afb3ff0dSNeerav Parikh **/
i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)109afb3ff0dSNeerav Parikh static void i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
110afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
111afb3ff0dSNeerav Parikh {
112afb3ff0dSNeerav Parikh u8 *buf = tlv->tlvinfo;
113afb3ff0dSNeerav Parikh u16 offset = 0;
114afb3ff0dSNeerav Parikh u8 priority;
115afb3ff0dSNeerav Parikh int i;
116afb3ff0dSNeerav Parikh
117afb3ff0dSNeerav Parikh /* Move offset to priority table */
118afb3ff0dSNeerav Parikh offset++;
119afb3ff0dSNeerav Parikh
120afb3ff0dSNeerav Parikh /* Priority Assignment Table (4 octets)
121afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 | 4 |
122afb3ff0dSNeerav Parikh * -----------------------------------------
123afb3ff0dSNeerav Parikh * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
124afb3ff0dSNeerav Parikh * -----------------------------------------
125afb3ff0dSNeerav Parikh * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
126afb3ff0dSNeerav Parikh * -----------------------------------------
127afb3ff0dSNeerav Parikh */
128afb3ff0dSNeerav Parikh for (i = 0; i < 4; i++) {
129afb3ff0dSNeerav Parikh priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
130afb3ff0dSNeerav Parikh I40E_IEEE_ETS_PRIO_1_SHIFT);
131afb3ff0dSNeerav Parikh dcbcfg->etsrec.prioritytable[i*2] = priority;
132afb3ff0dSNeerav Parikh priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
133afb3ff0dSNeerav Parikh I40E_IEEE_ETS_PRIO_0_SHIFT);
134afb3ff0dSNeerav Parikh dcbcfg->etsrec.prioritytable[i*2 + 1] = priority;
135afb3ff0dSNeerav Parikh offset++;
136afb3ff0dSNeerav Parikh }
137afb3ff0dSNeerav Parikh
138afb3ff0dSNeerav Parikh /* TC Bandwidth Table (8 octets)
139afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
140afb3ff0dSNeerav Parikh * ---------------------------------
141afb3ff0dSNeerav Parikh * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
142afb3ff0dSNeerav Parikh * ---------------------------------
143afb3ff0dSNeerav Parikh */
144afb3ff0dSNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
145afb3ff0dSNeerav Parikh dcbcfg->etsrec.tcbwtable[i] = buf[offset++];
146afb3ff0dSNeerav Parikh
147afb3ff0dSNeerav Parikh /* TSA Assignment Table (8 octets)
148afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
149afb3ff0dSNeerav Parikh * ---------------------------------
150afb3ff0dSNeerav Parikh * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
151afb3ff0dSNeerav Parikh * ---------------------------------
152afb3ff0dSNeerav Parikh */
153afb3ff0dSNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
154afb3ff0dSNeerav Parikh dcbcfg->etsrec.tsatable[i] = buf[offset++];
155afb3ff0dSNeerav Parikh }
156afb3ff0dSNeerav Parikh
157afb3ff0dSNeerav Parikh /**
158afb3ff0dSNeerav Parikh * i40e_parse_ieee_pfccfg_tlv
159afb3ff0dSNeerav Parikh * @tlv: IEEE 802.1Qaz PFC CFG TLV
160afb3ff0dSNeerav Parikh * @dcbcfg: Local store to update PFC CFG data
161afb3ff0dSNeerav Parikh *
162afb3ff0dSNeerav Parikh * Parses IEEE 802.1Qaz PFC CFG TLV
163afb3ff0dSNeerav Parikh **/
i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)164afb3ff0dSNeerav Parikh static void i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv *tlv,
165afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
166afb3ff0dSNeerav Parikh {
167afb3ff0dSNeerav Parikh u8 *buf = tlv->tlvinfo;
168afb3ff0dSNeerav Parikh
169afb3ff0dSNeerav Parikh /* ----------------------------------------
170afb3ff0dSNeerav Parikh * |will-|MBC | Re- | PFC | PFC Enable |
171afb3ff0dSNeerav Parikh * |ing | |served| cap | |
172afb3ff0dSNeerav Parikh * -----------------------------------------
173afb3ff0dSNeerav Parikh * |1bit | 1bit|2 bits|4bits| 1 octet |
174afb3ff0dSNeerav Parikh */
175afb3ff0dSNeerav Parikh dcbcfg->pfc.willing = (u8)((buf[0] & I40E_IEEE_PFC_WILLING_MASK) >>
176afb3ff0dSNeerav Parikh I40E_IEEE_PFC_WILLING_SHIFT);
177afb3ff0dSNeerav Parikh dcbcfg->pfc.mbc = (u8)((buf[0] & I40E_IEEE_PFC_MBC_MASK) >>
178afb3ff0dSNeerav Parikh I40E_IEEE_PFC_MBC_SHIFT);
179afb3ff0dSNeerav Parikh dcbcfg->pfc.pfccap = (u8)((buf[0] & I40E_IEEE_PFC_CAP_MASK) >>
180afb3ff0dSNeerav Parikh I40E_IEEE_PFC_CAP_SHIFT);
181afb3ff0dSNeerav Parikh dcbcfg->pfc.pfcenable = buf[1];
182afb3ff0dSNeerav Parikh }
183afb3ff0dSNeerav Parikh
184afb3ff0dSNeerav Parikh /**
185afb3ff0dSNeerav Parikh * i40e_parse_ieee_app_tlv
186afb3ff0dSNeerav Parikh * @tlv: IEEE 802.1Qaz APP TLV
187afb3ff0dSNeerav Parikh * @dcbcfg: Local store to update APP PRIO data
188afb3ff0dSNeerav Parikh *
189afb3ff0dSNeerav Parikh * Parses IEEE 802.1Qaz APP PRIO TLV
190afb3ff0dSNeerav Parikh **/
i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)191afb3ff0dSNeerav Parikh static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv,
192afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
193afb3ff0dSNeerav Parikh {
194afb3ff0dSNeerav Parikh u16 typelength;
195afb3ff0dSNeerav Parikh u16 offset = 0;
196afb3ff0dSNeerav Parikh u16 length;
197afb3ff0dSNeerav Parikh int i = 0;
198afb3ff0dSNeerav Parikh u8 *buf;
199afb3ff0dSNeerav Parikh
200afb3ff0dSNeerav Parikh typelength = ntohs(tlv->typelength);
201afb3ff0dSNeerav Parikh length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
202afb3ff0dSNeerav Parikh I40E_LLDP_TLV_LEN_SHIFT);
203afb3ff0dSNeerav Parikh buf = tlv->tlvinfo;
204afb3ff0dSNeerav Parikh
205afb3ff0dSNeerav Parikh /* The App priority table starts 5 octets after TLV header */
206afb3ff0dSNeerav Parikh length -= (sizeof(tlv->ouisubtype) + 1);
207afb3ff0dSNeerav Parikh
208afb3ff0dSNeerav Parikh /* Move offset to App Priority Table */
209afb3ff0dSNeerav Parikh offset++;
210afb3ff0dSNeerav Parikh
211afb3ff0dSNeerav Parikh /* Application Priority Table (3 octets)
212afb3ff0dSNeerav Parikh * Octets:| 1 | 2 | 3 |
213afb3ff0dSNeerav Parikh * -----------------------------------------
214afb3ff0dSNeerav Parikh * |Priority|Rsrvd| Sel | Protocol ID |
215afb3ff0dSNeerav Parikh * -----------------------------------------
216afb3ff0dSNeerav Parikh * Bits:|23 21|20 19|18 16|15 0|
217afb3ff0dSNeerav Parikh * -----------------------------------------
218afb3ff0dSNeerav Parikh */
219afb3ff0dSNeerav Parikh while (offset < length) {
220afb3ff0dSNeerav Parikh dcbcfg->app[i].priority = (u8)((buf[offset] &
221afb3ff0dSNeerav Parikh I40E_IEEE_APP_PRIO_MASK) >>
222afb3ff0dSNeerav Parikh I40E_IEEE_APP_PRIO_SHIFT);
223afb3ff0dSNeerav Parikh dcbcfg->app[i].selector = (u8)((buf[offset] &
224afb3ff0dSNeerav Parikh I40E_IEEE_APP_SEL_MASK) >>
225afb3ff0dSNeerav Parikh I40E_IEEE_APP_SEL_SHIFT);
226afb3ff0dSNeerav Parikh dcbcfg->app[i].protocolid = (buf[offset + 1] << 0x8) |
227afb3ff0dSNeerav Parikh buf[offset + 2];
228afb3ff0dSNeerav Parikh /* Move to next app */
229afb3ff0dSNeerav Parikh offset += 3;
230afb3ff0dSNeerav Parikh i++;
231afb3ff0dSNeerav Parikh if (i >= I40E_DCBX_MAX_APPS)
232afb3ff0dSNeerav Parikh break;
233afb3ff0dSNeerav Parikh }
234afb3ff0dSNeerav Parikh
235afb3ff0dSNeerav Parikh dcbcfg->numapps = i;
236afb3ff0dSNeerav Parikh }
237afb3ff0dSNeerav Parikh
238afb3ff0dSNeerav Parikh /**
239262de08fSJesse Brandeburg * i40e_parse_ieee_tlv
240afb3ff0dSNeerav Parikh * @tlv: IEEE 802.1Qaz TLV
241afb3ff0dSNeerav Parikh * @dcbcfg: Local store to update ETS REC data
242afb3ff0dSNeerav Parikh *
243afb3ff0dSNeerav Parikh * Get the TLV subtype and send it to parsing function
244afb3ff0dSNeerav Parikh * based on the subtype value
245afb3ff0dSNeerav Parikh **/
i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)246afb3ff0dSNeerav Parikh static void i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv *tlv,
247afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
248afb3ff0dSNeerav Parikh {
249afb3ff0dSNeerav Parikh u32 ouisubtype;
250afb3ff0dSNeerav Parikh u8 subtype;
251afb3ff0dSNeerav Parikh
252afb3ff0dSNeerav Parikh ouisubtype = ntohl(tlv->ouisubtype);
253afb3ff0dSNeerav Parikh subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
254afb3ff0dSNeerav Parikh I40E_LLDP_TLV_SUBTYPE_SHIFT);
255afb3ff0dSNeerav Parikh switch (subtype) {
256afb3ff0dSNeerav Parikh case I40E_IEEE_SUBTYPE_ETS_CFG:
257afb3ff0dSNeerav Parikh i40e_parse_ieee_etscfg_tlv(tlv, dcbcfg);
258afb3ff0dSNeerav Parikh break;
259afb3ff0dSNeerav Parikh case I40E_IEEE_SUBTYPE_ETS_REC:
260afb3ff0dSNeerav Parikh i40e_parse_ieee_etsrec_tlv(tlv, dcbcfg);
261afb3ff0dSNeerav Parikh break;
262afb3ff0dSNeerav Parikh case I40E_IEEE_SUBTYPE_PFC_CFG:
263afb3ff0dSNeerav Parikh i40e_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
264afb3ff0dSNeerav Parikh break;
265afb3ff0dSNeerav Parikh case I40E_IEEE_SUBTYPE_APP_PRI:
266afb3ff0dSNeerav Parikh i40e_parse_ieee_app_tlv(tlv, dcbcfg);
267afb3ff0dSNeerav Parikh break;
268afb3ff0dSNeerav Parikh default:
269afb3ff0dSNeerav Parikh break;
270afb3ff0dSNeerav Parikh }
271afb3ff0dSNeerav Parikh }
272afb3ff0dSNeerav Parikh
273afb3ff0dSNeerav Parikh /**
274909b2d16SNeerav Parikh * i40e_parse_cee_pgcfg_tlv
275909b2d16SNeerav Parikh * @tlv: CEE DCBX PG CFG TLV
276909b2d16SNeerav Parikh * @dcbcfg: Local store to update ETS CFG data
277909b2d16SNeerav Parikh *
278909b2d16SNeerav Parikh * Parses CEE DCBX PG CFG TLV
279909b2d16SNeerav Parikh **/
i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv * tlv,struct i40e_dcbx_config * dcbcfg)280909b2d16SNeerav Parikh static void i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv *tlv,
281909b2d16SNeerav Parikh struct i40e_dcbx_config *dcbcfg)
282909b2d16SNeerav Parikh {
283909b2d16SNeerav Parikh struct i40e_dcb_ets_config *etscfg;
284909b2d16SNeerav Parikh u8 *buf = tlv->tlvinfo;
285909b2d16SNeerav Parikh u16 offset = 0;
286909b2d16SNeerav Parikh u8 priority;
287909b2d16SNeerav Parikh int i;
288909b2d16SNeerav Parikh
289909b2d16SNeerav Parikh etscfg = &dcbcfg->etscfg;
290909b2d16SNeerav Parikh
291909b2d16SNeerav Parikh if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
292909b2d16SNeerav Parikh etscfg->willing = 1;
293909b2d16SNeerav Parikh
294909b2d16SNeerav Parikh etscfg->cbs = 0;
295909b2d16SNeerav Parikh /* Priority Group Table (4 octets)
296909b2d16SNeerav Parikh * Octets:| 1 | 2 | 3 | 4 |
297909b2d16SNeerav Parikh * -----------------------------------------
298909b2d16SNeerav Parikh * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
299909b2d16SNeerav Parikh * -----------------------------------------
300909b2d16SNeerav Parikh * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
301909b2d16SNeerav Parikh * -----------------------------------------
302909b2d16SNeerav Parikh */
303909b2d16SNeerav Parikh for (i = 0; i < 4; i++) {
304909b2d16SNeerav Parikh priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_1_MASK) >>
305909b2d16SNeerav Parikh I40E_CEE_PGID_PRIO_1_SHIFT);
306909b2d16SNeerav Parikh etscfg->prioritytable[i * 2] = priority;
307909b2d16SNeerav Parikh priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_0_MASK) >>
308909b2d16SNeerav Parikh I40E_CEE_PGID_PRIO_0_SHIFT);
309909b2d16SNeerav Parikh etscfg->prioritytable[i * 2 + 1] = priority;
310909b2d16SNeerav Parikh offset++;
311909b2d16SNeerav Parikh }
312909b2d16SNeerav Parikh
313909b2d16SNeerav Parikh /* PG Percentage Table (8 octets)
314909b2d16SNeerav Parikh * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
315909b2d16SNeerav Parikh * ---------------------------------
316909b2d16SNeerav Parikh * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|
317909b2d16SNeerav Parikh * ---------------------------------
318909b2d16SNeerav Parikh */
319909b2d16SNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
320909b2d16SNeerav Parikh etscfg->tcbwtable[i] = buf[offset++];
321909b2d16SNeerav Parikh
322909b2d16SNeerav Parikh /* Number of TCs supported (1 octet) */
323909b2d16SNeerav Parikh etscfg->maxtcs = buf[offset];
324909b2d16SNeerav Parikh }
325909b2d16SNeerav Parikh
326909b2d16SNeerav Parikh /**
327909b2d16SNeerav Parikh * i40e_parse_cee_pfccfg_tlv
328909b2d16SNeerav Parikh * @tlv: CEE DCBX PFC CFG TLV
329909b2d16SNeerav Parikh * @dcbcfg: Local store to update PFC CFG data
330909b2d16SNeerav Parikh *
331909b2d16SNeerav Parikh * Parses CEE DCBX PFC CFG TLV
332909b2d16SNeerav Parikh **/
i40e_parse_cee_pfccfg_tlv(struct i40e_cee_feat_tlv * tlv,struct i40e_dcbx_config * dcbcfg)333909b2d16SNeerav Parikh static void i40e_parse_cee_pfccfg_tlv(struct i40e_cee_feat_tlv *tlv,
334909b2d16SNeerav Parikh struct i40e_dcbx_config *dcbcfg)
335909b2d16SNeerav Parikh {
336909b2d16SNeerav Parikh u8 *buf = tlv->tlvinfo;
337909b2d16SNeerav Parikh
338909b2d16SNeerav Parikh if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
339909b2d16SNeerav Parikh dcbcfg->pfc.willing = 1;
340909b2d16SNeerav Parikh
341909b2d16SNeerav Parikh /* ------------------------
342909b2d16SNeerav Parikh * | PFC Enable | PFC TCs |
343909b2d16SNeerav Parikh * ------------------------
344909b2d16SNeerav Parikh * | 1 octet | 1 octet |
345909b2d16SNeerav Parikh */
346909b2d16SNeerav Parikh dcbcfg->pfc.pfcenable = buf[0];
347909b2d16SNeerav Parikh dcbcfg->pfc.pfccap = buf[1];
348909b2d16SNeerav Parikh }
349909b2d16SNeerav Parikh
350909b2d16SNeerav Parikh /**
351909b2d16SNeerav Parikh * i40e_parse_cee_app_tlv
352909b2d16SNeerav Parikh * @tlv: CEE DCBX APP TLV
353909b2d16SNeerav Parikh * @dcbcfg: Local store to update APP PRIO data
354909b2d16SNeerav Parikh *
355909b2d16SNeerav Parikh * Parses CEE DCBX APP PRIO TLV
356909b2d16SNeerav Parikh **/
i40e_parse_cee_app_tlv(struct i40e_cee_feat_tlv * tlv,struct i40e_dcbx_config * dcbcfg)357909b2d16SNeerav Parikh static void i40e_parse_cee_app_tlv(struct i40e_cee_feat_tlv *tlv,
358909b2d16SNeerav Parikh struct i40e_dcbx_config *dcbcfg)
359909b2d16SNeerav Parikh {
360909b2d16SNeerav Parikh u16 length, typelength, offset = 0;
361909b2d16SNeerav Parikh struct i40e_cee_app_prio *app;
362dd54a1adSJesse Brandeburg u8 i;
363909b2d16SNeerav Parikh
364909b2d16SNeerav Parikh typelength = ntohs(tlv->hdr.typelen);
365909b2d16SNeerav Parikh length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
366909b2d16SNeerav Parikh I40E_LLDP_TLV_LEN_SHIFT);
367909b2d16SNeerav Parikh
368909b2d16SNeerav Parikh dcbcfg->numapps = length / sizeof(*app);
369dd54a1adSJesse Brandeburg
370909b2d16SNeerav Parikh if (!dcbcfg->numapps)
371909b2d16SNeerav Parikh return;
3721e998547SSudheer Mogilappagari if (dcbcfg->numapps > I40E_DCBX_MAX_APPS)
3731e998547SSudheer Mogilappagari dcbcfg->numapps = I40E_DCBX_MAX_APPS;
374909b2d16SNeerav Parikh
375909b2d16SNeerav Parikh for (i = 0; i < dcbcfg->numapps; i++) {
376dd54a1adSJesse Brandeburg u8 up, selector;
377dd54a1adSJesse Brandeburg
378909b2d16SNeerav Parikh app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
379909b2d16SNeerav Parikh for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
380ab252253SNeerav Parikh if (app->prio_map & BIT(up))
381909b2d16SNeerav Parikh break;
382909b2d16SNeerav Parikh }
383909b2d16SNeerav Parikh dcbcfg->app[i].priority = up;
38441c3ae8bSGreg Bowers
38541c3ae8bSGreg Bowers /* Get Selector from lower 2 bits, and convert to IEEE */
38641c3ae8bSGreg Bowers selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
387dd54a1adSJesse Brandeburg switch (selector) {
388dd54a1adSJesse Brandeburg case I40E_CEE_APP_SEL_ETHTYPE:
38941c3ae8bSGreg Bowers dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
390dd54a1adSJesse Brandeburg break;
391dd54a1adSJesse Brandeburg case I40E_CEE_APP_SEL_TCPIP:
39241c3ae8bSGreg Bowers dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
393dd54a1adSJesse Brandeburg break;
394dd54a1adSJesse Brandeburg default:
39541c3ae8bSGreg Bowers /* Keep selector as it is for unknown types */
39641c3ae8bSGreg Bowers dcbcfg->app[i].selector = selector;
397dd54a1adSJesse Brandeburg }
39841c3ae8bSGreg Bowers
399909b2d16SNeerav Parikh dcbcfg->app[i].protocolid = ntohs(app->protocol);
400909b2d16SNeerav Parikh /* Move to next app */
401909b2d16SNeerav Parikh offset += sizeof(*app);
402909b2d16SNeerav Parikh }
403909b2d16SNeerav Parikh }
404909b2d16SNeerav Parikh
405909b2d16SNeerav Parikh /**
406909b2d16SNeerav Parikh * i40e_parse_cee_tlv
407909b2d16SNeerav Parikh * @tlv: CEE DCBX TLV
408909b2d16SNeerav Parikh * @dcbcfg: Local store to update DCBX config data
409909b2d16SNeerav Parikh *
410909b2d16SNeerav Parikh * Get the TLV subtype and send it to parsing function
411909b2d16SNeerav Parikh * based on the subtype value
412909b2d16SNeerav Parikh **/
i40e_parse_cee_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)413909b2d16SNeerav Parikh static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
414909b2d16SNeerav Parikh struct i40e_dcbx_config *dcbcfg)
415909b2d16SNeerav Parikh {
416909b2d16SNeerav Parikh u16 len, tlvlen, sublen, typelength;
417909b2d16SNeerav Parikh struct i40e_cee_feat_tlv *sub_tlv;
418909b2d16SNeerav Parikh u8 subtype, feat_tlv_count = 0;
419909b2d16SNeerav Parikh u32 ouisubtype;
420909b2d16SNeerav Parikh
421909b2d16SNeerav Parikh ouisubtype = ntohl(tlv->ouisubtype);
422909b2d16SNeerav Parikh subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
423909b2d16SNeerav Parikh I40E_LLDP_TLV_SUBTYPE_SHIFT);
424909b2d16SNeerav Parikh /* Return if not CEE DCBX */
425909b2d16SNeerav Parikh if (subtype != I40E_CEE_DCBX_TYPE)
426909b2d16SNeerav Parikh return;
427909b2d16SNeerav Parikh
428909b2d16SNeerav Parikh typelength = ntohs(tlv->typelength);
429909b2d16SNeerav Parikh tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
430909b2d16SNeerav Parikh I40E_LLDP_TLV_LEN_SHIFT);
431909b2d16SNeerav Parikh len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
432909b2d16SNeerav Parikh sizeof(struct i40e_cee_ctrl_tlv);
433909b2d16SNeerav Parikh /* Return if no CEE DCBX Feature TLVs */
434909b2d16SNeerav Parikh if (tlvlen <= len)
435909b2d16SNeerav Parikh return;
436909b2d16SNeerav Parikh
437909b2d16SNeerav Parikh sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
438909b2d16SNeerav Parikh while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
439909b2d16SNeerav Parikh typelength = ntohs(sub_tlv->hdr.typelen);
440909b2d16SNeerav Parikh sublen = (u16)((typelength &
441909b2d16SNeerav Parikh I40E_LLDP_TLV_LEN_MASK) >>
442909b2d16SNeerav Parikh I40E_LLDP_TLV_LEN_SHIFT);
443909b2d16SNeerav Parikh subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
444909b2d16SNeerav Parikh I40E_LLDP_TLV_TYPE_SHIFT);
445909b2d16SNeerav Parikh switch (subtype) {
446909b2d16SNeerav Parikh case I40E_CEE_SUBTYPE_PG_CFG:
447909b2d16SNeerav Parikh i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
448909b2d16SNeerav Parikh break;
449909b2d16SNeerav Parikh case I40E_CEE_SUBTYPE_PFC_CFG:
450909b2d16SNeerav Parikh i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
451909b2d16SNeerav Parikh break;
452909b2d16SNeerav Parikh case I40E_CEE_SUBTYPE_APP_PRI:
453909b2d16SNeerav Parikh i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
454909b2d16SNeerav Parikh break;
455909b2d16SNeerav Parikh default:
456909b2d16SNeerav Parikh return; /* Invalid Sub-type return */
457909b2d16SNeerav Parikh }
458909b2d16SNeerav Parikh feat_tlv_count++;
459909b2d16SNeerav Parikh /* Move to next sub TLV */
460909b2d16SNeerav Parikh sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
461909b2d16SNeerav Parikh sizeof(sub_tlv->hdr.typelen) +
462909b2d16SNeerav Parikh sublen);
463909b2d16SNeerav Parikh }
464909b2d16SNeerav Parikh }
465909b2d16SNeerav Parikh
466909b2d16SNeerav Parikh /**
467afb3ff0dSNeerav Parikh * i40e_parse_org_tlv
468afb3ff0dSNeerav Parikh * @tlv: Organization specific TLV
469afb3ff0dSNeerav Parikh * @dcbcfg: Local store to update ETS REC data
470afb3ff0dSNeerav Parikh *
471afb3ff0dSNeerav Parikh * Currently only IEEE 802.1Qaz TLV is supported, all others
472afb3ff0dSNeerav Parikh * will be returned
473afb3ff0dSNeerav Parikh **/
i40e_parse_org_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)474afb3ff0dSNeerav Parikh static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
475afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
476afb3ff0dSNeerav Parikh {
477afb3ff0dSNeerav Parikh u32 ouisubtype;
478afb3ff0dSNeerav Parikh u32 oui;
479afb3ff0dSNeerav Parikh
480afb3ff0dSNeerav Parikh ouisubtype = ntohl(tlv->ouisubtype);
481afb3ff0dSNeerav Parikh oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
482afb3ff0dSNeerav Parikh I40E_LLDP_TLV_OUI_SHIFT);
483afb3ff0dSNeerav Parikh switch (oui) {
484afb3ff0dSNeerav Parikh case I40E_IEEE_8021QAZ_OUI:
485afb3ff0dSNeerav Parikh i40e_parse_ieee_tlv(tlv, dcbcfg);
486afb3ff0dSNeerav Parikh break;
487909b2d16SNeerav Parikh case I40E_CEE_DCBX_OUI:
488909b2d16SNeerav Parikh i40e_parse_cee_tlv(tlv, dcbcfg);
489909b2d16SNeerav Parikh break;
490afb3ff0dSNeerav Parikh default:
491afb3ff0dSNeerav Parikh break;
492afb3ff0dSNeerav Parikh }
493afb3ff0dSNeerav Parikh }
494afb3ff0dSNeerav Parikh
495afb3ff0dSNeerav Parikh /**
496afb3ff0dSNeerav Parikh * i40e_lldp_to_dcb_config
497afb3ff0dSNeerav Parikh * @lldpmib: LLDPDU to be parsed
498afb3ff0dSNeerav Parikh * @dcbcfg: store for LLDPDU data
499afb3ff0dSNeerav Parikh *
500afb3ff0dSNeerav Parikh * Parse DCB configuration from the LLDPDU
501afb3ff0dSNeerav Parikh **/
i40e_lldp_to_dcb_config(u8 * lldpmib,struct i40e_dcbx_config * dcbcfg)5025180ff13SJan Sokolowski int i40e_lldp_to_dcb_config(u8 *lldpmib,
503afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
504afb3ff0dSNeerav Parikh {
505afb3ff0dSNeerav Parikh struct i40e_lldp_org_tlv *tlv;
506afb3ff0dSNeerav Parikh u16 typelength;
50771f6a85aSNeerav Parikh u16 offset = 0;
5085180ff13SJan Sokolowski int ret = 0;
5095180ff13SJan Sokolowski u16 length;
5105180ff13SJan Sokolowski u16 type;
511afb3ff0dSNeerav Parikh
512afb3ff0dSNeerav Parikh if (!lldpmib || !dcbcfg)
513230f3d53SJan Sokolowski return -EINVAL;
514afb3ff0dSNeerav Parikh
515afb3ff0dSNeerav Parikh /* set to the start of LLDPDU */
516afb3ff0dSNeerav Parikh lldpmib += ETH_HLEN;
517afb3ff0dSNeerav Parikh tlv = (struct i40e_lldp_org_tlv *)lldpmib;
51871f6a85aSNeerav Parikh while (1) {
519afb3ff0dSNeerav Parikh typelength = ntohs(tlv->typelength);
520afb3ff0dSNeerav Parikh type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
521afb3ff0dSNeerav Parikh I40E_LLDP_TLV_TYPE_SHIFT);
522afb3ff0dSNeerav Parikh length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
523afb3ff0dSNeerav Parikh I40E_LLDP_TLV_LEN_SHIFT);
52471f6a85aSNeerav Parikh offset += sizeof(typelength) + length;
525afb3ff0dSNeerav Parikh
52671f6a85aSNeerav Parikh /* END TLV or beyond LLDPDU size */
52771f6a85aSNeerav Parikh if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
52871f6a85aSNeerav Parikh break;
529afb3ff0dSNeerav Parikh
530afb3ff0dSNeerav Parikh switch (type) {
531afb3ff0dSNeerav Parikh case I40E_TLV_TYPE_ORG:
532afb3ff0dSNeerav Parikh i40e_parse_org_tlv(tlv, dcbcfg);
533afb3ff0dSNeerav Parikh break;
534afb3ff0dSNeerav Parikh default:
535afb3ff0dSNeerav Parikh break;
536afb3ff0dSNeerav Parikh }
537afb3ff0dSNeerav Parikh
538afb3ff0dSNeerav Parikh /* Move to next TLV */
539afb3ff0dSNeerav Parikh tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
540afb3ff0dSNeerav Parikh sizeof(tlv->typelength) +
541afb3ff0dSNeerav Parikh length);
542afb3ff0dSNeerav Parikh }
543afb3ff0dSNeerav Parikh
544afb3ff0dSNeerav Parikh return ret;
545afb3ff0dSNeerav Parikh }
546afb3ff0dSNeerav Parikh
547afb3ff0dSNeerav Parikh /**
548afb3ff0dSNeerav Parikh * i40e_aq_get_dcb_config
549afb3ff0dSNeerav Parikh * @hw: pointer to the hw struct
550afb3ff0dSNeerav Parikh * @mib_type: mib type for the query
551afb3ff0dSNeerav Parikh * @bridgetype: bridge type for the query (remote)
552afb3ff0dSNeerav Parikh * @dcbcfg: store for LLDPDU data
553afb3ff0dSNeerav Parikh *
554afb3ff0dSNeerav Parikh * Query DCB configuration from the Firmware
555afb3ff0dSNeerav Parikh **/
i40e_aq_get_dcb_config(struct i40e_hw * hw,u8 mib_type,u8 bridgetype,struct i40e_dcbx_config * dcbcfg)5565180ff13SJan Sokolowski int i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
557afb3ff0dSNeerav Parikh u8 bridgetype,
558afb3ff0dSNeerav Parikh struct i40e_dcbx_config *dcbcfg)
559afb3ff0dSNeerav Parikh {
560afb3ff0dSNeerav Parikh struct i40e_virt_mem mem;
5615180ff13SJan Sokolowski int ret = 0;
562afb3ff0dSNeerav Parikh u8 *lldpmib;
563afb3ff0dSNeerav Parikh
564afb3ff0dSNeerav Parikh /* Allocate the LLDPDU */
565afb3ff0dSNeerav Parikh ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
566afb3ff0dSNeerav Parikh if (ret)
567afb3ff0dSNeerav Parikh return ret;
568afb3ff0dSNeerav Parikh
569afb3ff0dSNeerav Parikh lldpmib = (u8 *)mem.va;
570afb3ff0dSNeerav Parikh ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
571afb3ff0dSNeerav Parikh (void *)lldpmib, I40E_LLDPDU_SIZE,
572afb3ff0dSNeerav Parikh NULL, NULL, NULL);
573afb3ff0dSNeerav Parikh if (ret)
574afb3ff0dSNeerav Parikh goto free_mem;
575afb3ff0dSNeerav Parikh
576afb3ff0dSNeerav Parikh /* Parse LLDP MIB to get dcb configuration */
577afb3ff0dSNeerav Parikh ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
578afb3ff0dSNeerav Parikh
579afb3ff0dSNeerav Parikh free_mem:
580afb3ff0dSNeerav Parikh i40e_free_virt_mem(hw, &mem);
581afb3ff0dSNeerav Parikh return ret;
582afb3ff0dSNeerav Parikh }
583afb3ff0dSNeerav Parikh
584afb3ff0dSNeerav Parikh /**
5859fa61dd2SNeerav Parikh * i40e_cee_to_dcb_v1_config
5869fa61dd2SNeerav Parikh * @cee_cfg: pointer to CEE v1 response configuration struct
5879fa61dd2SNeerav Parikh * @dcbcfg: DCB configuration struct
5889fa61dd2SNeerav Parikh *
5899fa61dd2SNeerav Parikh * Convert CEE v1 configuration from firmware to DCB configuration
5909fa61dd2SNeerav Parikh **/
i40e_cee_to_dcb_v1_config(struct i40e_aqc_get_cee_dcb_cfg_v1_resp * cee_cfg,struct i40e_dcbx_config * dcbcfg)5919fa61dd2SNeerav Parikh static void i40e_cee_to_dcb_v1_config(
5929fa61dd2SNeerav Parikh struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
5939fa61dd2SNeerav Parikh struct i40e_dcbx_config *dcbcfg)
5949fa61dd2SNeerav Parikh {
5959fa61dd2SNeerav Parikh u16 status, tlv_status = le16_to_cpu(cee_cfg->tlv_status);
5969fa61dd2SNeerav Parikh u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
5970f575bf3SJesse Brandeburg u8 i, tc, err;
5989fa61dd2SNeerav Parikh
5999fa61dd2SNeerav Parikh /* CEE PG data to ETS config */
6009fa61dd2SNeerav Parikh dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
6019fa61dd2SNeerav Parikh
60268fb13a7SGreg Bowers /* Note that the FW creates the oper_prio_tc nibbles reversed
60368fb13a7SGreg Bowers * from those in the CEE Priority Group sub-TLV.
60468fb13a7SGreg Bowers */
6059fa61dd2SNeerav Parikh for (i = 0; i < 4; i++) {
6069fa61dd2SNeerav Parikh tc = (u8)((cee_cfg->oper_prio_tc[i] &
6079fa61dd2SNeerav Parikh I40E_CEE_PGID_PRIO_0_MASK) >>
6089fa61dd2SNeerav Parikh I40E_CEE_PGID_PRIO_0_SHIFT);
60968fb13a7SGreg Bowers dcbcfg->etscfg.prioritytable[i * 2] = tc;
61068fb13a7SGreg Bowers tc = (u8)((cee_cfg->oper_prio_tc[i] &
61168fb13a7SGreg Bowers I40E_CEE_PGID_PRIO_1_MASK) >>
61268fb13a7SGreg Bowers I40E_CEE_PGID_PRIO_1_SHIFT);
6139fa61dd2SNeerav Parikh dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
6149fa61dd2SNeerav Parikh }
6159fa61dd2SNeerav Parikh
6169fa61dd2SNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
6179fa61dd2SNeerav Parikh dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
6189fa61dd2SNeerav Parikh
6199fa61dd2SNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
6209fa61dd2SNeerav Parikh if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
6219fa61dd2SNeerav Parikh /* Map it to next empty TC */
6229fa61dd2SNeerav Parikh dcbcfg->etscfg.prioritytable[i] =
6239fa61dd2SNeerav Parikh cee_cfg->oper_num_tc - 1;
6249fa61dd2SNeerav Parikh dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
6259fa61dd2SNeerav Parikh } else {
6269fa61dd2SNeerav Parikh dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
6279fa61dd2SNeerav Parikh }
6289fa61dd2SNeerav Parikh }
6299fa61dd2SNeerav Parikh
6309fa61dd2SNeerav Parikh /* CEE PFC data to ETS config */
6319fa61dd2SNeerav Parikh dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
6329fa61dd2SNeerav Parikh dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
6339fa61dd2SNeerav Parikh
6349fa61dd2SNeerav Parikh status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
6359fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_STATUS_SHIFT;
6369fa61dd2SNeerav Parikh err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
6370f575bf3SJesse Brandeburg /* Add APPs if Error is False */
6387589f65bSNeerav Parikh if (!err) {
6399fa61dd2SNeerav Parikh /* CEE operating configuration supports FCoE/iSCSI/FIP only */
6409fa61dd2SNeerav Parikh dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
6419fa61dd2SNeerav Parikh
6429fa61dd2SNeerav Parikh /* FCoE APP */
6439fa61dd2SNeerav Parikh dcbcfg->app[0].priority =
6449fa61dd2SNeerav Parikh (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
6459fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_FCOE_SHIFT;
6469fa61dd2SNeerav Parikh dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
6479fa61dd2SNeerav Parikh dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
6489fa61dd2SNeerav Parikh
6499fa61dd2SNeerav Parikh /* iSCSI APP */
6509fa61dd2SNeerav Parikh dcbcfg->app[1].priority =
6519fa61dd2SNeerav Parikh (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
6529fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_ISCSI_SHIFT;
6539fa61dd2SNeerav Parikh dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
6549fa61dd2SNeerav Parikh dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
6559fa61dd2SNeerav Parikh
6569fa61dd2SNeerav Parikh /* FIP APP */
6579fa61dd2SNeerav Parikh dcbcfg->app[2].priority =
6589fa61dd2SNeerav Parikh (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
6599fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_FIP_SHIFT;
6609fa61dd2SNeerav Parikh dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
6619fa61dd2SNeerav Parikh dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
6629fa61dd2SNeerav Parikh }
6639fa61dd2SNeerav Parikh }
6649fa61dd2SNeerav Parikh
6659fa61dd2SNeerav Parikh /**
6669fa61dd2SNeerav Parikh * i40e_cee_to_dcb_config
6679fa61dd2SNeerav Parikh * @cee_cfg: pointer to CEE configuration struct
6689fa61dd2SNeerav Parikh * @dcbcfg: DCB configuration struct
6699fa61dd2SNeerav Parikh *
6709fa61dd2SNeerav Parikh * Convert CEE configuration from firmware to DCB configuration
6719fa61dd2SNeerav Parikh **/
i40e_cee_to_dcb_config(struct i40e_aqc_get_cee_dcb_cfg_resp * cee_cfg,struct i40e_dcbx_config * dcbcfg)6729fa61dd2SNeerav Parikh static void i40e_cee_to_dcb_config(
6739fa61dd2SNeerav Parikh struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
6749fa61dd2SNeerav Parikh struct i40e_dcbx_config *dcbcfg)
6759fa61dd2SNeerav Parikh {
6769fa61dd2SNeerav Parikh u32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status);
6779fa61dd2SNeerav Parikh u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
6789fa61dd2SNeerav Parikh u8 i, tc, err, sync, oper;
6799fa61dd2SNeerav Parikh
6809fa61dd2SNeerav Parikh /* CEE PG data to ETS config */
6819fa61dd2SNeerav Parikh dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
6829fa61dd2SNeerav Parikh
68395e5613fSGreg Bowers /* Note that the FW creates the oper_prio_tc nibbles reversed
68495e5613fSGreg Bowers * from those in the CEE Priority Group sub-TLV.
68595e5613fSGreg Bowers */
6869fa61dd2SNeerav Parikh for (i = 0; i < 4; i++) {
6879fa61dd2SNeerav Parikh tc = (u8)((cee_cfg->oper_prio_tc[i] &
6889fa61dd2SNeerav Parikh I40E_CEE_PGID_PRIO_0_MASK) >>
6899fa61dd2SNeerav Parikh I40E_CEE_PGID_PRIO_0_SHIFT);
69095e5613fSGreg Bowers dcbcfg->etscfg.prioritytable[i * 2] = tc;
69195e5613fSGreg Bowers tc = (u8)((cee_cfg->oper_prio_tc[i] &
69295e5613fSGreg Bowers I40E_CEE_PGID_PRIO_1_MASK) >>
69395e5613fSGreg Bowers I40E_CEE_PGID_PRIO_1_SHIFT);
6949fa61dd2SNeerav Parikh dcbcfg->etscfg.prioritytable[i * 2 + 1] = tc;
6959fa61dd2SNeerav Parikh }
6969fa61dd2SNeerav Parikh
6979fa61dd2SNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
6989fa61dd2SNeerav Parikh dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
6999fa61dd2SNeerav Parikh
7009fa61dd2SNeerav Parikh for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
7019fa61dd2SNeerav Parikh if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
7029fa61dd2SNeerav Parikh /* Map it to next empty TC */
7039fa61dd2SNeerav Parikh dcbcfg->etscfg.prioritytable[i] =
7049fa61dd2SNeerav Parikh cee_cfg->oper_num_tc - 1;
7059fa61dd2SNeerav Parikh dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
7069fa61dd2SNeerav Parikh } else {
7079fa61dd2SNeerav Parikh dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
7089fa61dd2SNeerav Parikh }
7099fa61dd2SNeerav Parikh }
7109fa61dd2SNeerav Parikh
7119fa61dd2SNeerav Parikh /* CEE PFC data to ETS config */
7129fa61dd2SNeerav Parikh dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
7139fa61dd2SNeerav Parikh dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
7149fa61dd2SNeerav Parikh
7152642f025SNeerav Parikh i = 0;
7162642f025SNeerav Parikh status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
7172642f025SNeerav Parikh I40E_AQC_CEE_FCOE_STATUS_SHIFT;
7189fa61dd2SNeerav Parikh err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
7199fa61dd2SNeerav Parikh sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
7209fa61dd2SNeerav Parikh oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
7212642f025SNeerav Parikh /* Add FCoE APP if Error is False and Oper/Sync is True */
7229fa61dd2SNeerav Parikh if (!err && sync && oper) {
7239fa61dd2SNeerav Parikh /* FCoE APP */
7242642f025SNeerav Parikh dcbcfg->app[i].priority =
7259fa61dd2SNeerav Parikh (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
7269fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_FCOE_SHIFT;
7272642f025SNeerav Parikh dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
7282642f025SNeerav Parikh dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
7292642f025SNeerav Parikh i++;
7302642f025SNeerav Parikh }
7319fa61dd2SNeerav Parikh
7322642f025SNeerav Parikh status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
7332642f025SNeerav Parikh I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
7342642f025SNeerav Parikh err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
7352642f025SNeerav Parikh sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
7362642f025SNeerav Parikh oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
7372642f025SNeerav Parikh /* Add iSCSI APP if Error is False and Oper/Sync is True */
7382642f025SNeerav Parikh if (!err && sync && oper) {
7399fa61dd2SNeerav Parikh /* iSCSI APP */
7402642f025SNeerav Parikh dcbcfg->app[i].priority =
7419fa61dd2SNeerav Parikh (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
7429fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_ISCSI_SHIFT;
7432642f025SNeerav Parikh dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
7442642f025SNeerav Parikh dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
7452642f025SNeerav Parikh i++;
7462642f025SNeerav Parikh }
7479fa61dd2SNeerav Parikh
7482642f025SNeerav Parikh status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
7492642f025SNeerav Parikh I40E_AQC_CEE_FIP_STATUS_SHIFT;
7502642f025SNeerav Parikh err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
7512642f025SNeerav Parikh sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
7522642f025SNeerav Parikh oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
7532642f025SNeerav Parikh /* Add FIP APP if Error is False and Oper/Sync is True */
7542642f025SNeerav Parikh if (!err && sync && oper) {
7559fa61dd2SNeerav Parikh /* FIP APP */
7562642f025SNeerav Parikh dcbcfg->app[i].priority =
7579fa61dd2SNeerav Parikh (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
7589fa61dd2SNeerav Parikh I40E_AQC_CEE_APP_FIP_SHIFT;
7592642f025SNeerav Parikh dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
7602642f025SNeerav Parikh dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
7612642f025SNeerav Parikh i++;
7629fa61dd2SNeerav Parikh }
7632642f025SNeerav Parikh dcbcfg->numapps = i;
7649fa61dd2SNeerav Parikh }
7659fa61dd2SNeerav Parikh
7669fa61dd2SNeerav Parikh /**
7671a9375ebSNeerav Parikh * i40e_get_ieee_dcb_config
7681a9375ebSNeerav Parikh * @hw: pointer to the hw struct
7691a9375ebSNeerav Parikh *
7701a9375ebSNeerav Parikh * Get IEEE mode DCB configuration from the Firmware
7711a9375ebSNeerav Parikh **/
i40e_get_ieee_dcb_config(struct i40e_hw * hw)7725180ff13SJan Sokolowski static int i40e_get_ieee_dcb_config(struct i40e_hw *hw)
7731a9375ebSNeerav Parikh {
7745180ff13SJan Sokolowski int ret = 0;
7751a9375ebSNeerav Parikh
7761a9375ebSNeerav Parikh /* IEEE mode */
7771a9375ebSNeerav Parikh hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
7781a9375ebSNeerav Parikh /* Get Local DCB Config */
7791a9375ebSNeerav Parikh ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
7801a9375ebSNeerav Parikh &hw->local_dcbx_config);
7811a9375ebSNeerav Parikh if (ret)
7821a9375ebSNeerav Parikh goto out;
7831a9375ebSNeerav Parikh
7841a9375ebSNeerav Parikh /* Get Remote DCB Config */
7851a9375ebSNeerav Parikh ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
7861a9375ebSNeerav Parikh I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
7871a9375ebSNeerav Parikh &hw->remote_dcbx_config);
7881a9375ebSNeerav Parikh /* Don't treat ENOENT as an error for Remote MIBs */
7891a9375ebSNeerav Parikh if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
7901a9375ebSNeerav Parikh ret = 0;
7911a9375ebSNeerav Parikh
7921a9375ebSNeerav Parikh out:
7931a9375ebSNeerav Parikh return ret;
7941a9375ebSNeerav Parikh }
7951a9375ebSNeerav Parikh
7961a9375ebSNeerav Parikh /**
797afb3ff0dSNeerav Parikh * i40e_get_dcb_config
798afb3ff0dSNeerav Parikh * @hw: pointer to the hw struct
799afb3ff0dSNeerav Parikh *
800afb3ff0dSNeerav Parikh * Get DCB configuration from the Firmware
801afb3ff0dSNeerav Parikh **/
i40e_get_dcb_config(struct i40e_hw * hw)8025180ff13SJan Sokolowski int i40e_get_dcb_config(struct i40e_hw *hw)
803afb3ff0dSNeerav Parikh {
8049fa61dd2SNeerav Parikh struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
8055180ff13SJan Sokolowski struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
8065180ff13SJan Sokolowski int ret = 0;
807afb3ff0dSNeerav Parikh
8086dfae389SGreg Bowers /* If Firmware version < v4.33 on X710/XL710, IEEE only */
8096dfae389SGreg Bowers if ((hw->mac.type == I40E_MAC_XL710) &&
8106dfae389SGreg Bowers (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
8116dfae389SGreg Bowers (hw->aq.fw_maj_ver < 4)))
8121a9375ebSNeerav Parikh return i40e_get_ieee_dcb_config(hw);
8139fa61dd2SNeerav Parikh
8146dfae389SGreg Bowers /* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
8156dfae389SGreg Bowers if ((hw->mac.type == I40E_MAC_XL710) &&
8166dfae389SGreg Bowers ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
8179fa61dd2SNeerav Parikh ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
8189fa61dd2SNeerav Parikh sizeof(cee_v1_cfg), NULL);
8199fa61dd2SNeerav Parikh if (!ret) {
8209fa61dd2SNeerav Parikh /* CEE mode */
8219fa61dd2SNeerav Parikh hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
8229fffa3f3SNeerav Parikh hw->local_dcbx_config.tlv_status =
8239fffa3f3SNeerav Parikh le16_to_cpu(cee_v1_cfg.tlv_status);
8249fa61dd2SNeerav Parikh i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
8259fa61dd2SNeerav Parikh &hw->local_dcbx_config);
8269fa61dd2SNeerav Parikh }
8279fa61dd2SNeerav Parikh } else {
8289fa61dd2SNeerav Parikh ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
8299fa61dd2SNeerav Parikh sizeof(cee_cfg), NULL);
8309fa61dd2SNeerav Parikh if (!ret) {
8319fa61dd2SNeerav Parikh /* CEE mode */
8329fa61dd2SNeerav Parikh hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
8339fffa3f3SNeerav Parikh hw->local_dcbx_config.tlv_status =
8349fffa3f3SNeerav Parikh le32_to_cpu(cee_cfg.tlv_status);
8359fa61dd2SNeerav Parikh i40e_cee_to_dcb_config(&cee_cfg,
8369fa61dd2SNeerav Parikh &hw->local_dcbx_config);
8379fa61dd2SNeerav Parikh }
8389fa61dd2SNeerav Parikh }
8399fa61dd2SNeerav Parikh
8409fa61dd2SNeerav Parikh /* CEE mode not enabled try querying IEEE data */
8419fa61dd2SNeerav Parikh if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
8421a9375ebSNeerav Parikh return i40e_get_ieee_dcb_config(hw);
8431a9375ebSNeerav Parikh
8441a9375ebSNeerav Parikh if (ret)
8459fa61dd2SNeerav Parikh goto out;
8469fa61dd2SNeerav Parikh
8471a9375ebSNeerav Parikh /* Get CEE DCB Desired Config */
848afb3ff0dSNeerav Parikh ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
8491a9375ebSNeerav Parikh &hw->desired_dcbx_config);
850afb3ff0dSNeerav Parikh if (ret)
851afb3ff0dSNeerav Parikh goto out;
852afb3ff0dSNeerav Parikh
853afb3ff0dSNeerav Parikh /* Get Remote DCB Config */
854afb3ff0dSNeerav Parikh ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
855afb3ff0dSNeerav Parikh I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
856afb3ff0dSNeerav Parikh &hw->remote_dcbx_config);
8579fa61dd2SNeerav Parikh /* Don't treat ENOENT as an error for Remote MIBs */
8589fa61dd2SNeerav Parikh if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
8599fa61dd2SNeerav Parikh ret = 0;
8609fa61dd2SNeerav Parikh
861afb3ff0dSNeerav Parikh out:
862afb3ff0dSNeerav Parikh return ret;
863afb3ff0dSNeerav Parikh }
864afb3ff0dSNeerav Parikh
865afb3ff0dSNeerav Parikh /**
866afb3ff0dSNeerav Parikh * i40e_init_dcb
867afb3ff0dSNeerav Parikh * @hw: pointer to the hw struct
86854dea0e7SChinh T Cao * @enable_mib_change: enable mib change event
869afb3ff0dSNeerav Parikh *
870afb3ff0dSNeerav Parikh * Update DCB configuration from the Firmware
871afb3ff0dSNeerav Parikh **/
i40e_init_dcb(struct i40e_hw * hw,bool enable_mib_change)8725180ff13SJan Sokolowski int i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
873afb3ff0dSNeerav Parikh {
874e1c4751eSNeerav Parikh struct i40e_lldp_variables lldp_cfg;
875e1c4751eSNeerav Parikh u8 adminstatus = 0;
8765180ff13SJan Sokolowski int ret = 0;
877afb3ff0dSNeerav Parikh
878afb3ff0dSNeerav Parikh if (!hw->func_caps.dcb)
879230f3d53SJan Sokolowski return -EOPNOTSUPP;
880afb3ff0dSNeerav Parikh
881e1c4751eSNeerav Parikh /* Read LLDP NVM area */
88265c275e4SSylwia Wnuczko if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) {
88365c275e4SSylwia Wnuczko u8 offset = 0;
88465c275e4SSylwia Wnuczko
88565c275e4SSylwia Wnuczko if (hw->mac.type == I40E_MAC_XL710)
88665c275e4SSylwia Wnuczko offset = I40E_LLDP_CURRENT_STATUS_XL710_OFFSET;
88765c275e4SSylwia Wnuczko else if (hw->mac.type == I40E_MAC_X722)
88865c275e4SSylwia Wnuczko offset = I40E_LLDP_CURRENT_STATUS_X722_OFFSET;
88965c275e4SSylwia Wnuczko else
890230f3d53SJan Sokolowski return -EOPNOTSUPP;
89165c275e4SSylwia Wnuczko
89265c275e4SSylwia Wnuczko ret = i40e_read_nvm_module_data(hw,
89365c275e4SSylwia Wnuczko I40E_SR_EMP_SR_SETTINGS_PTR,
894ff924657SSylwia Wnuczko offset,
895ff924657SSylwia Wnuczko I40E_LLDP_CURRENT_STATUS_OFFSET,
896ff924657SSylwia Wnuczko I40E_LLDP_CURRENT_STATUS_SIZE,
89765c275e4SSylwia Wnuczko &lldp_cfg.adminstatus);
89865c275e4SSylwia Wnuczko } else {
899e1c4751eSNeerav Parikh ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
90065c275e4SSylwia Wnuczko }
901e1c4751eSNeerav Parikh if (ret)
902230f3d53SJan Sokolowski return -EBUSY;
903e1c4751eSNeerav Parikh
904e1c4751eSNeerav Parikh /* Get the LLDP AdminStatus for the current port */
905e1c4751eSNeerav Parikh adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
906e1c4751eSNeerav Parikh adminstatus &= 0xF;
907e1c4751eSNeerav Parikh
908e1c4751eSNeerav Parikh /* LLDP agent disabled */
909e1c4751eSNeerav Parikh if (!adminstatus) {
910e1c4751eSNeerav Parikh hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
911230f3d53SJan Sokolowski return -EBUSY;
912e1c4751eSNeerav Parikh }
913e1c4751eSNeerav Parikh
914afb3ff0dSNeerav Parikh /* Get DCBX status */
915afb3ff0dSNeerav Parikh ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
916afb3ff0dSNeerav Parikh if (ret)
917afb3ff0dSNeerav Parikh return ret;
918afb3ff0dSNeerav Parikh
919afb3ff0dSNeerav Parikh /* Check the DCBX Status */
92054dea0e7SChinh T Cao if (hw->dcbx_status == I40E_DCBX_STATUS_DONE ||
92154dea0e7SChinh T Cao hw->dcbx_status == I40E_DCBX_STATUS_IN_PROGRESS) {
922afb3ff0dSNeerav Parikh /* Get current DCBX configuration */
923afb3ff0dSNeerav Parikh ret = i40e_get_dcb_config(hw);
924e1c4751eSNeerav Parikh if (ret)
925e1c4751eSNeerav Parikh return ret;
92654dea0e7SChinh T Cao } else if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) {
927230f3d53SJan Sokolowski return -EBUSY;
928afb3ff0dSNeerav Parikh }
929afb3ff0dSNeerav Parikh
930afb3ff0dSNeerav Parikh /* Configure the LLDP MIB change event */
93154dea0e7SChinh T Cao if (enable_mib_change)
932afb3ff0dSNeerav Parikh ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
933afb3ff0dSNeerav Parikh
934afb3ff0dSNeerav Parikh return ret;
935afb3ff0dSNeerav Parikh }
936e1c4751eSNeerav Parikh
937e1c4751eSNeerav Parikh /**
93890bc8e00SArkadiusz Kubalewski * i40e_get_fw_lldp_status
93990bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
94090bc8e00SArkadiusz Kubalewski * @lldp_status: pointer to the status enum
94190bc8e00SArkadiusz Kubalewski *
94290bc8e00SArkadiusz Kubalewski * Get status of FW Link Layer Discovery Protocol (LLDP) Agent.
94390bc8e00SArkadiusz Kubalewski * Status of agent is reported via @lldp_status parameter.
94490bc8e00SArkadiusz Kubalewski **/
9455180ff13SJan Sokolowski int
i40e_get_fw_lldp_status(struct i40e_hw * hw,enum i40e_get_fw_lldp_status_resp * lldp_status)94690bc8e00SArkadiusz Kubalewski i40e_get_fw_lldp_status(struct i40e_hw *hw,
94790bc8e00SArkadiusz Kubalewski enum i40e_get_fw_lldp_status_resp *lldp_status)
94890bc8e00SArkadiusz Kubalewski {
94990bc8e00SArkadiusz Kubalewski struct i40e_virt_mem mem;
95090bc8e00SArkadiusz Kubalewski u8 *lldpmib;
9515180ff13SJan Sokolowski int ret;
95290bc8e00SArkadiusz Kubalewski
95390bc8e00SArkadiusz Kubalewski if (!lldp_status)
954230f3d53SJan Sokolowski return -EINVAL;
95590bc8e00SArkadiusz Kubalewski
95690bc8e00SArkadiusz Kubalewski /* Allocate buffer for the LLDPDU */
95790bc8e00SArkadiusz Kubalewski ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
95890bc8e00SArkadiusz Kubalewski if (ret)
95990bc8e00SArkadiusz Kubalewski return ret;
96090bc8e00SArkadiusz Kubalewski
96190bc8e00SArkadiusz Kubalewski lldpmib = (u8 *)mem.va;
96290bc8e00SArkadiusz Kubalewski ret = i40e_aq_get_lldp_mib(hw, 0, 0, (void *)lldpmib,
96390bc8e00SArkadiusz Kubalewski I40E_LLDPDU_SIZE, NULL, NULL, NULL);
96490bc8e00SArkadiusz Kubalewski
96590bc8e00SArkadiusz Kubalewski if (!ret) {
96690bc8e00SArkadiusz Kubalewski *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED;
96790bc8e00SArkadiusz Kubalewski } else if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT) {
96890bc8e00SArkadiusz Kubalewski /* MIB is not available yet but the agent is running */
96990bc8e00SArkadiusz Kubalewski *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED;
97090bc8e00SArkadiusz Kubalewski ret = 0;
97190bc8e00SArkadiusz Kubalewski } else if (hw->aq.asq_last_status == I40E_AQ_RC_EPERM) {
97290bc8e00SArkadiusz Kubalewski *lldp_status = I40E_GET_FW_LLDP_STATUS_DISABLED;
97390bc8e00SArkadiusz Kubalewski ret = 0;
97490bc8e00SArkadiusz Kubalewski }
97590bc8e00SArkadiusz Kubalewski
97690bc8e00SArkadiusz Kubalewski i40e_free_virt_mem(hw, &mem);
97790bc8e00SArkadiusz Kubalewski return ret;
97890bc8e00SArkadiusz Kubalewski }
97990bc8e00SArkadiusz Kubalewski
98090bc8e00SArkadiusz Kubalewski /**
98190bc8e00SArkadiusz Kubalewski * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
98290bc8e00SArkadiusz Kubalewski * @tlv: Fill the ETS config data in IEEE format
98390bc8e00SArkadiusz Kubalewski * @dcbcfg: Local store which holds the DCB Config
98490bc8e00SArkadiusz Kubalewski *
98590bc8e00SArkadiusz Kubalewski * Prepare IEEE 802.1Qaz ETS CFG TLV
98690bc8e00SArkadiusz Kubalewski **/
i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)98790bc8e00SArkadiusz Kubalewski static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
98890bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg)
98990bc8e00SArkadiusz Kubalewski {
99090bc8e00SArkadiusz Kubalewski u8 priority0, priority1, maxtcwilling = 0;
99190bc8e00SArkadiusz Kubalewski struct i40e_dcb_ets_config *etscfg;
99290bc8e00SArkadiusz Kubalewski u16 offset = 0, typelength, i;
99390bc8e00SArkadiusz Kubalewski u8 *buf = tlv->tlvinfo;
99490bc8e00SArkadiusz Kubalewski u32 ouisubtype;
99590bc8e00SArkadiusz Kubalewski
99690bc8e00SArkadiusz Kubalewski typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
99790bc8e00SArkadiusz Kubalewski I40E_IEEE_ETS_TLV_LENGTH);
99890bc8e00SArkadiusz Kubalewski tlv->typelength = htons(typelength);
99990bc8e00SArkadiusz Kubalewski
100090bc8e00SArkadiusz Kubalewski ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
100190bc8e00SArkadiusz Kubalewski I40E_IEEE_SUBTYPE_ETS_CFG);
100290bc8e00SArkadiusz Kubalewski tlv->ouisubtype = htonl(ouisubtype);
100390bc8e00SArkadiusz Kubalewski
100490bc8e00SArkadiusz Kubalewski /* First Octet post subtype
100590bc8e00SArkadiusz Kubalewski * --------------------------
100690bc8e00SArkadiusz Kubalewski * |will-|CBS | Re- | Max |
100790bc8e00SArkadiusz Kubalewski * |ing | |served| TCs |
100890bc8e00SArkadiusz Kubalewski * --------------------------
100990bc8e00SArkadiusz Kubalewski * |1bit | 1bit|3 bits|3bits|
101090bc8e00SArkadiusz Kubalewski */
101190bc8e00SArkadiusz Kubalewski etscfg = &dcbcfg->etscfg;
101290bc8e00SArkadiusz Kubalewski if (etscfg->willing)
101390bc8e00SArkadiusz Kubalewski maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
101490bc8e00SArkadiusz Kubalewski maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
101590bc8e00SArkadiusz Kubalewski buf[offset] = maxtcwilling;
101690bc8e00SArkadiusz Kubalewski
101790bc8e00SArkadiusz Kubalewski /* Move offset to Priority Assignment Table */
101890bc8e00SArkadiusz Kubalewski offset++;
101990bc8e00SArkadiusz Kubalewski
102090bc8e00SArkadiusz Kubalewski /* Priority Assignment Table (4 octets)
102190bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 | 4 |
102290bc8e00SArkadiusz Kubalewski * -----------------------------------------
102390bc8e00SArkadiusz Kubalewski * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
102490bc8e00SArkadiusz Kubalewski * -----------------------------------------
102590bc8e00SArkadiusz Kubalewski * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
102690bc8e00SArkadiusz Kubalewski * -----------------------------------------
102790bc8e00SArkadiusz Kubalewski */
102890bc8e00SArkadiusz Kubalewski for (i = 0; i < 4; i++) {
102990bc8e00SArkadiusz Kubalewski priority0 = etscfg->prioritytable[i * 2] & 0xF;
103090bc8e00SArkadiusz Kubalewski priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
103190bc8e00SArkadiusz Kubalewski buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
103290bc8e00SArkadiusz Kubalewski priority1;
103390bc8e00SArkadiusz Kubalewski offset++;
103490bc8e00SArkadiusz Kubalewski }
103590bc8e00SArkadiusz Kubalewski
103690bc8e00SArkadiusz Kubalewski /* TC Bandwidth Table (8 octets)
103790bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
103890bc8e00SArkadiusz Kubalewski * ---------------------------------
103990bc8e00SArkadiusz Kubalewski * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
104090bc8e00SArkadiusz Kubalewski * ---------------------------------
104190bc8e00SArkadiusz Kubalewski */
104290bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
104390bc8e00SArkadiusz Kubalewski buf[offset++] = etscfg->tcbwtable[i];
104490bc8e00SArkadiusz Kubalewski
104590bc8e00SArkadiusz Kubalewski /* TSA Assignment Table (8 octets)
104690bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
104790bc8e00SArkadiusz Kubalewski * ---------------------------------
104890bc8e00SArkadiusz Kubalewski * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
104990bc8e00SArkadiusz Kubalewski * ---------------------------------
105090bc8e00SArkadiusz Kubalewski */
105190bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
105290bc8e00SArkadiusz Kubalewski buf[offset++] = etscfg->tsatable[i];
105390bc8e00SArkadiusz Kubalewski }
105490bc8e00SArkadiusz Kubalewski
105590bc8e00SArkadiusz Kubalewski /**
105690bc8e00SArkadiusz Kubalewski * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
105790bc8e00SArkadiusz Kubalewski * @tlv: Fill ETS Recommended TLV in IEEE format
105890bc8e00SArkadiusz Kubalewski * @dcbcfg: Local store which holds the DCB Config
105990bc8e00SArkadiusz Kubalewski *
106090bc8e00SArkadiusz Kubalewski * Prepare IEEE 802.1Qaz ETS REC TLV
106190bc8e00SArkadiusz Kubalewski **/
i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)106290bc8e00SArkadiusz Kubalewski static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
106390bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg)
106490bc8e00SArkadiusz Kubalewski {
106590bc8e00SArkadiusz Kubalewski struct i40e_dcb_ets_config *etsrec;
106690bc8e00SArkadiusz Kubalewski u16 offset = 0, typelength, i;
106790bc8e00SArkadiusz Kubalewski u8 priority0, priority1;
106890bc8e00SArkadiusz Kubalewski u8 *buf = tlv->tlvinfo;
106990bc8e00SArkadiusz Kubalewski u32 ouisubtype;
107090bc8e00SArkadiusz Kubalewski
107190bc8e00SArkadiusz Kubalewski typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
107290bc8e00SArkadiusz Kubalewski I40E_IEEE_ETS_TLV_LENGTH);
107390bc8e00SArkadiusz Kubalewski tlv->typelength = htons(typelength);
107490bc8e00SArkadiusz Kubalewski
107590bc8e00SArkadiusz Kubalewski ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
107690bc8e00SArkadiusz Kubalewski I40E_IEEE_SUBTYPE_ETS_REC);
107790bc8e00SArkadiusz Kubalewski tlv->ouisubtype = htonl(ouisubtype);
107890bc8e00SArkadiusz Kubalewski
107990bc8e00SArkadiusz Kubalewski etsrec = &dcbcfg->etsrec;
108090bc8e00SArkadiusz Kubalewski /* First Octet is reserved */
108190bc8e00SArkadiusz Kubalewski /* Move offset to Priority Assignment Table */
108290bc8e00SArkadiusz Kubalewski offset++;
108390bc8e00SArkadiusz Kubalewski
108490bc8e00SArkadiusz Kubalewski /* Priority Assignment Table (4 octets)
108590bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 | 4 |
108690bc8e00SArkadiusz Kubalewski * -----------------------------------------
108790bc8e00SArkadiusz Kubalewski * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
108890bc8e00SArkadiusz Kubalewski * -----------------------------------------
108990bc8e00SArkadiusz Kubalewski * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
109090bc8e00SArkadiusz Kubalewski * -----------------------------------------
109190bc8e00SArkadiusz Kubalewski */
109290bc8e00SArkadiusz Kubalewski for (i = 0; i < 4; i++) {
109390bc8e00SArkadiusz Kubalewski priority0 = etsrec->prioritytable[i * 2] & 0xF;
109490bc8e00SArkadiusz Kubalewski priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
109590bc8e00SArkadiusz Kubalewski buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
109690bc8e00SArkadiusz Kubalewski priority1;
109790bc8e00SArkadiusz Kubalewski offset++;
109890bc8e00SArkadiusz Kubalewski }
109990bc8e00SArkadiusz Kubalewski
110090bc8e00SArkadiusz Kubalewski /* TC Bandwidth Table (8 octets)
110190bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
110290bc8e00SArkadiusz Kubalewski * ---------------------------------
110390bc8e00SArkadiusz Kubalewski * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
110490bc8e00SArkadiusz Kubalewski * ---------------------------------
110590bc8e00SArkadiusz Kubalewski */
110690bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
110790bc8e00SArkadiusz Kubalewski buf[offset++] = etsrec->tcbwtable[i];
110890bc8e00SArkadiusz Kubalewski
110990bc8e00SArkadiusz Kubalewski /* TSA Assignment Table (8 octets)
111090bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
111190bc8e00SArkadiusz Kubalewski * ---------------------------------
111290bc8e00SArkadiusz Kubalewski * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
111390bc8e00SArkadiusz Kubalewski * ---------------------------------
111490bc8e00SArkadiusz Kubalewski */
111590bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
111690bc8e00SArkadiusz Kubalewski buf[offset++] = etsrec->tsatable[i];
111790bc8e00SArkadiusz Kubalewski }
111890bc8e00SArkadiusz Kubalewski
111990bc8e00SArkadiusz Kubalewski /**
112090bc8e00SArkadiusz Kubalewski * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
112190bc8e00SArkadiusz Kubalewski * @tlv: Fill PFC TLV in IEEE format
112290bc8e00SArkadiusz Kubalewski * @dcbcfg: Local store to get PFC CFG data
112390bc8e00SArkadiusz Kubalewski *
112490bc8e00SArkadiusz Kubalewski * Prepare IEEE 802.1Qaz PFC CFG TLV
112590bc8e00SArkadiusz Kubalewski **/
i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)112690bc8e00SArkadiusz Kubalewski static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
112790bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg)
112890bc8e00SArkadiusz Kubalewski {
112990bc8e00SArkadiusz Kubalewski u8 *buf = tlv->tlvinfo;
113090bc8e00SArkadiusz Kubalewski u32 ouisubtype;
113190bc8e00SArkadiusz Kubalewski u16 typelength;
113290bc8e00SArkadiusz Kubalewski
113390bc8e00SArkadiusz Kubalewski typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
113490bc8e00SArkadiusz Kubalewski I40E_IEEE_PFC_TLV_LENGTH);
113590bc8e00SArkadiusz Kubalewski tlv->typelength = htons(typelength);
113690bc8e00SArkadiusz Kubalewski
113790bc8e00SArkadiusz Kubalewski ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
113890bc8e00SArkadiusz Kubalewski I40E_IEEE_SUBTYPE_PFC_CFG);
113990bc8e00SArkadiusz Kubalewski tlv->ouisubtype = htonl(ouisubtype);
114090bc8e00SArkadiusz Kubalewski
114190bc8e00SArkadiusz Kubalewski /* ----------------------------------------
114290bc8e00SArkadiusz Kubalewski * |will-|MBC | Re- | PFC | PFC Enable |
114390bc8e00SArkadiusz Kubalewski * |ing | |served| cap | |
114490bc8e00SArkadiusz Kubalewski * -----------------------------------------
114590bc8e00SArkadiusz Kubalewski * |1bit | 1bit|2 bits|4bits| 1 octet |
114690bc8e00SArkadiusz Kubalewski */
114790bc8e00SArkadiusz Kubalewski if (dcbcfg->pfc.willing)
114890bc8e00SArkadiusz Kubalewski buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
114990bc8e00SArkadiusz Kubalewski
115090bc8e00SArkadiusz Kubalewski if (dcbcfg->pfc.mbc)
115190bc8e00SArkadiusz Kubalewski buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
115290bc8e00SArkadiusz Kubalewski
115390bc8e00SArkadiusz Kubalewski buf[0] |= dcbcfg->pfc.pfccap & 0xF;
115490bc8e00SArkadiusz Kubalewski buf[1] = dcbcfg->pfc.pfcenable;
115590bc8e00SArkadiusz Kubalewski }
115690bc8e00SArkadiusz Kubalewski
115790bc8e00SArkadiusz Kubalewski /**
115890bc8e00SArkadiusz Kubalewski * i40e_add_ieee_app_pri_tlv - Prepare APP TLV in IEEE format
115990bc8e00SArkadiusz Kubalewski * @tlv: Fill APP TLV in IEEE format
116090bc8e00SArkadiusz Kubalewski * @dcbcfg: Local store to get APP CFG data
116190bc8e00SArkadiusz Kubalewski *
116290bc8e00SArkadiusz Kubalewski * Prepare IEEE 802.1Qaz APP CFG TLV
116390bc8e00SArkadiusz Kubalewski **/
i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg)116490bc8e00SArkadiusz Kubalewski static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
116590bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg)
116690bc8e00SArkadiusz Kubalewski {
116790bc8e00SArkadiusz Kubalewski u16 typelength, length, offset = 0;
116890bc8e00SArkadiusz Kubalewski u8 priority, selector, i = 0;
116990bc8e00SArkadiusz Kubalewski u8 *buf = tlv->tlvinfo;
117090bc8e00SArkadiusz Kubalewski u32 ouisubtype;
117190bc8e00SArkadiusz Kubalewski
117290bc8e00SArkadiusz Kubalewski /* No APP TLVs then just return */
117390bc8e00SArkadiusz Kubalewski if (dcbcfg->numapps == 0)
117490bc8e00SArkadiusz Kubalewski return;
117590bc8e00SArkadiusz Kubalewski ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
117690bc8e00SArkadiusz Kubalewski I40E_IEEE_SUBTYPE_APP_PRI);
117790bc8e00SArkadiusz Kubalewski tlv->ouisubtype = htonl(ouisubtype);
117890bc8e00SArkadiusz Kubalewski
117990bc8e00SArkadiusz Kubalewski /* Move offset to App Priority Table */
118090bc8e00SArkadiusz Kubalewski offset++;
118190bc8e00SArkadiusz Kubalewski /* Application Priority Table (3 octets)
118290bc8e00SArkadiusz Kubalewski * Octets:| 1 | 2 | 3 |
118390bc8e00SArkadiusz Kubalewski * -----------------------------------------
118490bc8e00SArkadiusz Kubalewski * |Priority|Rsrvd| Sel | Protocol ID |
118590bc8e00SArkadiusz Kubalewski * -----------------------------------------
118690bc8e00SArkadiusz Kubalewski * Bits:|23 21|20 19|18 16|15 0|
118790bc8e00SArkadiusz Kubalewski * -----------------------------------------
118890bc8e00SArkadiusz Kubalewski */
118990bc8e00SArkadiusz Kubalewski while (i < dcbcfg->numapps) {
119090bc8e00SArkadiusz Kubalewski priority = dcbcfg->app[i].priority & 0x7;
119190bc8e00SArkadiusz Kubalewski selector = dcbcfg->app[i].selector & 0x7;
119290bc8e00SArkadiusz Kubalewski buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
119390bc8e00SArkadiusz Kubalewski buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
119490bc8e00SArkadiusz Kubalewski buf[offset + 2] = dcbcfg->app[i].protocolid & 0xFF;
119590bc8e00SArkadiusz Kubalewski /* Move to next app */
119690bc8e00SArkadiusz Kubalewski offset += 3;
119790bc8e00SArkadiusz Kubalewski i++;
119890bc8e00SArkadiusz Kubalewski if (i >= I40E_DCBX_MAX_APPS)
119990bc8e00SArkadiusz Kubalewski break;
120090bc8e00SArkadiusz Kubalewski }
120190bc8e00SArkadiusz Kubalewski /* length includes size of ouisubtype + 1 reserved + 3*numapps */
120290bc8e00SArkadiusz Kubalewski length = sizeof(tlv->ouisubtype) + 1 + (i * 3);
120390bc8e00SArkadiusz Kubalewski typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
120490bc8e00SArkadiusz Kubalewski (length & 0x1FF));
120590bc8e00SArkadiusz Kubalewski tlv->typelength = htons(typelength);
120690bc8e00SArkadiusz Kubalewski }
120790bc8e00SArkadiusz Kubalewski
120890bc8e00SArkadiusz Kubalewski /**
120990bc8e00SArkadiusz Kubalewski * i40e_add_dcb_tlv - Add all IEEE TLVs
121090bc8e00SArkadiusz Kubalewski * @tlv: pointer to org tlv
121190bc8e00SArkadiusz Kubalewski * @dcbcfg: pointer to modified dcbx config structure *
121290bc8e00SArkadiusz Kubalewski * @tlvid: tlv id to be added
121390bc8e00SArkadiusz Kubalewski * add tlv information
121490bc8e00SArkadiusz Kubalewski **/
i40e_add_dcb_tlv(struct i40e_lldp_org_tlv * tlv,struct i40e_dcbx_config * dcbcfg,u16 tlvid)121590bc8e00SArkadiusz Kubalewski static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
121690bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg,
121790bc8e00SArkadiusz Kubalewski u16 tlvid)
121890bc8e00SArkadiusz Kubalewski {
121990bc8e00SArkadiusz Kubalewski switch (tlvid) {
122090bc8e00SArkadiusz Kubalewski case I40E_IEEE_TLV_ID_ETS_CFG:
122190bc8e00SArkadiusz Kubalewski i40e_add_ieee_ets_tlv(tlv, dcbcfg);
122290bc8e00SArkadiusz Kubalewski break;
122390bc8e00SArkadiusz Kubalewski case I40E_IEEE_TLV_ID_ETS_REC:
122490bc8e00SArkadiusz Kubalewski i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
122590bc8e00SArkadiusz Kubalewski break;
122690bc8e00SArkadiusz Kubalewski case I40E_IEEE_TLV_ID_PFC_CFG:
122790bc8e00SArkadiusz Kubalewski i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
122890bc8e00SArkadiusz Kubalewski break;
122990bc8e00SArkadiusz Kubalewski case I40E_IEEE_TLV_ID_APP_PRI:
123090bc8e00SArkadiusz Kubalewski i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
123190bc8e00SArkadiusz Kubalewski break;
123290bc8e00SArkadiusz Kubalewski default:
123390bc8e00SArkadiusz Kubalewski break;
123490bc8e00SArkadiusz Kubalewski }
123590bc8e00SArkadiusz Kubalewski }
123690bc8e00SArkadiusz Kubalewski
123790bc8e00SArkadiusz Kubalewski /**
123890bc8e00SArkadiusz Kubalewski * i40e_set_dcb_config - Set the local LLDP MIB to FW
123990bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
124090bc8e00SArkadiusz Kubalewski *
124190bc8e00SArkadiusz Kubalewski * Set DCB configuration to the Firmware
124290bc8e00SArkadiusz Kubalewski **/
i40e_set_dcb_config(struct i40e_hw * hw)12435180ff13SJan Sokolowski int i40e_set_dcb_config(struct i40e_hw *hw)
124490bc8e00SArkadiusz Kubalewski {
124590bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg;
124690bc8e00SArkadiusz Kubalewski struct i40e_virt_mem mem;
124790bc8e00SArkadiusz Kubalewski u8 mib_type, *lldpmib;
124890bc8e00SArkadiusz Kubalewski u16 miblen;
12495180ff13SJan Sokolowski int ret;
125090bc8e00SArkadiusz Kubalewski
125190bc8e00SArkadiusz Kubalewski /* update the hw local config */
125290bc8e00SArkadiusz Kubalewski dcbcfg = &hw->local_dcbx_config;
125390bc8e00SArkadiusz Kubalewski /* Allocate the LLDPDU */
125490bc8e00SArkadiusz Kubalewski ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
125590bc8e00SArkadiusz Kubalewski if (ret)
125690bc8e00SArkadiusz Kubalewski return ret;
125790bc8e00SArkadiusz Kubalewski
125890bc8e00SArkadiusz Kubalewski mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
125990bc8e00SArkadiusz Kubalewski if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
126090bc8e00SArkadiusz Kubalewski mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
126190bc8e00SArkadiusz Kubalewski SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
126290bc8e00SArkadiusz Kubalewski }
126390bc8e00SArkadiusz Kubalewski lldpmib = (u8 *)mem.va;
126490bc8e00SArkadiusz Kubalewski i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
126590bc8e00SArkadiusz Kubalewski ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
126690bc8e00SArkadiusz Kubalewski
126790bc8e00SArkadiusz Kubalewski i40e_free_virt_mem(hw, &mem);
126890bc8e00SArkadiusz Kubalewski return ret;
126990bc8e00SArkadiusz Kubalewski }
127090bc8e00SArkadiusz Kubalewski
127190bc8e00SArkadiusz Kubalewski /**
127290bc8e00SArkadiusz Kubalewski * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
127390bc8e00SArkadiusz Kubalewski * @lldpmib: pointer to mib to be output
127490bc8e00SArkadiusz Kubalewski * @miblen: pointer to u16 for length of lldpmib
127590bc8e00SArkadiusz Kubalewski * @dcbcfg: store for LLDPDU data
127690bc8e00SArkadiusz Kubalewski *
127790bc8e00SArkadiusz Kubalewski * send DCB configuration to FW
127890bc8e00SArkadiusz Kubalewski **/
i40e_dcb_config_to_lldp(u8 * lldpmib,u16 * miblen,struct i40e_dcbx_config * dcbcfg)12795180ff13SJan Sokolowski int i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
128090bc8e00SArkadiusz Kubalewski struct i40e_dcbx_config *dcbcfg)
128190bc8e00SArkadiusz Kubalewski {
128290bc8e00SArkadiusz Kubalewski u16 length, offset = 0, tlvid, typelength;
128390bc8e00SArkadiusz Kubalewski struct i40e_lldp_org_tlv *tlv;
128490bc8e00SArkadiusz Kubalewski
128590bc8e00SArkadiusz Kubalewski tlv = (struct i40e_lldp_org_tlv *)lldpmib;
128690bc8e00SArkadiusz Kubalewski tlvid = I40E_TLV_ID_START;
128790bc8e00SArkadiusz Kubalewski do {
128890bc8e00SArkadiusz Kubalewski i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
128990bc8e00SArkadiusz Kubalewski typelength = ntohs(tlv->typelength);
129090bc8e00SArkadiusz Kubalewski length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
129190bc8e00SArkadiusz Kubalewski I40E_LLDP_TLV_LEN_SHIFT);
129290bc8e00SArkadiusz Kubalewski if (length)
129390bc8e00SArkadiusz Kubalewski offset += length + I40E_IEEE_TLV_HEADER_LENGTH;
129490bc8e00SArkadiusz Kubalewski /* END TLV or beyond LLDPDU size */
129590bc8e00SArkadiusz Kubalewski if (tlvid >= I40E_TLV_ID_END_OF_LLDPPDU ||
129690bc8e00SArkadiusz Kubalewski offset >= I40E_LLDPDU_SIZE)
129790bc8e00SArkadiusz Kubalewski break;
129890bc8e00SArkadiusz Kubalewski /* Move to next TLV */
129990bc8e00SArkadiusz Kubalewski if (length)
130090bc8e00SArkadiusz Kubalewski tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
130190bc8e00SArkadiusz Kubalewski sizeof(tlv->typelength) + length);
130290bc8e00SArkadiusz Kubalewski } while (tlvid < I40E_TLV_ID_END_OF_LLDPPDU);
130390bc8e00SArkadiusz Kubalewski *miblen = offset;
1304230f3d53SJan Sokolowski return 0;
130590bc8e00SArkadiusz Kubalewski }
130690bc8e00SArkadiusz Kubalewski
130790bc8e00SArkadiusz Kubalewski /**
130890bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_rx_fifo_config
130990bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
131090bc8e00SArkadiusz Kubalewski * @ets_mode: Strict Priority or Round Robin mode
131190bc8e00SArkadiusz Kubalewski * @non_ets_mode: Strict Priority or Round Robin
131290bc8e00SArkadiusz Kubalewski * @max_exponent: Exponent to calculate max refill credits
131390bc8e00SArkadiusz Kubalewski * @lltc_map: Low latency TC bitmap
131490bc8e00SArkadiusz Kubalewski *
131590bc8e00SArkadiusz Kubalewski * Configure HW Rx FIFO as part of DCB configuration.
131690bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_rx_fifo_config(struct i40e_hw * hw,enum i40e_dcb_arbiter_mode ets_mode,enum i40e_dcb_arbiter_mode non_ets_mode,u32 max_exponent,u8 lltc_map)131790bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_rx_fifo_config(struct i40e_hw *hw,
131890bc8e00SArkadiusz Kubalewski enum i40e_dcb_arbiter_mode ets_mode,
131990bc8e00SArkadiusz Kubalewski enum i40e_dcb_arbiter_mode non_ets_mode,
132090bc8e00SArkadiusz Kubalewski u32 max_exponent,
132190bc8e00SArkadiusz Kubalewski u8 lltc_map)
132290bc8e00SArkadiusz Kubalewski {
132390bc8e00SArkadiusz Kubalewski u32 reg = rd32(hw, I40E_PRTDCB_RETSC);
132490bc8e00SArkadiusz Kubalewski
132590bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_RETSC_ETS_MODE_MASK;
132690bc8e00SArkadiusz Kubalewski reg |= ((u32)ets_mode << I40E_PRTDCB_RETSC_ETS_MODE_SHIFT) &
132790bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSC_ETS_MODE_MASK;
132890bc8e00SArkadiusz Kubalewski
132990bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK;
133090bc8e00SArkadiusz Kubalewski reg |= ((u32)non_ets_mode << I40E_PRTDCB_RETSC_NON_ETS_MODE_SHIFT) &
133190bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSC_NON_ETS_MODE_MASK;
133290bc8e00SArkadiusz Kubalewski
133390bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK;
133490bc8e00SArkadiusz Kubalewski reg |= (max_exponent << I40E_PRTDCB_RETSC_ETS_MAX_EXP_SHIFT) &
133590bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSC_ETS_MAX_EXP_MASK;
133690bc8e00SArkadiusz Kubalewski
133790bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_RETSC_LLTC_MASK;
133890bc8e00SArkadiusz Kubalewski reg |= (lltc_map << I40E_PRTDCB_RETSC_LLTC_SHIFT) &
133990bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSC_LLTC_MASK;
134090bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_RETSC, reg);
134190bc8e00SArkadiusz Kubalewski }
134290bc8e00SArkadiusz Kubalewski
134390bc8e00SArkadiusz Kubalewski /**
134490bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_rx_cmd_monitor_config
134590bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
134690bc8e00SArkadiusz Kubalewski * @num_tc: Total number of traffic class
134790bc8e00SArkadiusz Kubalewski * @num_ports: Total number of ports on device
134890bc8e00SArkadiusz Kubalewski *
134990bc8e00SArkadiusz Kubalewski * Configure HW Rx command monitor as part of DCB configuration.
135090bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_rx_cmd_monitor_config(struct i40e_hw * hw,u8 num_tc,u8 num_ports)135190bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_rx_cmd_monitor_config(struct i40e_hw *hw,
135290bc8e00SArkadiusz Kubalewski u8 num_tc, u8 num_ports)
135390bc8e00SArkadiusz Kubalewski {
135490bc8e00SArkadiusz Kubalewski u32 threshold;
135590bc8e00SArkadiusz Kubalewski u32 fifo_size;
135690bc8e00SArkadiusz Kubalewski u32 reg;
135790bc8e00SArkadiusz Kubalewski
135890bc8e00SArkadiusz Kubalewski /* Set the threshold and fifo_size based on number of ports */
135990bc8e00SArkadiusz Kubalewski switch (num_ports) {
136090bc8e00SArkadiusz Kubalewski case 1:
136190bc8e00SArkadiusz Kubalewski threshold = I40E_DCB_1_PORT_THRESHOLD;
136290bc8e00SArkadiusz Kubalewski fifo_size = I40E_DCB_1_PORT_FIFO_SIZE;
136390bc8e00SArkadiusz Kubalewski break;
136490bc8e00SArkadiusz Kubalewski case 2:
136590bc8e00SArkadiusz Kubalewski if (num_tc > 4) {
136690bc8e00SArkadiusz Kubalewski threshold = I40E_DCB_2_PORT_THRESHOLD_HIGH_NUM_TC;
136790bc8e00SArkadiusz Kubalewski fifo_size = I40E_DCB_2_PORT_FIFO_SIZE_HIGH_NUM_TC;
136890bc8e00SArkadiusz Kubalewski } else {
136990bc8e00SArkadiusz Kubalewski threshold = I40E_DCB_2_PORT_THRESHOLD_LOW_NUM_TC;
137090bc8e00SArkadiusz Kubalewski fifo_size = I40E_DCB_2_PORT_FIFO_SIZE_LOW_NUM_TC;
137190bc8e00SArkadiusz Kubalewski }
137290bc8e00SArkadiusz Kubalewski break;
137390bc8e00SArkadiusz Kubalewski case 4:
137490bc8e00SArkadiusz Kubalewski if (num_tc > 4) {
137590bc8e00SArkadiusz Kubalewski threshold = I40E_DCB_4_PORT_THRESHOLD_HIGH_NUM_TC;
137690bc8e00SArkadiusz Kubalewski fifo_size = I40E_DCB_4_PORT_FIFO_SIZE_HIGH_NUM_TC;
137790bc8e00SArkadiusz Kubalewski } else {
137890bc8e00SArkadiusz Kubalewski threshold = I40E_DCB_4_PORT_THRESHOLD_LOW_NUM_TC;
137990bc8e00SArkadiusz Kubalewski fifo_size = I40E_DCB_4_PORT_FIFO_SIZE_LOW_NUM_TC;
138090bc8e00SArkadiusz Kubalewski }
138190bc8e00SArkadiusz Kubalewski break;
138290bc8e00SArkadiusz Kubalewski default:
138390bc8e00SArkadiusz Kubalewski i40e_debug(hw, I40E_DEBUG_DCB, "Invalid num_ports %u.\n",
138490bc8e00SArkadiusz Kubalewski (u32)num_ports);
138590bc8e00SArkadiusz Kubalewski return;
138690bc8e00SArkadiusz Kubalewski }
138790bc8e00SArkadiusz Kubalewski
138890bc8e00SArkadiusz Kubalewski /* The hardware manual describes setting up of I40E_PRT_SWR_PM_THR
138990bc8e00SArkadiusz Kubalewski * based on the number of ports and traffic classes for a given port as
139090bc8e00SArkadiusz Kubalewski * part of DCB configuration.
139190bc8e00SArkadiusz Kubalewski */
139290bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRT_SWR_PM_THR);
139390bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRT_SWR_PM_THR_THRESHOLD_MASK;
139490bc8e00SArkadiusz Kubalewski reg |= (threshold << I40E_PRT_SWR_PM_THR_THRESHOLD_SHIFT) &
139590bc8e00SArkadiusz Kubalewski I40E_PRT_SWR_PM_THR_THRESHOLD_MASK;
139690bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRT_SWR_PM_THR, reg);
139790bc8e00SArkadiusz Kubalewski
139890bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_RPPMC);
139990bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK;
140090bc8e00SArkadiusz Kubalewski reg |= (fifo_size << I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_SHIFT) &
140190bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RPPMC_RX_FIFO_SIZE_MASK;
140290bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_RPPMC, reg);
140390bc8e00SArkadiusz Kubalewski }
140490bc8e00SArkadiusz Kubalewski
140590bc8e00SArkadiusz Kubalewski /**
140690bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_pfc_config
140790bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
140890bc8e00SArkadiusz Kubalewski * @pfc_en: Bitmap of PFC enabled priorities
140990bc8e00SArkadiusz Kubalewski * @prio_tc: priority to tc assignment indexed by priority
141090bc8e00SArkadiusz Kubalewski *
141190bc8e00SArkadiusz Kubalewski * Configure HW Priority Flow Controller as part of DCB configuration.
141290bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_pfc_config(struct i40e_hw * hw,u8 pfc_en,u8 * prio_tc)141390bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_pfc_config(struct i40e_hw *hw,
141490bc8e00SArkadiusz Kubalewski u8 pfc_en, u8 *prio_tc)
141590bc8e00SArkadiusz Kubalewski {
141690bc8e00SArkadiusz Kubalewski u16 refresh_time = (u16)I40E_DEFAULT_PAUSE_TIME / 2;
141790bc8e00SArkadiusz Kubalewski u32 link_speed = hw->phy.link_info.link_speed;
141890bc8e00SArkadiusz Kubalewski u8 first_pfc_prio = 0;
141990bc8e00SArkadiusz Kubalewski u8 num_pfc_tc = 0;
142090bc8e00SArkadiusz Kubalewski u8 tc2pfc = 0;
142190bc8e00SArkadiusz Kubalewski u32 reg;
142290bc8e00SArkadiusz Kubalewski u8 i;
142390bc8e00SArkadiusz Kubalewski
142490bc8e00SArkadiusz Kubalewski /* Get Number of PFC TCs and TC2PFC map */
142590bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_USER_PRIORITY; i++) {
142690bc8e00SArkadiusz Kubalewski if (pfc_en & BIT(i)) {
142790bc8e00SArkadiusz Kubalewski if (!first_pfc_prio)
142890bc8e00SArkadiusz Kubalewski first_pfc_prio = i;
142990bc8e00SArkadiusz Kubalewski /* Set bit for the PFC TC */
143090bc8e00SArkadiusz Kubalewski tc2pfc |= BIT(prio_tc[i]);
143190bc8e00SArkadiusz Kubalewski num_pfc_tc++;
143290bc8e00SArkadiusz Kubalewski }
143390bc8e00SArkadiusz Kubalewski }
143490bc8e00SArkadiusz Kubalewski
143590bc8e00SArkadiusz Kubalewski switch (link_speed) {
143690bc8e00SArkadiusz Kubalewski case I40E_LINK_SPEED_10GB:
143790bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_MFLCN);
143890bc8e00SArkadiusz Kubalewski reg |= BIT(I40E_PRTDCB_MFLCN_DPF_SHIFT) &
143990bc8e00SArkadiusz Kubalewski I40E_PRTDCB_MFLCN_DPF_MASK;
144090bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_MFLCN_RFCE_MASK;
144190bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_MFLCN_RPFCE_MASK;
144290bc8e00SArkadiusz Kubalewski if (pfc_en) {
144390bc8e00SArkadiusz Kubalewski reg |= BIT(I40E_PRTDCB_MFLCN_RPFCM_SHIFT) &
144490bc8e00SArkadiusz Kubalewski I40E_PRTDCB_MFLCN_RPFCM_MASK;
144590bc8e00SArkadiusz Kubalewski reg |= ((u32)pfc_en << I40E_PRTDCB_MFLCN_RPFCE_SHIFT) &
144690bc8e00SArkadiusz Kubalewski I40E_PRTDCB_MFLCN_RPFCE_MASK;
144790bc8e00SArkadiusz Kubalewski }
144890bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_MFLCN, reg);
144990bc8e00SArkadiusz Kubalewski
145090bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_FCCFG);
145190bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_FCCFG_TFCE_MASK;
145290bc8e00SArkadiusz Kubalewski if (pfc_en)
145390bc8e00SArkadiusz Kubalewski reg |= (I40E_DCB_PFC_ENABLED <<
145490bc8e00SArkadiusz Kubalewski I40E_PRTDCB_FCCFG_TFCE_SHIFT) &
145590bc8e00SArkadiusz Kubalewski I40E_PRTDCB_FCCFG_TFCE_MASK;
145690bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_FCCFG, reg);
145790bc8e00SArkadiusz Kubalewski
145890bc8e00SArkadiusz Kubalewski /* FCTTV and FCRTV to be set by default */
145990bc8e00SArkadiusz Kubalewski break;
146090bc8e00SArkadiusz Kubalewski case I40E_LINK_SPEED_40GB:
146190bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP);
146290bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_MASK;
146390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP, reg);
146490bc8e00SArkadiusz Kubalewski
146590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP);
146690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTMAC_HSEC_CTL_RX_ENABLE_GPP_MASK;
146790bc8e00SArkadiusz Kubalewski reg |= BIT(I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_SHIFT) &
146890bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP_MASK;
146990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTMAC_HSEC_CTL_RX_ENABLE_PPP, reg);
147090bc8e00SArkadiusz Kubalewski
147190bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE);
147290bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_MASK;
147390bc8e00SArkadiusz Kubalewski reg |= ((u32)pfc_en <<
147490bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_SHIFT) &
147590bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE_MASK;
147690bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTMAC_HSEC_CTL_RX_PAUSE_ENABLE, reg);
147790bc8e00SArkadiusz Kubalewski
147890bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE);
147990bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_MASK;
148090bc8e00SArkadiusz Kubalewski reg |= ((u32)pfc_en <<
148190bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_SHIFT) &
148290bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE_MASK;
148390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_ENABLE, reg);
148490bc8e00SArkadiusz Kubalewski
148590bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MAX_INDEX; i++) {
148690bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(i));
148790bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK;
148890bc8e00SArkadiusz Kubalewski if (pfc_en) {
148990bc8e00SArkadiusz Kubalewski reg |= ((u32)refresh_time <<
149090bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_SHIFT) &
149190bc8e00SArkadiusz Kubalewski I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_MASK;
149290bc8e00SArkadiusz Kubalewski }
149390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(i), reg);
149490bc8e00SArkadiusz Kubalewski }
149590bc8e00SArkadiusz Kubalewski /* PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA default value is 0xFFFF
149690bc8e00SArkadiusz Kubalewski * for all user priorities
149790bc8e00SArkadiusz Kubalewski */
149890bc8e00SArkadiusz Kubalewski break;
149990bc8e00SArkadiusz Kubalewski }
150090bc8e00SArkadiusz Kubalewski
150190bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_TC2PFC);
150290bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_TC2PFC_TC2PFC_MASK;
150390bc8e00SArkadiusz Kubalewski reg |= ((u32)tc2pfc << I40E_PRTDCB_TC2PFC_TC2PFC_SHIFT) &
150490bc8e00SArkadiusz Kubalewski I40E_PRTDCB_TC2PFC_TC2PFC_MASK;
150590bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_TC2PFC, reg);
150690bc8e00SArkadiusz Kubalewski
150790bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_RUP);
150890bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_RUP_NOVLANUP_MASK;
150990bc8e00SArkadiusz Kubalewski reg |= ((u32)first_pfc_prio << I40E_PRTDCB_RUP_NOVLANUP_SHIFT) &
151090bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RUP_NOVLANUP_MASK;
151190bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_RUP, reg);
151290bc8e00SArkadiusz Kubalewski
151390bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_TDPMC);
151490bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_TDPMC_TCPM_MODE_MASK;
151590bc8e00SArkadiusz Kubalewski if (num_pfc_tc > I40E_DCB_PFC_FORCED_NUM_TC) {
151690bc8e00SArkadiusz Kubalewski reg |= BIT(I40E_PRTDCB_TDPMC_TCPM_MODE_SHIFT) &
151790bc8e00SArkadiusz Kubalewski I40E_PRTDCB_TDPMC_TCPM_MODE_MASK;
151890bc8e00SArkadiusz Kubalewski }
151990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_TDPMC, reg);
152090bc8e00SArkadiusz Kubalewski
152190bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_TCPMC);
152290bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_TCPMC_TCPM_MODE_MASK;
152390bc8e00SArkadiusz Kubalewski if (num_pfc_tc > I40E_DCB_PFC_FORCED_NUM_TC) {
152490bc8e00SArkadiusz Kubalewski reg |= BIT(I40E_PRTDCB_TCPMC_TCPM_MODE_SHIFT) &
152590bc8e00SArkadiusz Kubalewski I40E_PRTDCB_TCPMC_TCPM_MODE_MASK;
152690bc8e00SArkadiusz Kubalewski }
152790bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_TCPMC, reg);
152890bc8e00SArkadiusz Kubalewski }
152990bc8e00SArkadiusz Kubalewski
153090bc8e00SArkadiusz Kubalewski /**
153190bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_set_num_tc
153290bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
153390bc8e00SArkadiusz Kubalewski * @num_tc: number of traffic classes
153490bc8e00SArkadiusz Kubalewski *
153590bc8e00SArkadiusz Kubalewski * Configure number of traffic classes in HW
153690bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_set_num_tc(struct i40e_hw * hw,u8 num_tc)153790bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_set_num_tc(struct i40e_hw *hw, u8 num_tc)
153890bc8e00SArkadiusz Kubalewski {
153990bc8e00SArkadiusz Kubalewski u32 reg = rd32(hw, I40E_PRTDCB_GENC);
154090bc8e00SArkadiusz Kubalewski
154190bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTDCB_GENC_NUMTC_MASK;
154290bc8e00SArkadiusz Kubalewski reg |= ((u32)num_tc << I40E_PRTDCB_GENC_NUMTC_SHIFT) &
154390bc8e00SArkadiusz Kubalewski I40E_PRTDCB_GENC_NUMTC_MASK;
154490bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_GENC, reg);
154590bc8e00SArkadiusz Kubalewski }
154690bc8e00SArkadiusz Kubalewski
154790bc8e00SArkadiusz Kubalewski /**
154890bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_get_num_tc
154990bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
155090bc8e00SArkadiusz Kubalewski *
155190bc8e00SArkadiusz Kubalewski * Returns number of traffic classes configured in HW
155290bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_get_num_tc(struct i40e_hw * hw)155390bc8e00SArkadiusz Kubalewski u8 i40e_dcb_hw_get_num_tc(struct i40e_hw *hw)
155490bc8e00SArkadiusz Kubalewski {
155590bc8e00SArkadiusz Kubalewski u32 reg = rd32(hw, I40E_PRTDCB_GENC);
155690bc8e00SArkadiusz Kubalewski
155790bc8e00SArkadiusz Kubalewski return (u8)((reg & I40E_PRTDCB_GENC_NUMTC_MASK) >>
155890bc8e00SArkadiusz Kubalewski I40E_PRTDCB_GENC_NUMTC_SHIFT);
155990bc8e00SArkadiusz Kubalewski }
156090bc8e00SArkadiusz Kubalewski
156190bc8e00SArkadiusz Kubalewski /**
156290bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_rx_ets_bw_config
156390bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
156490bc8e00SArkadiusz Kubalewski * @bw_share: Bandwidth share indexed per traffic class
156590bc8e00SArkadiusz Kubalewski * @mode: Strict Priority or Round Robin mode between UP sharing same
156690bc8e00SArkadiusz Kubalewski * traffic class
156790bc8e00SArkadiusz Kubalewski * @prio_type: TC is ETS enabled or strict priority
156890bc8e00SArkadiusz Kubalewski *
156990bc8e00SArkadiusz Kubalewski * Configure HW Rx ETS bandwidth as part of DCB configuration.
157090bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_rx_ets_bw_config(struct i40e_hw * hw,u8 * bw_share,u8 * mode,u8 * prio_type)157190bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_rx_ets_bw_config(struct i40e_hw *hw, u8 *bw_share,
157290bc8e00SArkadiusz Kubalewski u8 *mode, u8 *prio_type)
157390bc8e00SArkadiusz Kubalewski {
157490bc8e00SArkadiusz Kubalewski u32 reg;
157590bc8e00SArkadiusz Kubalewski u8 i;
157690bc8e00SArkadiusz Kubalewski
157790bc8e00SArkadiusz Kubalewski for (i = 0; i <= I40E_PRTDCB_RETSTCC_MAX_INDEX; i++) {
157890bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTDCB_RETSTCC(i));
157990bc8e00SArkadiusz Kubalewski reg &= ~(I40E_PRTDCB_RETSTCC_BWSHARE_MASK |
158090bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK |
158190bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSTCC_ETSTC_SHIFT);
158290bc8e00SArkadiusz Kubalewski reg |= ((u32)bw_share[i] << I40E_PRTDCB_RETSTCC_BWSHARE_SHIFT) &
158390bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSTCC_BWSHARE_MASK;
158490bc8e00SArkadiusz Kubalewski reg |= ((u32)mode[i] << I40E_PRTDCB_RETSTCC_UPINTC_MODE_SHIFT) &
158590bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSTCC_UPINTC_MODE_MASK;
158690bc8e00SArkadiusz Kubalewski reg |= ((u32)prio_type[i] << I40E_PRTDCB_RETSTCC_ETSTC_SHIFT) &
158790bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RETSTCC_ETSTC_MASK;
158890bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_RETSTCC(i), reg);
158990bc8e00SArkadiusz Kubalewski }
159090bc8e00SArkadiusz Kubalewski }
159190bc8e00SArkadiusz Kubalewski
159290bc8e00SArkadiusz Kubalewski /**
1593262de08fSJesse Brandeburg * i40e_dcb_hw_rx_up2tc_config
159490bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
159590bc8e00SArkadiusz Kubalewski * @prio_tc: priority to tc assignment indexed by priority
159690bc8e00SArkadiusz Kubalewski *
159790bc8e00SArkadiusz Kubalewski * Configure HW Rx UP2TC map as part of DCB configuration.
159890bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_rx_up2tc_config(struct i40e_hw * hw,u8 * prio_tc)159990bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_rx_up2tc_config(struct i40e_hw *hw, u8 *prio_tc)
160090bc8e00SArkadiusz Kubalewski {
160190bc8e00SArkadiusz Kubalewski u32 reg = rd32(hw, I40E_PRTDCB_RUP2TC);
160290bc8e00SArkadiusz Kubalewski #define I40E_UP2TC_REG(val, i) \
160390bc8e00SArkadiusz Kubalewski (((val) << I40E_PRTDCB_RUP2TC_UP##i##TC_SHIFT) & \
160490bc8e00SArkadiusz Kubalewski I40E_PRTDCB_RUP2TC_UP##i##TC_MASK)
160590bc8e00SArkadiusz Kubalewski
160690bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[0], 0);
160790bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[1], 1);
160890bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[2], 2);
160990bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[3], 3);
161090bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[4], 4);
161190bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[5], 5);
161290bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[6], 6);
161390bc8e00SArkadiusz Kubalewski reg |= I40E_UP2TC_REG(prio_tc[7], 7);
161490bc8e00SArkadiusz Kubalewski
161590bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTDCB_RUP2TC, reg);
161690bc8e00SArkadiusz Kubalewski }
161790bc8e00SArkadiusz Kubalewski
161890bc8e00SArkadiusz Kubalewski /**
161990bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_calculate_pool_sizes - configure dcb pool sizes
162090bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
162190bc8e00SArkadiusz Kubalewski * @num_ports: Number of available ports on the device
162290bc8e00SArkadiusz Kubalewski * @eee_enabled: EEE enabled for the given port
162390bc8e00SArkadiusz Kubalewski * @pfc_en: Bit map of PFC enabled traffic classes
162490bc8e00SArkadiusz Kubalewski * @mfs_tc: Array of max frame size for each traffic class
162590bc8e00SArkadiusz Kubalewski * @pb_cfg: pointer to packet buffer configuration
162690bc8e00SArkadiusz Kubalewski *
162790bc8e00SArkadiusz Kubalewski * Calculate the shared and dedicated per TC pool sizes,
162890bc8e00SArkadiusz Kubalewski * watermarks and threshold values.
162990bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_calculate_pool_sizes(struct i40e_hw * hw,u8 num_ports,bool eee_enabled,u8 pfc_en,u32 * mfs_tc,struct i40e_rx_pb_config * pb_cfg)163090bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_calculate_pool_sizes(struct i40e_hw *hw,
163190bc8e00SArkadiusz Kubalewski u8 num_ports, bool eee_enabled,
163290bc8e00SArkadiusz Kubalewski u8 pfc_en, u32 *mfs_tc,
163390bc8e00SArkadiusz Kubalewski struct i40e_rx_pb_config *pb_cfg)
163490bc8e00SArkadiusz Kubalewski {
163590bc8e00SArkadiusz Kubalewski u32 pool_size[I40E_MAX_TRAFFIC_CLASS];
163690bc8e00SArkadiusz Kubalewski u32 high_wm[I40E_MAX_TRAFFIC_CLASS];
163790bc8e00SArkadiusz Kubalewski u32 low_wm[I40E_MAX_TRAFFIC_CLASS];
163890bc8e00SArkadiusz Kubalewski u32 total_pool_size = 0;
163990bc8e00SArkadiusz Kubalewski int shared_pool_size; /* Need signed variable */
164090bc8e00SArkadiusz Kubalewski u32 port_pb_size;
1641f6724cd4SColin Ian King u32 mfs_max = 0;
164290bc8e00SArkadiusz Kubalewski u32 pcirtt;
164390bc8e00SArkadiusz Kubalewski u8 i;
164490bc8e00SArkadiusz Kubalewski
164590bc8e00SArkadiusz Kubalewski /* Get the MFS(max) for the port */
164690bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
164790bc8e00SArkadiusz Kubalewski if (mfs_tc[i] > mfs_max)
164890bc8e00SArkadiusz Kubalewski mfs_max = mfs_tc[i];
164990bc8e00SArkadiusz Kubalewski }
165090bc8e00SArkadiusz Kubalewski
165190bc8e00SArkadiusz Kubalewski pcirtt = I40E_BT2B(I40E_PCIRTT_LINK_SPEED_10G);
165290bc8e00SArkadiusz Kubalewski
165390bc8e00SArkadiusz Kubalewski /* Calculate effective Rx PB size per port */
165490bc8e00SArkadiusz Kubalewski port_pb_size = I40E_DEVICE_RPB_SIZE / num_ports;
165590bc8e00SArkadiusz Kubalewski if (eee_enabled)
165690bc8e00SArkadiusz Kubalewski port_pb_size -= I40E_BT2B(I40E_EEE_TX_LPI_EXIT_TIME);
165790bc8e00SArkadiusz Kubalewski port_pb_size -= mfs_max;
165890bc8e00SArkadiusz Kubalewski
165990bc8e00SArkadiusz Kubalewski /* Step 1 Calculating tc pool/shared pool sizes and watermarks */
166090bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
166190bc8e00SArkadiusz Kubalewski if (pfc_en & BIT(i)) {
166290bc8e00SArkadiusz Kubalewski low_wm[i] = (I40E_DCB_WATERMARK_START_FACTOR *
166390bc8e00SArkadiusz Kubalewski mfs_tc[i]) + pcirtt;
166490bc8e00SArkadiusz Kubalewski high_wm[i] = low_wm[i];
166590bc8e00SArkadiusz Kubalewski high_wm[i] += ((mfs_max > I40E_MAX_FRAME_SIZE)
166690bc8e00SArkadiusz Kubalewski ? mfs_max : I40E_MAX_FRAME_SIZE);
166790bc8e00SArkadiusz Kubalewski pool_size[i] = high_wm[i];
166890bc8e00SArkadiusz Kubalewski pool_size[i] += I40E_BT2B(I40E_STD_DV_TC(mfs_max,
166990bc8e00SArkadiusz Kubalewski mfs_tc[i]));
167090bc8e00SArkadiusz Kubalewski } else {
167190bc8e00SArkadiusz Kubalewski low_wm[i] = 0;
167290bc8e00SArkadiusz Kubalewski pool_size[i] = (I40E_DCB_WATERMARK_START_FACTOR *
167390bc8e00SArkadiusz Kubalewski mfs_tc[i]) + pcirtt;
167490bc8e00SArkadiusz Kubalewski high_wm[i] = pool_size[i];
167590bc8e00SArkadiusz Kubalewski }
167690bc8e00SArkadiusz Kubalewski total_pool_size += pool_size[i];
167790bc8e00SArkadiusz Kubalewski }
167890bc8e00SArkadiusz Kubalewski
167990bc8e00SArkadiusz Kubalewski shared_pool_size = port_pb_size - total_pool_size;
168090bc8e00SArkadiusz Kubalewski if (shared_pool_size > 0) {
168190bc8e00SArkadiusz Kubalewski pb_cfg->shared_pool_size = shared_pool_size;
168290bc8e00SArkadiusz Kubalewski pb_cfg->shared_pool_high_wm = shared_pool_size;
168390bc8e00SArkadiusz Kubalewski pb_cfg->shared_pool_low_wm = 0;
168490bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
168590bc8e00SArkadiusz Kubalewski pb_cfg->shared_pool_low_thresh[i] = 0;
168690bc8e00SArkadiusz Kubalewski pb_cfg->shared_pool_high_thresh[i] = shared_pool_size;
168790bc8e00SArkadiusz Kubalewski pb_cfg->tc_pool_size[i] = pool_size[i];
168890bc8e00SArkadiusz Kubalewski pb_cfg->tc_pool_high_wm[i] = high_wm[i];
168990bc8e00SArkadiusz Kubalewski pb_cfg->tc_pool_low_wm[i] = low_wm[i];
169090bc8e00SArkadiusz Kubalewski }
169190bc8e00SArkadiusz Kubalewski
169290bc8e00SArkadiusz Kubalewski } else {
169390bc8e00SArkadiusz Kubalewski i40e_debug(hw, I40E_DEBUG_DCB,
169490bc8e00SArkadiusz Kubalewski "The shared pool size for the port is negative %d.\n",
169590bc8e00SArkadiusz Kubalewski shared_pool_size);
169690bc8e00SArkadiusz Kubalewski }
169790bc8e00SArkadiusz Kubalewski }
169890bc8e00SArkadiusz Kubalewski
169990bc8e00SArkadiusz Kubalewski /**
170090bc8e00SArkadiusz Kubalewski * i40e_dcb_hw_rx_pb_config
170190bc8e00SArkadiusz Kubalewski * @hw: pointer to the hw struct
170290bc8e00SArkadiusz Kubalewski * @old_pb_cfg: Existing Rx Packet buffer configuration
170390bc8e00SArkadiusz Kubalewski * @new_pb_cfg: New Rx Packet buffer configuration
170490bc8e00SArkadiusz Kubalewski *
170590bc8e00SArkadiusz Kubalewski * Program the Rx Packet Buffer registers.
170690bc8e00SArkadiusz Kubalewski **/
i40e_dcb_hw_rx_pb_config(struct i40e_hw * hw,struct i40e_rx_pb_config * old_pb_cfg,struct i40e_rx_pb_config * new_pb_cfg)170790bc8e00SArkadiusz Kubalewski void i40e_dcb_hw_rx_pb_config(struct i40e_hw *hw,
170890bc8e00SArkadiusz Kubalewski struct i40e_rx_pb_config *old_pb_cfg,
170990bc8e00SArkadiusz Kubalewski struct i40e_rx_pb_config *new_pb_cfg)
171090bc8e00SArkadiusz Kubalewski {
171190bc8e00SArkadiusz Kubalewski u32 old_val;
171290bc8e00SArkadiusz Kubalewski u32 new_val;
171390bc8e00SArkadiusz Kubalewski u32 reg;
171490bc8e00SArkadiusz Kubalewski u8 i;
171590bc8e00SArkadiusz Kubalewski
171690bc8e00SArkadiusz Kubalewski /* The Rx Packet buffer register programming needs to be done in a
171790bc8e00SArkadiusz Kubalewski * certain order and the following code is based on that
171890bc8e00SArkadiusz Kubalewski * requirement.
171990bc8e00SArkadiusz Kubalewski */
172090bc8e00SArkadiusz Kubalewski
172190bc8e00SArkadiusz Kubalewski /* Program the shared pool low water mark per port if decreasing */
172290bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_low_wm;
172390bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_low_wm;
172490bc8e00SArkadiusz Kubalewski if (new_val < old_val) {
172590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SLW);
172690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SLW_SLW_MASK;
172790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SLW_SLW_SHIFT) &
172890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SLW_SLW_MASK;
172990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SLW, reg);
173090bc8e00SArkadiusz Kubalewski }
173190bc8e00SArkadiusz Kubalewski
173290bc8e00SArkadiusz Kubalewski /* Program the shared pool low threshold and tc pool
173390bc8e00SArkadiusz Kubalewski * low water mark per TC that are decreasing.
173490bc8e00SArkadiusz Kubalewski */
173590bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
173690bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_low_thresh[i];
173790bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_low_thresh[i];
173890bc8e00SArkadiusz Kubalewski if (new_val < old_val) {
173990bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SLT(i));
174090bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SLT_SLT_TCN_MASK;
174190bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SLT_SLT_TCN_SHIFT) &
174290bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SLT_SLT_TCN_MASK;
174390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SLT(i), reg);
174490bc8e00SArkadiusz Kubalewski }
174590bc8e00SArkadiusz Kubalewski
174690bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->tc_pool_low_wm[i];
174790bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->tc_pool_low_wm[i];
174890bc8e00SArkadiusz Kubalewski if (new_val < old_val) {
174990bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_DLW(i));
175090bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_DLW_DLW_TCN_MASK;
175190bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_DLW_DLW_TCN_SHIFT) &
175290bc8e00SArkadiusz Kubalewski I40E_PRTRPB_DLW_DLW_TCN_MASK;
175390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_DLW(i), reg);
175490bc8e00SArkadiusz Kubalewski }
175590bc8e00SArkadiusz Kubalewski }
175690bc8e00SArkadiusz Kubalewski
175790bc8e00SArkadiusz Kubalewski /* Program the shared pool high water mark per port if decreasing */
175890bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_high_wm;
175990bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_high_wm;
176090bc8e00SArkadiusz Kubalewski if (new_val < old_val) {
176190bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SHW);
176290bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SHW_SHW_MASK;
176390bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SHW_SHW_SHIFT) &
176490bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SHW_SHW_MASK;
176590bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SHW, reg);
176690bc8e00SArkadiusz Kubalewski }
176790bc8e00SArkadiusz Kubalewski
176890bc8e00SArkadiusz Kubalewski /* Program the shared pool high threshold and tc pool
176990bc8e00SArkadiusz Kubalewski * high water mark per TC that are decreasing.
177090bc8e00SArkadiusz Kubalewski */
177190bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
177290bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_high_thresh[i];
177390bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_high_thresh[i];
177490bc8e00SArkadiusz Kubalewski if (new_val < old_val) {
177590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SHT(i));
177690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SHT_SHT_TCN_MASK;
177790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SHT_SHT_TCN_SHIFT) &
177890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SHT_SHT_TCN_MASK;
177990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SHT(i), reg);
178090bc8e00SArkadiusz Kubalewski }
178190bc8e00SArkadiusz Kubalewski
178290bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->tc_pool_high_wm[i];
178390bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->tc_pool_high_wm[i];
178490bc8e00SArkadiusz Kubalewski if (new_val < old_val) {
178590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_DHW(i));
178690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_DHW_DHW_TCN_MASK;
178790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_DHW_DHW_TCN_SHIFT) &
178890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_DHW_DHW_TCN_MASK;
178990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_DHW(i), reg);
179090bc8e00SArkadiusz Kubalewski }
179190bc8e00SArkadiusz Kubalewski }
179290bc8e00SArkadiusz Kubalewski
179390bc8e00SArkadiusz Kubalewski /* Write Dedicated Pool Sizes per TC */
179490bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
179590bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->tc_pool_size[i];
179690bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_DPS(i));
179790bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_DPS_DPS_TCN_MASK;
179890bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_DPS_DPS_TCN_SHIFT) &
179990bc8e00SArkadiusz Kubalewski I40E_PRTRPB_DPS_DPS_TCN_MASK;
180090bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_DPS(i), reg);
180190bc8e00SArkadiusz Kubalewski }
180290bc8e00SArkadiusz Kubalewski
180390bc8e00SArkadiusz Kubalewski /* Write Shared Pool Size per port */
180490bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_size;
180590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SPS);
180690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SPS_SPS_MASK;
180790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SPS_SPS_SHIFT) &
180890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SPS_SPS_MASK;
180990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SPS, reg);
181090bc8e00SArkadiusz Kubalewski
181190bc8e00SArkadiusz Kubalewski /* Program the shared pool low water mark per port if increasing */
181290bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_low_wm;
181390bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_low_wm;
181490bc8e00SArkadiusz Kubalewski if (new_val > old_val) {
181590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SLW);
181690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SLW_SLW_MASK;
181790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SLW_SLW_SHIFT) &
181890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SLW_SLW_MASK;
181990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SLW, reg);
182090bc8e00SArkadiusz Kubalewski }
182190bc8e00SArkadiusz Kubalewski
182290bc8e00SArkadiusz Kubalewski /* Program the shared pool low threshold and tc pool
182390bc8e00SArkadiusz Kubalewski * low water mark per TC that are increasing.
182490bc8e00SArkadiusz Kubalewski */
182590bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
182690bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_low_thresh[i];
182790bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_low_thresh[i];
182890bc8e00SArkadiusz Kubalewski if (new_val > old_val) {
182990bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SLT(i));
183090bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SLT_SLT_TCN_MASK;
183190bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SLT_SLT_TCN_SHIFT) &
183290bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SLT_SLT_TCN_MASK;
183390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SLT(i), reg);
183490bc8e00SArkadiusz Kubalewski }
183590bc8e00SArkadiusz Kubalewski
183690bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->tc_pool_low_wm[i];
183790bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->tc_pool_low_wm[i];
183890bc8e00SArkadiusz Kubalewski if (new_val > old_val) {
183990bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_DLW(i));
184090bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_DLW_DLW_TCN_MASK;
184190bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_DLW_DLW_TCN_SHIFT) &
184290bc8e00SArkadiusz Kubalewski I40E_PRTRPB_DLW_DLW_TCN_MASK;
184390bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_DLW(i), reg);
184490bc8e00SArkadiusz Kubalewski }
184590bc8e00SArkadiusz Kubalewski }
184690bc8e00SArkadiusz Kubalewski
184790bc8e00SArkadiusz Kubalewski /* Program the shared pool high water mark per port if increasing */
184890bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_high_wm;
184990bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_high_wm;
185090bc8e00SArkadiusz Kubalewski if (new_val > old_val) {
185190bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SHW);
185290bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SHW_SHW_MASK;
185390bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SHW_SHW_SHIFT) &
185490bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SHW_SHW_MASK;
185590bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SHW, reg);
185690bc8e00SArkadiusz Kubalewski }
185790bc8e00SArkadiusz Kubalewski
185890bc8e00SArkadiusz Kubalewski /* Program the shared pool high threshold and tc pool
185990bc8e00SArkadiusz Kubalewski * high water mark per TC that are increasing.
186090bc8e00SArkadiusz Kubalewski */
186190bc8e00SArkadiusz Kubalewski for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
186290bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->shared_pool_high_thresh[i];
186390bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->shared_pool_high_thresh[i];
186490bc8e00SArkadiusz Kubalewski if (new_val > old_val) {
186590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_SHT(i));
186690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_SHT_SHT_TCN_MASK;
186790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_SHT_SHT_TCN_SHIFT) &
186890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_SHT_SHT_TCN_MASK;
186990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_SHT(i), reg);
187090bc8e00SArkadiusz Kubalewski }
187190bc8e00SArkadiusz Kubalewski
187290bc8e00SArkadiusz Kubalewski old_val = old_pb_cfg->tc_pool_high_wm[i];
187390bc8e00SArkadiusz Kubalewski new_val = new_pb_cfg->tc_pool_high_wm[i];
187490bc8e00SArkadiusz Kubalewski if (new_val > old_val) {
187590bc8e00SArkadiusz Kubalewski reg = rd32(hw, I40E_PRTRPB_DHW(i));
187690bc8e00SArkadiusz Kubalewski reg &= ~I40E_PRTRPB_DHW_DHW_TCN_MASK;
187790bc8e00SArkadiusz Kubalewski reg |= (new_val << I40E_PRTRPB_DHW_DHW_TCN_SHIFT) &
187890bc8e00SArkadiusz Kubalewski I40E_PRTRPB_DHW_DHW_TCN_MASK;
187990bc8e00SArkadiusz Kubalewski wr32(hw, I40E_PRTRPB_DHW(i), reg);
188090bc8e00SArkadiusz Kubalewski }
188190bc8e00SArkadiusz Kubalewski }
188290bc8e00SArkadiusz Kubalewski }
188390bc8e00SArkadiusz Kubalewski
188490bc8e00SArkadiusz Kubalewski /**
18856334f243SMariusz Stachura * _i40e_read_lldp_cfg - generic read of LLDP Configuration data from NVM
18866334f243SMariusz Stachura * @hw: pointer to the HW structure
18876334f243SMariusz Stachura * @lldp_cfg: pointer to hold lldp configuration variables
18886334f243SMariusz Stachura * @module: address of the module pointer
18896334f243SMariusz Stachura * @word_offset: offset of LLDP configuration
18906334f243SMariusz Stachura *
18916334f243SMariusz Stachura * Reads the LLDP configuration data from NVM using passed addresses
18926334f243SMariusz Stachura **/
_i40e_read_lldp_cfg(struct i40e_hw * hw,struct i40e_lldp_variables * lldp_cfg,u8 module,u32 word_offset)18935180ff13SJan Sokolowski static int _i40e_read_lldp_cfg(struct i40e_hw *hw,
18946334f243SMariusz Stachura struct i40e_lldp_variables *lldp_cfg,
18956334f243SMariusz Stachura u8 module, u32 word_offset)
18966334f243SMariusz Stachura {
18976334f243SMariusz Stachura u32 address, offset = (2 * word_offset);
18986334f243SMariusz Stachura __le16 raw_mem;
18995180ff13SJan Sokolowski int ret;
19006334f243SMariusz Stachura u16 mem;
19016334f243SMariusz Stachura
19026334f243SMariusz Stachura ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
19036334f243SMariusz Stachura if (ret)
19046334f243SMariusz Stachura return ret;
19056334f243SMariusz Stachura
19066334f243SMariusz Stachura ret = i40e_aq_read_nvm(hw, 0x0, module * 2, sizeof(raw_mem), &raw_mem,
19076334f243SMariusz Stachura true, NULL);
19086334f243SMariusz Stachura i40e_release_nvm(hw);
19096334f243SMariusz Stachura if (ret)
19106334f243SMariusz Stachura return ret;
19116334f243SMariusz Stachura
19126334f243SMariusz Stachura mem = le16_to_cpu(raw_mem);
19136334f243SMariusz Stachura /* Check if this pointer needs to be read in word size or 4K sector
19146334f243SMariusz Stachura * units.
19156334f243SMariusz Stachura */
19166334f243SMariusz Stachura if (mem & I40E_PTR_TYPE)
19176334f243SMariusz Stachura address = (0x7FFF & mem) * 4096;
19186334f243SMariusz Stachura else
19196334f243SMariusz Stachura address = (0x7FFF & mem) * 2;
19206334f243SMariusz Stachura
19216334f243SMariusz Stachura ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
19226334f243SMariusz Stachura if (ret)
19236334f243SMariusz Stachura goto err_lldp_cfg;
19246334f243SMariusz Stachura
19256334f243SMariusz Stachura ret = i40e_aq_read_nvm(hw, module, offset, sizeof(raw_mem), &raw_mem,
19266334f243SMariusz Stachura true, NULL);
19276334f243SMariusz Stachura i40e_release_nvm(hw);
19286334f243SMariusz Stachura if (ret)
19296334f243SMariusz Stachura return ret;
19306334f243SMariusz Stachura
19316334f243SMariusz Stachura mem = le16_to_cpu(raw_mem);
19326334f243SMariusz Stachura offset = mem + word_offset;
19336334f243SMariusz Stachura offset *= 2;
19346334f243SMariusz Stachura
19356334f243SMariusz Stachura ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
19366334f243SMariusz Stachura if (ret)
19376334f243SMariusz Stachura goto err_lldp_cfg;
19386334f243SMariusz Stachura
19396334f243SMariusz Stachura ret = i40e_aq_read_nvm(hw, 0, address + offset,
19406334f243SMariusz Stachura sizeof(struct i40e_lldp_variables), lldp_cfg,
19416334f243SMariusz Stachura true, NULL);
19426334f243SMariusz Stachura i40e_release_nvm(hw);
19436334f243SMariusz Stachura
19446334f243SMariusz Stachura err_lldp_cfg:
19456334f243SMariusz Stachura return ret;
19466334f243SMariusz Stachura }
19476334f243SMariusz Stachura
19486334f243SMariusz Stachura /**
1949e1c4751eSNeerav Parikh * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1950e1c4751eSNeerav Parikh * @hw: pointer to the HW structure
1951e1c4751eSNeerav Parikh * @lldp_cfg: pointer to hold lldp configuration variables
1952e1c4751eSNeerav Parikh *
1953e1c4751eSNeerav Parikh * Reads the LLDP configuration data from NVM
1954e1c4751eSNeerav Parikh **/
i40e_read_lldp_cfg(struct i40e_hw * hw,struct i40e_lldp_variables * lldp_cfg)19555180ff13SJan Sokolowski int i40e_read_lldp_cfg(struct i40e_hw *hw,
1956e1c4751eSNeerav Parikh struct i40e_lldp_variables *lldp_cfg)
1957e1c4751eSNeerav Parikh {
19585180ff13SJan Sokolowski int ret = 0;
19596334f243SMariusz Stachura u32 mem;
1960e1c4751eSNeerav Parikh
1961e1c4751eSNeerav Parikh if (!lldp_cfg)
1962230f3d53SJan Sokolowski return -EINVAL;
1963e1c4751eSNeerav Parikh
1964e1c4751eSNeerav Parikh ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1965e1c4751eSNeerav Parikh if (ret)
19666334f243SMariusz Stachura return ret;
1967e1c4751eSNeerav Parikh
19686334f243SMariusz Stachura ret = i40e_aq_read_nvm(hw, I40E_SR_NVM_CONTROL_WORD, 0, sizeof(mem),
19696334f243SMariusz Stachura &mem, true, NULL);
1970e1c4751eSNeerav Parikh i40e_release_nvm(hw);
19716334f243SMariusz Stachura if (ret)
19726334f243SMariusz Stachura return ret;
1973e1c4751eSNeerav Parikh
19746334f243SMariusz Stachura /* Read a bit that holds information whether we are running flat or
19756334f243SMariusz Stachura * structured NVM image. Flat image has LLDP configuration in shadow
19766334f243SMariusz Stachura * ram, so there is a need to pass different addresses for both cases.
19776334f243SMariusz Stachura */
19786334f243SMariusz Stachura if (mem & I40E_SR_NVM_MAP_STRUCTURE_TYPE) {
19796334f243SMariusz Stachura /* Flat NVM case */
19806334f243SMariusz Stachura ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_SR_EMP_MODULE_PTR,
19816334f243SMariusz Stachura I40E_SR_LLDP_CFG_PTR);
19826334f243SMariusz Stachura } else {
19836334f243SMariusz Stachura /* Good old structured NVM image */
19846334f243SMariusz Stachura ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_EMP_MODULE_PTR,
19856334f243SMariusz Stachura I40E_NVM_LLDP_CFG_PTR);
19866334f243SMariusz Stachura }
19876334f243SMariusz Stachura
1988e1c4751eSNeerav Parikh return ret;
1989e1c4751eSNeerav Parikh }
1990