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