1  /* SPDX-License-Identifier: GPL-2.0-only */
2  /*
3   * Shared CARL9170 Header
4   *
5   * Firmware descriptor format
6   *
7   * Copyright 2009-2011 Christian Lamparter <chunkeey@googlemail.com>
8   */
9  
10  #ifndef __CARL9170_SHARED_FWDESC_H
11  #define __CARL9170_SHARED_FWDESC_H
12  
13  /* NOTE: Don't mess with the order of the flags! */
14  enum carl9170fw_feature_list {
15  	/* Always set */
16  	CARL9170FW_DUMMY_FEATURE,
17  
18  	/*
19  	 * Indicates that this image has special boot block which prevents
20  	 * legacy drivers to drive the firmware.
21  	 */
22  	CARL9170FW_MINIBOOT,
23  
24  	/* usb registers are initialized by the firmware */
25  	CARL9170FW_USB_INIT_FIRMWARE,
26  
27  	/* command traps & notifications are send through EP2 */
28  	CARL9170FW_USB_RESP_EP2,
29  
30  	/* usb download (app -> fw) stream */
31  	CARL9170FW_USB_DOWN_STREAM,
32  
33  	/* usb upload (fw -> app) stream */
34  	CARL9170FW_USB_UP_STREAM,
35  
36  	/* unusable - reserved to flag non-functional debug firmwares */
37  	CARL9170FW_UNUSABLE,
38  
39  	/* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */
40  	CARL9170FW_COMMAND_PHY,
41  
42  	/* AR9170_CMD_EKEY, AR9170_CMD_DKEY */
43  	CARL9170FW_COMMAND_CAM,
44  
45  	/* Firmware has a software Content After Beacon Queueing mechanism */
46  	CARL9170FW_WLANTX_CAB,
47  
48  	/* The firmware is capable of responding to incoming BAR frames */
49  	CARL9170FW_HANDLE_BACK_REQ,
50  
51  	/* GPIO Interrupt | CARL9170_RSP_GPIO */
52  	CARL9170FW_GPIO_INTERRUPT,
53  
54  	/* Firmware PSM support | CARL9170_CMD_PSM */
55  	CARL9170FW_PSM,
56  
57  	/* Firmware RX filter | CARL9170_CMD_RX_FILTER */
58  	CARL9170FW_RX_FILTER,
59  
60  	/* Wake up on WLAN */
61  	CARL9170FW_WOL,
62  
63  	/* Firmware supports PSM in the 5GHZ Band */
64  	CARL9170FW_FIXED_5GHZ_PSM,
65  
66  	/* HW (ANI, CCA, MIB) tally counters */
67  	CARL9170FW_HW_COUNTERS,
68  
69  	/* Firmware will pass BA when BARs are queued */
70  	CARL9170FW_RX_BA_FILTER,
71  
72  	/* Firmware has support to write a byte at a time */
73  	CARL9170FW_HAS_WREGB_CMD,
74  
75  	/* Pattern generator */
76  	CARL9170FW_PATTERN_GENERATOR,
77  
78  	/* KEEP LAST */
79  	__CARL9170FW_FEATURE_NUM
80  };
81  
82  #define OTUS_MAGIC	"OTAR"
83  #define MOTD_MAGIC	"MOTD"
84  #define FIX_MAGIC	"FIX\0"
85  #define DBG_MAGIC	"DBG\0"
86  #define CHK_MAGIC	"CHK\0"
87  #define TXSQ_MAGIC	"TXSQ"
88  #define WOL_MAGIC	"WOL\0"
89  #define LAST_MAGIC	"LAST"
90  
91  #define CARL9170FW_SET_DAY(d) (((d) - 1) % 31)
92  #define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31)
93  #define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372)
94  
95  #define CARL9170FW_GET_DAY(d) (((d) % 31) + 1)
96  #define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1)
97  #define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10)
98  
99  #define CARL9170FW_MAGIC_SIZE			4
100  
101  struct carl9170fw_desc_head {
102  	u8	magic[CARL9170FW_MAGIC_SIZE];
103  	__le16 length;
104  	u8 min_ver;
105  	u8 cur_ver;
106  } __packed;
107  #define CARL9170FW_DESC_HEAD_SIZE			\
108  	(sizeof(struct carl9170fw_desc_head))
109  
110  #define CARL9170FW_OTUS_DESC_MIN_VER		6
111  #define CARL9170FW_OTUS_DESC_CUR_VER		7
112  struct carl9170fw_otus_desc {
113  	struct carl9170fw_desc_head head;
114  	__le32 feature_set;
115  	__le32 fw_address;
116  	__le32 bcn_addr;
117  	__le16 bcn_len;
118  	__le16 miniboot_size;
119  	__le16 tx_frag_len;
120  	__le16 rx_max_frame_len;
121  	u8 tx_descs;
122  	u8 cmd_bufs;
123  	u8 api_ver;
124  	u8 vif_num;
125  } __packed;
126  #define CARL9170FW_OTUS_DESC_SIZE			\
127  	(sizeof(struct carl9170fw_otus_desc))
128  
129  #define CARL9170FW_MOTD_STRING_LEN			24
130  #define CARL9170FW_MOTD_RELEASE_LEN			20
131  #define CARL9170FW_MOTD_DESC_MIN_VER			1
132  #define CARL9170FW_MOTD_DESC_CUR_VER			2
133  struct carl9170fw_motd_desc {
134  	struct carl9170fw_desc_head head;
135  	__le32 fw_year_month_day;
136  	char desc[CARL9170FW_MOTD_STRING_LEN];
137  	char release[CARL9170FW_MOTD_RELEASE_LEN];
138  } __packed;
139  #define CARL9170FW_MOTD_DESC_SIZE			\
140  	(sizeof(struct carl9170fw_motd_desc))
141  
142  #define CARL9170FW_FIX_DESC_MIN_VER			1
143  #define CARL9170FW_FIX_DESC_CUR_VER			2
144  struct carl9170fw_fix_entry {
145  	__le32 address;
146  	__le32 mask;
147  	__le32 value;
148  } __packed;
149  
150  struct carl9170fw_fix_desc {
151  	struct carl9170fw_desc_head head;
152  	struct carl9170fw_fix_entry data[];
153  } __packed;
154  #define CARL9170FW_FIX_DESC_SIZE			\
155  	(sizeof(struct carl9170fw_fix_desc))
156  
157  #define CARL9170FW_DBG_DESC_MIN_VER			1
158  #define CARL9170FW_DBG_DESC_CUR_VER			3
159  struct carl9170fw_dbg_desc {
160  	struct carl9170fw_desc_head head;
161  
162  	__le32 bogoclock_addr;
163  	__le32 counter_addr;
164  	__le32 rx_total_addr;
165  	__le32 rx_overrun_addr;
166  	__le32 rx_filter;
167  
168  	/* Put your debugging definitions here */
169  } __packed;
170  #define CARL9170FW_DBG_DESC_SIZE			\
171  	(sizeof(struct carl9170fw_dbg_desc))
172  
173  #define CARL9170FW_CHK_DESC_MIN_VER			1
174  #define CARL9170FW_CHK_DESC_CUR_VER			2
175  struct carl9170fw_chk_desc {
176  	struct carl9170fw_desc_head head;
177  	__le32 fw_crc32;
178  	__le32 hdr_crc32;
179  } __packed;
180  #define CARL9170FW_CHK_DESC_SIZE			\
181  	(sizeof(struct carl9170fw_chk_desc))
182  
183  #define CARL9170FW_TXSQ_DESC_MIN_VER			1
184  #define CARL9170FW_TXSQ_DESC_CUR_VER			1
185  struct carl9170fw_txsq_desc {
186  	struct carl9170fw_desc_head head;
187  
188  	__le32 seq_table_addr;
189  } __packed;
190  #define CARL9170FW_TXSQ_DESC_SIZE			\
191  	(sizeof(struct carl9170fw_txsq_desc))
192  
193  #define CARL9170FW_WOL_DESC_MIN_VER			1
194  #define CARL9170FW_WOL_DESC_CUR_VER			1
195  struct carl9170fw_wol_desc {
196  	struct carl9170fw_desc_head head;
197  
198  	__le32 supported_triggers;	/* CARL9170_WOL_ */
199  } __packed;
200  #define CARL9170FW_WOL_DESC_SIZE			\
201  	(sizeof(struct carl9170fw_wol_desc))
202  
203  #define CARL9170FW_LAST_DESC_MIN_VER			1
204  #define CARL9170FW_LAST_DESC_CUR_VER			2
205  struct carl9170fw_last_desc {
206  	struct carl9170fw_desc_head head;
207  } __packed;
208  #define CARL9170FW_LAST_DESC_SIZE			\
209  	(sizeof(struct carl9170fw_fix_desc))
210  
211  #define CARL9170FW_DESC_MAX_LENGTH			8192
212  
213  #define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver)	\
214  	.head = {							\
215  		.magic = _magic,					\
216  		.length = cpu_to_le16(_length),				\
217  		.min_ver = _min_ver,					\
218  		.cur_ver = _cur_ver,					\
219  	}
220  
carl9170fw_fill_desc(struct carl9170fw_desc_head * head,u8 magic[CARL9170FW_MAGIC_SIZE],__le16 length,u8 min_ver,u8 cur_ver)221  static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head,
222  					 u8 magic[CARL9170FW_MAGIC_SIZE],
223  					 __le16 length, u8 min_ver, u8 cur_ver)
224  {
225  	head->magic[0] = magic[0];
226  	head->magic[1] = magic[1];
227  	head->magic[2] = magic[2];
228  	head->magic[3] = magic[3];
229  
230  	head->length = length;
231  	head->min_ver = min_ver;
232  	head->cur_ver = cur_ver;
233  }
234  
235  #define carl9170fw_for_each_hdr(desc, fw_desc)				\
236  	for (desc = fw_desc;						\
237  	     memcmp(desc->magic, LAST_MAGIC, CARL9170FW_MAGIC_SIZE) &&	\
238  	     le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE &&	\
239  	     le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH;	\
240  	     desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length)))
241  
242  #define CHECK_HDR_VERSION(head, _min_ver)				\
243  	(((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver))	\
244  
carl9170fw_supports(__le32 list,u8 feature)245  static inline bool carl9170fw_supports(__le32 list, u8 feature)
246  {
247  	return le32_to_cpu(list) & BIT(feature);
248  }
249  
carl9170fw_desc_cmp(const struct carl9170fw_desc_head * head,const u8 descid[CARL9170FW_MAGIC_SIZE],u16 min_len,u8 compatible_revision)250  static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head,
251  				       const u8 descid[CARL9170FW_MAGIC_SIZE],
252  				       u16 min_len, u8 compatible_revision)
253  {
254  	if (descid[0] == head->magic[0] && descid[1] == head->magic[1] &&
255  	    descid[2] == head->magic[2] && descid[3] == head->magic[3] &&
256  	    !CHECK_HDR_VERSION(head, compatible_revision) &&
257  	    (le16_to_cpu(head->length) >= min_len))
258  		return true;
259  
260  	return false;
261  }
262  
263  #define CARL9170FW_MIN_SIZE	32
264  #define CARL9170FW_MAX_SIZE	16384
265  
carl9170fw_size_check(unsigned int len)266  static inline bool carl9170fw_size_check(unsigned int len)
267  {
268  	return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE);
269  }
270  
271  #endif /* __CARL9170_SHARED_FWDESC_H */
272