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_H__ 40#define __IWM_H__ 41 42#include <linux/netdevice.h> 43#include <linux/wireless.h> 44#include <net/cfg80211.h> 45 46#include "debug.h" 47#include "hal.h" 48#include "umac.h" 49#include "lmac.h" 50#include "eeprom.h" 51#include "trace.h" 52 53#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" 54#define IWM_AUTHOR "<ilw@linux.intel.com>" 55 56#define IWM_SRC_LMAC UMAC_HDI_IN_SOURCE_FHRX 57#define IWM_SRC_UDMA UMAC_HDI_IN_SOURCE_UDMA 58#define IWM_SRC_UMAC UMAC_HDI_IN_SOURCE_FW 59#define IWM_SRC_NUM 3 60 61#define IWM_POWER_INDEX_MIN 0 62#define IWM_POWER_INDEX_MAX 5 63#define IWM_POWER_INDEX_DEFAULT 3 64 65struct iwm_conf { 66 u32 sdio_ior_timeout; 67 unsigned long calib_map; 68 unsigned long expected_calib_map; 69 u8 ct_kill_entry; 70 u8 ct_kill_exit; 71 bool reset_on_fatal_err; 72 bool auto_connect; 73 bool wimax_not_present; 74 bool enable_qos; 75 u32 mode; 76 77 u32 power_index; 78 u32 frag_threshold; 79 u32 rts_threshold; 80 bool cts_to_self; 81 82 u32 assoc_timeout; 83 u32 roam_timeout; 84 u32 wireless_mode; 85 86 u8 ibss_band; 87 u8 ibss_channel; 88 89 u8 mac_addr[ETH_ALEN]; 90}; 91 92enum { 93 COEX_MODE_SA = 1, 94 COEX_MODE_XOR, 95 COEX_MODE_CM, 96 COEX_MODE_MAX, 97}; 98 99struct iwm_if_ops; 100struct iwm_wifi_cmd; 101 102struct pool_entry { 103 int id; /* group id */ 104 int sid; /* super group id */ 105 int min_pages; /* min capacity in pages */ 106 int max_pages; /* max capacity in pages */ 107 int alloc_pages; /* allocated # of pages. incresed by driver */ 108 int total_freed_pages; /* total freed # of pages. incresed by UMAC */ 109}; 110 111struct spool_entry { 112 int id; 113 int max_pages; 114 int alloc_pages; 115}; 116 117struct iwm_tx_credit { 118 spinlock_t lock; 119 int pool_nr; 120 unsigned long full_pools_map; /* bitmap for # of filled tx pools */ 121 struct pool_entry pools[IWM_MACS_OUT_GROUPS]; 122 struct spool_entry spools[IWM_MACS_OUT_SGROUPS]; 123}; 124 125struct iwm_notif { 126 struct list_head pending; 127 u32 cmd_id; 128 void *cmd; 129 u8 src; 130 void *buf; 131 unsigned long buf_size; 132}; 133 134struct iwm_tid_info { 135 __le16 last_seq_num; 136 bool stopped; 137 struct mutex mutex; 138}; 139 140struct iwm_sta_info { 141 u8 addr[ETH_ALEN]; 142 bool valid; 143 bool qos; 144 u8 color; 145 struct iwm_tid_info tid_info[IWM_UMAC_TID_NR]; 146}; 147 148struct iwm_tx_info { 149 u8 sta; 150 u8 color; 151 u8 tid; 152}; 153 154struct iwm_rx_info { 155 unsigned long rx_size; 156 unsigned long rx_buf_size; 157}; 158 159#define IWM_NUM_KEYS 4 160 161struct iwm_umac_key_hdr { 162 u8 mac[ETH_ALEN]; 163 u8 key_idx; 164 u8 multicast; /* BCast encrypt & BCast decrypt of frames FROM mac */ 165} __packed; 166 167struct iwm_key { 168 struct iwm_umac_key_hdr hdr; 169 u32 cipher; 170 u8 key[WLAN_MAX_KEY_LEN]; 171 u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; 172 int key_len; 173 int seq_len; 174}; 175 176#define IWM_RX_ID_HASH 0xff 177#define IWM_RX_ID_GET_HASH(id) ((id) % IWM_RX_ID_HASH) 178 179#define IWM_STA_TABLE_NUM 16 180#define IWM_TX_LIST_SIZE 64 181#define IWM_RX_LIST_SIZE 256 182 183#define IWM_SCAN_ID_MAX 0xff 184 185#define IWM_STATUS_READY 0 186#define IWM_STATUS_SCANNING 1 187#define IWM_STATUS_SCAN_ABORTING 2 188#define IWM_STATUS_SME_CONNECTING 3 189#define IWM_STATUS_ASSOCIATED 4 190#define IWM_STATUS_RESETTING 5 191 192struct iwm_tx_queue { 193 int id; 194 struct sk_buff_head queue; 195 struct sk_buff_head stopped_queue; 196 spinlock_t lock; 197 struct workqueue_struct *wq; 198 struct work_struct worker; 199 u8 concat_buf[IWM_HAL_CONCATENATE_BUF_SIZE]; 200 int concat_count; 201 u8 *concat_ptr; 202}; 203 204/* Queues 0 ~ 3 for AC data, 5 for iPAN */ 205#define IWM_TX_QUEUES 5 206#define IWM_TX_DATA_QUEUES 4 207#define IWM_TX_CMD_QUEUE 4 208 209struct iwm_bss_info { 210 struct list_head node; 211 struct cfg80211_bss *cfg_bss; 212 struct iwm_umac_notif_bss_info *bss; 213}; 214 215typedef int (*iwm_handler)(struct iwm_priv *priv, u8 *buf, 216 unsigned long buf_size, struct iwm_wifi_cmd *cmd); 217 218#define IWM_WATCHDOG_PERIOD (6 * HZ) 219 220struct iwm_priv { 221 struct wireless_dev *wdev; 222 struct iwm_if_ops *bus_ops; 223 224 struct iwm_conf conf; 225 226 unsigned long status; 227 228 struct list_head pending_notif; 229 wait_queue_head_t notif_queue; 230 231 wait_queue_head_t nonwifi_queue; 232 233 unsigned long calib_done_map; 234 struct { 235 u8 *buf; 236 u32 size; 237 } calib_res[CALIBRATION_CMD_NUM]; 238 239 struct iwm_umac_profile *umac_profile; 240 bool umac_profile_active; 241 242 u8 bssid[ETH_ALEN]; 243 u8 channel; 244 u16 rate; 245 u32 txpower; 246 247 struct iwm_sta_info sta_table[IWM_STA_TABLE_NUM]; 248 struct list_head bss_list; 249 250 void (*nonwifi_rx_handlers[UMAC_HDI_IN_OPCODE_NONWIFI_MAX]) 251 (struct iwm_priv *priv, u8 *buf, unsigned long buf_size); 252 253 const iwm_handler *umac_handlers; 254 const iwm_handler *lmac_handlers; 255 DECLARE_BITMAP(lmac_handler_map, LMAC_COMMAND_ID_NUM); 256 DECLARE_BITMAP(umac_handler_map, LMAC_COMMAND_ID_NUM); 257 DECLARE_BITMAP(udma_handler_map, LMAC_COMMAND_ID_NUM); 258 259 struct list_head wifi_pending_cmd; 260 struct list_head nonwifi_pending_cmd; 261 u16 wifi_seq_num; 262 u8 nonwifi_seq_num; 263 spinlock_t cmd_lock; 264 265 u32 core_enabled; 266 267 u8 scan_id; 268 struct cfg80211_scan_request *scan_request; 269 270 struct sk_buff_head rx_list; 271 struct list_head rx_tickets; 272 spinlock_t ticket_lock; 273 struct list_head rx_packets[IWM_RX_ID_HASH]; 274 spinlock_t packet_lock[IWM_RX_ID_HASH]; 275 struct workqueue_struct *rx_wq; 276 struct work_struct rx_worker; 277 278 struct iwm_tx_credit tx_credit; 279 struct iwm_tx_queue txq[IWM_TX_QUEUES]; 280 281 struct iwm_key keys[IWM_NUM_KEYS]; 282 s8 default_key; 283 284 DECLARE_BITMAP(wifi_ntfy, WIFI_IF_NTFY_MAX); 285 wait_queue_head_t wifi_ntfy_queue; 286 287 wait_queue_head_t mlme_queue; 288 289 struct iw_statistics wstats; 290 struct delayed_work stats_request; 291 struct delayed_work disconnect; 292 struct delayed_work ct_kill_delay; 293 294 struct iwm_debugfs dbg; 295 296 u8 *eeprom; 297 struct timer_list watchdog; 298 struct work_struct reset_worker; 299 struct work_struct auth_retry_worker; 300 struct mutex mutex; 301 302 u8 *req_ie; 303 int req_ie_len; 304 u8 *resp_ie; 305 int resp_ie_len; 306 307 struct iwm_fw_error_hdr *last_fw_err; 308 char umac_version[8]; 309 char lmac_version[8]; 310 311 char private[0] __attribute__((__aligned__(NETDEV_ALIGN))); 312}; 313 314static inline void *iwm_private(struct iwm_priv *iwm) 315{ 316 BUG_ON(!iwm); 317 return &iwm->private; 318} 319 320#define hw_to_iwm(h) (h->iwm) 321#define iwm_to_dev(i) (wiphy_dev(i->wdev->wiphy)) 322#define iwm_to_wiphy(i) (i->wdev->wiphy) 323#define wiphy_to_iwm(w) (struct iwm_priv *)(wiphy_priv(w)) 324#define iwm_to_wdev(i) (i->wdev) 325#define wdev_to_iwm(w) (struct iwm_priv *)(wdev_priv(w)) 326#define iwm_to_ndev(i) (i->wdev->netdev) 327#define ndev_to_iwm(n) (wdev_to_iwm(n->ieee80211_ptr)) 328#define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb)) 329#define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb) 330 331void *iwm_if_alloc(int sizeof_bus, struct device *dev, 332 struct iwm_if_ops *if_ops); 333void iwm_if_free(struct iwm_priv *iwm); 334int iwm_if_add(struct iwm_priv *iwm); 335void iwm_if_remove(struct iwm_priv *iwm); 336int iwm_mode_to_nl80211_iftype(int mode); 337int iwm_priv_init(struct iwm_priv *iwm); 338void iwm_priv_deinit(struct iwm_priv *iwm); 339void iwm_reset(struct iwm_priv *iwm); 340void iwm_resetting(struct iwm_priv *iwm); 341void iwm_tx_credit_init_pools(struct iwm_priv *iwm, 342 struct iwm_umac_notif_alive *alive); 343int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb); 344int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd, 345 u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size); 346int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout); 347void iwm_init_default_profile(struct iwm_priv *iwm, 348 struct iwm_umac_profile *profile); 349void iwm_link_on(struct iwm_priv *iwm); 350void iwm_link_off(struct iwm_priv *iwm); 351int iwm_up(struct iwm_priv *iwm); 352int iwm_down(struct iwm_priv *iwm); 353 354/* TX API */ 355int iwm_tid_to_queue(u16 tid); 356void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages); 357void iwm_tx_worker(struct work_struct *work); 358int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev); 359 360/* RX API */ 361void iwm_rx_setup_handlers(struct iwm_priv *iwm); 362int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size); 363int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size, 364 struct iwm_wifi_cmd *cmd); 365void iwm_rx_free(struct iwm_priv *iwm); 366 367#endif 368