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