1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2013-2014 Chelsio Communications. All rights reserved.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Written by Anish Bhatt (anish@chelsio.com)
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #ifndef __CXGB4_DCB_H
9*4882a593Smuzhiyun #define __CXGB4_DCB_H
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #include <linux/netdevice.h>
12*4882a593Smuzhiyun #include <linux/dcbnl.h>
13*4882a593Smuzhiyun #include <net/dcbnl.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #ifdef CONFIG_CHELSIO_T4_DCB
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define CXGB4_DCBX_FW_SUPPORT \
18*4882a593Smuzhiyun (DCB_CAP_DCBX_VER_CEE | \
19*4882a593Smuzhiyun DCB_CAP_DCBX_VER_IEEE | \
20*4882a593Smuzhiyun DCB_CAP_DCBX_LLD_MANAGED)
21*4882a593Smuzhiyun #define CXGB4_DCBX_HOST_SUPPORT \
22*4882a593Smuzhiyun (DCB_CAP_DCBX_VER_CEE | \
23*4882a593Smuzhiyun DCB_CAP_DCBX_VER_IEEE | \
24*4882a593Smuzhiyun DCB_CAP_DCBX_HOST)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define CXGB4_MAX_PRIORITY CXGB4_MAX_DCBX_APP_SUPPORTED
27*4882a593Smuzhiyun #define CXGB4_MAX_TCS CXGB4_MAX_DCBX_APP_SUPPORTED
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define INIT_PORT_DCB_CMD(__pcmd, __port, __op, __action) \
30*4882a593Smuzhiyun do { \
31*4882a593Smuzhiyun memset(&(__pcmd), 0, sizeof(__pcmd)); \
32*4882a593Smuzhiyun (__pcmd).op_to_portid = \
33*4882a593Smuzhiyun cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) | \
34*4882a593Smuzhiyun FW_CMD_REQUEST_F | \
35*4882a593Smuzhiyun FW_CMD_##__op##_F | \
36*4882a593Smuzhiyun FW_PORT_CMD_PORTID_V(__port)); \
37*4882a593Smuzhiyun (__pcmd).action_to_len16 = \
38*4882a593Smuzhiyun cpu_to_be32(FW_PORT_CMD_ACTION_V(__action) | \
39*4882a593Smuzhiyun FW_LEN16(pcmd)); \
40*4882a593Smuzhiyun } while (0)
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun #define INIT_PORT_DCB_READ_PEER_CMD(__pcmd, __port) \
43*4882a593Smuzhiyun INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_RECV)
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #define INIT_PORT_DCB_READ_LOCAL_CMD(__pcmd, __port) \
46*4882a593Smuzhiyun INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_TRANS)
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun #define INIT_PORT_DCB_READ_SYNC_CMD(__pcmd, __port) \
49*4882a593Smuzhiyun INIT_PORT_DCB_CMD(__pcmd, __port, READ, FW_PORT_ACTION_DCB_READ_DET)
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #define INIT_PORT_DCB_WRITE_CMD(__pcmd, __port) \
52*4882a593Smuzhiyun INIT_PORT_DCB_CMD(__pcmd, __port, EXEC, FW_PORT_ACTION_L2_DCB_CFG)
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define IEEE_FAUX_SYNC(__dev, __dcb) \
55*4882a593Smuzhiyun do { \
56*4882a593Smuzhiyun if ((__dcb)->dcb_version == FW_PORT_DCB_VER_IEEE) \
57*4882a593Smuzhiyun cxgb4_dcb_state_fsm((__dev), \
58*4882a593Smuzhiyun CXGB4_DCB_INPUT_FW_ALLSYNCED); \
59*4882a593Smuzhiyun } while (0)
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun /* States we can be in for a port's Data Center Bridging.
62*4882a593Smuzhiyun */
63*4882a593Smuzhiyun enum cxgb4_dcb_state {
64*4882a593Smuzhiyun CXGB4_DCB_STATE_START, /* initial unknown state */
65*4882a593Smuzhiyun CXGB4_DCB_STATE_HOST, /* we're using Host DCB (if at all) */
66*4882a593Smuzhiyun CXGB4_DCB_STATE_FW_INCOMPLETE, /* using firmware DCB, incomplete */
67*4882a593Smuzhiyun CXGB4_DCB_STATE_FW_ALLSYNCED, /* using firmware DCB, all sync'ed */
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /* Data Center Bridging state input for the Finite State Machine.
71*4882a593Smuzhiyun */
72*4882a593Smuzhiyun enum cxgb4_dcb_state_input {
73*4882a593Smuzhiyun /* Input from the firmware.
74*4882a593Smuzhiyun */
75*4882a593Smuzhiyun CXGB4_DCB_INPUT_FW_DISABLED, /* firmware DCB disabled */
76*4882a593Smuzhiyun CXGB4_DCB_INPUT_FW_ENABLED, /* firmware DCB enabled */
77*4882a593Smuzhiyun CXGB4_DCB_INPUT_FW_INCOMPLETE, /* firmware reports incomplete DCB */
78*4882a593Smuzhiyun CXGB4_DCB_INPUT_FW_ALLSYNCED, /* firmware reports all sync'ed */
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun };
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* Firmware DCB messages that we've received so far ...
83*4882a593Smuzhiyun */
84*4882a593Smuzhiyun enum cxgb4_dcb_fw_msgs {
85*4882a593Smuzhiyun CXGB4_DCB_FW_PGID = 0x01,
86*4882a593Smuzhiyun CXGB4_DCB_FW_PGRATE = 0x02,
87*4882a593Smuzhiyun CXGB4_DCB_FW_PRIORATE = 0x04,
88*4882a593Smuzhiyun CXGB4_DCB_FW_PFC = 0x08,
89*4882a593Smuzhiyun CXGB4_DCB_FW_APP_ID = 0x10,
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun #define CXGB4_MAX_DCBX_APP_SUPPORTED 8
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /* Data Center Bridging support;
95*4882a593Smuzhiyun */
96*4882a593Smuzhiyun struct port_dcb_info {
97*4882a593Smuzhiyun enum cxgb4_dcb_state state; /* DCB State Machine */
98*4882a593Smuzhiyun enum cxgb4_dcb_fw_msgs msgs; /* DCB Firmware messages received */
99*4882a593Smuzhiyun unsigned int supported; /* OS DCB capabilities supported */
100*4882a593Smuzhiyun bool enabled; /* OS Enabled state */
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /* Cached copies of DCB information sent by the firmware (in Host
103*4882a593Smuzhiyun * Native Endian format).
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun u32 pgid; /* Priority Group[0..7] */
106*4882a593Smuzhiyun u8 dcb_version; /* Running DCBx version */
107*4882a593Smuzhiyun u8 pfcen; /* Priority Flow Control[0..7] */
108*4882a593Smuzhiyun u8 pg_num_tcs_supported; /* max PG Traffic Classes */
109*4882a593Smuzhiyun u8 pfc_num_tcs_supported; /* max PFC Traffic Classes */
110*4882a593Smuzhiyun u8 pgrate[8]; /* Priority Group Rate[0..7] */
111*4882a593Smuzhiyun u8 priorate[8]; /* Priority Rate[0..7] */
112*4882a593Smuzhiyun u8 tsa[8]; /* TSA Algorithm[0..7] */
113*4882a593Smuzhiyun struct app_priority { /* Application Information */
114*4882a593Smuzhiyun u8 user_prio_map; /* Priority Map bitfield */
115*4882a593Smuzhiyun u8 sel_field; /* Protocol ID interpretation */
116*4882a593Smuzhiyun u16 protocolid; /* Protocol ID */
117*4882a593Smuzhiyun } app_priority[CXGB4_MAX_DCBX_APP_SUPPORTED];
118*4882a593Smuzhiyun };
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun void cxgb4_dcb_state_init(struct net_device *);
121*4882a593Smuzhiyun void cxgb4_dcb_version_init(struct net_device *);
122*4882a593Smuzhiyun void cxgb4_dcb_reset(struct net_device *dev);
123*4882a593Smuzhiyun void cxgb4_dcb_state_fsm(struct net_device *, enum cxgb4_dcb_state_input);
124*4882a593Smuzhiyun void cxgb4_dcb_handle_fw_update(struct adapter *, const struct fw_port_cmd *);
125*4882a593Smuzhiyun void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *);
126*4882a593Smuzhiyun extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops;
127*4882a593Smuzhiyun
bitswap_1(unsigned char val)128*4882a593Smuzhiyun static inline __u8 bitswap_1(unsigned char val)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun return ((val & 0x80) >> 7) |
131*4882a593Smuzhiyun ((val & 0x40) >> 5) |
132*4882a593Smuzhiyun ((val & 0x20) >> 3) |
133*4882a593Smuzhiyun ((val & 0x10) >> 1) |
134*4882a593Smuzhiyun ((val & 0x08) << 1) |
135*4882a593Smuzhiyun ((val & 0x04) << 3) |
136*4882a593Smuzhiyun ((val & 0x02) << 5) |
137*4882a593Smuzhiyun ((val & 0x01) << 7);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun extern const char * const dcb_ver_array[];
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun #define CXGB4_DCB_ENABLED true
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun #else /* !CONFIG_CHELSIO_T4_DCB */
145*4882a593Smuzhiyun
cxgb4_dcb_state_init(struct net_device * dev)146*4882a593Smuzhiyun static inline void cxgb4_dcb_state_init(struct net_device *dev)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun #define CXGB4_DCB_ENABLED false
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun #endif /* !CONFIG_CHELSIO_T4_DCB */
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun #endif /* __CXGB4_DCB_H */
155