1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /* Copyright (C) 2023 Intel Corporation */
3 
4 #ifndef _IDPF_CONTROLQ_H_
5 #define _IDPF_CONTROLQ_H_
6 
7 #include <linux/slab.h>
8 
9 #include "idpf_controlq_api.h"
10 
11 /* Maximum buffer length for all control queue types */
12 #define IDPF_CTLQ_MAX_BUF_LEN	4096
13 
14 #define IDPF_CTLQ_DESC(R, i) \
15 	(&(((struct idpf_ctlq_desc *)((R)->desc_ring.va))[i]))
16 
17 #define IDPF_CTLQ_DESC_UNUSED(R) \
18 	((u16)((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->ring_size) + \
19 	       (R)->next_to_clean - (R)->next_to_use - 1))
20 
21 /* Control Queue default settings */
22 #define IDPF_CTRL_SQ_CMD_TIMEOUT	250  /* msecs */
23 
24 struct idpf_ctlq_desc {
25 	/* Control queue descriptor flags */
26 	__le16 flags;
27 	/* Control queue message opcode */
28 	__le16 opcode;
29 	__le16 datalen;		/* 0 for direct commands */
30 	union {
31 		__le16 ret_val;
32 		__le16 pfid_vfid;
33 #define IDPF_CTLQ_DESC_VF_ID_S	0
34 #define IDPF_CTLQ_DESC_VF_ID_M	(0x7FF << IDPF_CTLQ_DESC_VF_ID_S)
35 #define IDPF_CTLQ_DESC_PF_ID_S	11
36 #define IDPF_CTLQ_DESC_PF_ID_M	(0x1F << IDPF_CTLQ_DESC_PF_ID_S)
37 	};
38 
39 	/* Virtchnl message opcode and virtchnl descriptor type
40 	 * v_opcode=[27:0], v_dtype=[31:28]
41 	 */
42 	__le32 v_opcode_dtype;
43 	/* Virtchnl return value */
44 	__le32 v_retval;
45 	union {
46 		struct {
47 			__le32 param0;
48 			__le32 param1;
49 			__le32 param2;
50 			__le32 param3;
51 		} direct;
52 		struct {
53 			__le32 param0;
54 			__le16 sw_cookie;
55 			/* Virtchnl flags */
56 			__le16 v_flags;
57 			__le32 addr_high;
58 			__le32 addr_low;
59 		} indirect;
60 		u8 raw[16];
61 	} params;
62 };
63 
64 /* Flags sub-structure
65  * |0  |1  |2  |3  |4  |5  |6  |7  |8  |9  |10 |11 |12 |13 |14 |15 |
66  * |DD |CMP|ERR|  * RSV *  |FTYPE  | *RSV* |RD |VFC|BUF|  HOST_ID  |
67  */
68 /* command flags and offsets */
69 #define IDPF_CTLQ_FLAG_DD_S		0
70 #define IDPF_CTLQ_FLAG_CMP_S		1
71 #define IDPF_CTLQ_FLAG_ERR_S		2
72 #define IDPF_CTLQ_FLAG_FTYPE_S		6
73 #define IDPF_CTLQ_FLAG_RD_S		10
74 #define IDPF_CTLQ_FLAG_VFC_S		11
75 #define IDPF_CTLQ_FLAG_BUF_S		12
76 #define IDPF_CTLQ_FLAG_HOST_ID_S	13
77 
78 #define IDPF_CTLQ_FLAG_DD	BIT(IDPF_CTLQ_FLAG_DD_S)	/* 0x1	  */
79 #define IDPF_CTLQ_FLAG_CMP	BIT(IDPF_CTLQ_FLAG_CMP_S)	/* 0x2	  */
80 #define IDPF_CTLQ_FLAG_ERR	BIT(IDPF_CTLQ_FLAG_ERR_S)	/* 0x4	  */
81 #define IDPF_CTLQ_FLAG_FTYPE_VM	BIT(IDPF_CTLQ_FLAG_FTYPE_S)	/* 0x40	  */
82 #define IDPF_CTLQ_FLAG_FTYPE_PF	BIT(IDPF_CTLQ_FLAG_FTYPE_S + 1)	/* 0x80   */
83 #define IDPF_CTLQ_FLAG_RD	BIT(IDPF_CTLQ_FLAG_RD_S)	/* 0x400  */
84 #define IDPF_CTLQ_FLAG_VFC	BIT(IDPF_CTLQ_FLAG_VFC_S)	/* 0x800  */
85 #define IDPF_CTLQ_FLAG_BUF	BIT(IDPF_CTLQ_FLAG_BUF_S)	/* 0x1000 */
86 
87 /* Host ID is a special field that has 3b and not a 1b flag */
88 #define IDPF_CTLQ_FLAG_HOST_ID_M MAKE_MASK(0x7000UL, IDPF_CTLQ_FLAG_HOST_ID_S)
89 
90 struct idpf_mbxq_desc {
91 	u8 pad[8];		/* CTLQ flags/opcode/len/retval fields */
92 	u32 chnl_opcode;	/* avoid confusion with desc->opcode */
93 	u32 chnl_retval;	/* ditto for desc->retval */
94 	u32 pf_vf_id;		/* used by CP when sending to PF */
95 };
96 
97 /* Define the driver hardware struct to replace other control structs as needed
98  * Align to ctlq_hw_info
99  */
100 struct idpf_hw {
101 	void __iomem *hw_addr;
102 	resource_size_t hw_addr_len;
103 
104 	struct idpf_adapter *back;
105 
106 	/* control queue - send and receive */
107 	struct idpf_ctlq_info *asq;
108 	struct idpf_ctlq_info *arq;
109 
110 	/* pci info */
111 	u16 device_id;
112 	u16 vendor_id;
113 	u16 subsystem_device_id;
114 	u16 subsystem_vendor_id;
115 	u8 revision_id;
116 	bool adapter_stopped;
117 
118 	struct list_head cq_list_head;
119 };
120 
121 int idpf_ctlq_alloc_ring_res(struct idpf_hw *hw,
122 			     struct idpf_ctlq_info *cq);
123 
124 void idpf_ctlq_dealloc_ring_res(struct idpf_hw *hw, struct idpf_ctlq_info *cq);
125 
126 /* prototype for functions used for dynamic memory allocation */
127 void *idpf_alloc_dma_mem(struct idpf_hw *hw, struct idpf_dma_mem *mem,
128 			 u64 size);
129 void idpf_free_dma_mem(struct idpf_hw *hw, struct idpf_dma_mem *mem);
130 #endif /* _IDPF_CONTROLQ_H_ */
131