1/* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */
2/* Copyright(c) 2023 Advanced Micro Devices, Inc. */
3
4#ifndef _PDS_CORE_IF_H_
5#define _PDS_CORE_IF_H_
6
7#define PCI_VENDOR_ID_PENSANDO			0x1dd8
8#define PCI_DEVICE_ID_PENSANDO_CORE_PF		0x100c
9#define PCI_DEVICE_ID_VIRTIO_NET_TRANS		0x1000
10#define PCI_DEVICE_ID_PENSANDO_IONIC_ETH_VF	0x1003
11#define PCI_DEVICE_ID_PENSANDO_VDPA_VF		0x100b
12#define PDS_CORE_BARS_MAX			4
13#define PDS_CORE_PCI_BAR_DBELL			1
14
15/* Bar0 */
16#define PDS_CORE_DEV_INFO_SIGNATURE		0x44455649 /* 'DEVI' */
17#define PDS_CORE_BAR0_SIZE			0x8000
18#define PDS_CORE_BAR0_DEV_INFO_REGS_OFFSET	0x0000
19#define PDS_CORE_BAR0_DEV_CMD_REGS_OFFSET	0x0800
20#define PDS_CORE_BAR0_DEV_CMD_DATA_REGS_OFFSET	0x0c00
21#define PDS_CORE_BAR0_INTR_STATUS_OFFSET	0x1000
22#define PDS_CORE_BAR0_INTR_CTRL_OFFSET		0x2000
23#define PDS_CORE_DEV_CMD_DONE			0x00000001
24
25#define PDS_CORE_DEVCMD_TIMEOUT			5
26
27#define PDS_CORE_CLIENT_ID			0
28#define PDS_CORE_ASIC_TYPE_CAPRI		0
29
30/*
31 * enum pds_core_cmd_opcode - Device commands
32 */
33enum pds_core_cmd_opcode {
34	/* Core init */
35	PDS_CORE_CMD_NOP		= 0,
36	PDS_CORE_CMD_IDENTIFY		= 1,
37	PDS_CORE_CMD_RESET		= 2,
38	PDS_CORE_CMD_INIT		= 3,
39
40	PDS_CORE_CMD_FW_DOWNLOAD	= 4,
41	PDS_CORE_CMD_FW_CONTROL		= 5,
42
43	/* SR/IOV commands */
44	PDS_CORE_CMD_VF_GETATTR		= 60,
45	PDS_CORE_CMD_VF_SETATTR		= 61,
46	PDS_CORE_CMD_VF_CTRL		= 62,
47
48	/* Add commands before this line */
49	PDS_CORE_CMD_MAX,
50	PDS_CORE_CMD_COUNT
51};
52
53/*
54 * enum pds_core_status_code - Device command return codes
55 */
56enum pds_core_status_code {
57	PDS_RC_SUCCESS	= 0,	/* Success */
58	PDS_RC_EVERSION	= 1,	/* Incorrect version for request */
59	PDS_RC_EOPCODE	= 2,	/* Invalid cmd opcode */
60	PDS_RC_EIO	= 3,	/* I/O error */
61	PDS_RC_EPERM	= 4,	/* Permission denied */
62	PDS_RC_EQID	= 5,	/* Bad qid */
63	PDS_RC_EQTYPE	= 6,	/* Bad qtype */
64	PDS_RC_ENOENT	= 7,	/* No such element */
65	PDS_RC_EINTR	= 8,	/* operation interrupted */
66	PDS_RC_EAGAIN	= 9,	/* Try again */
67	PDS_RC_ENOMEM	= 10,	/* Out of memory */
68	PDS_RC_EFAULT	= 11,	/* Bad address */
69	PDS_RC_EBUSY	= 12,	/* Device or resource busy */
70	PDS_RC_EEXIST	= 13,	/* object already exists */
71	PDS_RC_EINVAL	= 14,	/* Invalid argument */
72	PDS_RC_ENOSPC	= 15,	/* No space left or alloc failure */
73	PDS_RC_ERANGE	= 16,	/* Parameter out of range */
74	PDS_RC_BAD_ADDR	= 17,	/* Descriptor contains a bad ptr */
75	PDS_RC_DEV_CMD	= 18,	/* Device cmd attempted on AdminQ */
76	PDS_RC_ENOSUPP	= 19,	/* Operation not supported */
77	PDS_RC_ERROR	= 29,	/* Generic error */
78	PDS_RC_ERDMA	= 30,	/* Generic RDMA error */
79	PDS_RC_EVFID	= 31,	/* VF ID does not exist */
80	PDS_RC_BAD_FW	= 32,	/* FW file is invalid or corrupted */
81	PDS_RC_ECLIENT	= 33,   /* No such client id */
82	PDS_RC_BAD_PCI	= 255,  /* Broken PCI when reading status */
83};
84
85/**
86 * struct pds_core_drv_identity - Driver identity information
87 * @drv_type:         Driver type (enum pds_core_driver_type)
88 * @os_dist:          OS distribution, numeric format
89 * @os_dist_str:      OS distribution, string format
90 * @kernel_ver:       Kernel version, numeric format
91 * @kernel_ver_str:   Kernel version, string format
92 * @driver_ver_str:   Driver version, string format
93 */
94struct pds_core_drv_identity {
95	__le32 drv_type;
96	__le32 os_dist;
97	char   os_dist_str[128];
98	__le32 kernel_ver;
99	char   kernel_ver_str[32];
100	char   driver_ver_str[32];
101};
102
103#define PDS_DEV_TYPE_MAX	16
104/**
105 * struct pds_core_dev_identity - Device identity information
106 * @version:	      Version of device identify
107 * @type:	      Identify type (0 for now)
108 * @state:	      Device state
109 * @rsvd:	      Word boundary padding
110 * @nlifs:	      Number of LIFs provisioned
111 * @nintrs:	      Number of interrupts provisioned
112 * @ndbpgs_per_lif:   Number of doorbell pages per LIF
113 * @intr_coal_mult:   Interrupt coalescing multiplication factor
114 *		      Scale user-supplied interrupt coalescing
115 *		      value in usecs to device units using:
116 *		      device units = usecs * mult / div
117 * @intr_coal_div:    Interrupt coalescing division factor
118 *		      Scale user-supplied interrupt coalescing
119 *		      value in usecs to device units using:
120 *		      device units = usecs * mult / div
121 * @vif_types:        How many of each VIF device type is supported
122 */
123struct pds_core_dev_identity {
124	u8     version;
125	u8     type;
126	u8     state;
127	u8     rsvd;
128	__le32 nlifs;
129	__le32 nintrs;
130	__le32 ndbpgs_per_lif;
131	__le32 intr_coal_mult;
132	__le32 intr_coal_div;
133	__le16 vif_types[PDS_DEV_TYPE_MAX];
134};
135
136#define PDS_CORE_IDENTITY_VERSION_1	1
137
138/**
139 * struct pds_core_dev_identify_cmd - Driver/device identify command
140 * @opcode:	Opcode PDS_CORE_CMD_IDENTIFY
141 * @ver:	Highest version of identify supported by driver
142 *
143 * Expects to find driver identification info (struct pds_core_drv_identity)
144 * in cmd_regs->data.  Driver should keep the devcmd interface locked
145 * while preparing the driver info.
146 */
147struct pds_core_dev_identify_cmd {
148	u8 opcode;
149	u8 ver;
150};
151
152/**
153 * struct pds_core_dev_identify_comp - Device identify command completion
154 * @status:	Status of the command (enum pds_core_status_code)
155 * @ver:	Version of identify returned by device
156 *
157 * Device identification info (struct pds_core_dev_identity) can be found
158 * in cmd_regs->data.  Driver should keep the devcmd interface locked
159 * while reading the results.
160 */
161struct pds_core_dev_identify_comp {
162	u8 status;
163	u8 ver;
164};
165
166/**
167 * struct pds_core_dev_reset_cmd - Device reset command
168 * @opcode:	Opcode PDS_CORE_CMD_RESET
169 *
170 * Resets and clears all LIFs, VDevs, and VIFs on the device.
171 */
172struct pds_core_dev_reset_cmd {
173	u8 opcode;
174};
175
176/**
177 * struct pds_core_dev_reset_comp - Reset command completion
178 * @status:	Status of the command (enum pds_core_status_code)
179 */
180struct pds_core_dev_reset_comp {
181	u8 status;
182};
183
184/*
185 * struct pds_core_dev_init_data - Pointers and info needed for the Core
186 * initialization PDS_CORE_CMD_INIT command.  The in and out structs are
187 * overlays on the pds_core_dev_cmd_regs.data space for passing data down
188 * to the firmware on init, and then returning initialization results.
189 */
190struct pds_core_dev_init_data_in {
191	__le64 adminq_q_base;
192	__le64 adminq_cq_base;
193	__le64 notifyq_cq_base;
194	__le32 flags;
195	__le16 intr_index;
196	u8     adminq_ring_size;
197	u8     notifyq_ring_size;
198};
199
200struct pds_core_dev_init_data_out {
201	__le32 core_hw_index;
202	__le32 adminq_hw_index;
203	__le32 notifyq_hw_index;
204	u8     adminq_hw_type;
205	u8     notifyq_hw_type;
206};
207
208/**
209 * struct pds_core_dev_init_cmd - Core device initialize
210 * @opcode:          opcode PDS_CORE_CMD_INIT
211 *
212 * Initializes the core device and sets up the AdminQ and NotifyQ.
213 * Expects to find initialization data (struct pds_core_dev_init_data_in)
214 * in cmd_regs->data.  Driver should keep the devcmd interface locked
215 * while preparing the driver info.
216 */
217struct pds_core_dev_init_cmd {
218	u8     opcode;
219};
220
221/**
222 * struct pds_core_dev_init_comp - Core init completion
223 * @status:     Status of the command (enum pds_core_status_code)
224 *
225 * Initialization result data (struct pds_core_dev_init_data_in)
226 * is found in cmd_regs->data.
227 */
228struct pds_core_dev_init_comp {
229	u8     status;
230};
231
232/**
233 * struct pds_core_fw_download_cmd - Firmware download command
234 * @opcode:     opcode
235 * @rsvd:	Word boundary padding
236 * @addr:       DMA address of the firmware buffer
237 * @offset:     offset of the firmware buffer within the full image
238 * @length:     number of valid bytes in the firmware buffer
239 */
240struct pds_core_fw_download_cmd {
241	u8     opcode;
242	u8     rsvd[3];
243	__le32 offset;
244	__le64 addr;
245	__le32 length;
246};
247
248/**
249 * struct pds_core_fw_download_comp - Firmware download completion
250 * @status:     Status of the command (enum pds_core_status_code)
251 */
252struct pds_core_fw_download_comp {
253	u8     status;
254};
255
256/**
257 * enum pds_core_fw_control_oper - FW control operations
258 * @PDS_CORE_FW_INSTALL_ASYNC:     Install firmware asynchronously
259 * @PDS_CORE_FW_INSTALL_STATUS:    Firmware installation status
260 * @PDS_CORE_FW_ACTIVATE_ASYNC:    Activate firmware asynchronously
261 * @PDS_CORE_FW_ACTIVATE_STATUS:   Firmware activate status
262 * @PDS_CORE_FW_UPDATE_CLEANUP:    Cleanup any firmware update leftovers
263 * @PDS_CORE_FW_GET_BOOT:          Return current active firmware slot
264 * @PDS_CORE_FW_SET_BOOT:          Set active firmware slot for next boot
265 * @PDS_CORE_FW_GET_LIST:          Return list of installed firmware images
266 */
267enum pds_core_fw_control_oper {
268	PDS_CORE_FW_INSTALL_ASYNC          = 0,
269	PDS_CORE_FW_INSTALL_STATUS         = 1,
270	PDS_CORE_FW_ACTIVATE_ASYNC         = 2,
271	PDS_CORE_FW_ACTIVATE_STATUS        = 3,
272	PDS_CORE_FW_UPDATE_CLEANUP         = 4,
273	PDS_CORE_FW_GET_BOOT               = 5,
274	PDS_CORE_FW_SET_BOOT               = 6,
275	PDS_CORE_FW_GET_LIST               = 7,
276};
277
278enum pds_core_fw_slot {
279	PDS_CORE_FW_SLOT_INVALID    = 0,
280	PDS_CORE_FW_SLOT_A	    = 1,
281	PDS_CORE_FW_SLOT_B          = 2,
282	PDS_CORE_FW_SLOT_GOLD       = 3,
283};
284
285/**
286 * struct pds_core_fw_control_cmd - Firmware control command
287 * @opcode:    opcode
288 * @rsvd:      Word boundary padding
289 * @oper:      firmware control operation (enum pds_core_fw_control_oper)
290 * @slot:      slot to operate on (enum pds_core_fw_slot)
291 */
292struct pds_core_fw_control_cmd {
293	u8  opcode;
294	u8  rsvd[3];
295	u8  oper;
296	u8  slot;
297};
298
299/**
300 * struct pds_core_fw_control_comp - Firmware control copletion
301 * @status:	Status of the command (enum pds_core_status_code)
302 * @rsvd:	Word alignment space
303 * @slot:	Slot number (enum pds_core_fw_slot)
304 * @rsvd1:	Struct padding
305 * @color:	Color bit
306 */
307struct pds_core_fw_control_comp {
308	u8     status;
309	u8     rsvd[3];
310	u8     slot;
311	u8     rsvd1[10];
312	u8     color;
313};
314
315struct pds_core_fw_name_info {
316#define PDS_CORE_FWSLOT_BUFLEN		8
317#define PDS_CORE_FWVERS_BUFLEN		32
318	char   slotname[PDS_CORE_FWSLOT_BUFLEN];
319	char   fw_version[PDS_CORE_FWVERS_BUFLEN];
320};
321
322struct pds_core_fw_list_info {
323#define PDS_CORE_FWVERS_LIST_LEN	16
324	u8 num_fw_slots;
325	struct pds_core_fw_name_info fw_names[PDS_CORE_FWVERS_LIST_LEN];
326} __packed;
327
328enum pds_core_vf_attr {
329	PDS_CORE_VF_ATTR_SPOOFCHK	= 1,
330	PDS_CORE_VF_ATTR_TRUST		= 2,
331	PDS_CORE_VF_ATTR_MAC		= 3,
332	PDS_CORE_VF_ATTR_LINKSTATE	= 4,
333	PDS_CORE_VF_ATTR_VLAN		= 5,
334	PDS_CORE_VF_ATTR_RATE		= 6,
335	PDS_CORE_VF_ATTR_STATSADDR	= 7,
336};
337
338/**
339 * enum pds_core_vf_link_status - Virtual Function link status
340 * @PDS_CORE_VF_LINK_STATUS_AUTO:   Use link state of the uplink
341 * @PDS_CORE_VF_LINK_STATUS_UP:     Link always up
342 * @PDS_CORE_VF_LINK_STATUS_DOWN:   Link always down
343 */
344enum pds_core_vf_link_status {
345	PDS_CORE_VF_LINK_STATUS_AUTO = 0,
346	PDS_CORE_VF_LINK_STATUS_UP   = 1,
347	PDS_CORE_VF_LINK_STATUS_DOWN = 2,
348};
349
350/**
351 * struct pds_core_vf_setattr_cmd - Set VF attributes on the NIC
352 * @opcode:     Opcode
353 * @attr:       Attribute type (enum pds_core_vf_attr)
354 * @vf_index:   VF index
355 * @macaddr:	mac address
356 * @vlanid:	vlan ID
357 * @maxrate:	max Tx rate in Mbps
358 * @spoofchk:	enable address spoof checking
359 * @trust:	enable VF trust
360 * @linkstate:	set link up or down
361 * @stats:	stats addr struct
362 * @stats.pa:	set DMA address for VF stats
363 * @stats.len:	length of VF stats space
364 * @pad:	force union to specific size
365 */
366struct pds_core_vf_setattr_cmd {
367	u8     opcode;
368	u8     attr;
369	__le16 vf_index;
370	union {
371		u8     macaddr[6];
372		__le16 vlanid;
373		__le32 maxrate;
374		u8     spoofchk;
375		u8     trust;
376		u8     linkstate;
377		struct {
378			__le64 pa;
379			__le32 len;
380		} stats;
381		u8     pad[60];
382	} __packed;
383};
384
385struct pds_core_vf_setattr_comp {
386	u8     status;
387	u8     attr;
388	__le16 vf_index;
389	__le16 comp_index;
390	u8     rsvd[9];
391	u8     color;
392};
393
394/**
395 * struct pds_core_vf_getattr_cmd - Get VF attributes from the NIC
396 * @opcode:     Opcode
397 * @attr:       Attribute type (enum pds_core_vf_attr)
398 * @vf_index:   VF index
399 */
400struct pds_core_vf_getattr_cmd {
401	u8     opcode;
402	u8     attr;
403	__le16 vf_index;
404};
405
406struct pds_core_vf_getattr_comp {
407	u8     status;
408	u8     attr;
409	__le16 vf_index;
410	union {
411		u8     macaddr[6];
412		__le16 vlanid;
413		__le32 maxrate;
414		u8     spoofchk;
415		u8     trust;
416		u8     linkstate;
417		__le64 stats_pa;
418		u8     pad[11];
419	} __packed;
420	u8     color;
421};
422
423enum pds_core_vf_ctrl_opcode {
424	PDS_CORE_VF_CTRL_START_ALL	= 0,
425	PDS_CORE_VF_CTRL_START		= 1,
426};
427
428/**
429 * struct pds_core_vf_ctrl_cmd - VF control command
430 * @opcode:         Opcode for the command
431 * @ctrl_opcode:    VF control operation type
432 * @vf_index:       VF Index. It is unused if op START_ALL is used.
433 */
434
435struct pds_core_vf_ctrl_cmd {
436	u8	opcode;
437	u8	ctrl_opcode;
438	__le16	vf_index;
439};
440
441/**
442 * struct pds_core_vf_ctrl_comp - VF_CTRL command completion.
443 * @status:     Status of the command (enum pds_core_status_code)
444 */
445struct pds_core_vf_ctrl_comp {
446	u8	status;
447};
448
449/*
450 * union pds_core_dev_cmd - Overlay of core device command structures
451 */
452union pds_core_dev_cmd {
453	u8     opcode;
454	u32    words[16];
455
456	struct pds_core_dev_identify_cmd identify;
457	struct pds_core_dev_init_cmd     init;
458	struct pds_core_dev_reset_cmd    reset;
459	struct pds_core_fw_download_cmd  fw_download;
460	struct pds_core_fw_control_cmd   fw_control;
461
462	struct pds_core_vf_setattr_cmd   vf_setattr;
463	struct pds_core_vf_getattr_cmd   vf_getattr;
464	struct pds_core_vf_ctrl_cmd      vf_ctrl;
465};
466
467/*
468 * union pds_core_dev_comp - Overlay of core device completion structures
469 */
470union pds_core_dev_comp {
471	u8                                status;
472	u8                                bytes[16];
473
474	struct pds_core_dev_identify_comp identify;
475	struct pds_core_dev_reset_comp    reset;
476	struct pds_core_dev_init_comp     init;
477	struct pds_core_fw_download_comp  fw_download;
478	struct pds_core_fw_control_comp   fw_control;
479
480	struct pds_core_vf_setattr_comp   vf_setattr;
481	struct pds_core_vf_getattr_comp   vf_getattr;
482	struct pds_core_vf_ctrl_comp      vf_ctrl;
483};
484
485/**
486 * struct pds_core_dev_hwstamp_regs - Hardware current timestamp registers
487 * @tick_low:        Low 32 bits of hardware timestamp
488 * @tick_high:       High 32 bits of hardware timestamp
489 */
490struct pds_core_dev_hwstamp_regs {
491	u32    tick_low;
492	u32    tick_high;
493};
494
495/**
496 * struct pds_core_dev_info_regs - Device info register format (read-only)
497 * @signature:       Signature value of 0x44455649 ('DEVI')
498 * @version:         Current version of info
499 * @asic_type:       Asic type
500 * @asic_rev:        Asic revision
501 * @fw_status:       Firmware status
502 *			bit 0   - 1 = fw running
503 *			bit 4-7 - 4 bit generation number, changes on fw restart
504 * @fw_heartbeat:    Firmware heartbeat counter
505 * @serial_num:      Serial number
506 * @fw_version:      Firmware version
507 * @oprom_regs:      oprom_regs to store oprom debug enable/disable and bmp
508 * @rsvd_pad1024:    Struct padding
509 * @hwstamp:         Hardware current timestamp registers
510 * @rsvd_pad2048:    Struct padding
511 */
512struct pds_core_dev_info_regs {
513#define PDS_CORE_DEVINFO_FWVERS_BUFLEN 32
514#define PDS_CORE_DEVINFO_SERIAL_BUFLEN 32
515	u32    signature;
516	u8     version;
517	u8     asic_type;
518	u8     asic_rev;
519#define PDS_CORE_FW_STS_F_STOPPED	0x00
520#define PDS_CORE_FW_STS_F_RUNNING	0x01
521#define PDS_CORE_FW_STS_F_GENERATION	0xF0
522	u8     fw_status;
523	__le32 fw_heartbeat;
524	char   fw_version[PDS_CORE_DEVINFO_FWVERS_BUFLEN];
525	char   serial_num[PDS_CORE_DEVINFO_SERIAL_BUFLEN];
526	u8     oprom_regs[32];     /* reserved */
527	u8     rsvd_pad1024[916];
528	struct pds_core_dev_hwstamp_regs hwstamp;   /* on 1k boundary */
529	u8     rsvd_pad2048[1016];
530} __packed;
531
532/**
533 * struct pds_core_dev_cmd_regs - Device command register format (read-write)
534 * @doorbell:	Device Cmd Doorbell, write-only
535 *              Write a 1 to signal device to process cmd
536 * @done:	Command completed indicator, poll for completion
537 *              bit 0 == 1 when command is complete
538 * @cmd:	Opcode-specific command bytes
539 * @comp:	Opcode-specific response bytes
540 * @rsvd:	Struct padding
541 * @data:	Opcode-specific side-data
542 */
543struct pds_core_dev_cmd_regs {
544	u32                     doorbell;
545	u32                     done;
546	union pds_core_dev_cmd  cmd;
547	union pds_core_dev_comp comp;
548	u8                      rsvd[48];
549	u32                     data[478];
550} __packed;
551
552/**
553 * struct pds_core_dev_regs - Device register format for bar 0 page 0
554 * @info:            Device info registers
555 * @devcmd:          Device command registers
556 */
557struct pds_core_dev_regs {
558	struct pds_core_dev_info_regs info;
559	struct pds_core_dev_cmd_regs  devcmd;
560} __packed;
561
562#ifndef __CHECKER__
563static_assert(sizeof(struct pds_core_drv_identity) <= 1912);
564static_assert(sizeof(struct pds_core_dev_identity) <= 1912);
565static_assert(sizeof(union pds_core_dev_cmd) == 64);
566static_assert(sizeof(union pds_core_dev_comp) == 16);
567static_assert(sizeof(struct pds_core_dev_info_regs) == 2048);
568static_assert(sizeof(struct pds_core_dev_cmd_regs) == 2048);
569static_assert(sizeof(struct pds_core_dev_regs) == 4096);
570#endif /* __CHECKER__ */
571
572#endif /* _PDS_CORE_IF_H_ */
573