xref: /openbmc/linux/drivers/net/ethernet/qlogic/qed/qed_dcbx.c (revision e4781421e883340b796da5a724bda7226817990b)
1 /* QLogic qed NIC Driver
2  * Copyright (c) 2015-2017  QLogic Corporation
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and /or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 #include <linux/types.h>
34 #include <asm/byteorder.h>
35 #include <linux/bitops.h>
36 #include <linux/dcbnl.h>
37 #include <linux/errno.h>
38 #include <linux/kernel.h>
39 #include <linux/slab.h>
40 #include <linux/string.h>
41 #include "qed.h"
42 #include "qed_cxt.h"
43 #include "qed_dcbx.h"
44 #include "qed_hsi.h"
45 #include "qed_sp.h"
46 #include "qed_sriov.h"
47 #ifdef CONFIG_DCB
48 #include <linux/qed/qed_eth_if.h>
49 #endif
50 
51 #define QED_DCBX_MAX_MIB_READ_TRY       (100)
52 #define QED_ETH_TYPE_DEFAULT            (0)
53 #define QED_ETH_TYPE_ROCE               (0x8915)
54 #define QED_UDP_PORT_TYPE_ROCE_V2       (0x12B7)
55 #define QED_ETH_TYPE_FCOE               (0x8906)
56 #define QED_TCP_PORT_ISCSI              (0xCBC)
57 
58 #define QED_DCBX_INVALID_PRIORITY       0xFF
59 
60 /* Get Traffic Class from priority traffic class table, 4 bits represent
61  * the traffic class corresponding to the priority.
62  */
63 #define QED_DCBX_PRIO2TC(prio_tc_tbl, prio) \
64 	((u32)(prio_tc_tbl >> ((7 - prio) * 4)) & 0x7)
65 
66 static const struct qed_dcbx_app_metadata qed_dcbx_app_update[] = {
67 	{DCBX_PROTOCOL_ISCSI, "ISCSI", QED_PCI_DEFAULT},
68 	{DCBX_PROTOCOL_FCOE, "FCOE", QED_PCI_DEFAULT},
69 	{DCBX_PROTOCOL_ROCE, "ROCE", QED_PCI_DEFAULT},
70 	{DCBX_PROTOCOL_ROCE_V2, "ROCE_V2", QED_PCI_DEFAULT},
71 	{DCBX_PROTOCOL_ETH, "ETH", QED_PCI_ETH}
72 };
73 
74 static bool qed_dcbx_app_ethtype(u32 app_info_bitmap)
75 {
76 	return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
77 		  DCBX_APP_SF_ETHTYPE);
78 }
79 
80 static bool qed_dcbx_ieee_app_ethtype(u32 app_info_bitmap)
81 {
82 	u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
83 
84 	/* Old MFW */
85 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
86 		return qed_dcbx_app_ethtype(app_info_bitmap);
87 
88 	return !!(mfw_val == DCBX_APP_SF_IEEE_ETHTYPE);
89 }
90 
91 static bool qed_dcbx_app_port(u32 app_info_bitmap)
92 {
93 	return !!(QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF) ==
94 		  DCBX_APP_SF_PORT);
95 }
96 
97 static bool qed_dcbx_ieee_app_port(u32 app_info_bitmap, u8 type)
98 {
99 	u8 mfw_val = QED_MFW_GET_FIELD(app_info_bitmap, DCBX_APP_SF_IEEE);
100 
101 	/* Old MFW */
102 	if (mfw_val == DCBX_APP_SF_IEEE_RESERVED)
103 		return qed_dcbx_app_port(app_info_bitmap);
104 
105 	return !!(mfw_val == type || mfw_val == DCBX_APP_SF_IEEE_TCP_UDP_PORT);
106 }
107 
108 static bool qed_dcbx_default_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
109 {
110 	bool ethtype;
111 
112 	if (ieee)
113 		ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap);
114 	else
115 		ethtype = qed_dcbx_app_ethtype(app_info_bitmap);
116 
117 	return !!(ethtype && (proto_id == QED_ETH_TYPE_DEFAULT));
118 }
119 
120 static bool qed_dcbx_iscsi_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
121 {
122 	bool port;
123 
124 	if (ieee)
125 		port = qed_dcbx_ieee_app_port(app_info_bitmap,
126 					      DCBX_APP_SF_IEEE_TCP_PORT);
127 	else
128 		port = qed_dcbx_app_port(app_info_bitmap);
129 
130 	return !!(port && (proto_id == QED_TCP_PORT_ISCSI));
131 }
132 
133 static bool qed_dcbx_fcoe_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
134 {
135 	bool ethtype;
136 
137 	if (ieee)
138 		ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap);
139 	else
140 		ethtype = qed_dcbx_app_ethtype(app_info_bitmap);
141 
142 	return !!(ethtype && (proto_id == QED_ETH_TYPE_FCOE));
143 }
144 
145 static bool qed_dcbx_roce_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
146 {
147 	bool ethtype;
148 
149 	if (ieee)
150 		ethtype = qed_dcbx_ieee_app_ethtype(app_info_bitmap);
151 	else
152 		ethtype = qed_dcbx_app_ethtype(app_info_bitmap);
153 
154 	return !!(ethtype && (proto_id == QED_ETH_TYPE_ROCE));
155 }
156 
157 static bool qed_dcbx_roce_v2_tlv(u32 app_info_bitmap, u16 proto_id, bool ieee)
158 {
159 	bool port;
160 
161 	if (ieee)
162 		port = qed_dcbx_ieee_app_port(app_info_bitmap,
163 					      DCBX_APP_SF_IEEE_UDP_PORT);
164 	else
165 		port = qed_dcbx_app_port(app_info_bitmap);
166 
167 	return !!(port && (proto_id == QED_UDP_PORT_TYPE_ROCE_V2));
168 }
169 
170 static void
171 qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data)
172 {
173 	enum dcbx_protocol_type id;
174 	int i;
175 
176 	DP_VERBOSE(p_hwfn, QED_MSG_DCB, "DCBX negotiated: %d\n",
177 		   p_data->dcbx_enabled);
178 
179 	for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) {
180 		id = qed_dcbx_app_update[i].id;
181 
182 		DP_VERBOSE(p_hwfn, QED_MSG_DCB,
183 			   "%s info: update %d, enable %d, prio %d, tc %d, num_tc %d\n",
184 			   qed_dcbx_app_update[i].name, p_data->arr[id].update,
185 			   p_data->arr[id].enable, p_data->arr[id].priority,
186 			   p_data->arr[id].tc, p_hwfn->hw_info.num_tc);
187 	}
188 }
189 
190 static void
191 qed_dcbx_set_params(struct qed_dcbx_results *p_data,
192 		    struct qed_hw_info *p_info,
193 		    bool enable,
194 		    bool update,
195 		    u8 prio,
196 		    u8 tc,
197 		    enum dcbx_protocol_type type,
198 		    enum qed_pci_personality personality)
199 {
200 	/* PF update ramrod data */
201 	p_data->arr[type].update = update;
202 	p_data->arr[type].enable = enable;
203 	p_data->arr[type].priority = prio;
204 	p_data->arr[type].tc = tc;
205 
206 	/* QM reconf data */
207 	if (p_info->personality == personality) {
208 		if (personality == QED_PCI_ETH)
209 			p_info->non_offload_tc = tc;
210 		else
211 			p_info->offload_tc = tc;
212 	}
213 }
214 
215 /* Update app protocol data and hw_info fields with the TLV info */
216 static void
217 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
218 			 struct qed_hwfn *p_hwfn,
219 			 bool enable,
220 			 bool update,
221 			 u8 prio, u8 tc, enum dcbx_protocol_type type)
222 {
223 	struct qed_hw_info *p_info = &p_hwfn->hw_info;
224 	enum qed_pci_personality personality;
225 	enum dcbx_protocol_type id;
226 	char *name;
227 	int i;
228 
229 	for (i = 0; i < ARRAY_SIZE(qed_dcbx_app_update); i++) {
230 		id = qed_dcbx_app_update[i].id;
231 
232 		if (type != id)
233 			continue;
234 
235 		personality = qed_dcbx_app_update[i].personality;
236 		name = qed_dcbx_app_update[i].name;
237 
238 		qed_dcbx_set_params(p_data, p_info, enable, update,
239 				    prio, tc, type, personality);
240 	}
241 }
242 
243 static bool
244 qed_dcbx_get_app_protocol_type(struct qed_hwfn *p_hwfn,
245 			       u32 app_prio_bitmap,
246 			       u16 id, enum dcbx_protocol_type *type, bool ieee)
247 {
248 	if (qed_dcbx_fcoe_tlv(app_prio_bitmap, id, ieee)) {
249 		*type = DCBX_PROTOCOL_FCOE;
250 	} else if (qed_dcbx_roce_tlv(app_prio_bitmap, id, ieee)) {
251 		*type = DCBX_PROTOCOL_ROCE;
252 	} else if (qed_dcbx_iscsi_tlv(app_prio_bitmap, id, ieee)) {
253 		*type = DCBX_PROTOCOL_ISCSI;
254 	} else if (qed_dcbx_default_tlv(app_prio_bitmap, id, ieee)) {
255 		*type = DCBX_PROTOCOL_ETH;
256 	} else if (qed_dcbx_roce_v2_tlv(app_prio_bitmap, id, ieee)) {
257 		*type = DCBX_PROTOCOL_ROCE_V2;
258 	} else {
259 		*type = DCBX_MAX_PROTOCOL_TYPE;
260 		DP_ERR(p_hwfn,
261 		       "No action required, App TLV id = 0x%x app_prio_bitmap = 0x%x\n",
262 		       id, app_prio_bitmap);
263 		return false;
264 	}
265 
266 	return true;
267 }
268 
269 /* Parse app TLV's to update TC information in hw_info structure for
270  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
271  */
272 static int
273 qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
274 		     struct qed_dcbx_results *p_data,
275 		     struct dcbx_app_priority_entry *p_tbl,
276 		     u32 pri_tc_tbl, int count, u8 dcbx_version)
277 {
278 	u8 tc, priority_map;
279 	enum dcbx_protocol_type type;
280 	bool enable, ieee;
281 	u16 protocol_id;
282 	int priority;
283 	int i;
284 
285 	DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Num APP entries = %d\n", count);
286 
287 	ieee = (dcbx_version == DCBX_CONFIG_VERSION_IEEE);
288 	/* Parse APP TLV */
289 	for (i = 0; i < count; i++) {
290 		protocol_id = QED_MFW_GET_FIELD(p_tbl[i].entry,
291 						DCBX_APP_PROTOCOL_ID);
292 		priority_map = QED_MFW_GET_FIELD(p_tbl[i].entry,
293 						 DCBX_APP_PRI_MAP);
294 		priority = ffs(priority_map) - 1;
295 		if (priority < 0) {
296 			DP_ERR(p_hwfn, "Invalid priority\n");
297 			return -EINVAL;
298 		}
299 
300 		tc = QED_DCBX_PRIO2TC(pri_tc_tbl, priority);
301 		if (qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
302 						   protocol_id, &type, ieee)) {
303 			/* ETH always have the enable bit reset, as it gets
304 			 * vlan information per packet. For other protocols,
305 			 * should be set according to the dcbx_enabled
306 			 * indication, but we only got here if there was an
307 			 * app tlv for the protocol, so dcbx must be enabled.
308 			 */
309 			enable = !(type == DCBX_PROTOCOL_ETH);
310 
311 			qed_dcbx_update_app_info(p_data, p_hwfn, enable, true,
312 						 priority, tc, type);
313 		}
314 	}
315 
316 	/* If RoCE-V2 TLV is not detected, driver need to use RoCE app
317 	 * data for RoCE-v2 not the default app data.
318 	 */
319 	if (!p_data->arr[DCBX_PROTOCOL_ROCE_V2].update &&
320 	    p_data->arr[DCBX_PROTOCOL_ROCE].update) {
321 		tc = p_data->arr[DCBX_PROTOCOL_ROCE].tc;
322 		priority = p_data->arr[DCBX_PROTOCOL_ROCE].priority;
323 		qed_dcbx_update_app_info(p_data, p_hwfn, true, true,
324 					 priority, tc, DCBX_PROTOCOL_ROCE_V2);
325 	}
326 
327 	/* Update ramrod protocol data and hw_info fields
328 	 * with default info when corresponding APP TLV's are not detected.
329 	 * The enabled field has a different logic for ethernet as only for
330 	 * ethernet dcb should disabled by default, as the information arrives
331 	 * from the OS (unless an explicit app tlv was present).
332 	 */
333 	tc = p_data->arr[DCBX_PROTOCOL_ETH].tc;
334 	priority = p_data->arr[DCBX_PROTOCOL_ETH].priority;
335 	for (type = 0; type < DCBX_MAX_PROTOCOL_TYPE; type++) {
336 		if (p_data->arr[type].update)
337 			continue;
338 
339 		enable = !(type == DCBX_PROTOCOL_ETH);
340 		qed_dcbx_update_app_info(p_data, p_hwfn, enable, true,
341 					 priority, tc, type);
342 	}
343 
344 	return 0;
345 }
346 
347 /* Parse app TLV's to update TC information in hw_info structure for
348  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
349  */
350 static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn)
351 {
352 	struct dcbx_app_priority_feature *p_app;
353 	struct dcbx_app_priority_entry *p_tbl;
354 	struct qed_dcbx_results data = { 0 };
355 	struct dcbx_ets_feature *p_ets;
356 	struct qed_hw_info *p_info;
357 	u32 pri_tc_tbl, flags;
358 	u8 dcbx_version;
359 	int num_entries;
360 	int rc = 0;
361 
362 	flags = p_hwfn->p_dcbx_info->operational.flags;
363 	dcbx_version = QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION);
364 
365 	p_app = &p_hwfn->p_dcbx_info->operational.features.app;
366 	p_tbl = p_app->app_pri_tbl;
367 
368 	p_ets = &p_hwfn->p_dcbx_info->operational.features.ets;
369 	pri_tc_tbl = p_ets->pri_tc_tbl[0];
370 
371 	p_info = &p_hwfn->hw_info;
372 	num_entries = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES);
373 
374 	rc = qed_dcbx_process_tlv(p_hwfn, &data, p_tbl, pri_tc_tbl,
375 				  num_entries, dcbx_version);
376 	if (rc)
377 		return rc;
378 
379 	p_info->num_tc = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_MAX_TCS);
380 	data.pf_id = p_hwfn->rel_pf_id;
381 	data.dcbx_enabled = !!dcbx_version;
382 
383 	qed_dcbx_dp_protocol(p_hwfn, &data);
384 
385 	memcpy(&p_hwfn->p_dcbx_info->results, &data,
386 	       sizeof(struct qed_dcbx_results));
387 
388 	return 0;
389 }
390 
391 static int
392 qed_dcbx_copy_mib(struct qed_hwfn *p_hwfn,
393 		  struct qed_ptt *p_ptt,
394 		  struct qed_dcbx_mib_meta_data *p_data,
395 		  enum qed_mib_read_type type)
396 {
397 	u32 prefix_seq_num, suffix_seq_num;
398 	int read_count = 0;
399 	int rc = 0;
400 
401 	/* The data is considered to be valid only if both sequence numbers are
402 	 * the same.
403 	 */
404 	do {
405 		if (type == QED_DCBX_REMOTE_LLDP_MIB) {
406 			qed_memcpy_from(p_hwfn, p_ptt, p_data->lldp_remote,
407 					p_data->addr, p_data->size);
408 			prefix_seq_num = p_data->lldp_remote->prefix_seq_num;
409 			suffix_seq_num = p_data->lldp_remote->suffix_seq_num;
410 		} else {
411 			qed_memcpy_from(p_hwfn, p_ptt, p_data->mib,
412 					p_data->addr, p_data->size);
413 			prefix_seq_num = p_data->mib->prefix_seq_num;
414 			suffix_seq_num = p_data->mib->suffix_seq_num;
415 		}
416 		read_count++;
417 
418 		DP_VERBOSE(p_hwfn,
419 			   QED_MSG_DCB,
420 			   "mib type = %d, try count = %d prefix seq num  = %d suffix seq num = %d\n",
421 			   type, read_count, prefix_seq_num, suffix_seq_num);
422 	} while ((prefix_seq_num != suffix_seq_num) &&
423 		 (read_count < QED_DCBX_MAX_MIB_READ_TRY));
424 
425 	if (read_count >= QED_DCBX_MAX_MIB_READ_TRY) {
426 		DP_ERR(p_hwfn,
427 		       "MIB read err, mib type = %d, try count = %d prefix seq num = %d suffix seq num = %d\n",
428 		       type, read_count, prefix_seq_num, suffix_seq_num);
429 		rc = -EIO;
430 	}
431 
432 	return rc;
433 }
434 
435 #ifdef CONFIG_DCB
436 static void
437 qed_dcbx_get_priority_info(struct qed_hwfn *p_hwfn,
438 			   struct qed_dcbx_app_prio *p_prio,
439 			   struct qed_dcbx_results *p_results)
440 {
441 	u8 val;
442 
443 	p_prio->roce = QED_DCBX_INVALID_PRIORITY;
444 	p_prio->roce_v2 = QED_DCBX_INVALID_PRIORITY;
445 	p_prio->iscsi = QED_DCBX_INVALID_PRIORITY;
446 	p_prio->fcoe = QED_DCBX_INVALID_PRIORITY;
447 
448 	if (p_results->arr[DCBX_PROTOCOL_ROCE].update &&
449 	    p_results->arr[DCBX_PROTOCOL_ROCE].enable)
450 		p_prio->roce = p_results->arr[DCBX_PROTOCOL_ROCE].priority;
451 
452 	if (p_results->arr[DCBX_PROTOCOL_ROCE_V2].update &&
453 	    p_results->arr[DCBX_PROTOCOL_ROCE_V2].enable) {
454 		val = p_results->arr[DCBX_PROTOCOL_ROCE_V2].priority;
455 		p_prio->roce_v2 = val;
456 	}
457 
458 	if (p_results->arr[DCBX_PROTOCOL_ISCSI].update &&
459 	    p_results->arr[DCBX_PROTOCOL_ISCSI].enable)
460 		p_prio->iscsi = p_results->arr[DCBX_PROTOCOL_ISCSI].priority;
461 
462 	if (p_results->arr[DCBX_PROTOCOL_FCOE].update &&
463 	    p_results->arr[DCBX_PROTOCOL_FCOE].enable)
464 		p_prio->fcoe = p_results->arr[DCBX_PROTOCOL_FCOE].priority;
465 
466 	if (p_results->arr[DCBX_PROTOCOL_ETH].update &&
467 	    p_results->arr[DCBX_PROTOCOL_ETH].enable)
468 		p_prio->eth = p_results->arr[DCBX_PROTOCOL_ETH].priority;
469 
470 	DP_VERBOSE(p_hwfn, QED_MSG_DCB,
471 		   "Priorities: iscsi %d, roce %d, roce v2 %d, fcoe %d, eth %d\n",
472 		   p_prio->iscsi, p_prio->roce, p_prio->roce_v2, p_prio->fcoe,
473 		   p_prio->eth);
474 }
475 
476 static void
477 qed_dcbx_get_app_data(struct qed_hwfn *p_hwfn,
478 		      struct dcbx_app_priority_feature *p_app,
479 		      struct dcbx_app_priority_entry *p_tbl,
480 		      struct qed_dcbx_params *p_params, bool ieee)
481 {
482 	struct qed_app_entry *entry;
483 	u8 pri_map;
484 	int i;
485 
486 	p_params->app_willing = QED_MFW_GET_FIELD(p_app->flags,
487 						  DCBX_APP_WILLING);
488 	p_params->app_valid = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ENABLED);
489 	p_params->app_error = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_ERROR);
490 	p_params->num_app_entries = QED_MFW_GET_FIELD(p_app->flags,
491 						      DCBX_APP_NUM_ENTRIES);
492 	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
493 		entry = &p_params->app_entry[i];
494 		if (ieee) {
495 			u8 sf_ieee;
496 			u32 val;
497 
498 			sf_ieee = QED_MFW_GET_FIELD(p_tbl[i].entry,
499 						    DCBX_APP_SF_IEEE);
500 			switch (sf_ieee) {
501 			case DCBX_APP_SF_IEEE_RESERVED:
502 				/* Old MFW */
503 				val = QED_MFW_GET_FIELD(p_tbl[i].entry,
504 							DCBX_APP_SF);
505 				entry->sf_ieee = val ?
506 				    QED_DCBX_SF_IEEE_TCP_UDP_PORT :
507 				    QED_DCBX_SF_IEEE_ETHTYPE;
508 				break;
509 			case DCBX_APP_SF_IEEE_ETHTYPE:
510 				entry->sf_ieee = QED_DCBX_SF_IEEE_ETHTYPE;
511 				break;
512 			case DCBX_APP_SF_IEEE_TCP_PORT:
513 				entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_PORT;
514 				break;
515 			case DCBX_APP_SF_IEEE_UDP_PORT:
516 				entry->sf_ieee = QED_DCBX_SF_IEEE_UDP_PORT;
517 				break;
518 			case DCBX_APP_SF_IEEE_TCP_UDP_PORT:
519 				entry->sf_ieee = QED_DCBX_SF_IEEE_TCP_UDP_PORT;
520 				break;
521 			}
522 		} else {
523 			entry->ethtype = !(QED_MFW_GET_FIELD(p_tbl[i].entry,
524 							     DCBX_APP_SF));
525 		}
526 
527 		pri_map = QED_MFW_GET_FIELD(p_tbl[i].entry, DCBX_APP_PRI_MAP);
528 		entry->prio = ffs(pri_map) - 1;
529 		entry->proto_id = QED_MFW_GET_FIELD(p_tbl[i].entry,
530 						    DCBX_APP_PROTOCOL_ID);
531 		qed_dcbx_get_app_protocol_type(p_hwfn, p_tbl[i].entry,
532 					       entry->proto_id,
533 					       &entry->proto_type, ieee);
534 	}
535 
536 	DP_VERBOSE(p_hwfn, QED_MSG_DCB,
537 		   "APP params: willing %d, valid %d error = %d\n",
538 		   p_params->app_willing, p_params->app_valid,
539 		   p_params->app_error);
540 }
541 
542 static void
543 qed_dcbx_get_pfc_data(struct qed_hwfn *p_hwfn,
544 		      u32 pfc, struct qed_dcbx_params *p_params)
545 {
546 	u8 pfc_map;
547 
548 	p_params->pfc.willing = QED_MFW_GET_FIELD(pfc, DCBX_PFC_WILLING);
549 	p_params->pfc.max_tc = QED_MFW_GET_FIELD(pfc, DCBX_PFC_CAPS);
550 	p_params->pfc.enabled = QED_MFW_GET_FIELD(pfc, DCBX_PFC_ENABLED);
551 	pfc_map = QED_MFW_GET_FIELD(pfc, DCBX_PFC_PRI_EN_BITMAP);
552 	p_params->pfc.prio[0] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_0);
553 	p_params->pfc.prio[1] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_1);
554 	p_params->pfc.prio[2] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_2);
555 	p_params->pfc.prio[3] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_3);
556 	p_params->pfc.prio[4] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_4);
557 	p_params->pfc.prio[5] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_5);
558 	p_params->pfc.prio[6] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_6);
559 	p_params->pfc.prio[7] = !!(pfc_map & DCBX_PFC_PRI_EN_BITMAP_PRI_7);
560 
561 	DP_VERBOSE(p_hwfn, QED_MSG_DCB,
562 		   "PFC params: willing %d, pfc_bitmap %d\n",
563 		   p_params->pfc.willing, pfc_map);
564 }
565 
566 static void
567 qed_dcbx_get_ets_data(struct qed_hwfn *p_hwfn,
568 		      struct dcbx_ets_feature *p_ets,
569 		      struct qed_dcbx_params *p_params)
570 {
571 	u32 bw_map[2], tsa_map[2], pri_map;
572 	int i;
573 
574 	p_params->ets_willing = QED_MFW_GET_FIELD(p_ets->flags,
575 						  DCBX_ETS_WILLING);
576 	p_params->ets_enabled = QED_MFW_GET_FIELD(p_ets->flags,
577 						  DCBX_ETS_ENABLED);
578 	p_params->ets_cbs = QED_MFW_GET_FIELD(p_ets->flags, DCBX_ETS_CBS);
579 	p_params->max_ets_tc = QED_MFW_GET_FIELD(p_ets->flags,
580 						 DCBX_ETS_MAX_TCS);
581 	DP_VERBOSE(p_hwfn, QED_MSG_DCB,
582 		   "ETS params: willing %d, ets_cbs %d pri_tc_tbl_0 %x max_ets_tc %d\n",
583 		   p_params->ets_willing,
584 		   p_params->ets_cbs,
585 		   p_ets->pri_tc_tbl[0], p_params->max_ets_tc);
586 
587 	/* 8 bit tsa and bw data corresponding to each of the 8 TC's are
588 	 * encoded in a type u32 array of size 2.
589 	 */
590 	bw_map[0] = be32_to_cpu(p_ets->tc_bw_tbl[0]);
591 	bw_map[1] = be32_to_cpu(p_ets->tc_bw_tbl[1]);
592 	tsa_map[0] = be32_to_cpu(p_ets->tc_tsa_tbl[0]);
593 	tsa_map[1] = be32_to_cpu(p_ets->tc_tsa_tbl[1]);
594 	pri_map = p_ets->pri_tc_tbl[0];
595 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) {
596 		p_params->ets_tc_bw_tbl[i] = ((u8 *)bw_map)[i];
597 		p_params->ets_tc_tsa_tbl[i] = ((u8 *)tsa_map)[i];
598 		p_params->ets_pri_tc_tbl[i] = QED_DCBX_PRIO2TC(pri_map, i);
599 		DP_VERBOSE(p_hwfn, QED_MSG_DCB,
600 			   "elem %d  bw_tbl %x tsa_tbl %x\n",
601 			   i, p_params->ets_tc_bw_tbl[i],
602 			   p_params->ets_tc_tsa_tbl[i]);
603 	}
604 }
605 
606 static void
607 qed_dcbx_get_common_params(struct qed_hwfn *p_hwfn,
608 			   struct dcbx_app_priority_feature *p_app,
609 			   struct dcbx_app_priority_entry *p_tbl,
610 			   struct dcbx_ets_feature *p_ets,
611 			   u32 pfc, struct qed_dcbx_params *p_params, bool ieee)
612 {
613 	qed_dcbx_get_app_data(p_hwfn, p_app, p_tbl, p_params, ieee);
614 	qed_dcbx_get_ets_data(p_hwfn, p_ets, p_params);
615 	qed_dcbx_get_pfc_data(p_hwfn, pfc, p_params);
616 }
617 
618 static void
619 qed_dcbx_get_local_params(struct qed_hwfn *p_hwfn,
620 			  struct qed_ptt *p_ptt, struct qed_dcbx_get *params)
621 {
622 	struct dcbx_features *p_feat;
623 
624 	p_feat = &p_hwfn->p_dcbx_info->local_admin.features;
625 	qed_dcbx_get_common_params(p_hwfn, &p_feat->app,
626 				   p_feat->app.app_pri_tbl, &p_feat->ets,
627 				   p_feat->pfc, &params->local.params, false);
628 	params->local.valid = true;
629 }
630 
631 static void
632 qed_dcbx_get_remote_params(struct qed_hwfn *p_hwfn,
633 			   struct qed_ptt *p_ptt, struct qed_dcbx_get *params)
634 {
635 	struct dcbx_features *p_feat;
636 
637 	p_feat = &p_hwfn->p_dcbx_info->remote.features;
638 	qed_dcbx_get_common_params(p_hwfn, &p_feat->app,
639 				   p_feat->app.app_pri_tbl, &p_feat->ets,
640 				   p_feat->pfc, &params->remote.params, false);
641 	params->remote.valid = true;
642 }
643 
644 static void
645 qed_dcbx_get_operational_params(struct qed_hwfn *p_hwfn,
646 				struct qed_ptt *p_ptt,
647 				struct qed_dcbx_get *params)
648 {
649 	struct qed_dcbx_operational_params *p_operational;
650 	struct qed_dcbx_results *p_results;
651 	struct dcbx_features *p_feat;
652 	bool enabled, err;
653 	u32 flags;
654 	bool val;
655 
656 	flags = p_hwfn->p_dcbx_info->operational.flags;
657 
658 	/* If DCBx version is non zero, then negotiation
659 	 * was successfuly performed
660 	 */
661 	p_operational = &params->operational;
662 	enabled = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) !=
663 		     DCBX_CONFIG_VERSION_DISABLED);
664 	if (!enabled) {
665 		p_operational->enabled = enabled;
666 		p_operational->valid = false;
667 		return;
668 	}
669 
670 	p_feat = &p_hwfn->p_dcbx_info->operational.features;
671 	p_results = &p_hwfn->p_dcbx_info->results;
672 
673 	val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
674 		 DCBX_CONFIG_VERSION_IEEE);
675 	p_operational->ieee = val;
676 	val = !!(QED_MFW_GET_FIELD(flags, DCBX_CONFIG_VERSION) ==
677 		 DCBX_CONFIG_VERSION_CEE);
678 	p_operational->cee = val;
679 
680 	DP_VERBOSE(p_hwfn, QED_MSG_DCB, "Version support: ieee %d, cee %d\n",
681 		   p_operational->ieee, p_operational->cee);
682 
683 	qed_dcbx_get_common_params(p_hwfn, &p_feat->app,
684 				   p_feat->app.app_pri_tbl, &p_feat->ets,
685 				   p_feat->pfc, &params->operational.params,
686 				   p_operational->ieee);
687 	qed_dcbx_get_priority_info(p_hwfn, &p_operational->app_prio, p_results);
688 	err = QED_MFW_GET_FIELD(p_feat->app.flags, DCBX_APP_ERROR);
689 	p_operational->err = err;
690 	p_operational->enabled = enabled;
691 	p_operational->valid = true;
692 }
693 
694 static void
695 qed_dcbx_get_local_lldp_params(struct qed_hwfn *p_hwfn,
696 			       struct qed_ptt *p_ptt,
697 			       struct qed_dcbx_get *params)
698 {
699 	struct lldp_config_params_s *p_local;
700 
701 	p_local = &p_hwfn->p_dcbx_info->lldp_local[LLDP_NEAREST_BRIDGE];
702 
703 	memcpy(params->lldp_local.local_chassis_id, p_local->local_chassis_id,
704 	       ARRAY_SIZE(p_local->local_chassis_id));
705 	memcpy(params->lldp_local.local_port_id, p_local->local_port_id,
706 	       ARRAY_SIZE(p_local->local_port_id));
707 }
708 
709 static void
710 qed_dcbx_get_remote_lldp_params(struct qed_hwfn *p_hwfn,
711 				struct qed_ptt *p_ptt,
712 				struct qed_dcbx_get *params)
713 {
714 	struct lldp_status_params_s *p_remote;
715 
716 	p_remote = &p_hwfn->p_dcbx_info->lldp_remote[LLDP_NEAREST_BRIDGE];
717 
718 	memcpy(params->lldp_remote.peer_chassis_id, p_remote->peer_chassis_id,
719 	       ARRAY_SIZE(p_remote->peer_chassis_id));
720 	memcpy(params->lldp_remote.peer_port_id, p_remote->peer_port_id,
721 	       ARRAY_SIZE(p_remote->peer_port_id));
722 }
723 
724 static int
725 qed_dcbx_get_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
726 		    struct qed_dcbx_get *p_params,
727 		    enum qed_mib_read_type type)
728 {
729 	switch (type) {
730 	case QED_DCBX_REMOTE_MIB:
731 		qed_dcbx_get_remote_params(p_hwfn, p_ptt, p_params);
732 		break;
733 	case QED_DCBX_LOCAL_MIB:
734 		qed_dcbx_get_local_params(p_hwfn, p_ptt, p_params);
735 		break;
736 	case QED_DCBX_OPERATIONAL_MIB:
737 		qed_dcbx_get_operational_params(p_hwfn, p_ptt, p_params);
738 		break;
739 	case QED_DCBX_REMOTE_LLDP_MIB:
740 		qed_dcbx_get_remote_lldp_params(p_hwfn, p_ptt, p_params);
741 		break;
742 	case QED_DCBX_LOCAL_LLDP_MIB:
743 		qed_dcbx_get_local_lldp_params(p_hwfn, p_ptt, p_params);
744 		break;
745 	default:
746 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
747 		return -EINVAL;
748 	}
749 
750 	return 0;
751 }
752 #endif
753 
754 static int
755 qed_dcbx_read_local_lldp_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
756 {
757 	struct qed_dcbx_mib_meta_data data;
758 	int rc = 0;
759 
760 	memset(&data, 0, sizeof(data));
761 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
762 							   lldp_config_params);
763 	data.lldp_local = p_hwfn->p_dcbx_info->lldp_local;
764 	data.size = sizeof(struct lldp_config_params_s);
765 	qed_memcpy_from(p_hwfn, p_ptt, data.lldp_local, data.addr, data.size);
766 
767 	return rc;
768 }
769 
770 static int
771 qed_dcbx_read_remote_lldp_mib(struct qed_hwfn *p_hwfn,
772 			      struct qed_ptt *p_ptt,
773 			      enum qed_mib_read_type type)
774 {
775 	struct qed_dcbx_mib_meta_data data;
776 	int rc = 0;
777 
778 	memset(&data, 0, sizeof(data));
779 	data.addr = p_hwfn->mcp_info->port_addr + offsetof(struct public_port,
780 							   lldp_status_params);
781 	data.lldp_remote = p_hwfn->p_dcbx_info->lldp_remote;
782 	data.size = sizeof(struct lldp_status_params_s);
783 	rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
784 
785 	return rc;
786 }
787 
788 static int
789 qed_dcbx_read_operational_mib(struct qed_hwfn *p_hwfn,
790 			      struct qed_ptt *p_ptt,
791 			      enum qed_mib_read_type type)
792 {
793 	struct qed_dcbx_mib_meta_data data;
794 	int rc = 0;
795 
796 	memset(&data, 0, sizeof(data));
797 	data.addr = p_hwfn->mcp_info->port_addr +
798 		    offsetof(struct public_port, operational_dcbx_mib);
799 	data.mib = &p_hwfn->p_dcbx_info->operational;
800 	data.size = sizeof(struct dcbx_mib);
801 	rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
802 
803 	return rc;
804 }
805 
806 static int
807 qed_dcbx_read_remote_mib(struct qed_hwfn *p_hwfn,
808 			 struct qed_ptt *p_ptt, enum qed_mib_read_type type)
809 {
810 	struct qed_dcbx_mib_meta_data data;
811 	int rc = 0;
812 
813 	memset(&data, 0, sizeof(data));
814 	data.addr = p_hwfn->mcp_info->port_addr +
815 		    offsetof(struct public_port, remote_dcbx_mib);
816 	data.mib = &p_hwfn->p_dcbx_info->remote;
817 	data.size = sizeof(struct dcbx_mib);
818 	rc = qed_dcbx_copy_mib(p_hwfn, p_ptt, &data, type);
819 
820 	return rc;
821 }
822 
823 static int
824 qed_dcbx_read_local_mib(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
825 {
826 	struct qed_dcbx_mib_meta_data data;
827 	int rc = 0;
828 
829 	memset(&data, 0, sizeof(data));
830 	data.addr = p_hwfn->mcp_info->port_addr +
831 		    offsetof(struct public_port, local_admin_dcbx_mib);
832 	data.local_admin = &p_hwfn->p_dcbx_info->local_admin;
833 	data.size = sizeof(struct dcbx_local_params);
834 	qed_memcpy_from(p_hwfn, p_ptt, data.local_admin, data.addr, data.size);
835 
836 	return rc;
837 }
838 
839 static int qed_dcbx_read_mib(struct qed_hwfn *p_hwfn,
840 			     struct qed_ptt *p_ptt, enum qed_mib_read_type type)
841 {
842 	int rc = -EINVAL;
843 
844 	switch (type) {
845 	case QED_DCBX_OPERATIONAL_MIB:
846 		rc = qed_dcbx_read_operational_mib(p_hwfn, p_ptt, type);
847 		break;
848 	case QED_DCBX_REMOTE_MIB:
849 		rc = qed_dcbx_read_remote_mib(p_hwfn, p_ptt, type);
850 		break;
851 	case QED_DCBX_LOCAL_MIB:
852 		rc = qed_dcbx_read_local_mib(p_hwfn, p_ptt);
853 		break;
854 	case QED_DCBX_REMOTE_LLDP_MIB:
855 		rc = qed_dcbx_read_remote_lldp_mib(p_hwfn, p_ptt, type);
856 		break;
857 	case QED_DCBX_LOCAL_LLDP_MIB:
858 		rc = qed_dcbx_read_local_lldp_mib(p_hwfn, p_ptt);
859 		break;
860 	default:
861 		DP_ERR(p_hwfn, "MIB read err, unknown mib type %d\n", type);
862 	}
863 
864 	return rc;
865 }
866 
867 /* Read updated MIB.
868  * Reconfigure QM and invoke PF update ramrod command if operational MIB
869  * change is detected.
870  */
871 int
872 qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn,
873 			  struct qed_ptt *p_ptt, enum qed_mib_read_type type)
874 {
875 	int rc = 0;
876 
877 	rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type);
878 	if (rc)
879 		return rc;
880 
881 	if (type == QED_DCBX_OPERATIONAL_MIB) {
882 		rc = qed_dcbx_process_mib_info(p_hwfn);
883 		if (!rc) {
884 			/* reconfigure tcs of QM queues according
885 			 * to negotiation results
886 			 */
887 			qed_qm_reconf(p_hwfn, p_ptt);
888 
889 			/* update storm FW with negotiation results */
890 			qed_sp_pf_update(p_hwfn);
891 		}
892 	}
893 
894 	return rc;
895 }
896 
897 int qed_dcbx_info_alloc(struct qed_hwfn *p_hwfn)
898 {
899 	int rc = 0;
900 
901 	p_hwfn->p_dcbx_info = kzalloc(sizeof(*p_hwfn->p_dcbx_info), GFP_KERNEL);
902 	if (!p_hwfn->p_dcbx_info)
903 		rc = -ENOMEM;
904 
905 	return rc;
906 }
907 
908 void qed_dcbx_info_free(struct qed_hwfn *p_hwfn,
909 			struct qed_dcbx_info *p_dcbx_info)
910 {
911 	kfree(p_hwfn->p_dcbx_info);
912 }
913 
914 static void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
915 					  struct qed_dcbx_results *p_src,
916 					  enum dcbx_protocol_type type)
917 {
918 	p_data->dcb_enable_flag = p_src->arr[type].enable;
919 	p_data->dcb_priority = p_src->arr[type].priority;
920 	p_data->dcb_tc = p_src->arr[type].tc;
921 }
922 
923 /* Set pf update ramrod command params */
924 void qed_dcbx_set_pf_update_params(struct qed_dcbx_results *p_src,
925 				   struct pf_update_ramrod_data *p_dest)
926 {
927 	struct protocol_dcb_data *p_dcb_data;
928 	bool update_flag = false;
929 
930 	p_dest->pf_id = p_src->pf_id;
931 
932 	update_flag = p_src->arr[DCBX_PROTOCOL_FCOE].update;
933 	p_dest->update_fcoe_dcb_data_flag = update_flag;
934 
935 	update_flag = p_src->arr[DCBX_PROTOCOL_ROCE].update;
936 	p_dest->update_roce_dcb_data_flag = update_flag;
937 	update_flag = p_src->arr[DCBX_PROTOCOL_ROCE_V2].update;
938 	p_dest->update_roce_dcb_data_flag = update_flag;
939 
940 	update_flag = p_src->arr[DCBX_PROTOCOL_ISCSI].update;
941 	p_dest->update_iscsi_dcb_data_flag = update_flag;
942 	update_flag = p_src->arr[DCBX_PROTOCOL_ETH].update;
943 	p_dest->update_eth_dcb_data_flag = update_flag;
944 
945 	p_dcb_data = &p_dest->fcoe_dcb_data;
946 	qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_FCOE);
947 	p_dcb_data = &p_dest->roce_dcb_data;
948 
949 	if (p_src->arr[DCBX_PROTOCOL_ROCE].update)
950 		qed_dcbx_update_protocol_data(p_dcb_data, p_src,
951 					      DCBX_PROTOCOL_ROCE);
952 	if (p_src->arr[DCBX_PROTOCOL_ROCE_V2].update)
953 		qed_dcbx_update_protocol_data(p_dcb_data, p_src,
954 					      DCBX_PROTOCOL_ROCE_V2);
955 
956 	p_dcb_data = &p_dest->iscsi_dcb_data;
957 	qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ISCSI);
958 	p_dcb_data = &p_dest->eth_dcb_data;
959 	qed_dcbx_update_protocol_data(p_dcb_data, p_src, DCBX_PROTOCOL_ETH);
960 }
961 
962 #ifdef CONFIG_DCB
963 static int qed_dcbx_query_params(struct qed_hwfn *p_hwfn,
964 				 struct qed_dcbx_get *p_get,
965 				 enum qed_mib_read_type type)
966 {
967 	struct qed_ptt *p_ptt;
968 	int rc;
969 
970 	if (IS_VF(p_hwfn->cdev))
971 		return -EINVAL;
972 
973 	p_ptt = qed_ptt_acquire(p_hwfn);
974 	if (!p_ptt)
975 		return -EBUSY;
976 
977 	rc = qed_dcbx_read_mib(p_hwfn, p_ptt, type);
978 	if (rc)
979 		goto out;
980 
981 	rc = qed_dcbx_get_params(p_hwfn, p_ptt, p_get, type);
982 
983 out:
984 	qed_ptt_release(p_hwfn, p_ptt);
985 	return rc;
986 }
987 
988 static void
989 qed_dcbx_set_pfc_data(struct qed_hwfn *p_hwfn,
990 		      u32 *pfc, struct qed_dcbx_params *p_params)
991 {
992 	u8 pfc_map = 0;
993 	int i;
994 
995 	if (p_params->pfc.willing)
996 		*pfc |= DCBX_PFC_WILLING_MASK;
997 	else
998 		*pfc &= ~DCBX_PFC_WILLING_MASK;
999 
1000 	if (p_params->pfc.enabled)
1001 		*pfc |= DCBX_PFC_ENABLED_MASK;
1002 	else
1003 		*pfc &= ~DCBX_PFC_ENABLED_MASK;
1004 
1005 	*pfc &= ~DCBX_PFC_CAPS_MASK;
1006 	*pfc |= (u32)p_params->pfc.max_tc << DCBX_PFC_CAPS_SHIFT;
1007 
1008 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++)
1009 		if (p_params->pfc.prio[i])
1010 			pfc_map |= BIT(i);
1011 
1012 	*pfc &= ~DCBX_PFC_PRI_EN_BITMAP_MASK;
1013 	*pfc |= (pfc_map << DCBX_PFC_PRI_EN_BITMAP_SHIFT);
1014 
1015 	DP_VERBOSE(p_hwfn, QED_MSG_DCB, "pfc = 0x%x\n", *pfc);
1016 }
1017 
1018 static void
1019 qed_dcbx_set_ets_data(struct qed_hwfn *p_hwfn,
1020 		      struct dcbx_ets_feature *p_ets,
1021 		      struct qed_dcbx_params *p_params)
1022 {
1023 	u8 *bw_map, *tsa_map;
1024 	u32 val;
1025 	int i;
1026 
1027 	if (p_params->ets_willing)
1028 		p_ets->flags |= DCBX_ETS_WILLING_MASK;
1029 	else
1030 		p_ets->flags &= ~DCBX_ETS_WILLING_MASK;
1031 
1032 	if (p_params->ets_cbs)
1033 		p_ets->flags |= DCBX_ETS_CBS_MASK;
1034 	else
1035 		p_ets->flags &= ~DCBX_ETS_CBS_MASK;
1036 
1037 	if (p_params->ets_enabled)
1038 		p_ets->flags |= DCBX_ETS_ENABLED_MASK;
1039 	else
1040 		p_ets->flags &= ~DCBX_ETS_ENABLED_MASK;
1041 
1042 	p_ets->flags &= ~DCBX_ETS_MAX_TCS_MASK;
1043 	p_ets->flags |= (u32)p_params->max_ets_tc << DCBX_ETS_MAX_TCS_SHIFT;
1044 
1045 	bw_map = (u8 *)&p_ets->tc_bw_tbl[0];
1046 	tsa_map = (u8 *)&p_ets->tc_tsa_tbl[0];
1047 	p_ets->pri_tc_tbl[0] = 0;
1048 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) {
1049 		bw_map[i] = p_params->ets_tc_bw_tbl[i];
1050 		tsa_map[i] = p_params->ets_tc_tsa_tbl[i];
1051 		/* Copy the priority value to the corresponding 4 bits in the
1052 		 * traffic class table.
1053 		 */
1054 		val = (((u32)p_params->ets_pri_tc_tbl[i]) << ((7 - i) * 4));
1055 		p_ets->pri_tc_tbl[0] |= val;
1056 	}
1057 	for (i = 0; i < 2; i++) {
1058 		p_ets->tc_bw_tbl[i] = cpu_to_be32(p_ets->tc_bw_tbl[i]);
1059 		p_ets->tc_tsa_tbl[i] = cpu_to_be32(p_ets->tc_tsa_tbl[i]);
1060 	}
1061 }
1062 
1063 static void
1064 qed_dcbx_set_app_data(struct qed_hwfn *p_hwfn,
1065 		      struct dcbx_app_priority_feature *p_app,
1066 		      struct qed_dcbx_params *p_params, bool ieee)
1067 {
1068 	u32 *entry;
1069 	int i;
1070 
1071 	if (p_params->app_willing)
1072 		p_app->flags |= DCBX_APP_WILLING_MASK;
1073 	else
1074 		p_app->flags &= ~DCBX_APP_WILLING_MASK;
1075 
1076 	if (p_params->app_valid)
1077 		p_app->flags |= DCBX_APP_ENABLED_MASK;
1078 	else
1079 		p_app->flags &= ~DCBX_APP_ENABLED_MASK;
1080 
1081 	p_app->flags &= ~DCBX_APP_NUM_ENTRIES_MASK;
1082 	p_app->flags |= (u32)p_params->num_app_entries <<
1083 	    DCBX_APP_NUM_ENTRIES_SHIFT;
1084 
1085 	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
1086 		entry = &p_app->app_pri_tbl[i].entry;
1087 		*entry = 0;
1088 		if (ieee) {
1089 			*entry &= ~(DCBX_APP_SF_IEEE_MASK | DCBX_APP_SF_MASK);
1090 			switch (p_params->app_entry[i].sf_ieee) {
1091 			case QED_DCBX_SF_IEEE_ETHTYPE:
1092 				*entry |= ((u32)DCBX_APP_SF_IEEE_ETHTYPE <<
1093 					   DCBX_APP_SF_IEEE_SHIFT);
1094 				*entry |= ((u32)DCBX_APP_SF_ETHTYPE <<
1095 					   DCBX_APP_SF_SHIFT);
1096 				break;
1097 			case QED_DCBX_SF_IEEE_TCP_PORT:
1098 				*entry |= ((u32)DCBX_APP_SF_IEEE_TCP_PORT <<
1099 					   DCBX_APP_SF_IEEE_SHIFT);
1100 				*entry |= ((u32)DCBX_APP_SF_PORT <<
1101 					   DCBX_APP_SF_SHIFT);
1102 				break;
1103 			case QED_DCBX_SF_IEEE_UDP_PORT:
1104 				*entry |= ((u32)DCBX_APP_SF_IEEE_UDP_PORT <<
1105 					   DCBX_APP_SF_IEEE_SHIFT);
1106 				*entry |= ((u32)DCBX_APP_SF_PORT <<
1107 					   DCBX_APP_SF_SHIFT);
1108 				break;
1109 			case QED_DCBX_SF_IEEE_TCP_UDP_PORT:
1110 				*entry |= ((u32)DCBX_APP_SF_IEEE_TCP_UDP_PORT <<
1111 					   DCBX_APP_SF_IEEE_SHIFT);
1112 				*entry |= ((u32)DCBX_APP_SF_PORT <<
1113 					   DCBX_APP_SF_SHIFT);
1114 				break;
1115 			}
1116 		} else {
1117 			*entry &= ~DCBX_APP_SF_MASK;
1118 			if (p_params->app_entry[i].ethtype)
1119 				*entry |= ((u32)DCBX_APP_SF_ETHTYPE <<
1120 					   DCBX_APP_SF_SHIFT);
1121 			else
1122 				*entry |= ((u32)DCBX_APP_SF_PORT <<
1123 					   DCBX_APP_SF_SHIFT);
1124 		}
1125 
1126 		*entry &= ~DCBX_APP_PROTOCOL_ID_MASK;
1127 		*entry |= ((u32)p_params->app_entry[i].proto_id <<
1128 			   DCBX_APP_PROTOCOL_ID_SHIFT);
1129 		*entry &= ~DCBX_APP_PRI_MAP_MASK;
1130 		*entry |= ((u32)(p_params->app_entry[i].prio) <<
1131 			   DCBX_APP_PRI_MAP_SHIFT);
1132 	}
1133 }
1134 
1135 static void
1136 qed_dcbx_set_local_params(struct qed_hwfn *p_hwfn,
1137 			  struct dcbx_local_params *local_admin,
1138 			  struct qed_dcbx_set *params)
1139 {
1140 	bool ieee = false;
1141 
1142 	local_admin->flags = 0;
1143 	memcpy(&local_admin->features,
1144 	       &p_hwfn->p_dcbx_info->operational.features,
1145 	       sizeof(local_admin->features));
1146 
1147 	if (params->enabled) {
1148 		local_admin->config = params->ver_num;
1149 		ieee = !!(params->ver_num & DCBX_CONFIG_VERSION_IEEE);
1150 	} else {
1151 		local_admin->config = DCBX_CONFIG_VERSION_DISABLED;
1152 	}
1153 
1154 	if (params->override_flags & QED_DCBX_OVERRIDE_PFC_CFG)
1155 		qed_dcbx_set_pfc_data(p_hwfn, &local_admin->features.pfc,
1156 				      &params->config.params);
1157 
1158 	if (params->override_flags & QED_DCBX_OVERRIDE_ETS_CFG)
1159 		qed_dcbx_set_ets_data(p_hwfn, &local_admin->features.ets,
1160 				      &params->config.params);
1161 
1162 	if (params->override_flags & QED_DCBX_OVERRIDE_APP_CFG)
1163 		qed_dcbx_set_app_data(p_hwfn, &local_admin->features.app,
1164 				      &params->config.params, ieee);
1165 }
1166 
1167 int qed_dcbx_config_params(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
1168 			   struct qed_dcbx_set *params, bool hw_commit)
1169 {
1170 	struct dcbx_local_params local_admin;
1171 	struct qed_dcbx_mib_meta_data data;
1172 	u32 resp = 0, param = 0;
1173 	int rc = 0;
1174 
1175 	if (!hw_commit) {
1176 		memcpy(&p_hwfn->p_dcbx_info->set, params,
1177 		       sizeof(struct qed_dcbx_set));
1178 		return 0;
1179 	}
1180 
1181 	/* clear set-parmas cache */
1182 	memset(&p_hwfn->p_dcbx_info->set, 0, sizeof(p_hwfn->p_dcbx_info->set));
1183 
1184 	memset(&local_admin, 0, sizeof(local_admin));
1185 	qed_dcbx_set_local_params(p_hwfn, &local_admin, params);
1186 
1187 	data.addr = p_hwfn->mcp_info->port_addr +
1188 	    offsetof(struct public_port, local_admin_dcbx_mib);
1189 	data.local_admin = &local_admin;
1190 	data.size = sizeof(struct dcbx_local_params);
1191 	qed_memcpy_to(p_hwfn, p_ptt, data.addr, data.local_admin, data.size);
1192 
1193 	rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_SET_DCBX,
1194 			 1 << DRV_MB_PARAM_LLDP_SEND_SHIFT, &resp, &param);
1195 	if (rc)
1196 		DP_NOTICE(p_hwfn, "Failed to send DCBX update request\n");
1197 
1198 	return rc;
1199 }
1200 
1201 int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn,
1202 			       struct qed_dcbx_set *params)
1203 {
1204 	struct qed_dcbx_get *dcbx_info;
1205 	int rc;
1206 
1207 	if (p_hwfn->p_dcbx_info->set.config.valid) {
1208 		memcpy(params, &p_hwfn->p_dcbx_info->set,
1209 		       sizeof(struct qed_dcbx_set));
1210 		return 0;
1211 	}
1212 
1213 	dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL);
1214 	if (!dcbx_info)
1215 		return -ENOMEM;
1216 
1217 	memset(dcbx_info, 0, sizeof(*dcbx_info));
1218 	rc = qed_dcbx_query_params(p_hwfn, dcbx_info, QED_DCBX_OPERATIONAL_MIB);
1219 	if (rc) {
1220 		kfree(dcbx_info);
1221 		return rc;
1222 	}
1223 
1224 	p_hwfn->p_dcbx_info->set.override_flags = 0;
1225 	p_hwfn->p_dcbx_info->set.ver_num = DCBX_CONFIG_VERSION_DISABLED;
1226 	if (dcbx_info->operational.cee)
1227 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_CEE;
1228 	if (dcbx_info->operational.ieee)
1229 		p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_IEEE;
1230 
1231 	p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled;
1232 	memcpy(&p_hwfn->p_dcbx_info->set.config.params,
1233 	       &dcbx_info->operational.params,
1234 	       sizeof(struct qed_dcbx_admin_params));
1235 	p_hwfn->p_dcbx_info->set.config.valid = true;
1236 
1237 	memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set));
1238 
1239 	kfree(dcbx_info);
1240 
1241 	return 0;
1242 }
1243 
1244 static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn,
1245 					       enum qed_mib_read_type type)
1246 {
1247 	struct qed_dcbx_get *dcbx_info;
1248 
1249 	dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL);
1250 	if (!dcbx_info)
1251 		return NULL;
1252 
1253 	memset(dcbx_info, 0, sizeof(*dcbx_info));
1254 	if (qed_dcbx_query_params(hwfn, dcbx_info, type)) {
1255 		kfree(dcbx_info);
1256 		return NULL;
1257 	}
1258 
1259 	if ((type == QED_DCBX_OPERATIONAL_MIB) &&
1260 	    !dcbx_info->operational.enabled) {
1261 		DP_INFO(hwfn, "DCBX is not enabled/operational\n");
1262 		kfree(dcbx_info);
1263 		return NULL;
1264 	}
1265 
1266 	return dcbx_info;
1267 }
1268 
1269 static u8 qed_dcbnl_getstate(struct qed_dev *cdev)
1270 {
1271 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1272 	struct qed_dcbx_get *dcbx_info;
1273 	bool enabled;
1274 
1275 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1276 	if (!dcbx_info)
1277 		return 0;
1278 
1279 	enabled = dcbx_info->operational.enabled;
1280 	DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", enabled);
1281 	kfree(dcbx_info);
1282 
1283 	return enabled;
1284 }
1285 
1286 static u8 qed_dcbnl_setstate(struct qed_dev *cdev, u8 state)
1287 {
1288 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1289 	struct qed_dcbx_set dcbx_set;
1290 	struct qed_ptt *ptt;
1291 	int rc;
1292 
1293 	DP_VERBOSE(hwfn, QED_MSG_DCB, "DCB state = %d\n", state);
1294 
1295 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1296 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1297 	if (rc)
1298 		return 1;
1299 
1300 	dcbx_set.enabled = !!state;
1301 
1302 	ptt = qed_ptt_acquire(hwfn);
1303 	if (!ptt)
1304 		return 1;
1305 
1306 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1307 
1308 	qed_ptt_release(hwfn, ptt);
1309 
1310 	return rc ? 1 : 0;
1311 }
1312 
1313 static void qed_dcbnl_getpgtccfgtx(struct qed_dev *cdev, int tc, u8 *prio_type,
1314 				   u8 *pgid, u8 *bw_pct, u8 *up_map)
1315 {
1316 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1317 	struct qed_dcbx_get *dcbx_info;
1318 
1319 	DP_VERBOSE(hwfn, QED_MSG_DCB, "tc = %d\n", tc);
1320 	*prio_type = *pgid = *bw_pct = *up_map = 0;
1321 	if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) {
1322 		DP_INFO(hwfn, "Invalid tc %d\n", tc);
1323 		return;
1324 	}
1325 
1326 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1327 	if (!dcbx_info)
1328 		return;
1329 
1330 	*pgid = dcbx_info->operational.params.ets_pri_tc_tbl[tc];
1331 	kfree(dcbx_info);
1332 }
1333 
1334 static void qed_dcbnl_getpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 *bw_pct)
1335 {
1336 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1337 	struct qed_dcbx_get *dcbx_info;
1338 
1339 	*bw_pct = 0;
1340 	DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d\n", pgid);
1341 	if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) {
1342 		DP_INFO(hwfn, "Invalid pgid %d\n", pgid);
1343 		return;
1344 	}
1345 
1346 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1347 	if (!dcbx_info)
1348 		return;
1349 
1350 	*bw_pct = dcbx_info->operational.params.ets_tc_bw_tbl[pgid];
1351 	DP_VERBOSE(hwfn, QED_MSG_DCB, "bw_pct = %d\n", *bw_pct);
1352 	kfree(dcbx_info);
1353 }
1354 
1355 static void qed_dcbnl_getpgtccfgrx(struct qed_dev *cdev, int tc, u8 *prio,
1356 				   u8 *bwg_id, u8 *bw_pct, u8 *up_map)
1357 {
1358 	DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n");
1359 	*prio = *bwg_id = *bw_pct = *up_map = 0;
1360 }
1361 
1362 static void qed_dcbnl_getpgbwgcfgrx(struct qed_dev *cdev,
1363 				    int bwg_id, u8 *bw_pct)
1364 {
1365 	DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n");
1366 	*bw_pct = 0;
1367 }
1368 
1369 static void qed_dcbnl_getpfccfg(struct qed_dev *cdev,
1370 				int priority, u8 *setting)
1371 {
1372 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1373 	struct qed_dcbx_get *dcbx_info;
1374 
1375 	DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d\n", priority);
1376 	if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) {
1377 		DP_INFO(hwfn, "Invalid priority %d\n", priority);
1378 		return;
1379 	}
1380 
1381 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1382 	if (!dcbx_info)
1383 		return;
1384 
1385 	*setting = dcbx_info->operational.params.pfc.prio[priority];
1386 	DP_VERBOSE(hwfn, QED_MSG_DCB, "setting = %d\n", *setting);
1387 	kfree(dcbx_info);
1388 }
1389 
1390 static void qed_dcbnl_setpfccfg(struct qed_dev *cdev, int priority, u8 setting)
1391 {
1392 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1393 	struct qed_dcbx_set dcbx_set;
1394 	struct qed_ptt *ptt;
1395 	int rc;
1396 
1397 	DP_VERBOSE(hwfn, QED_MSG_DCB, "priority = %d setting = %d\n",
1398 		   priority, setting);
1399 	if (priority < 0 || priority >= QED_MAX_PFC_PRIORITIES) {
1400 		DP_INFO(hwfn, "Invalid priority %d\n", priority);
1401 		return;
1402 	}
1403 
1404 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1405 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1406 	if (rc)
1407 		return;
1408 
1409 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG;
1410 	dcbx_set.config.params.pfc.prio[priority] = !!setting;
1411 
1412 	ptt = qed_ptt_acquire(hwfn);
1413 	if (!ptt)
1414 		return;
1415 
1416 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1417 
1418 	qed_ptt_release(hwfn, ptt);
1419 }
1420 
1421 static u8 qed_dcbnl_getcap(struct qed_dev *cdev, int capid, u8 *cap)
1422 {
1423 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1424 	struct qed_dcbx_get *dcbx_info;
1425 	int rc = 0;
1426 
1427 	DP_VERBOSE(hwfn, QED_MSG_DCB, "capid = %d\n", capid);
1428 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1429 	if (!dcbx_info)
1430 		return 1;
1431 
1432 	switch (capid) {
1433 	case DCB_CAP_ATTR_PG:
1434 	case DCB_CAP_ATTR_PFC:
1435 	case DCB_CAP_ATTR_UP2TC:
1436 	case DCB_CAP_ATTR_GSP:
1437 		*cap = true;
1438 		break;
1439 	case DCB_CAP_ATTR_PG_TCS:
1440 	case DCB_CAP_ATTR_PFC_TCS:
1441 		*cap = 0x80;
1442 		break;
1443 	case DCB_CAP_ATTR_DCBX:
1444 		*cap = (DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_CEE |
1445 			DCB_CAP_DCBX_VER_IEEE);
1446 		break;
1447 	default:
1448 		*cap = false;
1449 		rc = 1;
1450 	}
1451 
1452 	DP_VERBOSE(hwfn, QED_MSG_DCB, "id = %d caps = %d\n", capid, *cap);
1453 	kfree(dcbx_info);
1454 
1455 	return rc;
1456 }
1457 
1458 static int qed_dcbnl_getnumtcs(struct qed_dev *cdev, int tcid, u8 *num)
1459 {
1460 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1461 	struct qed_dcbx_get *dcbx_info;
1462 	int rc = 0;
1463 
1464 	DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d\n", tcid);
1465 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1466 	if (!dcbx_info)
1467 		return -EINVAL;
1468 
1469 	switch (tcid) {
1470 	case DCB_NUMTCS_ATTR_PG:
1471 		*num = dcbx_info->operational.params.max_ets_tc;
1472 		break;
1473 	case DCB_NUMTCS_ATTR_PFC:
1474 		*num = dcbx_info->operational.params.pfc.max_tc;
1475 		break;
1476 	default:
1477 		rc = -EINVAL;
1478 	}
1479 
1480 	kfree(dcbx_info);
1481 	DP_VERBOSE(hwfn, QED_MSG_DCB, "numtcs = %d\n", *num);
1482 
1483 	return rc;
1484 }
1485 
1486 static u8 qed_dcbnl_getpfcstate(struct qed_dev *cdev)
1487 {
1488 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1489 	struct qed_dcbx_get *dcbx_info;
1490 	bool enabled;
1491 
1492 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1493 	if (!dcbx_info)
1494 		return 0;
1495 
1496 	enabled = dcbx_info->operational.params.pfc.enabled;
1497 	DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d\n", enabled);
1498 	kfree(dcbx_info);
1499 
1500 	return enabled;
1501 }
1502 
1503 static u8 qed_dcbnl_getdcbx(struct qed_dev *cdev)
1504 {
1505 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1506 	struct qed_dcbx_get *dcbx_info;
1507 	u8 mode = 0;
1508 
1509 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1510 	if (!dcbx_info)
1511 		return 0;
1512 
1513 	if (dcbx_info->operational.enabled)
1514 		mode |= DCB_CAP_DCBX_LLD_MANAGED;
1515 	if (dcbx_info->operational.ieee)
1516 		mode |= DCB_CAP_DCBX_VER_IEEE;
1517 	if (dcbx_info->operational.cee)
1518 		mode |= DCB_CAP_DCBX_VER_CEE;
1519 
1520 	DP_VERBOSE(hwfn, QED_MSG_DCB, "dcb mode = %d\n", mode);
1521 	kfree(dcbx_info);
1522 
1523 	return mode;
1524 }
1525 
1526 static void qed_dcbnl_setpgtccfgtx(struct qed_dev *cdev,
1527 				   int tc,
1528 				   u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map)
1529 {
1530 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1531 	struct qed_dcbx_set dcbx_set;
1532 	struct qed_ptt *ptt;
1533 	int rc;
1534 
1535 	DP_VERBOSE(hwfn, QED_MSG_DCB,
1536 		   "tc = %d pri_type = %d pgid = %d bw_pct = %d up_map = %d\n",
1537 		   tc, pri_type, pgid, bw_pct, up_map);
1538 
1539 	if (tc < 0 || tc >= QED_MAX_PFC_PRIORITIES) {
1540 		DP_INFO(hwfn, "Invalid tc %d\n", tc);
1541 		return;
1542 	}
1543 
1544 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1545 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1546 	if (rc)
1547 		return;
1548 
1549 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG;
1550 	dcbx_set.config.params.ets_pri_tc_tbl[tc] = pgid;
1551 
1552 	ptt = qed_ptt_acquire(hwfn);
1553 	if (!ptt)
1554 		return;
1555 
1556 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1557 
1558 	qed_ptt_release(hwfn, ptt);
1559 }
1560 
1561 static void qed_dcbnl_setpgtccfgrx(struct qed_dev *cdev, int prio,
1562 				   u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map)
1563 {
1564 	DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n");
1565 }
1566 
1567 static void qed_dcbnl_setpgbwgcfgtx(struct qed_dev *cdev, int pgid, u8 bw_pct)
1568 {
1569 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1570 	struct qed_dcbx_set dcbx_set;
1571 	struct qed_ptt *ptt;
1572 	int rc;
1573 
1574 	DP_VERBOSE(hwfn, QED_MSG_DCB, "pgid = %d bw_pct = %d\n", pgid, bw_pct);
1575 	if (pgid < 0 || pgid >= QED_MAX_PFC_PRIORITIES) {
1576 		DP_INFO(hwfn, "Invalid pgid %d\n", pgid);
1577 		return;
1578 	}
1579 
1580 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1581 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1582 	if (rc)
1583 		return;
1584 
1585 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG;
1586 	dcbx_set.config.params.ets_tc_bw_tbl[pgid] = bw_pct;
1587 
1588 	ptt = qed_ptt_acquire(hwfn);
1589 	if (!ptt)
1590 		return;
1591 
1592 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1593 
1594 	qed_ptt_release(hwfn, ptt);
1595 }
1596 
1597 static void qed_dcbnl_setpgbwgcfgrx(struct qed_dev *cdev, int pgid, u8 bw_pct)
1598 {
1599 	DP_INFO(QED_LEADING_HWFN(cdev), "Rx ETS is not supported\n");
1600 }
1601 
1602 static u8 qed_dcbnl_setall(struct qed_dev *cdev)
1603 {
1604 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1605 	struct qed_dcbx_set dcbx_set;
1606 	struct qed_ptt *ptt;
1607 	int rc;
1608 
1609 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1610 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1611 	if (rc)
1612 		return 1;
1613 
1614 	ptt = qed_ptt_acquire(hwfn);
1615 	if (!ptt)
1616 		return 1;
1617 
1618 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 1);
1619 
1620 	qed_ptt_release(hwfn, ptt);
1621 
1622 	return rc;
1623 }
1624 
1625 static int qed_dcbnl_setnumtcs(struct qed_dev *cdev, int tcid, u8 num)
1626 {
1627 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1628 	struct qed_dcbx_set dcbx_set;
1629 	struct qed_ptt *ptt;
1630 	int rc;
1631 
1632 	DP_VERBOSE(hwfn, QED_MSG_DCB, "tcid = %d num = %d\n", tcid, num);
1633 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1634 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1635 	if (rc)
1636 		return 1;
1637 
1638 	switch (tcid) {
1639 	case DCB_NUMTCS_ATTR_PG:
1640 		dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG;
1641 		dcbx_set.config.params.max_ets_tc = num;
1642 		break;
1643 	case DCB_NUMTCS_ATTR_PFC:
1644 		dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG;
1645 		dcbx_set.config.params.pfc.max_tc = num;
1646 		break;
1647 	default:
1648 		DP_INFO(hwfn, "Invalid tcid %d\n", tcid);
1649 		return -EINVAL;
1650 	}
1651 
1652 	ptt = qed_ptt_acquire(hwfn);
1653 	if (!ptt)
1654 		return -EINVAL;
1655 
1656 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1657 
1658 	qed_ptt_release(hwfn, ptt);
1659 
1660 	return 0;
1661 }
1662 
1663 static void qed_dcbnl_setpfcstate(struct qed_dev *cdev, u8 state)
1664 {
1665 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1666 	struct qed_dcbx_set dcbx_set;
1667 	struct qed_ptt *ptt;
1668 	int rc;
1669 
1670 	DP_VERBOSE(hwfn, QED_MSG_DCB, "new state = %d\n", state);
1671 
1672 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1673 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1674 	if (rc)
1675 		return;
1676 
1677 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG;
1678 	dcbx_set.config.params.pfc.enabled = !!state;
1679 
1680 	ptt = qed_ptt_acquire(hwfn);
1681 	if (!ptt)
1682 		return;
1683 
1684 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1685 
1686 	qed_ptt_release(hwfn, ptt);
1687 }
1688 
1689 static int qed_dcbnl_getapp(struct qed_dev *cdev, u8 idtype, u16 idval)
1690 {
1691 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1692 	struct qed_dcbx_get *dcbx_info;
1693 	struct qed_app_entry *entry;
1694 	bool ethtype;
1695 	u8 prio = 0;
1696 	int i;
1697 
1698 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1699 	if (!dcbx_info)
1700 		return -EINVAL;
1701 
1702 	ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE);
1703 	for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) {
1704 		entry = &dcbx_info->operational.params.app_entry[i];
1705 		if ((entry->ethtype == ethtype) && (entry->proto_id == idval)) {
1706 			prio = entry->prio;
1707 			break;
1708 		}
1709 	}
1710 
1711 	if (i == QED_DCBX_MAX_APP_PROTOCOL) {
1712 		DP_ERR(cdev, "App entry (%d, %d) not found\n", idtype, idval);
1713 		kfree(dcbx_info);
1714 		return -EINVAL;
1715 	}
1716 
1717 	kfree(dcbx_info);
1718 
1719 	return prio;
1720 }
1721 
1722 static int qed_dcbnl_setapp(struct qed_dev *cdev,
1723 			    u8 idtype, u16 idval, u8 pri_map)
1724 {
1725 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1726 	struct qed_dcbx_set dcbx_set;
1727 	struct qed_app_entry *entry;
1728 	struct qed_ptt *ptt;
1729 	bool ethtype;
1730 	int rc, i;
1731 
1732 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1733 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1734 	if (rc)
1735 		return -EINVAL;
1736 
1737 	ethtype = !!(idtype == DCB_APP_IDTYPE_ETHTYPE);
1738 	for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) {
1739 		entry = &dcbx_set.config.params.app_entry[i];
1740 		if ((entry->ethtype == ethtype) && (entry->proto_id == idval))
1741 			break;
1742 		/* First empty slot */
1743 		if (!entry->proto_id) {
1744 			dcbx_set.config.params.num_app_entries++;
1745 			break;
1746 		}
1747 	}
1748 
1749 	if (i == QED_DCBX_MAX_APP_PROTOCOL) {
1750 		DP_ERR(cdev, "App table is full\n");
1751 		return -EBUSY;
1752 	}
1753 
1754 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG;
1755 	dcbx_set.config.params.app_entry[i].ethtype = ethtype;
1756 	dcbx_set.config.params.app_entry[i].proto_id = idval;
1757 	dcbx_set.config.params.app_entry[i].prio = pri_map;
1758 
1759 	ptt = qed_ptt_acquire(hwfn);
1760 	if (!ptt)
1761 		return -EBUSY;
1762 
1763 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1764 
1765 	qed_ptt_release(hwfn, ptt);
1766 
1767 	return rc;
1768 }
1769 
1770 static u8 qed_dcbnl_setdcbx(struct qed_dev *cdev, u8 mode)
1771 {
1772 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1773 	struct qed_dcbx_set dcbx_set;
1774 	struct qed_ptt *ptt;
1775 	int rc;
1776 
1777 	DP_VERBOSE(hwfn, QED_MSG_DCB, "new mode = %x\n", mode);
1778 
1779 	if (!(mode & DCB_CAP_DCBX_VER_IEEE) && !(mode & DCB_CAP_DCBX_VER_CEE)) {
1780 		DP_INFO(hwfn, "Allowed mode is cee, ieee or both\n");
1781 		return 1;
1782 	}
1783 
1784 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1785 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1786 	if (rc)
1787 		return 1;
1788 
1789 	dcbx_set.ver_num = 0;
1790 	if (mode & DCB_CAP_DCBX_VER_CEE) {
1791 		dcbx_set.ver_num |= DCBX_CONFIG_VERSION_CEE;
1792 		dcbx_set.enabled = true;
1793 	}
1794 
1795 	if (mode & DCB_CAP_DCBX_VER_IEEE) {
1796 		dcbx_set.ver_num |= DCBX_CONFIG_VERSION_IEEE;
1797 		dcbx_set.enabled = true;
1798 	}
1799 
1800 	ptt = qed_ptt_acquire(hwfn);
1801 	if (!ptt)
1802 		return 1;
1803 
1804 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1805 
1806 	qed_ptt_release(hwfn, ptt);
1807 
1808 	return 0;
1809 }
1810 
1811 static u8 qed_dcbnl_getfeatcfg(struct qed_dev *cdev, int featid, u8 *flags)
1812 {
1813 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1814 	struct qed_dcbx_get *dcbx_info;
1815 
1816 	DP_VERBOSE(hwfn, QED_MSG_DCB, "Feature id  = %d\n", featid);
1817 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1818 	if (!dcbx_info)
1819 		return 1;
1820 
1821 	*flags = 0;
1822 	switch (featid) {
1823 	case DCB_FEATCFG_ATTR_PG:
1824 		if (dcbx_info->operational.params.ets_enabled)
1825 			*flags = DCB_FEATCFG_ENABLE;
1826 		else
1827 			*flags = DCB_FEATCFG_ERROR;
1828 		break;
1829 	case DCB_FEATCFG_ATTR_PFC:
1830 		if (dcbx_info->operational.params.pfc.enabled)
1831 			*flags = DCB_FEATCFG_ENABLE;
1832 		else
1833 			*flags = DCB_FEATCFG_ERROR;
1834 		break;
1835 	case DCB_FEATCFG_ATTR_APP:
1836 		if (dcbx_info->operational.params.app_valid)
1837 			*flags = DCB_FEATCFG_ENABLE;
1838 		else
1839 			*flags = DCB_FEATCFG_ERROR;
1840 		break;
1841 	default:
1842 		DP_INFO(hwfn, "Invalid feature-ID %d\n", featid);
1843 		kfree(dcbx_info);
1844 		return 1;
1845 	}
1846 
1847 	DP_VERBOSE(hwfn, QED_MSG_DCB, "flags = %d\n", *flags);
1848 	kfree(dcbx_info);
1849 
1850 	return 0;
1851 }
1852 
1853 static u8 qed_dcbnl_setfeatcfg(struct qed_dev *cdev, int featid, u8 flags)
1854 {
1855 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1856 	struct qed_dcbx_set dcbx_set;
1857 	bool enabled, willing;
1858 	struct qed_ptt *ptt;
1859 	int rc;
1860 
1861 	DP_VERBOSE(hwfn, QED_MSG_DCB, "featid = %d flags = %d\n",
1862 		   featid, flags);
1863 	memset(&dcbx_set, 0, sizeof(dcbx_set));
1864 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
1865 	if (rc)
1866 		return 1;
1867 
1868 	enabled = !!(flags & DCB_FEATCFG_ENABLE);
1869 	willing = !!(flags & DCB_FEATCFG_WILLING);
1870 	switch (featid) {
1871 	case DCB_FEATCFG_ATTR_PG:
1872 		dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG;
1873 		dcbx_set.config.params.ets_enabled = enabled;
1874 		dcbx_set.config.params.ets_willing = willing;
1875 		break;
1876 	case DCB_FEATCFG_ATTR_PFC:
1877 		dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG;
1878 		dcbx_set.config.params.pfc.enabled = enabled;
1879 		dcbx_set.config.params.pfc.willing = willing;
1880 		break;
1881 	case DCB_FEATCFG_ATTR_APP:
1882 		dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG;
1883 		dcbx_set.config.params.app_willing = willing;
1884 		break;
1885 	default:
1886 		DP_INFO(hwfn, "Invalid feature-ID %d\n", featid);
1887 		return 1;
1888 	}
1889 
1890 	ptt = qed_ptt_acquire(hwfn);
1891 	if (!ptt)
1892 		return 1;
1893 
1894 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
1895 
1896 	qed_ptt_release(hwfn, ptt);
1897 
1898 	return 0;
1899 }
1900 
1901 static int qed_dcbnl_peer_getappinfo(struct qed_dev *cdev,
1902 				     struct dcb_peer_app_info *info,
1903 				     u16 *app_count)
1904 {
1905 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1906 	struct qed_dcbx_get *dcbx_info;
1907 
1908 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB);
1909 	if (!dcbx_info)
1910 		return -EINVAL;
1911 
1912 	info->willing = dcbx_info->remote.params.app_willing;
1913 	info->error = dcbx_info->remote.params.app_error;
1914 	*app_count = dcbx_info->remote.params.num_app_entries;
1915 	kfree(dcbx_info);
1916 
1917 	return 0;
1918 }
1919 
1920 static int qed_dcbnl_peer_getapptable(struct qed_dev *cdev,
1921 				      struct dcb_app *table)
1922 {
1923 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1924 	struct qed_dcbx_get *dcbx_info;
1925 	int i;
1926 
1927 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB);
1928 	if (!dcbx_info)
1929 		return -EINVAL;
1930 
1931 	for (i = 0; i < dcbx_info->remote.params.num_app_entries; i++) {
1932 		if (dcbx_info->remote.params.app_entry[i].ethtype)
1933 			table[i].selector = DCB_APP_IDTYPE_ETHTYPE;
1934 		else
1935 			table[i].selector = DCB_APP_IDTYPE_PORTNUM;
1936 		table[i].priority = dcbx_info->remote.params.app_entry[i].prio;
1937 		table[i].protocol =
1938 		    dcbx_info->remote.params.app_entry[i].proto_id;
1939 	}
1940 
1941 	kfree(dcbx_info);
1942 
1943 	return 0;
1944 }
1945 
1946 static int qed_dcbnl_cee_peer_getpfc(struct qed_dev *cdev, struct cee_pfc *pfc)
1947 {
1948 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1949 	struct qed_dcbx_get *dcbx_info;
1950 	int i;
1951 
1952 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB);
1953 	if (!dcbx_info)
1954 		return -EINVAL;
1955 
1956 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++)
1957 		if (dcbx_info->remote.params.pfc.prio[i])
1958 			pfc->pfc_en |= BIT(i);
1959 
1960 	pfc->tcs_supported = dcbx_info->remote.params.pfc.max_tc;
1961 	DP_VERBOSE(hwfn, QED_MSG_DCB, "pfc state = %d tcs_supported = %d\n",
1962 		   pfc->pfc_en, pfc->tcs_supported);
1963 	kfree(dcbx_info);
1964 
1965 	return 0;
1966 }
1967 
1968 static int qed_dcbnl_cee_peer_getpg(struct qed_dev *cdev, struct cee_pg *pg)
1969 {
1970 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1971 	struct qed_dcbx_get *dcbx_info;
1972 	int i;
1973 
1974 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_REMOTE_MIB);
1975 	if (!dcbx_info)
1976 		return -EINVAL;
1977 
1978 	pg->willing = dcbx_info->remote.params.ets_willing;
1979 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++) {
1980 		pg->pg_bw[i] = dcbx_info->remote.params.ets_tc_bw_tbl[i];
1981 		pg->prio_pg[i] = dcbx_info->remote.params.ets_pri_tc_tbl[i];
1982 	}
1983 
1984 	DP_VERBOSE(hwfn, QED_MSG_DCB, "willing = %d", pg->willing);
1985 	kfree(dcbx_info);
1986 
1987 	return 0;
1988 }
1989 
1990 static int qed_dcbnl_get_ieee_pfc(struct qed_dev *cdev,
1991 				  struct ieee_pfc *pfc, bool remote)
1992 {
1993 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
1994 	struct qed_dcbx_params *params;
1995 	struct qed_dcbx_get *dcbx_info;
1996 	int rc, i;
1997 
1998 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
1999 	if (!dcbx_info)
2000 		return -EINVAL;
2001 
2002 	if (!dcbx_info->operational.ieee) {
2003 		DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n");
2004 		kfree(dcbx_info);
2005 		return -EINVAL;
2006 	}
2007 
2008 	if (remote) {
2009 		memset(dcbx_info, 0, sizeof(*dcbx_info));
2010 		rc = qed_dcbx_query_params(hwfn, dcbx_info,
2011 					   QED_DCBX_REMOTE_MIB);
2012 		if (rc) {
2013 			kfree(dcbx_info);
2014 			return -EINVAL;
2015 		}
2016 
2017 		params = &dcbx_info->remote.params;
2018 	} else {
2019 		params = &dcbx_info->operational.params;
2020 	}
2021 
2022 	pfc->pfc_cap = params->pfc.max_tc;
2023 	pfc->pfc_en = 0;
2024 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++)
2025 		if (params->pfc.prio[i])
2026 			pfc->pfc_en |= BIT(i);
2027 
2028 	kfree(dcbx_info);
2029 
2030 	return 0;
2031 }
2032 
2033 static int qed_dcbnl_ieee_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc)
2034 {
2035 	return qed_dcbnl_get_ieee_pfc(cdev, pfc, false);
2036 }
2037 
2038 static int qed_dcbnl_ieee_setpfc(struct qed_dev *cdev, struct ieee_pfc *pfc)
2039 {
2040 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2041 	struct qed_dcbx_get *dcbx_info;
2042 	struct qed_dcbx_set dcbx_set;
2043 	struct qed_ptt *ptt;
2044 	int rc, i;
2045 
2046 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
2047 	if (!dcbx_info)
2048 		return -EINVAL;
2049 
2050 	if (!dcbx_info->operational.ieee) {
2051 		DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n");
2052 		kfree(dcbx_info);
2053 		return -EINVAL;
2054 	}
2055 
2056 	kfree(dcbx_info);
2057 
2058 	memset(&dcbx_set, 0, sizeof(dcbx_set));
2059 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
2060 	if (rc)
2061 		return -EINVAL;
2062 
2063 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_PFC_CFG;
2064 	for (i = 0; i < QED_MAX_PFC_PRIORITIES; i++)
2065 		dcbx_set.config.params.pfc.prio[i] = !!(pfc->pfc_en & BIT(i));
2066 
2067 	ptt = qed_ptt_acquire(hwfn);
2068 	if (!ptt)
2069 		return -EINVAL;
2070 
2071 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
2072 
2073 	qed_ptt_release(hwfn, ptt);
2074 
2075 	return rc;
2076 }
2077 
2078 static int qed_dcbnl_get_ieee_ets(struct qed_dev *cdev,
2079 				  struct ieee_ets *ets, bool remote)
2080 {
2081 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2082 	struct qed_dcbx_get *dcbx_info;
2083 	struct qed_dcbx_params *params;
2084 	int rc;
2085 
2086 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
2087 	if (!dcbx_info)
2088 		return -EINVAL;
2089 
2090 	if (!dcbx_info->operational.ieee) {
2091 		DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n");
2092 		kfree(dcbx_info);
2093 		return -EINVAL;
2094 	}
2095 
2096 	if (remote) {
2097 		memset(dcbx_info, 0, sizeof(*dcbx_info));
2098 		rc = qed_dcbx_query_params(hwfn, dcbx_info,
2099 					   QED_DCBX_REMOTE_MIB);
2100 		if (rc) {
2101 			kfree(dcbx_info);
2102 			return -EINVAL;
2103 		}
2104 
2105 		params = &dcbx_info->remote.params;
2106 	} else {
2107 		params = &dcbx_info->operational.params;
2108 	}
2109 
2110 	ets->ets_cap = params->max_ets_tc;
2111 	ets->willing = params->ets_willing;
2112 	ets->cbs = params->ets_cbs;
2113 	memcpy(ets->tc_tx_bw, params->ets_tc_bw_tbl, sizeof(ets->tc_tx_bw));
2114 	memcpy(ets->tc_tsa, params->ets_tc_tsa_tbl, sizeof(ets->tc_tsa));
2115 	memcpy(ets->prio_tc, params->ets_pri_tc_tbl, sizeof(ets->prio_tc));
2116 	kfree(dcbx_info);
2117 
2118 	return 0;
2119 }
2120 
2121 static int qed_dcbnl_ieee_getets(struct qed_dev *cdev, struct ieee_ets *ets)
2122 {
2123 	return qed_dcbnl_get_ieee_ets(cdev, ets, false);
2124 }
2125 
2126 static int qed_dcbnl_ieee_setets(struct qed_dev *cdev, struct ieee_ets *ets)
2127 {
2128 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2129 	struct qed_dcbx_get *dcbx_info;
2130 	struct qed_dcbx_set dcbx_set;
2131 	struct qed_ptt *ptt;
2132 	int rc;
2133 
2134 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
2135 	if (!dcbx_info)
2136 		return -EINVAL;
2137 
2138 	if (!dcbx_info->operational.ieee) {
2139 		DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n");
2140 		kfree(dcbx_info);
2141 		return -EINVAL;
2142 	}
2143 
2144 	kfree(dcbx_info);
2145 
2146 	memset(&dcbx_set, 0, sizeof(dcbx_set));
2147 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
2148 	if (rc)
2149 		return -EINVAL;
2150 
2151 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_ETS_CFG;
2152 	dcbx_set.config.params.max_ets_tc = ets->ets_cap;
2153 	dcbx_set.config.params.ets_willing = ets->willing;
2154 	dcbx_set.config.params.ets_cbs = ets->cbs;
2155 	memcpy(dcbx_set.config.params.ets_tc_bw_tbl, ets->tc_tx_bw,
2156 	       sizeof(ets->tc_tx_bw));
2157 	memcpy(dcbx_set.config.params.ets_tc_tsa_tbl, ets->tc_tsa,
2158 	       sizeof(ets->tc_tsa));
2159 	memcpy(dcbx_set.config.params.ets_pri_tc_tbl, ets->prio_tc,
2160 	       sizeof(ets->prio_tc));
2161 
2162 	ptt = qed_ptt_acquire(hwfn);
2163 	if (!ptt)
2164 		return -EINVAL;
2165 
2166 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
2167 
2168 	qed_ptt_release(hwfn, ptt);
2169 
2170 	return rc;
2171 }
2172 
2173 static int
2174 qed_dcbnl_ieee_peer_getets(struct qed_dev *cdev, struct ieee_ets *ets)
2175 {
2176 	return qed_dcbnl_get_ieee_ets(cdev, ets, true);
2177 }
2178 
2179 static int
2180 qed_dcbnl_ieee_peer_getpfc(struct qed_dev *cdev, struct ieee_pfc *pfc)
2181 {
2182 	return qed_dcbnl_get_ieee_pfc(cdev, pfc, true);
2183 }
2184 
2185 static int qed_dcbnl_ieee_getapp(struct qed_dev *cdev, struct dcb_app *app)
2186 {
2187 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2188 	struct qed_dcbx_get *dcbx_info;
2189 	struct qed_app_entry *entry;
2190 	bool ethtype;
2191 	u8 prio = 0;
2192 	int i;
2193 
2194 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
2195 	if (!dcbx_info)
2196 		return -EINVAL;
2197 
2198 	if (!dcbx_info->operational.ieee) {
2199 		DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n");
2200 		kfree(dcbx_info);
2201 		return -EINVAL;
2202 	}
2203 
2204 	/* ieee defines the selector field value for ethertype to be 1 */
2205 	ethtype = !!((app->selector - 1) == DCB_APP_IDTYPE_ETHTYPE);
2206 	for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) {
2207 		entry = &dcbx_info->operational.params.app_entry[i];
2208 		if ((entry->ethtype == ethtype) &&
2209 		    (entry->proto_id == app->protocol)) {
2210 			prio = entry->prio;
2211 			break;
2212 		}
2213 	}
2214 
2215 	if (i == QED_DCBX_MAX_APP_PROTOCOL) {
2216 		DP_ERR(cdev, "App entry (%d, %d) not found\n", app->selector,
2217 		       app->protocol);
2218 		kfree(dcbx_info);
2219 		return -EINVAL;
2220 	}
2221 
2222 	app->priority = ffs(prio) - 1;
2223 
2224 	kfree(dcbx_info);
2225 
2226 	return 0;
2227 }
2228 
2229 static int qed_dcbnl_ieee_setapp(struct qed_dev *cdev, struct dcb_app *app)
2230 {
2231 	struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2232 	struct qed_dcbx_get *dcbx_info;
2233 	struct qed_dcbx_set dcbx_set;
2234 	struct qed_app_entry *entry;
2235 	struct qed_ptt *ptt;
2236 	bool ethtype;
2237 	int rc, i;
2238 
2239 	if (app->priority < 0 || app->priority >= QED_MAX_PFC_PRIORITIES) {
2240 		DP_INFO(hwfn, "Invalid priority %d\n", app->priority);
2241 		return -EINVAL;
2242 	}
2243 
2244 	dcbx_info = qed_dcbnl_get_dcbx(hwfn, QED_DCBX_OPERATIONAL_MIB);
2245 	if (!dcbx_info)
2246 		return -EINVAL;
2247 
2248 	if (!dcbx_info->operational.ieee) {
2249 		DP_INFO(hwfn, "DCBX is not enabled/operational in IEEE mode\n");
2250 		kfree(dcbx_info);
2251 		return -EINVAL;
2252 	}
2253 
2254 	kfree(dcbx_info);
2255 
2256 	memset(&dcbx_set, 0, sizeof(dcbx_set));
2257 	rc = qed_dcbx_get_config_params(hwfn, &dcbx_set);
2258 	if (rc)
2259 		return -EINVAL;
2260 
2261 	/* ieee defines the selector field value for ethertype to be 1 */
2262 	ethtype = !!((app->selector - 1) == DCB_APP_IDTYPE_ETHTYPE);
2263 	for (i = 0; i < QED_DCBX_MAX_APP_PROTOCOL; i++) {
2264 		entry = &dcbx_set.config.params.app_entry[i];
2265 		if ((entry->ethtype == ethtype) &&
2266 		    (entry->proto_id == app->protocol))
2267 			break;
2268 		/* First empty slot */
2269 		if (!entry->proto_id) {
2270 			dcbx_set.config.params.num_app_entries++;
2271 			break;
2272 		}
2273 	}
2274 
2275 	if (i == QED_DCBX_MAX_APP_PROTOCOL) {
2276 		DP_ERR(cdev, "App table is full\n");
2277 		return -EBUSY;
2278 	}
2279 
2280 	dcbx_set.override_flags |= QED_DCBX_OVERRIDE_APP_CFG;
2281 	dcbx_set.config.params.app_entry[i].ethtype = ethtype;
2282 	dcbx_set.config.params.app_entry[i].proto_id = app->protocol;
2283 	dcbx_set.config.params.app_entry[i].prio = BIT(app->priority);
2284 
2285 	ptt = qed_ptt_acquire(hwfn);
2286 	if (!ptt)
2287 		return -EBUSY;
2288 
2289 	rc = qed_dcbx_config_params(hwfn, ptt, &dcbx_set, 0);
2290 
2291 	qed_ptt_release(hwfn, ptt);
2292 
2293 	return rc;
2294 }
2295 
2296 const struct qed_eth_dcbnl_ops qed_dcbnl_ops_pass = {
2297 	.getstate = qed_dcbnl_getstate,
2298 	.setstate = qed_dcbnl_setstate,
2299 	.getpgtccfgtx = qed_dcbnl_getpgtccfgtx,
2300 	.getpgbwgcfgtx = qed_dcbnl_getpgbwgcfgtx,
2301 	.getpgtccfgrx = qed_dcbnl_getpgtccfgrx,
2302 	.getpgbwgcfgrx = qed_dcbnl_getpgbwgcfgrx,
2303 	.getpfccfg = qed_dcbnl_getpfccfg,
2304 	.setpfccfg = qed_dcbnl_setpfccfg,
2305 	.getcap = qed_dcbnl_getcap,
2306 	.getnumtcs = qed_dcbnl_getnumtcs,
2307 	.getpfcstate = qed_dcbnl_getpfcstate,
2308 	.getdcbx = qed_dcbnl_getdcbx,
2309 	.setpgtccfgtx = qed_dcbnl_setpgtccfgtx,
2310 	.setpgtccfgrx = qed_dcbnl_setpgtccfgrx,
2311 	.setpgbwgcfgtx = qed_dcbnl_setpgbwgcfgtx,
2312 	.setpgbwgcfgrx = qed_dcbnl_setpgbwgcfgrx,
2313 	.setall = qed_dcbnl_setall,
2314 	.setnumtcs = qed_dcbnl_setnumtcs,
2315 	.setpfcstate = qed_dcbnl_setpfcstate,
2316 	.setapp = qed_dcbnl_setapp,
2317 	.setdcbx = qed_dcbnl_setdcbx,
2318 	.setfeatcfg = qed_dcbnl_setfeatcfg,
2319 	.getfeatcfg = qed_dcbnl_getfeatcfg,
2320 	.getapp = qed_dcbnl_getapp,
2321 	.peer_getappinfo = qed_dcbnl_peer_getappinfo,
2322 	.peer_getapptable = qed_dcbnl_peer_getapptable,
2323 	.cee_peer_getpfc = qed_dcbnl_cee_peer_getpfc,
2324 	.cee_peer_getpg = qed_dcbnl_cee_peer_getpg,
2325 	.ieee_getpfc = qed_dcbnl_ieee_getpfc,
2326 	.ieee_setpfc = qed_dcbnl_ieee_setpfc,
2327 	.ieee_getets = qed_dcbnl_ieee_getets,
2328 	.ieee_setets = qed_dcbnl_ieee_setets,
2329 	.ieee_peer_getpfc = qed_dcbnl_ieee_peer_getpfc,
2330 	.ieee_peer_getets = qed_dcbnl_ieee_peer_getets,
2331 	.ieee_getapp = qed_dcbnl_ieee_getapp,
2332 	.ieee_setapp = qed_dcbnl_ieee_setapp,
2333 };
2334 
2335 #endif
2336