1 /* 2 * Intel Wireless Multicomm 3200 WiFi driver 3 * 4 * Copyright (C) 2009 Intel Corporation. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Intel Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * 33 * Intel Corporation <ilw@linux.intel.com> 34 * Samuel Ortiz <samuel.ortiz@intel.com> 35 * Zhu Yi <yi.zhu@intel.com> 36 * 37 */ 38 39 #ifndef _IWM_HAL_H_ 40 #define _IWM_HAL_H_ 41 42 #include "umac.h" 43 44 #define GET_VAL8(s, name) ((s >> name##_POS) & name##_SEED) 45 #define GET_VAL16(s, name) ((le16_to_cpu(s) >> name##_POS) & name##_SEED) 46 #define GET_VAL32(s, name) ((le32_to_cpu(s) >> name##_POS) & name##_SEED) 47 48 #define SET_VAL8(s, name, val) \ 49 do { \ 50 s = (s & ~(name##_SEED << name##_POS)) | \ 51 ((val & name##_SEED) << name##_POS); \ 52 } while (0) 53 54 #define SET_VAL16(s, name, val) \ 55 do { \ 56 s = cpu_to_le16((le16_to_cpu(s) & ~(name##_SEED << name##_POS)) | \ 57 ((val & name##_SEED) << name##_POS)); \ 58 } while (0) 59 60 #define SET_VAL32(s, name, val) \ 61 do { \ 62 s = cpu_to_le32((le32_to_cpu(s) & ~(name##_SEED << name##_POS)) | \ 63 ((val & name##_SEED) << name##_POS)); \ 64 } while (0) 65 66 67 #define UDMA_UMAC_INIT { .eop = 1, \ 68 .credit_group = 0x4, \ 69 .ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD, \ 70 .lmac_offset = 0 } 71 #define UDMA_LMAC_INIT { .eop = 1, \ 72 .credit_group = 0x4, \ 73 .ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD, \ 74 .lmac_offset = 4 } 75 76 77 /* UDMA IN OP CODE -- cmd bits [3:0] */ 78 #define UDMA_HDI_IN_NW_CMD_OPCODE_POS 0 79 #define UDMA_HDI_IN_NW_CMD_OPCODE_SEED 0xF 80 81 #define UDMA_IN_OPCODE_GENERAL_RESP 0x0 82 #define UDMA_IN_OPCODE_READ_RESP 0x1 83 #define UDMA_IN_OPCODE_WRITE_RESP 0x2 84 #define UDMA_IN_OPCODE_PERS_WRITE_RESP 0x5 85 #define UDMA_IN_OPCODE_PERS_READ_RESP 0x6 86 #define UDMA_IN_OPCODE_RD_MDFY_WR_RESP 0x7 87 #define UDMA_IN_OPCODE_EP_MNGMT_MSG 0x8 88 #define UDMA_IN_OPCODE_CRDT_CHNG_MSG 0x9 89 #define UDMA_IN_OPCODE_CNTRL_DATABASE_MSG 0xA 90 #define UDMA_IN_OPCODE_SW_MSG 0xB 91 #define UDMA_IN_OPCODE_WIFI 0xF 92 #define UDMA_IN_OPCODE_WIFI_LMAC 0x1F 93 #define UDMA_IN_OPCODE_WIFI_UMAC 0x2F 94 95 /* HW API: udma_hdi_nonwifi API (OUT and IN) */ 96 97 /* iwm_udma_nonwifi_cmd request response -- bits [9:9] */ 98 #define UDMA_HDI_OUT_NW_CMD_RESP_POS 9 99 #define UDMA_HDI_OUT_NW_CMD_RESP_SEED 0x1 100 101 /* iwm_udma_nonwifi_cmd handle by HW -- bits [11:11] */ 102 #define UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW_POS 11 103 #define UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW_SEED 0x1 104 105 /* iwm_udma_nonwifi_cmd sequence-number -- bits [12:15] */ 106 #define UDMA_HDI_OUT_NW_CMD_SEQ_NUM_POS 12 107 #define UDMA_HDI_OUT_NW_CMD_SEQ_NUM_SEED 0xF 108 109 /* UDMA IN Non-WIFI HW sequence number -- bits [12:15] */ 110 #define UDMA_IN_NW_HW_SEQ_NUM_POS 12 111 #define UDMA_IN_NW_HW_SEQ_NUM_SEED 0xF 112 113 /* UDMA IN Non-WIFI HW signature -- bits [16:31] */ 114 #define UDMA_IN_NW_HW_SIG_POS 16 115 #define UDMA_IN_NW_HW_SIG_SEED 0xFFFF 116 117 /* fixed signature */ 118 #define UDMA_IN_NW_HW_SIG 0xCBBC 119 120 /* UDMA IN Non-WIFI HW block length -- bits [32:35] */ 121 #define UDMA_IN_NW_HW_LENGTH_SEED 0xF 122 #define UDMA_IN_NW_HW_LENGTH_POS 32 123 124 /* End of HW API: udma_hdi_nonwifi API (OUT and IN) */ 125 126 #define IWM_SDIO_FW_MAX_CHUNK_SIZE 2032 127 #define IWM_MAX_WIFI_HEADERS_SIZE 32 128 #define IWM_MAX_NONWIFI_HEADERS_SIZE 16 129 #define IWM_MAX_NONWIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ 130 IWM_MAX_NONWIFI_HEADERS_SIZE) 131 #define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ 132 IWM_MAX_WIFI_HEADERS_SIZE) 133 134 #define IWM_HAL_CONCATENATE_BUF_SIZE (32 * 1024) 135 136 struct iwm_wifi_cmd_buff { 137 u16 len; 138 u8 *start; 139 u8 hdr[IWM_MAX_WIFI_HEADERS_SIZE]; 140 u8 payload[IWM_MAX_WIFI_CMD_BUFF_SIZE]; 141 }; 142 143 struct iwm_nonwifi_cmd_buff { 144 u16 len; 145 u8 *start; 146 u8 hdr[IWM_MAX_NONWIFI_HEADERS_SIZE]; 147 u8 payload[IWM_MAX_NONWIFI_CMD_BUFF_SIZE]; 148 }; 149 150 struct iwm_udma_nonwifi_cmd { 151 u8 opcode; 152 u8 eop; 153 u8 resp; 154 u8 handle_by_hw; 155 __le32 addr; 156 __le32 op1_sz; 157 __le32 op2; 158 __le16 seq_num; 159 }; 160 161 struct iwm_udma_wifi_cmd { 162 __le16 count; 163 u8 eop; 164 u8 credit_group; 165 u8 ra_tid; 166 u8 lmac_offset; 167 }; 168 169 struct iwm_umac_cmd { 170 u8 id; 171 __le16 count; 172 u8 resp; 173 __le16 seq_num; 174 u8 color; 175 }; 176 177 struct iwm_lmac_cmd { 178 u8 id; 179 __le16 count; 180 u8 resp; 181 __le16 seq_num; 182 }; 183 184 struct iwm_nonwifi_cmd { 185 u16 seq_num; 186 bool resp_received; 187 struct list_head pending; 188 struct iwm_udma_nonwifi_cmd udma_cmd; 189 struct iwm_umac_cmd umac_cmd; 190 struct iwm_lmac_cmd lmac_cmd; 191 struct iwm_nonwifi_cmd_buff buf; 192 u32 flags; 193 }; 194 195 struct iwm_wifi_cmd { 196 u16 seq_num; 197 struct list_head pending; 198 struct iwm_udma_wifi_cmd udma_cmd; 199 struct iwm_umac_cmd umac_cmd; 200 struct iwm_lmac_cmd lmac_cmd; 201 struct iwm_wifi_cmd_buff buf; 202 u32 flags; 203 }; 204 205 void iwm_cmd_flush(struct iwm_priv *iwm); 206 207 struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, 208 u16 seq_num); 209 struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, 210 u8 seq_num, u8 cmd_opcode); 211 212 213 int iwm_hal_send_target_cmd(struct iwm_priv *iwm, 214 struct iwm_udma_nonwifi_cmd *ucmd, 215 const void *payload); 216 217 int iwm_hal_send_host_cmd(struct iwm_priv *iwm, 218 struct iwm_udma_wifi_cmd *udma_cmd, 219 struct iwm_umac_cmd *umac_cmd, 220 struct iwm_lmac_cmd *lmac_cmd, 221 const void *payload, u16 payload_size); 222 223 int iwm_hal_send_umac_cmd(struct iwm_priv *iwm, 224 struct iwm_udma_wifi_cmd *udma_cmd, 225 struct iwm_umac_cmd *umac_cmd, 226 const void *payload, u16 payload_size); 227 228 u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm); 229 230 void iwm_udma_wifi_hdr_set_eop(struct iwm_priv *iwm, u8 *buf, u8 eop); 231 void iwm_build_udma_wifi_hdr(struct iwm_priv *iwm, 232 struct iwm_udma_out_wifi_hdr *hdr, 233 struct iwm_udma_wifi_cmd *cmd); 234 void iwm_build_umac_hdr(struct iwm_priv *iwm, 235 struct iwm_umac_fw_cmd_hdr *hdr, 236 struct iwm_umac_cmd *cmd); 237 #endif /* _IWM_HAL_H_ */ 238