• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright Gavin Shan, IBM Corporation 2016.
4  */
5 
6 #ifndef __NCSI_INTERNAL_H__
7 #define __NCSI_INTERNAL_H__
8 
9 enum {
10 	NCSI_CAP_BASE		= 0,
11 	NCSI_CAP_GENERIC	= 0,
12 	NCSI_CAP_BC,
13 	NCSI_CAP_MC,
14 	NCSI_CAP_BUFFER,
15 	NCSI_CAP_AEN,
16 	NCSI_CAP_VLAN,
17 	NCSI_CAP_MAX
18 };
19 
20 enum {
21 	NCSI_CAP_GENERIC_HWA             = 0x01, /* HW arbitration           */
22 	NCSI_CAP_GENERIC_HDS             = 0x02, /* HNC driver status change */
23 	NCSI_CAP_GENERIC_FC              = 0x04, /* HNC to MC flow control   */
24 	NCSI_CAP_GENERIC_FC1             = 0x08, /* MC to HNC flow control   */
25 	NCSI_CAP_GENERIC_MC              = 0x10, /* Global MC filtering      */
26 	NCSI_CAP_GENERIC_HWA_UNKNOWN     = 0x00, /* Unknown HW arbitration   */
27 	NCSI_CAP_GENERIC_HWA_SUPPORT     = 0x20, /* Supported HW arbitration */
28 	NCSI_CAP_GENERIC_HWA_NOT_SUPPORT = 0x40, /* No HW arbitration        */
29 	NCSI_CAP_GENERIC_HWA_RESERVED    = 0x60, /* Reserved HW arbitration  */
30 	NCSI_CAP_GENERIC_HWA_MASK        = 0x60, /* Mask for HW arbitration  */
31 	NCSI_CAP_GENERIC_MASK            = 0x7f,
32 	NCSI_CAP_BC_ARP                  = 0x01, /* ARP packet filtering     */
33 	NCSI_CAP_BC_DHCPC                = 0x02, /* DHCP client filtering    */
34 	NCSI_CAP_BC_DHCPS                = 0x04, /* DHCP server filtering    */
35 	NCSI_CAP_BC_NETBIOS              = 0x08, /* NetBIOS packet filtering */
36 	NCSI_CAP_BC_MASK                 = 0x0f,
37 	NCSI_CAP_MC_IPV6_NEIGHBOR        = 0x01, /* IPv6 neighbor filtering  */
38 	NCSI_CAP_MC_IPV6_ROUTER          = 0x02, /* IPv6 router filering     */
39 	NCSI_CAP_MC_DHCPV6_RELAY         = 0x04, /* DHCPv6 relay / server MC */
40 	NCSI_CAP_MC_DHCPV6_WELL_KNOWN    = 0x08, /* DHCPv6 well-known MC     */
41 	NCSI_CAP_MC_IPV6_MLD             = 0x10, /* IPv6 MLD filtering       */
42 	NCSI_CAP_MC_IPV6_NEIGHBOR_S      = 0x20, /* IPv6 neighbour filtering */
43 	NCSI_CAP_MC_MASK                 = 0x3f,
44 	NCSI_CAP_AEN_LSC                 = 0x01, /* Link status change       */
45 	NCSI_CAP_AEN_CR                  = 0x02, /* Configuration required   */
46 	NCSI_CAP_AEN_HDS                 = 0x04, /* HNC driver status        */
47 	NCSI_CAP_AEN_MASK                = 0x07,
48 	NCSI_CAP_VLAN_ONLY               = 0x01, /* Filter VLAN packet only  */
49 	NCSI_CAP_VLAN_NO                 = 0x02, /* Filter VLAN and non-VLAN */
50 	NCSI_CAP_VLAN_ANY                = 0x04, /* Filter Any-and-non-VLAN  */
51 	NCSI_CAP_VLAN_MASK               = 0x07
52 };
53 
54 enum {
55 	NCSI_MODE_BASE		= 0,
56 	NCSI_MODE_ENABLE	= 0,
57 	NCSI_MODE_TX_ENABLE,
58 	NCSI_MODE_LINK,
59 	NCSI_MODE_VLAN,
60 	NCSI_MODE_BC,
61 	NCSI_MODE_MC,
62 	NCSI_MODE_AEN,
63 	NCSI_MODE_FC,
64 	NCSI_MODE_MAX
65 };
66 
67 /* Supported media status bits for Mellanox Mac affinity command.
68  * Bit (0-2) for different protocol support; Bit 1 for RBT support,
69  * bit 1 for SMBUS support and bit 2 for PCIE support. Bit (3-5)
70  * for different protocol availability. Bit 4 for RBT, bit 4 for
71  * SMBUS and bit 5 for PCIE.
72  */
73 enum {
74 	MLX_MC_RBT_SUPPORT  = 0x01, /* MC supports RBT         */
75 	MLX_MC_RBT_AVL      = 0x08, /* RBT medium is available */
76 };
77 
78 /* OEM Vendor Manufacture ID */
79 #define NCSI_OEM_MFR_MLX_ID             0x8119
80 #define NCSI_OEM_MFR_BCM_ID             0x113d
81 /* Broadcom specific OEM Command */
82 #define NCSI_OEM_BCM_CMD_GMA            0x01   /* CMD ID for Get MAC */
83 /* Mellanox specific OEM Command */
84 #define NCSI_OEM_MLX_CMD_GMA            0x00   /* CMD ID for Get MAC */
85 #define NCSI_OEM_MLX_CMD_GMA_PARAM      0x1b   /* Parameter for GMA  */
86 #define NCSI_OEM_MLX_CMD_SMAF           0x01   /* CMD ID for Set MC Affinity */
87 #define NCSI_OEM_MLX_CMD_SMAF_PARAM     0x07   /* Parameter for SMAF         */
88 /* OEM Command payload lengths*/
89 #define NCSI_OEM_BCM_CMD_GMA_LEN        12
90 #define NCSI_OEM_MLX_CMD_GMA_LEN        8
91 #define NCSI_OEM_MLX_CMD_SMAF_LEN        60
92 /* Offset in OEM request */
93 #define MLX_SMAF_MAC_ADDR_OFFSET         8     /* Offset for MAC in SMAF    */
94 #define MLX_SMAF_MED_SUPPORT_OFFSET      14    /* Offset for medium in SMAF */
95 /* Mac address offset in OEM response */
96 #define BCM_MAC_ADDR_OFFSET             28
97 #define MLX_MAC_ADDR_OFFSET             8
98 
99 
100 struct ncsi_channel_version {
101 	u8   major;		/* NCSI version major */
102 	u8   minor;		/* NCSI version minor */
103 	u8   update;		/* NCSI version update */
104 	char alpha1;		/* NCSI version alpha1 */
105 	char alpha2;		/* NCSI version alpha2 */
106 	u8  fw_name[12];	/* Firmware name string                */
107 	u32 fw_version;		/* Firmware version                   */
108 	u16 pci_ids[4];		/* PCI identification                 */
109 	u32 mf_id;		/* Manufacture ID                     */
110 };
111 
112 struct ncsi_channel_cap {
113 	u32 index;	/* Index of channel capabilities */
114 	u32 cap;	/* NCSI channel capability       */
115 };
116 
117 struct ncsi_channel_mode {
118 	u32 index;	/* Index of channel modes      */
119 	u32 enable;	/* Enabled or disabled         */
120 	u32 size;	/* Valid entries in ncm_data[] */
121 	u32 data[8];	/* Data entries                */
122 };
123 
124 struct ncsi_channel_mac_filter {
125 	u8	n_uc;
126 	u8	n_mc;
127 	u8	n_mixed;
128 	u64	bitmap;
129 	unsigned char	*addrs;
130 };
131 
132 struct ncsi_channel_vlan_filter {
133 	u8	n_vids;
134 	u64	bitmap;
135 	u16	*vids;
136 };
137 
138 struct ncsi_channel_stats {
139 	u32 hnc_cnt_hi;		/* Counter cleared            */
140 	u32 hnc_cnt_lo;		/* Counter cleared            */
141 	u32 hnc_rx_bytes;	/* Rx bytes                   */
142 	u32 hnc_tx_bytes;	/* Tx bytes                   */
143 	u32 hnc_rx_uc_pkts;	/* Rx UC packets              */
144 	u32 hnc_rx_mc_pkts;     /* Rx MC packets              */
145 	u32 hnc_rx_bc_pkts;	/* Rx BC packets              */
146 	u32 hnc_tx_uc_pkts;	/* Tx UC packets              */
147 	u32 hnc_tx_mc_pkts;	/* Tx MC packets              */
148 	u32 hnc_tx_bc_pkts;	/* Tx BC packets              */
149 	u32 hnc_fcs_err;	/* FCS errors                 */
150 	u32 hnc_align_err;	/* Alignment errors           */
151 	u32 hnc_false_carrier;	/* False carrier detection    */
152 	u32 hnc_runt_pkts;	/* Rx runt packets            */
153 	u32 hnc_jabber_pkts;	/* Rx jabber packets          */
154 	u32 hnc_rx_pause_xon;	/* Rx pause XON frames        */
155 	u32 hnc_rx_pause_xoff;	/* Rx XOFF frames             */
156 	u32 hnc_tx_pause_xon;	/* Tx XON frames              */
157 	u32 hnc_tx_pause_xoff;	/* Tx XOFF frames             */
158 	u32 hnc_tx_s_collision;	/* Single collision frames    */
159 	u32 hnc_tx_m_collision;	/* Multiple collision frames  */
160 	u32 hnc_l_collision;	/* Late collision frames      */
161 	u32 hnc_e_collision;	/* Excessive collision frames */
162 	u32 hnc_rx_ctl_frames;	/* Rx control frames          */
163 	u32 hnc_rx_64_frames;	/* Rx 64-bytes frames         */
164 	u32 hnc_rx_127_frames;	/* Rx 65-127 bytes frames     */
165 	u32 hnc_rx_255_frames;	/* Rx 128-255 bytes frames    */
166 	u32 hnc_rx_511_frames;	/* Rx 256-511 bytes frames    */
167 	u32 hnc_rx_1023_frames;	/* Rx 512-1023 bytes frames   */
168 	u32 hnc_rx_1522_frames;	/* Rx 1024-1522 bytes frames  */
169 	u32 hnc_rx_9022_frames;	/* Rx 1523-9022 bytes frames  */
170 	u32 hnc_tx_64_frames;	/* Tx 64-bytes frames         */
171 	u32 hnc_tx_127_frames;	/* Tx 65-127 bytes frames     */
172 	u32 hnc_tx_255_frames;	/* Tx 128-255 bytes frames    */
173 	u32 hnc_tx_511_frames;	/* Tx 256-511 bytes frames    */
174 	u32 hnc_tx_1023_frames;	/* Tx 512-1023 bytes frames   */
175 	u32 hnc_tx_1522_frames;	/* Tx 1024-1522 bytes frames  */
176 	u32 hnc_tx_9022_frames;	/* Tx 1523-9022 bytes frames  */
177 	u32 hnc_rx_valid_bytes;	/* Rx valid bytes             */
178 	u32 hnc_rx_runt_pkts;	/* Rx error runt packets      */
179 	u32 hnc_rx_jabber_pkts;	/* Rx error jabber packets    */
180 	u32 ncsi_rx_cmds;	/* Rx NCSI commands           */
181 	u32 ncsi_dropped_cmds;	/* Dropped commands           */
182 	u32 ncsi_cmd_type_errs;	/* Command type errors        */
183 	u32 ncsi_cmd_csum_errs;	/* Command checksum errors    */
184 	u32 ncsi_rx_pkts;	/* Rx NCSI packets            */
185 	u32 ncsi_tx_pkts;	/* Tx NCSI packets            */
186 	u32 ncsi_tx_aen_pkts;	/* Tx AEN packets             */
187 	u32 pt_tx_pkts;		/* Tx packets                 */
188 	u32 pt_tx_dropped;	/* Tx dropped packets         */
189 	u32 pt_tx_channel_err;	/* Tx channel errors          */
190 	u32 pt_tx_us_err;	/* Tx undersize errors        */
191 	u32 pt_rx_pkts;		/* Rx packets                 */
192 	u32 pt_rx_dropped;	/* Rx dropped packets         */
193 	u32 pt_rx_channel_err;	/* Rx channel errors          */
194 	u32 pt_rx_us_err;	/* Rx undersize errors        */
195 	u32 pt_rx_os_err;	/* Rx oversize errors         */
196 };
197 
198 struct ncsi_dev_priv;
199 struct ncsi_package;
200 
201 #define NCSI_PACKAGE_SHIFT	5
202 #define NCSI_PACKAGE_INDEX(c)	(((c) >> NCSI_PACKAGE_SHIFT) & 0x7)
203 #define NCSI_RESERVED_CHANNEL	0x1f
204 #define NCSI_CHANNEL_INDEX(c)	((c) & ((1 << NCSI_PACKAGE_SHIFT) - 1))
205 #define NCSI_TO_CHANNEL(p, c)	(((p) << NCSI_PACKAGE_SHIFT) | (c))
206 #define NCSI_MAX_PACKAGE	8
207 #define NCSI_MAX_CHANNEL	32
208 
209 struct ncsi_channel {
210 	unsigned char               id;
211 	int                         state;
212 #define NCSI_CHANNEL_INACTIVE		1
213 #define NCSI_CHANNEL_ACTIVE		2
214 #define NCSI_CHANNEL_INVISIBLE		3
215 	bool                        reconfigure_needed;
216 	spinlock_t                  lock;	/* Protect filters etc */
217 	struct ncsi_package         *package;
218 	struct ncsi_channel_version version;
219 	struct ncsi_channel_cap	    caps[NCSI_CAP_MAX];
220 	struct ncsi_channel_mode    modes[NCSI_MODE_MAX];
221 	/* Filtering Settings */
222 	struct ncsi_channel_mac_filter	mac_filter;
223 	struct ncsi_channel_vlan_filter	vlan_filter;
224 	struct ncsi_channel_stats   stats;
225 	struct {
226 		struct timer_list   timer;
227 		bool                enabled;
228 		unsigned int        state;
229 #define NCSI_CHANNEL_MONITOR_START	0
230 #define NCSI_CHANNEL_MONITOR_RETRY	1
231 #define NCSI_CHANNEL_MONITOR_WAIT	2
232 #define NCSI_CHANNEL_MONITOR_WAIT_MAX	5
233 	} monitor;
234 	struct list_head            node;
235 	struct list_head            link;
236 };
237 
238 struct ncsi_package {
239 	unsigned char        id;          /* NCSI 3-bits package ID */
240 	unsigned char        uuid[16];    /* UUID                   */
241 	struct ncsi_dev_priv *ndp;        /* NCSI device            */
242 	spinlock_t           lock;        /* Protect the package    */
243 	unsigned int         channel_num; /* Number of channels     */
244 	struct list_head     channels;    /* List of chanels        */
245 	struct list_head     node;        /* Form list of packages  */
246 
247 	bool                 multi_channel; /* Enable multiple channels  */
248 	u32                  channel_whitelist; /* Channels to configure */
249 	struct ncsi_channel  *preferred_channel; /* Primary channel      */
250 };
251 
252 struct ncsi_request {
253 	unsigned char        id;      /* Request ID - 0 to 255           */
254 	bool                 used;    /* Request that has been assigned  */
255 	unsigned int         flags;   /* NCSI request property           */
256 #define NCSI_REQ_FLAG_EVENT_DRIVEN	1
257 #define NCSI_REQ_FLAG_NETLINK_DRIVEN	2
258 	struct ncsi_dev_priv *ndp;    /* Associated NCSI device          */
259 	struct sk_buff       *cmd;    /* Associated NCSI command packet  */
260 	struct sk_buff       *rsp;    /* Associated NCSI response packet */
261 	struct timer_list    timer;   /* Timer on waiting for response   */
262 	bool                 enabled; /* Time has been enabled or not    */
263 	u32                  snd_seq;     /* netlink sending sequence number */
264 	u32                  snd_portid;  /* netlink portid of sender        */
265 	struct nlmsghdr      nlhdr;       /* netlink message header          */
266 };
267 
268 enum {
269 	ncsi_dev_state_major		= 0xff00,
270 	ncsi_dev_state_minor		= 0x00ff,
271 	ncsi_dev_state_probe_deselect	= 0x0201,
272 	ncsi_dev_state_probe_package,
273 	ncsi_dev_state_probe_channel,
274 	ncsi_dev_state_probe_mlx_gma,
275 	ncsi_dev_state_probe_mlx_smaf,
276 	ncsi_dev_state_probe_cis,
277 	ncsi_dev_state_probe_gvi,
278 	ncsi_dev_state_probe_gc,
279 	ncsi_dev_state_probe_gls,
280 	ncsi_dev_state_probe_dp,
281 	ncsi_dev_state_config_sp	= 0x0301,
282 	ncsi_dev_state_config_cis,
283 	ncsi_dev_state_config_oem_gma,
284 	ncsi_dev_state_config_clear_vids,
285 	ncsi_dev_state_config_svf,
286 	ncsi_dev_state_config_ev,
287 	ncsi_dev_state_config_sma,
288 	ncsi_dev_state_config_ebf,
289 	ncsi_dev_state_config_dgmf,
290 	ncsi_dev_state_config_ecnt,
291 	ncsi_dev_state_config_ec,
292 	ncsi_dev_state_config_ae,
293 	ncsi_dev_state_config_gls,
294 	ncsi_dev_state_config_done,
295 	ncsi_dev_state_suspend_select	= 0x0401,
296 	ncsi_dev_state_suspend_gls,
297 	ncsi_dev_state_suspend_dcnt,
298 	ncsi_dev_state_suspend_dc,
299 	ncsi_dev_state_suspend_deselect,
300 	ncsi_dev_state_suspend_done
301 };
302 
303 struct vlan_vid {
304 	struct list_head list;
305 	__be16 proto;
306 	u16 vid;
307 };
308 
309 struct ncsi_dev_priv {
310 	struct ncsi_dev     ndev;            /* Associated NCSI device     */
311 	unsigned int        flags;           /* NCSI device flags          */
312 #define NCSI_DEV_PROBED		1            /* Finalized NCSI topology    */
313 #define NCSI_DEV_HWA		2            /* Enabled HW arbitration     */
314 #define NCSI_DEV_RESHUFFLE	4
315 #define NCSI_DEV_RESET		8            /* Reset state of NC          */
316 	unsigned int        gma_flag;        /* OEM GMA flag               */
317 	spinlock_t          lock;            /* Protect the NCSI device    */
318 	unsigned int        package_probe_id;/* Current ID during probe    */
319 	unsigned int        package_num;     /* Number of packages         */
320 	struct list_head    packages;        /* List of packages           */
321 	struct ncsi_channel *hot_channel;    /* Channel was ever active    */
322 	struct ncsi_request requests[256];   /* Request table              */
323 	unsigned int        request_id;      /* Last used request ID       */
324 #define NCSI_REQ_START_IDX	1
325 	unsigned int        pending_req_num; /* Number of pending requests */
326 	struct ncsi_package *active_package; /* Currently handled package  */
327 	struct ncsi_channel *active_channel; /* Currently handled channel  */
328 	struct list_head    channel_queue;   /* Config queue of channels   */
329 	struct work_struct  work;            /* For channel management     */
330 	struct packet_type  ptype;           /* NCSI packet Rx handler     */
331 	struct list_head    node;            /* Form NCSI device list      */
332 #define NCSI_MAX_VLAN_VIDS	15
333 	struct list_head    vlan_vids;       /* List of active VLAN IDs */
334 
335 	bool                multi_package;   /* Enable multiple packages   */
336 	bool                mlx_multi_host;  /* Enable multi host Mellanox */
337 	u32                 package_whitelist; /* Packages to configure    */
338 };
339 
340 struct ncsi_cmd_arg {
341 	struct ncsi_dev_priv *ndp;        /* Associated NCSI device        */
342 	unsigned char        type;        /* Command in the NCSI packet    */
343 	unsigned char        id;          /* Request ID (sequence number)  */
344 	unsigned char        package;     /* Destination package ID        */
345 	unsigned char        channel;     /* Detination channel ID or 0x1f */
346 	unsigned short       payload;     /* Command packet payload length */
347 	unsigned int         req_flags;   /* NCSI request properties       */
348 	union {
349 		unsigned char  bytes[16]; /* Command packet specific data  */
350 		unsigned short words[8];
351 		unsigned int   dwords[4];
352 	};
353 	unsigned char        *data;       /* NCSI OEM data                 */
354 	struct genl_info     *info;       /* Netlink information           */
355 };
356 
357 extern struct list_head ncsi_dev_list;
358 extern spinlock_t ncsi_dev_lock;
359 
360 #define TO_NCSI_DEV_PRIV(nd) \
361 	container_of(nd, struct ncsi_dev_priv, ndev)
362 #define NCSI_FOR_EACH_DEV(ndp) \
363 	list_for_each_entry_rcu(ndp, &ncsi_dev_list, node)
364 #define NCSI_FOR_EACH_PACKAGE(ndp, np) \
365 	list_for_each_entry_rcu(np, &ndp->packages, node)
366 #define NCSI_FOR_EACH_CHANNEL(np, nc) \
367 	list_for_each_entry_rcu(nc, &np->channels, node)
368 
369 /* Resources */
370 int ncsi_reset_dev(struct ncsi_dev *nd);
371 void ncsi_start_channel_monitor(struct ncsi_channel *nc);
372 void ncsi_stop_channel_monitor(struct ncsi_channel *nc);
373 struct ncsi_channel *ncsi_find_channel(struct ncsi_package *np,
374 				       unsigned char id);
375 struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np,
376 				      unsigned char id);
377 struct ncsi_package *ncsi_find_package(struct ncsi_dev_priv *ndp,
378 				       unsigned char id);
379 struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp,
380 				      unsigned char id);
381 void ncsi_remove_package(struct ncsi_package *np);
382 void ncsi_find_package_and_channel(struct ncsi_dev_priv *ndp,
383 				   unsigned char id,
384 				   struct ncsi_package **np,
385 				   struct ncsi_channel **nc);
386 struct ncsi_request *ncsi_alloc_request(struct ncsi_dev_priv *ndp,
387 					unsigned int req_flags);
388 void ncsi_free_request(struct ncsi_request *nr);
389 struct ncsi_dev *ncsi_find_dev(struct net_device *dev);
390 int ncsi_process_next_channel(struct ncsi_dev_priv *ndp);
391 bool ncsi_channel_has_link(struct ncsi_channel *channel);
392 bool ncsi_channel_is_last(struct ncsi_dev_priv *ndp,
393 			  struct ncsi_channel *channel);
394 int ncsi_update_tx_channel(struct ncsi_dev_priv *ndp,
395 			   struct ncsi_package *np,
396 			   struct ncsi_channel *disable,
397 			   struct ncsi_channel *enable);
398 
399 /* Packet handlers */
400 u32 ncsi_calculate_checksum(unsigned char *data, int len);
401 int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca);
402 int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
403 		 struct packet_type *pt, struct net_device *orig_dev);
404 int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb);
405 
406 #endif /* __NCSI_INTERNAL_H__ */
407