fwdesc.h (7208B)
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! */ 14enum 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 101struct 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 112struct 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 133struct 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 144struct carl9170fw_fix_entry { 145 __le32 address; 146 __le32 mask; 147 __le32 value; 148} __packed; 149 150struct 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 159struct 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 175struct 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 185struct 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 195struct 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 205struct 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 221static 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 245static inline bool carl9170fw_supports(__le32 list, u8 feature) 246{ 247 return le32_to_cpu(list) & BIT(feature); 248} 249 250static 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 266static 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 */