aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c1102
1 files changed, 287 insertions, 815 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index a23d4798653..0b733518171 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved.
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -45,13 +45,11 @@
#include <asm/div64.h>
+#include "iwl-eeprom.h"
+#include "iwl-core.h"
#include "iwl-4965.h"
#include "iwl-helpers.h"
-#ifdef CONFIG_IWL4965_DEBUG
-u32 iwl4965_debug_level;
-#endif
-
static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv,
struct iwl4965_tx_queue *txq);
@@ -90,15 +88,8 @@ int iwl4965_param_amsdu_size_8K; /* def: enable 8K amsdu size */
#define VS
#endif
-#define IWLWIFI_VERSION "1.2.23k" VD VS
-#define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation"
-#define DRV_VERSION IWLWIFI_VERSION
+#define DRV_VERSION IWLWIFI_VERSION VD VS
-/* Change firmware file name, using "-" and incrementing number,
- * *only* when uCode interface or architecture changes so that it
- * is not compatible with earlier drivers.
- * This number will also appear in << 8 position of 1st dword of uCode file */
-#define IWL4965_UCODE_API "-1"
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERSION);
@@ -115,16 +106,10 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr)
return NULL;
}
-static const struct ieee80211_hw_mode *iwl4965_get_hw_mode(
- struct iwl4965_priv *priv, int mode)
+static const struct ieee80211_supported_band *iwl4965_get_hw_mode(
+ struct iwl4965_priv *priv, enum ieee80211_band band)
{
- int i;
-
- for (i = 0; i < 3; i++)
- if (priv->modes[i].mode == mode)
- return &priv->modes[i];
-
- return NULL;
+ return priv->hw->wiphy->bands[band];
}
static int iwl4965_is_empty_essid(const char *essid, int essid_len)
@@ -167,17 +152,6 @@ static const char *iwl4965_escape_essid(const char *essid, u8 essid_len)
return escaped;
}
-static void iwl4965_print_hex_dump(int level, void *p, u32 len)
-{
-#ifdef CONFIG_IWL4965_DEBUG
- if (!(iwl4965_debug_level & level))
- return;
-
- print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1,
- p, len, 1);
-#endif
-}
-
/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
* DMA services
*
@@ -205,7 +179,7 @@ static void iwl4965_print_hex_dump(int level, void *p, u32 len)
* See more detailed info in iwl-4965-hw.h.
***************************************************/
-static int iwl4965_queue_space(const struct iwl4965_queue *q)
+int iwl4965_queue_space(const struct iwl4965_queue *q)
{
int s = q->read_ptr - q->write_ptr;
@@ -221,25 +195,6 @@ static int iwl4965_queue_space(const struct iwl4965_queue *q)
return s;
}
-/**
- * iwl4965_queue_inc_wrap - increment queue index, wrap back to beginning
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl4965_queue_inc_wrap(int index, int n_bd)
-{
- return ++index & (n_bd - 1);
-}
-
-/**
- * iwl4965_queue_dec_wrap - decrement queue index, wrap back to end
- * @index -- current index
- * @n_bd -- total number of entries in queue (must be power of 2)
- */
-static inline int iwl4965_queue_dec_wrap(int index, int n_bd)
-{
- return --index & (n_bd - 1);
-}
static inline int x2_queue_used(const struct iwl4965_queue *q, int i)
{
@@ -268,8 +223,8 @@ static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q
q->n_window = slots_num;
q->id = id;
- /* count must be power-of-two size, otherwise iwl4965_queue_inc_wrap
- * and iwl4965_queue_dec_wrap are broken. */
+ /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
+ * and iwl_queue_dec_wrap are broken. */
BUG_ON(!is_power_of_2(count));
/* slots_num must be power-of-two size, otherwise
@@ -369,7 +324,7 @@ int iwl4965_tx_queue_init(struct iwl4965_priv *priv,
txq->need_update = 0;
/* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * iwl4965_queue_inc_wrap and iwl4965_queue_dec_wrap are broken. */
+ * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
/* Initialize queue's high/low-water marks, and head/tail indexes */
@@ -400,7 +355,7 @@ void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *t
/* first, empty all BD's */
for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd))
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
iwl4965_hw_txq_free_tfd(priv, txq);
len = sizeof(struct iwl4965_cmd) * q->n_window;
@@ -741,7 +696,7 @@ static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_c
ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0);
/* Increment and update queue's write index */
- q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd);
+ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
iwl4965_tx_queue_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
@@ -937,28 +892,29 @@ static int iwl4965_rxon_add_station(struct iwl4965_priv *priv,
* NOTE: Does not commit to the hardware; it sets appropriate bit fields
* in the staging RXON flag structure based on the phymode
*/
-static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, u8 phymode,
+static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv,
+ enum ieee80211_band band,
u16 channel)
{
- if (!iwl4965_get_channel_info(priv, phymode, channel)) {
+ if (!iwl4965_get_channel_info(priv, band, channel)) {
IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
- channel, phymode);
+ channel, band);
return -EINVAL;
}
if ((le16_to_cpu(priv->staging_rxon.channel) == channel) &&
- (priv->phymode == phymode))
+ (priv->band == band))
return 0;
priv->staging_rxon.channel = cpu_to_le16(channel);
- if (phymode == MODE_IEEE80211A)
+ if (band == IEEE80211_BAND_5GHZ)
priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK;
else
priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
- priv->phymode = phymode;
+ priv->band = band;
- IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, phymode);
+ IWL_DEBUG_INFO("Staging channel set to %d [%d]\n", channel, band);
return 0;
}
@@ -1556,34 +1512,6 @@ unsigned int iwl4965_fill_beacon_frame(struct iwl4965_priv *priv,
return priv->ibss_beacon->len;
}
-int iwl4965_rate_index_from_plcp(int plcp)
-{
- int i = 0;
-
- /* 4965 HT rate format */
- if (plcp & RATE_MCS_HT_MSK) {
- i = (plcp & 0xff);
-
- if (i >= IWL_RATE_MIMO_6M_PLCP)
- i = i - IWL_RATE_MIMO_6M_PLCP;
-
- i += IWL_FIRST_OFDM_RATE;
- /* skip 9M not supported in ht*/
- if (i >= IWL_RATE_9M_INDEX)
- i += 1;
- if ((i >= IWL_FIRST_OFDM_RATE) &&
- (i <= IWL_LAST_OFDM_RATE))
- return i;
-
- /* 4965 legacy rate format, search for match in table */
- } else {
- for (i = 0; i < ARRAY_SIZE(iwl4965_rates); i++)
- if (iwl4965_rates[i].plcp == (plcp &0xFF))
- return i;
- }
- return -1;
-}
-
static u8 iwl4965_rate_get_lowest_plcp(int rate_mask)
{
u8 i;
@@ -1635,230 +1563,9 @@ static int iwl4965_send_beacon_cmd(struct iwl4965_priv *priv)
/******************************************************************************
*
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac)
-{
- memcpy(mac, priv->eeprom.mac_address, 6);
-}
-
-static inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv)
-{
- iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-}
-
-/**
- * iwl4965_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom
- *
- * NOTE: This routine uses the non-debug IO access functions.
- */
-int iwl4965_eeprom_init(struct iwl4965_priv *priv)
-{
- u16 *e = (u16 *)&priv->eeprom;
- u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP);
- u32 r;
- int sz = sizeof(priv->eeprom);
- int rc;
- int i;
- u16 addr;
-
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
-
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
- return -ENOENT;
- }
-
- /* Make sure driver (instead of uCode) is allowed to read EEPROM */
- rc = iwl4965_eeprom_acquire_semaphore(priv);
- if (rc < 0) {
- IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
- }
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- _iwl4965_write32(priv, CSR_EEPROM_REG, addr << 1);
- _iwl4965_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
-
- for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT;
- i += IWL_EEPROM_ACCESS_DELAY) {
- r = _iwl4965_read_direct32(priv, CSR_EEPROM_REG);
- if (r & CSR_EEPROM_REG_READ_VALID_MSK)
- break;
- udelay(IWL_EEPROM_ACCESS_DELAY);
- }
-
- if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
- IWL_ERROR("Time out reading EEPROM[%d]", addr);
- rc = -ETIMEDOUT;
- goto done;
- }
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
- }
- rc = 0;
-
-done:
- iwl4965_eeprom_release_semaphore(priv);
- return rc;
-}
-
-/******************************************************************************
- *
* Misc. internal state and helper functions
*
******************************************************************************/
-#ifdef CONFIG_IWL4965_DEBUG
-
-/**
- * iwl4965_report_frame - dump frame to syslog during debug sessions
- *
- * You may hack this function to show different aspects of received frames,
- * including selective frame dumps.
- * group100 parameter selects whether to show 1 out of 100 good frames.
- *
- * TODO: This was originally written for 3945, need to audit for
- * proper operation with 4965.
- */
-void iwl4965_report_frame(struct iwl4965_priv *priv,
- struct iwl4965_rx_packet *pkt,
- struct ieee80211_hdr *header, int group100)
-{
- u32 to_us;
- u32 print_summary = 0;
- u32 print_dump = 0; /* set to 1 to dump all frames' contents */
- u32 hundred = 0;
- u32 dataframe = 0;
- u16 fc;
- u16 seq_ctl;
- u16 channel;
- u16 phy_flags;
- int rate_sym;
- u16 length;
- u16 status;
- u16 bcn_tmr;
- u32 tsf_low;
- u64 tsf;
- u8 rssi;
- u8 agc;
- u16 sig_avg;
- u16 noise_diff;
- struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
- struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
- struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
- u8 *data = IWL_RX_DATA(pkt);
-
- /* MAC header */
- fc = le16_to_cpu(header->frame_control);
- seq_ctl = le16_to_cpu(header->seq_ctrl);
-
- /* metadata */
- channel = le16_to_cpu(rx_hdr->channel);
- phy_flags = le16_to_cpu(rx_hdr->phy_flags);
- rate_sym = rx_hdr->rate;
- length = le16_to_cpu(rx_hdr->len);
-
- /* end-of-frame status and timestamp */
- status = le32_to_cpu(rx_end->status);
- bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
- tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
- tsf = le64_to_cpu(rx_end->timestamp);
-
- /* signal statistics */
- rssi = rx_stats->rssi;
- agc = rx_stats->agc;
- sig_avg = le16_to_cpu(rx_stats->sig_avg);
- noise_diff = le16_to_cpu(rx_stats->noise_diff);
-
- to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
-
- /* if data frame is to us and all is good,
- * (optionally) print summary for only 1 out of every 100 */
- if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
- (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
- dataframe = 1;
- if (!group100)
- print_summary = 1; /* print each frame */
- else if (priv->framecnt_to_us < 100) {
- priv->framecnt_to_us++;
- print_summary = 0;
- } else {
- priv->framecnt_to_us = 0;
- print_summary = 1;
- hundred = 1;
- }
- } else {
- /* print summary for all other frames */
- print_summary = 1;
- }
-
- if (print_summary) {
- char *title;
- u32 rate;
-
- if (hundred)
- title = "100Frames";
- else if (fc & IEEE80211_FCTL_RETRY)
- title = "Retry";
- else if (ieee80211_is_assoc_response(fc))
- title = "AscRsp";
- else if (ieee80211_is_reassoc_response(fc))
- title = "RasRsp";
- else if (ieee80211_is_probe_response(fc)) {
- title = "PrbRsp";
- print_dump = 1; /* dump frame contents */
- } else if (ieee80211_is_beacon(fc)) {
- title = "Beacon";
- print_dump = 1; /* dump frame contents */
- } else if (ieee80211_is_atim(fc))
- title = "ATIM";
- else if (ieee80211_is_auth(fc))
- title = "Auth";
- else if (ieee80211_is_deauth(fc))
- title = "DeAuth";
- else if (ieee80211_is_disassoc(fc))
- title = "DisAssoc";
- else
- title = "Frame";
-
- rate = iwl4965_rate_index_from_plcp(rate_sym);
- if (rate == -1)
- rate = 0;
- else
- rate = iwl4965_rates[rate].ieee / 2;
-
- /* print frame summary.
- * MAC addresses show just the last byte (for brevity),
- * but you can hack it to show more, if you'd like to. */
- if (dataframe)
- IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
- "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
- title, fc, header->addr1[5],
- length, rssi, channel, rate);
- else {
- /* src/dst addresses assume managed mode */
- IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
- "src=0x%02x, rssi=%u, tim=%lu usec, "
- "phy=0x%02x, chnl=%d\n",
- title, fc, header->addr1[5],
- header->addr3[5], rssi,
- tsf_low - priv->scan_start_tsf,
- phy_flags, channel);
- }
- }
- if (print_dump)
- iwl4965_print_hex_dump(IWL_DL_RX, data, length);
-}
-#endif
static void iwl4965_unset_hw_setting(struct iwl4965_priv *priv)
{
@@ -1898,24 +1605,20 @@ static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate,
return ret_rates;
}
-#ifdef CONFIG_IWL4965_HT
-void static iwl4965_set_ht_capab(struct ieee80211_hw *hw,
- struct ieee80211_ht_cap *ht_cap,
- u8 use_current_config);
-#endif
-
/**
* iwl4965_fill_probe_req - fill in all required fields and IE for probe request
*/
static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv,
- struct ieee80211_mgmt *frame,
- int left, int is_direct)
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left, int is_direct)
{
int len = 0;
u8 *pos = NULL;
u16 active_rates, ret_rates, cck_rates, active_rate_basic;
#ifdef CONFIG_IWL4965_HT
- struct ieee80211_hw_mode *mode;
+ const struct ieee80211_supported_band *sband =
+ iwl4965_get_hw_mode(priv, band);
#endif /* CONFIG_IWL4965_HT */
/* Make sure there is enough space for the probe request,
@@ -2000,13 +1703,18 @@ static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv,
len += 2 + *pos;
#ifdef CONFIG_IWL4965_HT
- mode = priv->hw->conf.mode;
- if (mode->ht_info.ht_supported) {
+ if (sband && sband->ht_info.ht_supported) {
+ struct ieee80211_ht_cap *ht_cap;
pos += (*pos) + 1;
*pos++ = WLAN_EID_HT_CAPABILITY;
*pos++ = sizeof(struct ieee80211_ht_cap);
- iwl4965_set_ht_capab(priv->hw,
- (struct ieee80211_ht_cap *)pos, 0);
+ ht_cap = (struct ieee80211_ht_cap *)pos;
+ ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap);
+ memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16);
+ ht_cap->ampdu_params_info =(sband->ht_info.ampdu_factor &
+ IEEE80211_HT_CAP_AMPDU_FACTOR) |
+ ((sband->ht_info.ampdu_density << 2) &
+ IEEE80211_HT_CAP_AMPDU_DENSITY);
len += 2 + sizeof(struct ieee80211_ht_cap);
}
#endif /*CONFIG_IWL4965_HT */
@@ -2018,7 +1726,6 @@ static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv,
/*
* QoS support
*/
-#ifdef CONFIG_IWL4965_QOS
static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv,
struct iwl4965_qosparam_cmd *qos)
{
@@ -2152,7 +1859,6 @@ static void iwl4965_activate_qos(struct iwl4965_priv *priv, u8 force)
}
}
-#endif /* CONFIG_IWL4965_QOS */
/*
* Power management (not Tx power!) functions
*/
@@ -2571,9 +2277,10 @@ static int iwl4965_set_rxon_hwcrypto(struct iwl4965_priv *priv, int hw_decrypt)
return 0;
}
-static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode)
+static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv,
+ enum ieee80211_band band)
{
- if (phymode == MODE_IEEE80211A) {
+ if (band == IEEE80211_BAND_5GHZ) {
priv->staging_rxon.flags &=
~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
| RXON_FLG_CCK_MSK);
@@ -2636,7 +2343,7 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
#endif
- ch_info = iwl4965_get_channel_info(priv, priv->phymode,
+ ch_info = iwl4965_get_channel_info(priv, priv->band,
le16_to_cpu(priv->staging_rxon.channel));
if (!ch_info)
@@ -2651,12 +2358,9 @@ static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv)
ch_info = &priv->channel_info[0];
priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
- if (is_channel_a_band(ch_info))
- priv->phymode = MODE_IEEE80211A;
- else
- priv->phymode = MODE_IEEE80211G;
+ priv->band = ch_info->band;
- iwl4965_set_flags_for_phymode(priv, priv->phymode);
+ iwl4965_set_flags_for_phymode(priv, priv->band);
priv->staging_rxon.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -2678,7 +2382,7 @@ static int iwl4965_set_mode(struct iwl4965_priv *priv, int mode)
const struct iwl4965_channel_info *ch_info;
ch_info = iwl4965_get_channel_info(priv,
- priv->phymode,
+ priv->band,
le16_to_cpu(priv->staging_rxon.channel));
if (!ch_info || !is_channel_ibss(ch_info)) {
@@ -2918,7 +2622,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
goto drop_unlock;
}
- if ((ctl->tx_rate & 0xFF) == IWL_INVALID_RATE) {
+ if ((ctl->tx_rate->hw_value & 0xFF) == IWL_INVALID_RATE) {
IWL_ERROR("ERROR: No TX rate available.\n");
goto drop_unlock;
}
@@ -2972,11 +2676,10 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
__constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
seq_number += 0x10;
#ifdef CONFIG_IWL4965_HT
-#ifdef CONFIG_IWL4965_HT_AGG
/* aggregation is on for this <sta,tid> */
- if (ctl->flags & IEEE80211_TXCTL_HT_MPDU_AGG)
+ if (ctl->flags & IEEE80211_TXCTL_AMPDU)
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
-#endif /* CONFIG_IWL4965_HT_AGG */
+ priv->stations[sta_id].tid[tid].tfds_in_queue++;
#endif /* CONFIG_IWL4965_HT */
}
@@ -3076,14 +2779,6 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
out_cmd->cmd.tx.dram_lsb_ptr = cpu_to_le32(scratch_phys);
out_cmd->cmd.tx.dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);
-#ifdef CONFIG_IWL4965_HT_AGG
-#ifdef CONFIG_IWL4965_HT
- /* TODO: move this functionality to rate scaling */
- iwl4965_tl_get_stats(priv, hdr);
-#endif /* CONFIG_IWL4965_HT_AGG */
-#endif /*CONFIG_IWL4965_HT */
-
-
if (!ieee80211_get_morefrag(hdr)) {
txq->need_update = 1;
if (qc) {
@@ -3105,7 +2800,7 @@ static int iwl4965_tx_skb(struct iwl4965_priv *priv,
iwl4965_tx_queue_update_wr_ptr(priv, txq, len);
/* Tell device the write index *just past* this latest filled TFD */
- q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd);
+ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
rc = iwl4965_tx_queue_update_write_ptr(priv, txq);
spin_unlock_irqrestore(&priv->lock, flags);
@@ -3134,11 +2829,11 @@ drop:
static void iwl4965_set_rate(struct iwl4965_priv *priv)
{
- const struct ieee80211_hw_mode *hw = NULL;
+ const struct ieee80211_supported_band *hw = NULL;
struct ieee80211_rate *rate;
int i;
- hw = iwl4965_get_hw_mode(priv, priv->phymode);
+ hw = iwl4965_get_hw_mode(priv, priv->band);
if (!hw) {
IWL_ERROR("Failed to set rate: unable to get hw mode\n");
return;
@@ -3147,24 +2842,10 @@ static void iwl4965_set_rate(struct iwl4965_priv *priv)
priv->active_rate = 0;
priv->active_rate_basic = 0;
- IWL_DEBUG_RATE("Setting rates for 802.11%c\n",
- hw->mode == MODE_IEEE80211A ?
- 'a' : ((hw->mode == MODE_IEEE80211B) ? 'b' : 'g'));
-
- for (i = 0; i < hw->num_rates; i++) {
- rate = &(hw->rates[i]);
- if ((rate->val < IWL_RATE_COUNT) &&
- (rate->flags & IEEE80211_RATE_SUPPORTED)) {
- IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n",
- rate->val, iwl4965_rates[rate->val].plcp,
- (rate->flags & IEEE80211_RATE_BASIC) ?
- "*" : "");
- priv->active_rate |= (1 << rate->val);
- if (rate->flags & IEEE80211_RATE_BASIC)
- priv->active_rate_basic |= (1 << rate->val);
- } else
- IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n",
- rate->val, iwl4965_rates[rate->val].plcp);
+ for (i = 0; i < hw->n_bitrates; i++) {
+ rate = &(hw->bitrates[i]);
+ if (rate->hw_value < IWL_RATE_COUNT)
+ priv->active_rate |= (1 << rate->hw_value);
}
IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n",
@@ -3513,9 +3194,9 @@ int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index)
return 0;
}
- for (index = iwl4965_queue_inc_wrap(index, q->n_bd);
+ for (index = iwl_queue_inc_wrap(index, q->n_bd);
q->read_ptr != index;
- q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd)) {
+ q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
if (txq_id != IWL_CMD_QUEUE_NUM) {
iwl4965_txstatus_to_ieee(priv,
&(txq->txb[txq->q.read_ptr]));
@@ -3528,10 +3209,10 @@ int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index)
nfreed++;
}
- if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) &&
+/* if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) &&
(txq_id != IWL_CMD_QUEUE_NUM) &&
priv->mac80211_registered)
- ieee80211_wake_queue(priv->hw, txq_id);
+ ieee80211_wake_queue(priv->hw, txq_id); */
return nfreed;
@@ -3550,7 +3231,6 @@ static int iwl4965_is_tx_success(u32 status)
*
******************************************************************************/
#ifdef CONFIG_IWL4965_HT
-#ifdef CONFIG_IWL4965_HT_AGG
static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv,
struct ieee80211_hdr *hdr)
@@ -3585,11 +3265,11 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
*/
static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
struct iwl4965_ht_agg *agg,
- struct iwl4965_tx_resp *tx_resp,
+ struct iwl4965_tx_resp_agg *tx_resp,
u16 start_idx)
{
- u32 status;
- __le32 *frame_status = &tx_resp->status;
+ u16 status;
+ struct agg_tx_status *frame_status = &tx_resp->status;
struct ieee80211_tx_status *tx_status = NULL;
struct ieee80211_hdr *hdr = NULL;
int i, sh;
@@ -3602,30 +3282,30 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
agg->frame_count = tx_resp->frame_count;
agg->start_idx = start_idx;
agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
- agg->bitmap0 = agg->bitmap1 = 0;
+ agg->bitmap = 0;
/* # frames attempted by Tx command */
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
- struct iwl4965_tx_queue *txq ;
- status = le32_to_cpu(frame_status[0]);
+ status = le16_to_cpu(frame_status[0].status);
+ seq = le16_to_cpu(frame_status[0].sequence);
+ idx = SEQ_TO_INDEX(seq);
+ txq_id = SEQ_TO_QUEUE(seq);
- txq_id = agg->txq_id;
- txq = &priv->txq[txq_id];
/* FIXME: code repetition */
- IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d \n",
- agg->frame_count, agg->start_idx);
+ IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ agg->frame_count, agg->start_idx, idx);
- tx_status = &(priv->txq[txq_id].txb[txq->q.read_ptr].status);
+ tx_status = &(priv->txq[txq_id].txb[idx].status);
tx_status->retry_count = tx_resp->failure_frame;
tx_status->queue_number = status & 0xff;
- tx_status->queue_length = tx_resp->bt_kill_count;
- tx_status->queue_length |= tx_resp->failure_rts;
-
+ tx_status->queue_length = tx_resp->failure_rts;
+ tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU;
tx_status->flags = iwl4965_is_tx_success(status)?
IEEE80211_TX_STATUS_ACK : 0;
- tx_status->control.tx_rate =
- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags);
+ iwl4965_hwrate_to_tx_control(priv,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ &tx_status->control);
/* FIXME: code repetition end */
IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
@@ -3642,8 +3322,8 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
/* Construct bit-map of pending frames within Tx window */
for (i = 0; i < agg->frame_count; i++) {
u16 sc;
- status = le32_to_cpu(frame_status[i]);
- seq = status >> 16;
+ status = le16_to_cpu(frame_status[i].status);
+ seq = le16_to_cpu(frame_status[i].sequence);
idx = SEQ_TO_INDEX(seq);
txq_id = SEQ_TO_QUEUE(seq);
@@ -3687,13 +3367,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
start, (u32)(bitmap & 0xFFFFFFFF));
}
- agg->bitmap0 = bitmap & 0xFFFFFFFF;
- agg->bitmap1 = bitmap >> 32;
+ agg->bitmap = bitmap;
agg->start_idx = start;
agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
- IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%x\n",
+ IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
agg->frame_count, agg->start_idx,
- agg->bitmap0);
+ agg->bitmap);
if (bitmap)
agg->wait_for_ba = 1;
@@ -3701,7 +3380,6 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv,
return 0;
}
#endif
-#endif
/**
* iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
@@ -3718,9 +3396,9 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status);
#ifdef CONFIG_IWL4965_HT
-#ifdef CONFIG_IWL4965_HT_AGG
- int tid, sta_id;
-#endif
+ int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
+ struct ieee80211_hdr *hdr;
+ __le16 *qc;
#endif
if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) {
@@ -3732,44 +3410,51 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
}
#ifdef CONFIG_IWL4965_HT
-#ifdef CONFIG_IWL4965_HT_AGG
+ hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, index);
+ qc = ieee80211_get_qos_ctrl(hdr);
+
+ if (qc)
+ tid = le16_to_cpu(*qc) & 0xf;
+
+ sta_id = iwl4965_get_ra_sta_id(priv, hdr);
+ if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
+ IWL_ERROR("Station not known\n");
+ return;
+ }
+
if (txq->sched_retry) {
const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
- struct ieee80211_hdr *hdr =
- iwl4965_tx_queue_get_hdr(priv, txq_id, index);
struct iwl4965_ht_agg *agg = NULL;
- __le16 *qc = ieee80211_get_qos_ctrl(hdr);
-
- if (qc == NULL) {
- IWL_ERROR("BUG_ON qc is null!!!!\n");
- return;
- }
- tid = le16_to_cpu(*qc) & 0xf;
-
- sta_id = iwl4965_get_ra_sta_id(priv, hdr);
- if (unlikely(sta_id == IWL_INVALID_STATION)) {
- IWL_ERROR("Station not known for\n");
+ if (!qc)
return;
- }
agg = &priv->stations[sta_id].tid[tid].agg;
- iwl4965_tx_status_reply_tx(priv, agg, tx_resp, index);
+ iwl4965_tx_status_reply_tx(priv, agg,
+ (struct iwl4965_tx_resp_agg *)tx_resp, index);
if ((tx_resp->frame_count == 1) &&
!iwl4965_is_tx_success(status)) {
/* TODO: send BAR */
}
- if ((txq->q.read_ptr != (scd_ssn & 0xff))) {
- index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
+ if (txq->q.read_ptr != (scd_ssn & 0xff)) {
+ int freed;
+ index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn "
"%d index %d\n", scd_ssn , index);
- iwl4965_tx_queue_reclaim(priv, txq_id, index);
+ freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+
+ if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
+ txq_id >= 0 && priv->mac80211_registered &&
+ agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)
+ ieee80211_wake_queue(priv->hw, txq_id);
+
+ iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
}
} else {
-#endif /* CONFIG_IWL4965_HT_AGG */
#endif /* CONFIG_IWL4965_HT */
tx_status = &(txq->txb[txq->q.read_ptr].status);
@@ -3777,12 +3462,10 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
tx_status->queue_number = status;
tx_status->queue_length = tx_resp->bt_kill_count;
tx_status->queue_length |= tx_resp->failure_rts;
-
tx_status->flags =
iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
-
- tx_status->control.tx_rate =
- iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags);
+ iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
+ &tx_status->control);
IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
"retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status),
@@ -3790,12 +3473,21 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv,
tx_resp->failure_frame);
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
- if (index != -1)
- iwl4965_tx_queue_reclaim(priv, txq_id, index);
+ if (index != -1) {
+ int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index);
+#ifdef CONFIG_IWL4965_HT
+ if (tid != MAX_TID_COUNT)
+ priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+ if (iwl4965_queue_space(&txq->q) > txq->q.low_mark &&
+ (txq_id >= 0) &&
+ priv->mac80211_registered)
+ ieee80211_wake_queue(priv->hw, txq_id);
+ if (tid != MAX_TID_COUNT)
+ iwl4965_check_empty_hw_queue(priv, sta_id, tid, txq_id);
+#endif
+ }
#ifdef CONFIG_IWL4965_HT
-#ifdef CONFIG_IWL4965_HT_AGG
}
-#endif /* CONFIG_IWL4965_HT_AGG */
#endif /* CONFIG_IWL4965_HT */
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
@@ -4907,8 +4599,7 @@ static void iwl4965_dump_nic_error_log(struct iwl4965_priv *priv)
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
IWL_ERROR("Start IWL Error Log Dump:\n");
- IWL_ERROR("Status: 0x%08lX, Config: %08X count: %d\n",
- priv->status, priv->config, count);
+ IWL_ERROR("Status: 0x%08lX, count: %d\n", priv->status, count);
}
desc = iwl4965_read_targ_mem(priv, base + 1 * sizeof(u32));
@@ -5120,9 +4811,9 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
* atomic, make sure that inta covers all the interrupts that
* we've discovered, even if FH interrupt came in just after
* reading CSR_INT. */
- if (inta_fh & CSR_FH_INT_RX_MASK)
+ if (inta_fh & CSR49_FH_INT_RX_MASK)
inta |= CSR_INT_BIT_FH_RX;
- if (inta_fh & CSR_FH_INT_TX_MASK)
+ if (inta_fh & CSR49_FH_INT_TX_MASK)
inta |= CSR_INT_BIT_FH_TX;
/* Now service all interrupt bits discovered above. */
@@ -5170,7 +4861,7 @@ static void iwl4965_irq_tasklet(struct iwl4965_priv *priv)
/* Queue restart only if RF_KILL switch was set to "kill"
* when we loaded driver, and is now set to "enable".
* After we're Alive, RF_KILL gets handled by
- * iwl_rx_card_state_notif() */
+ * iwl4965_rx_card_state_notif() */
if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) {
clear_bit(STATUS_RF_KILL_HW, &priv->status);
queue_work(priv->workqueue, &priv->restart);
@@ -5416,24 +5107,23 @@ static void iwl4965_init_band_reference(const struct iwl4965_priv *priv,
* Based on band and channel number.
*/
const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv,
- int phymode, u16 channel)
+ enum ieee80211_band band, u16 channel)
{
int i;
- switch (phymode) {
- case MODE_IEEE80211A:
+ switch (band) {
+ case IEEE80211_BAND_5GHZ:
for (i = 14; i < priv->channel_count; i++) {
if (priv->channel_info[i].channel == channel)
return &priv->channel_info[i];
}
break;
-
- case MODE_IEEE80211B:
- case MODE_IEEE80211G:
+ case IEEE80211_BAND_2GHZ:
if (channel >= 1 && channel <= 14)
return &priv->channel_info[channel - 1];
break;
-
+ default:
+ BUG();
}
return NULL;
@@ -5496,8 +5186,8 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
/* Loop through each band adding each of the channels */
for (ch = 0; ch < eeprom_ch_count; ch++) {
ch_info->channel = eeprom_ch_index[ch];
- ch_info->phymode = (band == 1) ? MODE_IEEE80211B :
- MODE_IEEE80211A;
+ ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
+ IEEE80211_BAND_5GHZ;
/* permanently store EEPROM's channel regulatory flags
* and max power in channel info database. */
@@ -5524,11 +5214,12 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
ch_info->min_power = 0;
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
+ IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x"
" %ddBm): Ad-Hoc %ssupported\n",
ch_info->channel,
is_channel_a_band(ch_info) ?
"5.2" : "2.4",
+ CHECK_AND_PRINT(VALID),
CHECK_AND_PRINT(IBSS),
CHECK_AND_PRINT(ACTIVE),
CHECK_AND_PRINT(RADAR),
@@ -5556,14 +5247,14 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
for (band = 6; band <= 7; band++) {
- int phymode;
+ enum ieee80211_band ieeeband;
u8 fat_extension_chan;
iwl4965_init_band_reference(priv, band, &eeprom_ch_count,
&eeprom_ch_info, &eeprom_ch_index);
/* EEPROM band 6 is 2.4, band 7 is 5 GHz */
- phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A;
+ ieeeband = (band == 6) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
/* Loop through each band adding each of the channels */
for (ch = 0; ch < eeprom_ch_count; ch++) {
@@ -5577,13 +5268,13 @@ static int iwl4965_init_channel_map(struct iwl4965_priv *priv)
fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE;
/* Set up driver's info for lower half */
- iwl4965_set_fat_chan_info(priv, phymode,
+ iwl4965_set_fat_chan_info(priv, ieeeband,
eeprom_ch_index[ch],
&(eeprom_ch_info[ch]),
fat_extension_chan);
/* Set up driver's info for upper half */
- iwl4965_set_fat_chan_info(priv, phymode,
+ iwl4965_set_fat_chan_info(priv, ieeeband,
(eeprom_ch_index[ch] + 4),
&(eeprom_ch_info[ch]),
HT_IE_EXT_CHANNEL_BELOW);
@@ -5625,18 +5316,20 @@ static void iwl4965_free_channel_map(struct iwl4965_priv *priv)
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5
-static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, int phymode)
+static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv,
+ enum ieee80211_band band)
{
- if (phymode == MODE_IEEE80211A)
+ if (band == IEEE80211_BAND_5GHZ)
return IWL_ACTIVE_DWELL_TIME_52;
else
return IWL_ACTIVE_DWELL_TIME_24;
}
-static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode)
+static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv,
+ enum ieee80211_band band)
{
- u16 active = iwl4965_get_active_dwell_time(priv, phymode);
- u16 passive = (phymode != MODE_IEEE80211A) ?
+ u16 active = iwl4965_get_active_dwell_time(priv, band);
+ u16 passive = (band != IEEE80211_BAND_5GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
@@ -5656,28 +5349,29 @@ static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode
return passive;
}
-static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode,
+static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv,
+ enum ieee80211_band band,
u8 is_active, u8 direct_mask,
struct iwl4965_scan_channel *scan_ch)
{
const struct ieee80211_channel *channels = NULL;
- const struct ieee80211_hw_mode *hw_mode;
+ const struct ieee80211_supported_band *sband;
const struct iwl4965_channel_info *ch_info;
u16 passive_dwell = 0;
u16 active_dwell = 0;
int added, i;
- hw_mode = iwl4965_get_hw_mode(priv, phymode);
- if (!hw_mode)
+ sband = iwl4965_get_hw_mode(priv, band);
+ if (!sband)
return 0;
- channels = hw_mode->channels;
+ channels = sband->channels;
- active_dwell = iwl4965_get_active_dwell_time(priv, phymode);
- passive_dwell = iwl4965_get_passive_dwell_time(priv, phymode);
+ active_dwell = iwl4965_get_active_dwell_time(priv, band);
+ passive_dwell = iwl4965_get_passive_dwell_time(priv, band);
- for (i = 0, added = 0; i < hw_mode->num_channels; i++) {
- if (channels[i].chan ==
+ for (i = 0, added = 0; i < sband->n_channels; i++) {
+ if (ieee80211_frequency_to_channel(channels[i].center_freq) ==
le16_to_cpu(priv->active_rxon.channel)) {
if (iwl4965_is_associated(priv)) {
IWL_DEBUG_SCAN
@@ -5688,9 +5382,9 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode,
} else if (priv->only_active_channel)
continue;
- scan_ch->channel = channels[i].chan;
+ scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq);
- ch_info = iwl4965_get_channel_info(priv, phymode,
+ ch_info = iwl4965_get_channel_info(priv, band,
scan_ch->channel);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n",
@@ -5699,7 +5393,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode,
}
if (!is_active || is_channel_passive(ch_info) ||
- !(channels[i].flag & IEEE80211_CHAN_W_ACTIVE_SCAN))
+ (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
scan_ch->type = 0; /* passive */
else
scan_ch->type = 1; /* active */
@@ -5718,7 +5412,7 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode,
/* scan_pwr_info->tpc.dsp_atten; */
/*scan_pwr_info->tpc.tx_gain; */
- if (phymode == MODE_IEEE80211A)
+ if (band == IEEE80211_BAND_5GHZ)
scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3;
else {
scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3));
@@ -5742,41 +5436,24 @@ static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode,
return added;
}
-static void iwl4965_reset_channel_flag(struct iwl4965_priv *priv)
-{
- int i, j;
- for (i = 0; i < 3; i++) {
- struct ieee80211_hw_mode *hw_mode = (void *)&priv->modes[i];
- for (j = 0; j < hw_mode->num_channels; j++)
- hw_mode->channels[j].flag = hw_mode->channels[j].val;
- }
-}
-
static void iwl4965_init_hw_rates(struct iwl4965_priv *priv,
struct ieee80211_rate *rates)
{
int i;
for (i = 0; i < IWL_RATE_COUNT; i++) {
- rates[i].rate = iwl4965_rates[i].ieee * 5;
- rates[i].val = i; /* Rate scaling will work on indexes */
- rates[i].val2 = i;
- rates[i].flags = IEEE80211_RATE_SUPPORTED;
- /* Only OFDM have the bits-per-symbol set */
- if ((i <= IWL_LAST_OFDM_RATE) && (i >= IWL_FIRST_OFDM_RATE))
- rates[i].flags |= IEEE80211_RATE_OFDM;
- else {
+ rates[i].bitrate = iwl4965_rates[i].ieee * 5;
+ rates[i].hw_value = i; /* Rate scaling will work on indexes */
+ rates[i].hw_value_short = i;
+ rates[i].flags = 0;
+ if ((i > IWL_LAST_OFDM_RATE) || (i < IWL_FIRST_OFDM_RATE)) {
/*
- * If CCK 1M then set rate flag to CCK else CCK_2
- * which is CCK | PREAMBLE2
+ * If CCK != 1M then set short preamble rate flag.
*/
- rates[i].flags |= (iwl4965_rates[i].plcp == 10) ?
- IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2;
+ rates[i].flags |=
+ (iwl4965_rates[i].plcp == IWL_RATE_1M_PLCP) ?
+ 0 : IEEE80211_RATE_SHORT_PREAMBLE;
}
-
- /* Set up which ones are basic rates... */
- if (IWL_BASIC_RATES_MASK & (1 << i))
- rates[i].flags |= IEEE80211_RATE_BASIC;
}
}
@@ -5786,150 +5463,117 @@ static void iwl4965_init_hw_rates(struct iwl4965_priv *priv,
static int iwl4965_init_geos(struct iwl4965_priv *priv)
{
struct iwl4965_channel_info *ch;
- struct ieee80211_hw_mode *modes;
+ struct ieee80211_supported_band *sband;
struct ieee80211_channel *channels;
struct ieee80211_channel *geo_ch;
struct ieee80211_rate *rates;
int i = 0;
- enum {
- A = 0,
- B = 1,
- G = 2,
- };
- int mode_count = 3;
- if (priv->modes) {
+ if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
+ priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
IWL_DEBUG_INFO("Geography modes already initialized.\n");
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
}
- modes = kzalloc(sizeof(struct ieee80211_hw_mode) * mode_count,
- GFP_KERNEL);
- if (!modes)
- return -ENOMEM;
-
channels = kzalloc(sizeof(struct ieee80211_channel) *
priv->channel_count, GFP_KERNEL);
- if (!channels) {
- kfree(modes);
+ if (!channels)
return -ENOMEM;
- }
- rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_MAX_RATES + 1)),
+ rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
GFP_KERNEL);
if (!rates) {
- kfree(modes);
kfree(channels);
return -ENOMEM;
}
- /* 0 = 802.11a
- * 1 = 802.11b
- * 2 = 802.11g
- */
-
/* 5.2GHz channels start after the 2.4GHz channels */
- modes[A].mode = MODE_IEEE80211A;
- modes[A].channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)];
- modes[A].rates = rates;
- modes[A].num_rates = 8; /* just OFDM */
- modes[A].rates = &rates[4];
- modes[A].num_channels = 0;
-#ifdef CONFIG_IWL4965_HT
- iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A);
-#endif
+ sband = &priv->bands[IEEE80211_BAND_5GHZ];
+ sband->channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)];
+ /* just OFDM */
+ sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
+ sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
- modes[B].mode = MODE_IEEE80211B;
- modes[B].channels = channels;
- modes[B].rates = rates;
- modes[B].num_rates = 4; /* just CCK */
- modes[B].num_channels = 0;
-
- modes[G].mode = MODE_IEEE80211G;
- modes[G].channels = channels;
- modes[G].rates = rates;
- modes[G].num_rates = 12; /* OFDM & CCK */
- modes[G].num_channels = 0;
-#ifdef CONFIG_IWL4965_HT
- iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G);
-#endif
+ iwl4965_init_ht_hw_capab(&sband->ht_info, IEEE80211_BAND_5GHZ);
+
+ sband = &priv->bands[IEEE80211_BAND_2GHZ];
+ sband->channels = channels;
+ /* OFDM & CCK */
+ sband->bitrates = rates;
+ sband->n_bitrates = IWL_RATE_COUNT;
+
+ iwl4965_init_ht_hw_capab(&sband->ht_info, IEEE80211_BAND_2GHZ);
priv->ieee_channels = channels;
priv->ieee_rates = rates;
iwl4965_init_hw_rates(priv, rates);
- for (i = 0, geo_ch = channels; i < priv->channel_count; i++) {
+ for (i = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];
- if (!is_channel_valid(ch)) {
- IWL_DEBUG_INFO("Channel %d [%sGHz] is restricted -- "
- "skipping.\n",
- ch->channel, is_channel_a_band(ch) ?
- "5.2" : "2.4");
+ /* FIXME: might be removed if scan is OK */
+ if (!is_channel_valid(ch))
continue;
- }
- if (is_channel_a_band(ch)) {
- geo_ch = &modes[A].channels[modes[A].num_channels++];
- } else {
- geo_ch = &modes[B].channels[modes[B].num_channels++];
- modes[G].num_channels++;
- }
+ if (is_channel_a_band(ch))
+ sband = &priv->bands[IEEE80211_BAND_5GHZ];
+ else
+ sband = &priv->bands[IEEE80211_BAND_2GHZ];
- geo_ch->freq = ieee80211chan2mhz(ch->channel);
- geo_ch->chan = ch->channel;
- geo_ch->power_level = ch->max_power_avg;
- geo_ch->antenna_max = 0xff;
+ geo_ch = &sband->channels[sband->n_channels++];
+
+ geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
+ geo_ch->max_power = ch->max_power_avg;
+ geo_ch->max_antenna_gain = 0xff;
+ geo_ch->hw_value = ch->channel;
if (is_channel_valid(ch)) {
- geo_ch->flag = IEEE80211_CHAN_W_SCAN;
- if (ch->flags & EEPROM_CHANNEL_IBSS)
- geo_ch->flag |= IEEE80211_CHAN_W_IBSS;
+ if (!(ch->flags & EEPROM_CHANNEL_IBSS))
+ geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
- if (ch->flags & EEPROM_CHANNEL_ACTIVE)
- geo_ch->flag |= IEEE80211_CHAN_W_ACTIVE_SCAN;
+ if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
+ geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
if (ch->flags & EEPROM_CHANNEL_RADAR)
- geo_ch->flag |= IEEE80211_CHAN_W_RADAR_DETECT;
+ geo_ch->flags |= IEEE80211_CHAN_RADAR;
if (ch->max_power_avg > priv->max_channel_txpower_limit)
priv->max_channel_txpower_limit =
ch->max_power_avg;
+ } else {
+ geo_ch->flags |= IEEE80211_CHAN_DISABLED;
}
- geo_ch->val = geo_ch->flag;
+ /* Save flags for reg domain usage */
+ geo_ch->orig_flags = geo_ch->flags;
+
+ IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
+ ch->channel, geo_ch->center_freq,
+ is_channel_a_band(ch) ? "5.2" : "2.4",
+ geo_ch->flags & IEEE80211_CHAN_DISABLED ?
+ "restricted" : "valid",
+ geo_ch->flags);
}
- if ((modes[A].num_channels == 0) && priv->is_abg) {
+ if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
+ priv->cfg->sku & IWL_SKU_A) {
printk(KERN_INFO DRV_NAME
": Incorrectly detected BG card as ABG. Please send "
"your PCI ID 0x%04X:0x%04X to maintainer.\n",
priv->pci_dev->device, priv->pci_dev->subsystem_device);
- priv->is_abg = 0;
+ priv->cfg->sku &= ~IWL_SKU_A;
}
printk(KERN_INFO DRV_NAME
": Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- modes[G].num_channels, modes[A].num_channels);
+ priv->bands[IEEE80211_BAND_2GHZ].n_channels,
+ priv->bands[IEEE80211_BAND_5GHZ].n_channels);
- /*
- * NOTE: We register these in preference of order -- the
- * stack doesn't currently (as of 7.0.6 / Apr 24 '07) pick
- * a phymode based on rates or AP capabilities but seems to
- * configure it purely on if the channel being configured
- * is supported by a mode -- and the first match is taken
- */
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->bands[IEEE80211_BAND_2GHZ];
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ];
- if (modes[G].num_channels)
- ieee80211_register_hwmode(priv->hw, &modes[G]);
- if (modes[B].num_channels)
- ieee80211_register_hwmode(priv->hw, &modes[B]);
- if (modes[A].num_channels)
- ieee80211_register_hwmode(priv->hw, &modes[A]);
-
- priv->modes = modes;
set_bit(STATUS_GEO_CONFIGURED, &priv->status);
return 0;
@@ -5940,7 +5584,6 @@ static int iwl4965_init_geos(struct iwl4965_priv *priv)
*/
static void iwl4965_free_geos(struct iwl4965_priv *priv)
{
- kfree(priv->modes);
kfree(priv->ieee_channels);
kfree(priv->ieee_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
@@ -6269,7 +5912,7 @@ static int iwl4965_read_ucode(struct iwl4965_priv *priv)
struct iwl4965_ucode *ucode;
int ret;
const struct firmware *ucode_raw;
- const char *name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode";
+ const char *name = priv->cfg->fw_name;
u8 *src;
size_t len;
u32 ver, inst_size, data_size, init_size, init_data_size, boot_size;
@@ -6941,8 +6584,9 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
int rc = 0;
struct iwl4965_scan_cmd *scan;
struct ieee80211_conf *conf = NULL;
+ u16 cmd_len;
+ enum ieee80211_band band;
u8 direct_mask;
- int phymode;
conf = ieee80211_get_hw_conf(priv->hw);
@@ -7051,18 +6695,10 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
} else
direct_mask = 0;
- /* We don't build a direct scan probe request; the uCode will do
- * that based on the direct_mask added to each channel entry */
- scan->tx_cmd.len = cpu_to_le16(
- iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan), 0));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
- /* flags + rate selection */
-
- scan->tx_cmd.tx_flags |= cpu_to_le32(0x200);
switch (priv->scan_bands) {
case 2:
@@ -7072,7 +6708,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK);
scan->good_CRC_th = 0;
- phymode = MODE_IEEE80211G;
+ band = IEEE80211_BAND_2GHZ;
break;
case 1:
@@ -7080,7 +6716,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP,
RATE_MCS_ANT_B_MSK);
scan->good_CRC_th = IWL_GOOD_CRC_TH;
- phymode = MODE_IEEE80211A;
+ band = IEEE80211_BAND_5GHZ;
break;
default:
@@ -7088,6 +6724,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
goto done;
}
+ /* We don't build a direct scan probe request; the uCode will do
+ * that based on the direct_mask added to each channel entry */
+ cmd_len = iwl4965_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan), 0);
+
+ scan->tx_cmd.len = cpu_to_le16(cmd_len);
/* select Rx chains */
/* Force use of chains B and C (0x6) for scan Rx.
@@ -7101,18 +6744,23 @@ static void iwl4965_bg_request_scan(struct work_struct *data)
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
scan->filter_flags = RXON_FILTER_PROMISC_MSK;
- if (direct_mask)
+ if (direct_mask) {
IWL_DEBUG_SCAN
("Initiating direct scan for %s.\n",
iwl4965_escape_essid(priv->essid, priv->essid_len));
- else
+ scan->channel_count =
+ iwl4965_get_channels_for_scan(
+ priv, band, 1, /* active */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ } else {
IWL_DEBUG_SCAN("Initiating indirect scan.\n");
-
- scan->channel_count =
- iwl4965_get_channels_for_scan(
- priv, phymode, 1, /* active */
- direct_mask,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ scan->channel_count =
+ iwl4965_get_channels_for_scan(
+ priv, band, 0, /* passive */
+ direct_mask,
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ }
cmd.len += le16_to_cpu(scan->tx_cmd.len) +
scan->channel_count * sizeof(struct iwl4965_scan_channel);
@@ -7281,9 +6929,8 @@ static void iwl4965_bg_post_associate(struct work_struct *data)
if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
priv->assoc_station_added = 1;
-#ifdef CONFIG_IWL4965_QOS
iwl4965_activate_qos(priv, 0);
-#endif /* CONFIG_IWL4965_QOS */
+
/* we have just associated, don't start scan too early */
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
mutex_unlock(&priv->mutex);
@@ -7460,7 +7107,7 @@ static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
}
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
- ctl->tx_rate);
+ ctl->tx_rate->bitrate);
if (iwl4965_tx_skb(priv, skb, ctl))
dev_kfree_skb_any(skb);
@@ -7519,7 +7166,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
int ret = 0;
mutex_lock(&priv->mutex);
- IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel);
+ IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel->hw_value);
priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP);
@@ -7539,10 +7186,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
spin_lock_irqsave(&priv->lock, flags);
- ch_info = iwl4965_get_channel_info(priv, conf->phymode, conf->channel);
+ ch_info = iwl4965_get_channel_info(priv, conf->channel->band,
+ ieee80211_frequency_to_channel(conf->channel->center_freq));
if (!is_channel_valid(ch_info)) {
- IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n",
- conf->channel, conf->phymode);
IWL_DEBUG_MAC80211("leave - invalid channel\n");
spin_unlock_irqrestore(&priv->lock, flags);
ret = -EINVAL;
@@ -7550,10 +7196,10 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
}
#ifdef CONFIG_IWL4965_HT
- /* if we are switching fron ht to 2.4 clear flags
+ /* if we are switching from ht to 2.4 clear flags
* from any ht related info since 2.4 does not
* support ht */
- if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel)
+ if ((le16_to_cpu(priv->staging_rxon.channel) != conf->channel->hw_value)
#ifdef IEEE80211_CONF_CHANNEL_SWITCH
&& !(conf->flags & IEEE80211_CONF_CHANNEL_SWITCH)
#endif
@@ -7561,12 +7207,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
priv->staging_rxon.flags = 0;
#endif /* CONFIG_IWL4965_HT */
- iwl4965_set_rxon_channel(priv, conf->phymode, conf->channel);
+ iwl4965_set_rxon_channel(priv, conf->channel->band,
+ ieee80211_frequency_to_channel(conf->channel->center_freq));
- iwl4965_set_flags_for_phymode(priv, conf->phymode);
+ iwl4965_set_flags_for_phymode(priv, conf->channel->band);
/* The list of supported rates and rate mask can be different
- * for each phymode; since the phymode may have changed, reset
+ * for each band; since the band may have changed, reset
* the rate mask to what mac80211 lists */
iwl4965_set_rate(priv);
@@ -7658,9 +7305,7 @@ static void iwl4965_config_ap(struct iwl4965_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwl4965_commit_rxon(priv);
-#ifdef CONFIG_IWL4965_QOS
iwl4965_activate_qos(priv, 1);
-#endif
iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0);
}
iwl4965_send_beacon_cmd(priv);
@@ -7682,6 +7327,12 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
if (conf == NULL)
return -EIO;
+ if (priv->vif != vif) {
+ IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
+ mutex_unlock(&priv->mutex);
+ return 0;
+ }
+
if ((priv->iw_mode == IEEE80211_IF_TYPE_AP) &&
(!conf->beacon || !conf->ssid_len)) {
IWL_DEBUG_MAC80211
@@ -7704,17 +7355,6 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw,
if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
!(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
*/
- if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
- IWL_DEBUG_MAC80211("leave - scanning\n");
- mutex_unlock(&priv->mutex);
- return 0;
- }
-
- if (priv->vif != vif) {
- IWL_DEBUG_MAC80211("leave - priv->vif != vif\n");
- mutex_unlock(&priv->mutex);
- return 0;
- }
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
if (!conf->bssid) {
@@ -7836,7 +7476,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
- if (bss_conf->use_cts_prot && (priv->phymode != MODE_IEEE80211A))
+ if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
@@ -7974,10 +7614,8 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
const struct ieee80211_tx_queue_params *params)
{
struct iwl4965_priv *priv = hw->priv;
-#ifdef CONFIG_IWL4965_QOS
unsigned long flags;
int q;
-#endif /* CONFIG_IWL4965_QOS */
IWL_DEBUG_MAC80211("enter\n");
@@ -7991,7 +7629,6 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
return 0;
}
-#ifdef CONFIG_IWL4965_QOS
if (!priv->qos_data.qos_enable) {
priv->qos_data.qos_active = 0;
IWL_DEBUG_MAC80211("leave - qos not enabled\n");
@@ -8005,7 +7642,7 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
priv->qos_data.def_qos_parm.ac[q].edca_txop =
- cpu_to_le16((params->burst_time * 100));
+ cpu_to_le16((params->txop * 32));
priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
priv->qos_data.qos_active = 1;
@@ -8020,8 +7657,6 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue,
mutex_unlock(&priv->mutex);
-#endif /*CONFIG_IWL4965_QOS */
-
IWL_DEBUG_MAC80211("leave\n");
return 0;
}
@@ -8091,23 +7726,9 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw)
spin_lock_irqsave(&priv->lock, flags);
memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
spin_unlock_irqrestore(&priv->lock, flags);
-#ifdef CONFIG_IWL4965_HT_AGG
-/* if (priv->lq_mngr.agg_ctrl.granted_ba)
- iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);*/
-
- memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl4965_agg_control));
- priv->lq_mngr.agg_ctrl.tid_traffic_load_threshold = 10;
- priv->lq_mngr.agg_ctrl.ba_timeout = 5000;
- priv->lq_mngr.agg_ctrl.auto_agg = 1;
-
- if (priv->lq_mngr.agg_ctrl.auto_agg)
- priv->lq_mngr.agg_ctrl.requested_ba = TID_ALL_ENABLED;
-#endif /*CONFIG_IWL4965_HT_AGG */
#endif /* CONFIG_IWL4965_HT */
-#ifdef CONFIG_IWL4965_QOS
iwl4965_reset_qos(priv);
-#endif
cancel_delayed_work(&priv->post_associate);
@@ -8196,9 +7817,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
IWL_DEBUG_MAC80211("leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
-#ifdef CONFIG_IWL4965_QOS
iwl4965_reset_qos(priv);
-#endif
queue_work(priv->workqueue, &priv->post_associate.work);
@@ -8234,15 +7853,21 @@ static void iwl4965_ht_info_fill(struct ieee80211_conf *conf,
iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
iwl_conf->max_amsdu_size =
!!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
+
iwl_conf->supported_chan_width =
!!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH);
+ iwl_conf->extension_chan_offset =
+ ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
+ /* If no above or below channel supplied disable FAT channel */
+ if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE &&
+ iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW)
+ iwl_conf->supported_chan_width = 0;
+
iwl_conf->tx_mimo_ps_mode =
(u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2);
memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16);
iwl_conf->control_channel = ht_bss_conf->primary_channel;
- iwl_conf->extension_chan_offset =
- ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET;
iwl_conf->tx_chan_width =
!!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH);
iwl_conf->ht_protection =
@@ -8281,28 +7906,6 @@ static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw,
return 0;
}
-static void iwl4965_set_ht_capab(struct ieee80211_hw *hw,
- struct ieee80211_ht_cap *ht_cap,
- u8 use_current_config)
-{
- struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_hw_mode *mode = conf->mode;
-
- if (use_current_config) {
- ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap);
- memcpy(ht_cap->supp_mcs_set,
- conf->ht_conf.supp_mcs_set, 16);
- } else {
- ht_cap->cap_info = cpu_to_le16(mode->ht_info.cap);
- memcpy(ht_cap->supp_mcs_set,
- mode->ht_info.supp_mcs_set, 16);
- }
- ht_cap->ampdu_params_info =
- (mode->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) |
- ((mode->ht_info.ampdu_density << 2) &
- IEEE80211_HT_CAP_AMPDU_DENSITY);
-}
-
#endif /*CONFIG_IWL4965_HT*/
/*****************************************************************************
@@ -8497,65 +8100,6 @@ static ssize_t store_filter_flags(struct device *d,
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
store_filter_flags);
-static ssize_t show_tune(struct device *d,
- struct device_attribute *attr, char *buf)
-{
- struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
-
- return sprintf(buf, "0x%04X\n",
- (priv->phymode << 8) |
- le16_to_cpu(priv->active_rxon.channel));
-}
-
-static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode);
-
-static ssize_t store_tune(struct device *d,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data;
- char *p = (char *)buf;
- u16 tune = simple_strtoul(p, &p, 0);
- u8 phymode = (tune >> 8) & 0xff;
- u16 channel = tune & 0xff;
-
- IWL_DEBUG_INFO("Tune request to:%d channel:%d\n", phymode, channel);
-
- mutex_lock(&priv->mutex);
- if ((le16_to_cpu(priv->staging_rxon.channel) != channel) ||
- (priv->phymode != phymode)) {
- const struct iwl4965_channel_info *ch_info;
-
- ch_info = iwl4965_get_channel_info(priv, phymode, channel);
- if (!ch_info) {
- IWL_WARNING("Requested invalid phymode/channel "
- "combination: %d %d\n", phymode, channel);
- mutex_unlock(&priv->mutex);
- return -EINVAL;
- }
-
- /* Cancel any currently running scans... */
- if (iwl4965_scan_cancel_timeout(priv, 100))
- IWL_WARNING("Could not cancel scan.\n");
- else {
- IWL_DEBUG_INFO("Committing phymode and "
- "rxon.channel = %d %d\n",
- phymode, channel);
-
- iwl4965_set_rxon_channel(priv, phymode, channel);
- iwl4965_set_flags_for_phymode(priv, phymode);
-
- iwl4965_set_rate(priv);
- iwl4965_commit_rxon(priv);
- }
- }
- mutex_unlock(&priv->mutex);
-
- return count;
-}
-
-static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune);
-
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
static ssize_t show_measurement(struct device *d,
@@ -8745,73 +8289,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
static ssize_t show_channels(struct device *d,
struct device_attribute *attr, char *buf)
{
- struct iwl4965_priv *priv = dev_get_drvdata(d);
- int len = 0, i;
- struct ieee80211_channel *channels = NULL;
- const struct ieee80211_hw_mode *hw_mode = NULL;
- int count = 0;
-
- if (!iwl4965_is_ready(priv))
- return -EAGAIN;
-
- hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211G);
- if (!hw_mode)
- hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211B);
- if (hw_mode) {
- channels = hw_mode->channels;
- count = hw_mode->num_channels;
- }
-
- len +=
- sprintf(&buf[len],
- "Displaying %d channels in 2.4GHz band "
- "(802.11bg):\n", count);
-
- for (i = 0; i < count; i++)
- len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",
- channels[i].chan,
- channels[i].power_level,
- channels[i].
- flag & IEEE80211_CHAN_W_RADAR_DETECT ?
- " (IEEE 802.11h required)" : "",
- (!(channels[i].flag & IEEE80211_CHAN_W_IBSS)
- || (channels[i].
- flag &
- IEEE80211_CHAN_W_RADAR_DETECT)) ? "" :
- ", IBSS",
- channels[i].
- flag & IEEE80211_CHAN_W_ACTIVE_SCAN ?
- "active/passive" : "passive only");
-
- hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211A);
- if (hw_mode) {
- channels = hw_mode->channels;
- count = hw_mode->num_channels;
- } else {
- channels = NULL;
- count = 0;
- }
-
- len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band "
- "(802.11a):\n", count);
-
- for (i = 0; i < count; i++)
- len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n",
- channels[i].chan,
- channels[i].power_level,
- channels[i].
- flag & IEEE80211_CHAN_W_RADAR_DETECT ?
- " (IEEE 802.11h required)" : "",
- (!(channels[i].flag & IEEE80211_CHAN_W_IBSS)
- || (channels[i].
- flag &
- IEEE80211_CHAN_W_RADAR_DETECT)) ? "" :
- ", IBSS",
- channels[i].
- flag & IEEE80211_CHAN_W_ACTIVE_SCAN ?
- "active/passive" : "passive only");
-
- return len;
+ /* all this shit doesn't belong into sysfs anyway */
+ return 0;
}
static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL);
@@ -8990,7 +8469,6 @@ static struct attribute *iwl4965_sysfs_entries[] = {
&dev_attr_statistics.attr,
&dev_attr_status.attr,
&dev_attr_temperature.attr,
- &dev_attr_tune.attr,
&dev_attr_tx_power.attr,
NULL
@@ -9021,10 +8499,6 @@ static struct ieee80211_ops iwl4965_hw_ops = {
#ifdef CONFIG_IWL4965_HT
.conf_ht = iwl4965_mac_conf_ht,
.ampdu_action = iwl4965_mac_ampdu_action,
-#ifdef CONFIG_IWL4965_HT_AGG
- .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start,
- .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop,
-#endif /* CONFIG_IWL4965_HT_AGG */
#endif /* CONFIG_IWL4965_HT */
.hw_scan = iwl4965_mac_hw_scan
};
@@ -9034,6 +8508,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
int err = 0;
struct iwl4965_priv *priv;
struct ieee80211_hw *hw;
+ struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
int i;
DECLARE_MAC_BUF(mac);
@@ -9067,6 +8542,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
priv = hw->priv;
priv->hw = hw;
+ priv->cfg = cfg;
priv->pci_dev = pdev;
priv->antenna = (enum iwl4965_antenna)iwl4965_param_antenna;
@@ -9093,10 +8569,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
#ifdef CONFIG_IWL4965_HT
-#ifdef CONFIG_IWL4965_HT_AGG
/* Enhanced value; more queues, to support 11n aggregation */
hw->queues = 16;
-#endif /* CONFIG_IWL4965_HT_AGG */
#endif /* CONFIG_IWL4965_HT */
spin_lock_init(&priv->lock);
@@ -9124,7 +8598,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->data_retry_limit = -1;
priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
- priv->phymode = -1;
+ priv->band = IEEE80211_BAND_2GHZ;
err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (!err)
@@ -9171,8 +8645,9 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Choose which receivers/antennas to use */
iwl4965_set_rxon_chain(priv);
+
printk(KERN_INFO DRV_NAME
- ": Detected Intel Wireless WiFi Link 4965AGN\n");
+ ": Detected Intel Wireless WiFi Link %s\n", priv->cfg->name);
/* Device-specific setup */
if (iwl4965_hw_set_hw_setting(priv)) {
@@ -9180,7 +8655,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
goto out_iounmap;
}
-#ifdef CONFIG_IWL4965_QOS
if (iwl4965_param_qos_enable)
priv->qos_data.qos_enable = 1;
@@ -9188,9 +8662,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->qos_data.qos_active = 0;
priv->qos_data.qos_cap.val = 0;
-#endif /* CONFIG_IWL4965_QOS */
- iwl4965_set_rxon_channel(priv, MODE_IEEE80211G, 6);
+ iwl4965_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6);
iwl4965_setup_deferred_work(priv);
iwl4965_setup_rx_handlers(priv);
@@ -9220,13 +8693,13 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
goto out_remove_sysfs;
}
/* Read the EEPROM */
- err = iwl4965_eeprom_init(priv);
+ err = iwl_eeprom_init(priv);
if (err) {
IWL_ERROR("Unable to init EEPROM\n");
goto out_remove_sysfs;
}
/* MAC Address location in EEPROM same for 3945/4965 */
- get_eeprom_mac(priv, priv->mac_addr);
+ iwl_eeprom_get_mac(priv, priv->mac_addr);
IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr));
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
@@ -9241,7 +8714,6 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
IWL_ERROR("initializing geos failed: %d\n", err);
goto out_free_channel_map;
}
- iwl4965_reset_channel_flag(priv);
iwl4965_rate_control_register(priv->hw);
err = ieee80211_register_hw(priv->hw);