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