*
* GPL LICENSE SUMMARY
*
- * Copyright(c) 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* in the file called LICENSE.GPL.
*
* Contact Information:
- * Tomas Winkler <tomas.winkler@intel.com>
+ * Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*
* BSD LICENSE
*
- * Copyright(c) 2005 - 2008 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#define IWLWIFI_VERSION "1.3.27k"
-#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
+#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
+#define DRV_AUTHOR "<ilw@linux.intel.com>"
#define IWL_PCI_DEVICE(dev, subdev, cfg) \
.vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \
};
struct iwl_lib_ops {
- /* set hw dependant perameters */
+ /* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
- /* ucode shared memory */
- int (*alloc_shared_mem)(struct iwl_priv *priv);
- void (*free_shared_mem)(struct iwl_priv *priv);
- int (*shared_mem_rx_idx)(struct iwl_priv *priv);
/* Handling TX */
void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
+ int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr,
+ u16 len, u8 reset, u8 pad);
+ void (*txq_free_tfd)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
+ int (*txq_init)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
struct iwl_mod_params {
int disable; /* def: 0 = enable radio */
int sw_crypto; /* def: 0 = using hardware encryption */
- int debug; /* def: 0 = minimal debug log messages */
+ u32 debug; /* def: 0 = minimal debug log messages */
int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
int num_of_ampdu_queues;/* def: HW dependent */
- int enable_qos; /* def: 1 = use quality of service */
int disable_11n; /* def: 0 = disable 11n capabilities */
int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
int restart_fw; /* def: 1 = restart firmware */
};
+/**
+ * struct iwl_cfg
+ * @fw_name_pre: Firmware filename prefix. The api version and extension
+ * (.ucode) will be added to filename before loading from disk. The
+ * filename is constructed as fw_name_pre<api>.ucode.
+ * @ucode_api_max: Highest version of uCode API supported by driver.
+ * @ucode_api_min: Lowest version of uCode API supported by driver.
+ *
+ * We enable the driver to be backward compatible wrt API version. The
+ * driver specifies which APIs it supports (with @ucode_api_max being the
+ * highest and @ucode_api_min the lowest). Firmware will only be loaded if
+ * it has a supported API version. The firmware's API version will be
+ * stored in @iwl_priv, enabling the driver to make runtime changes based
+ * on firmware version used.
+ *
+ * For example,
+ * if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
+ * Driver interacts with Firmware API version >= 2.
+ * } else {
+ * Driver interacts with Firmware API version 1.
+ * }
+ *
+ * The ideal usage of this infrastructure is to treat a new ucode API
+ * release as a new hardware revision. That is, through utilizing the
+ * iwl_hcmd_utils_ops etc. we accommodate different command structures
+ * and flows between hardware versions (4965/5000) as well as their API
+ * versions.
+ */
struct iwl_cfg {
const char *name;
- const char *fw_name;
+ const char *fw_name_pre;
+ const unsigned int ucode_api_max;
+ const unsigned int ucode_api_min;
unsigned int sku;
int eeprom_size;
+ u16 eeprom_ver;
+ u16 eeprom_calib_ver;
const struct iwl_ops *ops;
const struct iwl_mod_params *mod_params;
+ u8 valid_tx_ant;
+ u8 valid_rx_ant;
+ bool need_pll_cfg;
};
/***************************
struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
struct ieee80211_ops *hw_ops);
void iwl_hw_detect(struct iwl_priv *priv);
-void iwl_clear_stations_table(struct iwl_priv *priv);
void iwl_reset_qos(struct iwl_priv *priv);
+void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
+int iwl_check_rxon_cmd(struct iwl_priv *priv);
+int iwl_full_rxon_required(struct iwl_priv *priv);
void iwl_set_rxon_chain(struct iwl_priv *priv);
int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info);
u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
- struct ieee80211_ht_info *sta_ht_inf);
+ struct ieee80211_sta_ht_cap *sta_ht_inf);
+void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
+void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
+int iwl_set_decrypted_flag(struct iwl_priv *priv,
+ struct ieee80211_hdr *hdr,
+ u32 decrypt_res,
+ struct ieee80211_rx_status *stats);
+void iwl_irq_handle_error(struct iwl_priv *priv);
+void iwl_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count, struct dev_addr_list *mc_list);
int iwl_hw_nic_init(struct iwl_priv *priv);
int iwl_setup_mac(struct iwl_priv *priv);
int iwl_set_hw_params(struct iwl_priv *priv);
int iwl_init_drv(struct iwl_priv *priv);
void iwl_uninit_drv(struct iwl_priv *priv);
-/* "keep warm" functions */
-int iwl_kw_init(struct iwl_priv *priv);
-int iwl_kw_alloc(struct iwl_priv *priv);
-void iwl_kw_free(struct iwl_priv *priv);
/*****************************************************
* RX
void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
void iwl_rx_replenish(struct iwl_priv *priv);
int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
-int iwl_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn);
-int iwl_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
int iwl_rx_queue_restock(struct iwl_priv *priv);
int iwl_rx_queue_space(const struct iwl_rx_queue *q);
void iwl_rx_allocate(struct iwl_priv *priv);
struct iwl_rx_mem_buffer *rxb);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
+void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
/* TX helpers */
* TX
******************************************************/
int iwl_txq_ctx_reset(struct iwl_priv *priv);
+void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq,
+ dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
-
/*****************************************************
* TX power
****************************************************/
* RF -Kill - here and not in iwl-rfkill.h to be available when
* RF-kill subsystem is not compiled.
****************************************************/
-void iwl_rf_kill(struct iwl_priv *priv);
+void iwl_bg_rf_kill(struct work_struct *work);
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
struct ieee80211_tx_info *info);
int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
+u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
+
+void iwl_set_rate(struct iwl_priv *priv);
+
+u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
+
+static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
+{
+ return BIT(ant_idx) << RATE_MCS_ANT_POS;
+}
+
static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
{
return le32_to_cpu(rate_n_flags) & 0xFF;
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_scan_initiate(struct iwl_priv *priv);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
+ struct ieee80211_mgmt *frame, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band);
+void iwl_bg_scan_check(struct work_struct *data);
+void iwl_bg_abort_scan(struct work_struct *work);
+void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+int iwl_send_scan_abort(struct iwl_priv *priv);
+
+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_ACTIVE_QUIET_TIME cpu_to_le16(10) /* msec */
+#define IWL_PLCP_QUIET_THRESH cpu_to_le16(1) /* packets */
+
/*******************************************************************************
* Calibrations - implemented in iwl-calib.c
int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len);
void iwl_calib_free_results(struct iwl_priv *priv);
+/*******************************************************************************
+ * Spectrum Measureemtns in iwl-spectrum.c
+ ******************************************************************************/
+#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT
+void iwl_setup_spectrum_handlers(struct iwl_priv *priv);
+#else
+static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {}
+#endif
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/
int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
+ u8 meta_flag);
+
+/*****************************************************
+ * PCI *
+ *****************************************************/
+void iwl_disable_interrupts(struct iwl_priv *priv);
+void iwl_enable_interrupts(struct iwl_priv *priv);
+static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
+{
+ int pos;
+ u16 pci_lnk_ctl;
+ pos = pci_find_capability(priv->pci_dev, PCI_CAP_ID_EXP);
+ pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
+ return pci_lnk_ctl;
+}
+
/*****************************************************
* Error Handling Debugging
******************************************************/
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);
+/*****************************************************
+* GEOS
+******************************************************/
+int iwlcore_init_geos(struct iwl_priv *priv);
+void iwlcore_free_geos(struct iwl_priv *priv);
+
/*************** DRIVER STATUS FUNCTIONS *****/
#define STATUS_HCMD_ACTIVE 0 /* host command in progress */
}
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
+extern int iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv,