18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright (C) 2013-2014 Chelsio Communications.  All rights reserved.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Written by Anish Bhatt (anish@chelsio.com)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __CXGB4_DCB_H
98c2ecf20Sopenharmony_ci#define __CXGB4_DCB_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
128c2ecf20Sopenharmony_ci#include <linux/dcbnl.h>
138c2ecf20Sopenharmony_ci#include <net/dcbnl.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#ifdef CONFIG_CHELSIO_T4_DCB
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define CXGB4_DCBX_FW_SUPPORT \
188c2ecf20Sopenharmony_ci	(DCB_CAP_DCBX_VER_CEE | \
198c2ecf20Sopenharmony_ci	 DCB_CAP_DCBX_VER_IEEE | \
208c2ecf20Sopenharmony_ci	 DCB_CAP_DCBX_LLD_MANAGED)
218c2ecf20Sopenharmony_ci#define CXGB4_DCBX_HOST_SUPPORT \
228c2ecf20Sopenharmony_ci	(DCB_CAP_DCBX_VER_CEE | \
238c2ecf20Sopenharmony_ci	 DCB_CAP_DCBX_VER_IEEE | \
248c2ecf20Sopenharmony_ci	 DCB_CAP_DCBX_HOST)
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define CXGB4_MAX_PRIORITY      CXGB4_MAX_DCBX_APP_SUPPORTED
278c2ecf20Sopenharmony_ci#define CXGB4_MAX_TCS           CXGB4_MAX_DCBX_APP_SUPPORTED
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define INIT_PORT_DCB_CMD(__pcmd, __port, __op, __action) \
308c2ecf20Sopenharmony_ci	do { \
318c2ecf20Sopenharmony_ci		memset(&(__pcmd), 0, sizeof(__pcmd)); \
328c2ecf20Sopenharmony_ci		(__pcmd).op_to_portid = \
338c2ecf20Sopenharmony_ci			cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | \
348c2ecf20Sopenharmony_ci				    FW_CMD_REQUEST_F | \
358c2ecf20Sopenharmony_ci				    FW_CMD_##__op##_F | \
368c2ecf20Sopenharmony_ci				    FW_PORT_CMD_PORTID_V(__port)); \
378c2ecf20Sopenharmony_ci		(__pcmd).action_to_len16 = \
388c2ecf20Sopenharmony_ci			cpu_to_be32(FW_PORT_CMD_ACTION_V(__action) | \
398c2ecf20Sopenharmony_ci				    FW_LEN16(pcmd)); \
408c2ecf20Sopenharmony_ci	} while (0)
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#define INIT_PORT_DCB_READ_PEER_CMD(__pcmd, __port) \
438c2ecf20Sopenharmony_ci	INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_RECV)
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#define INIT_PORT_DCB_READ_LOCAL_CMD(__pcmd, __port) \
468c2ecf20Sopenharmony_ci	INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_TRANS)
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#define INIT_PORT_DCB_READ_SYNC_CMD(__pcmd, __port) \
498c2ecf20Sopenharmony_ci	INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_DET)
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci#define INIT_PORT_DCB_WRITE_CMD(__pcmd, __port) \
528c2ecf20Sopenharmony_ci	INIT_PORT_DCB_CMD(__pcmd, __port, EXEC, FW_PORT_ACTION_L2_DCB_CFG)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#define IEEE_FAUX_SYNC(__dev, __dcb) \
558c2ecf20Sopenharmony_ci	do { \
568c2ecf20Sopenharmony_ci		if ((__dcb)->dcb_version == FW_PORT_DCB_VER_IEEE) \
578c2ecf20Sopenharmony_ci			cxgb4_dcb_state_fsm((__dev), \
588c2ecf20Sopenharmony_ci					    CXGB4_DCB_INPUT_FW_ALLSYNCED); \
598c2ecf20Sopenharmony_ci	} while (0)
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci/* States we can be in for a port's Data Center Bridging.
628c2ecf20Sopenharmony_ci */
638c2ecf20Sopenharmony_cienum cxgb4_dcb_state {
648c2ecf20Sopenharmony_ci	CXGB4_DCB_STATE_START,		/* initial unknown state */
658c2ecf20Sopenharmony_ci	CXGB4_DCB_STATE_HOST,		/* we're using Host DCB (if at all) */
668c2ecf20Sopenharmony_ci	CXGB4_DCB_STATE_FW_INCOMPLETE,	/* using firmware DCB, incomplete */
678c2ecf20Sopenharmony_ci	CXGB4_DCB_STATE_FW_ALLSYNCED,	/* using firmware DCB, all sync'ed */
688c2ecf20Sopenharmony_ci};
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci/* Data Center Bridging state input for the Finite State Machine.
718c2ecf20Sopenharmony_ci */
728c2ecf20Sopenharmony_cienum cxgb4_dcb_state_input {
738c2ecf20Sopenharmony_ci	/* Input from the firmware.
748c2ecf20Sopenharmony_ci	 */
758c2ecf20Sopenharmony_ci	CXGB4_DCB_INPUT_FW_DISABLED,	/* firmware DCB disabled */
768c2ecf20Sopenharmony_ci	CXGB4_DCB_INPUT_FW_ENABLED,	/* firmware DCB enabled */
778c2ecf20Sopenharmony_ci	CXGB4_DCB_INPUT_FW_INCOMPLETE,	/* firmware reports incomplete DCB */
788c2ecf20Sopenharmony_ci	CXGB4_DCB_INPUT_FW_ALLSYNCED,	/* firmware reports all sync'ed */
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci};
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/* Firmware DCB messages that we've received so far ...
838c2ecf20Sopenharmony_ci */
848c2ecf20Sopenharmony_cienum cxgb4_dcb_fw_msgs {
858c2ecf20Sopenharmony_ci	CXGB4_DCB_FW_PGID	= 0x01,
868c2ecf20Sopenharmony_ci	CXGB4_DCB_FW_PGRATE	= 0x02,
878c2ecf20Sopenharmony_ci	CXGB4_DCB_FW_PRIORATE	= 0x04,
888c2ecf20Sopenharmony_ci	CXGB4_DCB_FW_PFC	= 0x08,
898c2ecf20Sopenharmony_ci	CXGB4_DCB_FW_APP_ID	= 0x10,
908c2ecf20Sopenharmony_ci};
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#define CXGB4_MAX_DCBX_APP_SUPPORTED 8
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci/* Data Center Bridging support;
958c2ecf20Sopenharmony_ci */
968c2ecf20Sopenharmony_cistruct port_dcb_info {
978c2ecf20Sopenharmony_ci	enum cxgb4_dcb_state state;	/* DCB State Machine */
988c2ecf20Sopenharmony_ci	enum cxgb4_dcb_fw_msgs msgs;	/* DCB Firmware messages received */
998c2ecf20Sopenharmony_ci	unsigned int supported;		/* OS DCB capabilities supported */
1008c2ecf20Sopenharmony_ci	bool enabled;			/* OS Enabled state */
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	/* Cached copies of DCB information sent by the firmware (in Host
1038c2ecf20Sopenharmony_ci	 * Native Endian format).
1048c2ecf20Sopenharmony_ci	 */
1058c2ecf20Sopenharmony_ci	u32	pgid;			/* Priority Group[0..7] */
1068c2ecf20Sopenharmony_ci	u8	dcb_version;		/* Running DCBx version */
1078c2ecf20Sopenharmony_ci	u8	pfcen;			/* Priority Flow Control[0..7] */
1088c2ecf20Sopenharmony_ci	u8	pg_num_tcs_supported;	/* max PG Traffic Classes */
1098c2ecf20Sopenharmony_ci	u8	pfc_num_tcs_supported;	/* max PFC Traffic Classes */
1108c2ecf20Sopenharmony_ci	u8	pgrate[8];		/* Priority Group Rate[0..7] */
1118c2ecf20Sopenharmony_ci	u8	priorate[8];		/* Priority Rate[0..7] */
1128c2ecf20Sopenharmony_ci	u8	tsa[8];			/* TSA Algorithm[0..7] */
1138c2ecf20Sopenharmony_ci	struct app_priority { /* Application Information */
1148c2ecf20Sopenharmony_ci		u8	user_prio_map;	/* Priority Map bitfield */
1158c2ecf20Sopenharmony_ci		u8	sel_field;	/* Protocol ID interpretation */
1168c2ecf20Sopenharmony_ci		u16	protocolid;	/* Protocol ID */
1178c2ecf20Sopenharmony_ci	} app_priority[CXGB4_MAX_DCBX_APP_SUPPORTED];
1188c2ecf20Sopenharmony_ci};
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_civoid cxgb4_dcb_state_init(struct net_device *);
1218c2ecf20Sopenharmony_civoid cxgb4_dcb_version_init(struct net_device *);
1228c2ecf20Sopenharmony_civoid cxgb4_dcb_reset(struct net_device *dev);
1238c2ecf20Sopenharmony_civoid cxgb4_dcb_state_fsm(struct net_device *, enum cxgb4_dcb_state_input);
1248c2ecf20Sopenharmony_civoid cxgb4_dcb_handle_fw_update(struct adapter *, const struct fw_port_cmd *);
1258c2ecf20Sopenharmony_civoid cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *);
1268c2ecf20Sopenharmony_ciextern const struct dcbnl_rtnl_ops cxgb4_dcb_ops;
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_cistatic inline __u8 bitswap_1(unsigned char val)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	return ((val & 0x80) >> 7) |
1318c2ecf20Sopenharmony_ci	       ((val & 0x40) >> 5) |
1328c2ecf20Sopenharmony_ci	       ((val & 0x20) >> 3) |
1338c2ecf20Sopenharmony_ci	       ((val & 0x10) >> 1) |
1348c2ecf20Sopenharmony_ci	       ((val & 0x08) << 1) |
1358c2ecf20Sopenharmony_ci	       ((val & 0x04) << 3) |
1368c2ecf20Sopenharmony_ci	       ((val & 0x02) << 5) |
1378c2ecf20Sopenharmony_ci	       ((val & 0x01) << 7);
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ciextern const char * const dcb_ver_array[];
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci#define CXGB4_DCB_ENABLED true
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci#else /* !CONFIG_CHELSIO_T4_DCB */
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cistatic inline void cxgb4_dcb_state_init(struct net_device *dev)
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci#define CXGB4_DCB_ENABLED false
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci#endif /* !CONFIG_CHELSIO_T4_DCB */
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#endif /* __CXGB4_DCB_H */
155