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