summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-05-15 00:52:37 -0700
committerDavid S. Miller <davem@davemloft.net>2008-05-15 00:52:37 -0700
commitf42a44494bcdf03fc851c03d438464d59c0ceaf5 (patch)
tree986ea7b54e9fc79a64863fd7e92eabd99ffd37a3 /drivers/net/wireless/iwlwifi
parent63fe46da9c380b3f2bbdf3765044649517cc717c (diff)
parentef85ad541f9a6ccd3f89ec73f92b2d6f45a9d3e8 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig4
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-hw.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c36
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c661
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c220
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h101
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c422
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c61
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c373
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c58
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c1135
20 files changed, 1838 insertions, 1479 deletions
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 995dd537083f..5f3e849043f7 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -96,13 +96,13 @@ config IWLWIFI_DEBUG
control which debug output is sent to the kernel log by setting the
value in
- /sys/bus/pci/drivers/${DRIVER}/debug_level
+ /sys/class/net/wlan0/device/debug_level
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
- % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
+ % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
You can find the list of debug mask values in:
drivers/net/wireless/iwlwifi/iwl-4965-debug.h
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index b0b2b5ebfa61..5c73eede7193 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_IWLCORE) += iwlcore.o
iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
+iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
@@ -10,7 +11,7 @@ iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
obj-$(CONFIG_IWL4965) += iwl4965.o
-iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o iwl-sta.o
+iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o
ifeq ($(CONFIG_IWL5000),y)
iwl4965-objs += iwl-5000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 9df48b33f0ca..ad4e7b74ca24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -520,7 +520,7 @@ static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
{
/* First cache any information we need before we overwrite
* the information provided in the skb from the hardware */
- s8 signal = stats->ssi;
+ s8 signal = stats->signal;
s8 noise = 0;
int rate = stats->rate_idx;
u64 tsf = stats->mactime;
@@ -693,7 +693,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
}
/* Convert 3945's rssi indicator to dBm */
- rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET;
+ rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
/* Set default noise value to -127 */
if (priv->last_rx_noise == 0)
@@ -712,21 +712,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
* Calculate rx_status.signal (quality indicator in %) based on SNR. */
if (rx_stats_noise_diff) {
snr = rx_stats_sig_avg / rx_stats_noise_diff;
- rx_status.noise = rx_status.ssi -
+ rx_status.noise = rx_status.signal -
iwl3945_calc_db_from_ratio(snr);
- rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi,
+ rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal,
rx_status.noise);
/* If noise info not available, calculate signal quality indicator (%)
* using just the dBm signal level. */
} else {
rx_status.noise = priv->last_rx_noise;
- rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0);
+ rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0);
}
IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
- rx_status.ssi, rx_status.noise, rx_status.signal,
+ rx_status.signal, rx_status.noise, rx_status.qual,
rx_stats_sig_avg, rx_stats_noise_diff);
header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
@@ -736,8 +736,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
network_packet ? '*' : ' ',
le16_to_cpu(rx_hdr->channel),
- rx_status.ssi, rx_status.ssi,
- rx_status.ssi, rx_status.rate_idx);
+ rx_status.signal, rx_status.signal,
+ rx_status.noise, rx_status.rate_idx);
#ifdef CONFIG_IWL3945_DEBUG
if (iwl3945_debug_level & (IWL_DL_RX))
@@ -748,7 +748,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
priv->last_tsf = le64_to_cpu(rx_end->timestamp);
- priv->last_rx_rssi = rx_status.ssi;
+ priv->last_rx_rssi = rx_status.signal;
priv->last_rx_noise = rx_status.noise;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index fb96c62ad0ff..9fdc1405e853 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -886,6 +886,7 @@ struct iwl3945_priv {
struct work_struct report_work;
struct work_struct request_scan;
struct work_struct beacon_update;
+ struct work_struct set_monitor;
struct tasklet_struct irq_tasklet;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
index 29749e2a8ff0..ee55b283226b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h
@@ -829,7 +829,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
#define IWL49_NUM_QUEUES 16
/**
- * struct iwl4965_tfd_frame_data
+ * struct iwl_tfd_frame_data
*
* Describes up to 2 buffers containing (contiguous) portions of a Tx frame.
* Each buffer must be on dword boundary.
@@ -848,7 +848,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
* 31-20: Tx buffer 2 length (bytes)
* 19- 0: Tx buffer 2 address bits [35:16]
*/
-struct iwl4965_tfd_frame_data {
+struct iwl_tfd_frame_data {
__le32 tb1_addr;
__le32 val1;
@@ -878,7 +878,7 @@ struct iwl4965_tfd_frame_data {
/**
- * struct iwl4965_tfd_frame
+ * struct iwl_tfd_frame
*
* Transmit Frame Descriptor (TFD)
*
@@ -905,7 +905,7 @@ struct iwl4965_tfd_frame_data {
*
* A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx.
*/
-struct iwl4965_tfd_frame {
+struct iwl_tfd_frame {
__le32 val0;
/* __le32 rsvd1:24; */
/* __le32 num_tbs:5; */
@@ -914,7 +914,7 @@ struct iwl4965_tfd_frame {
#define IWL_num_tbs_SYM val0
/* __le32 rsvd2:1; */
/* __le32 padding:2; */
- struct iwl4965_tfd_frame_data pa[10];
+ struct iwl_tfd_frame_data pa[10];
__le32 reserved;
} __attribute__ ((packed));
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 24dee00b0e85..8e3660ebba7d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -360,9 +360,9 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
unsigned long state;
DECLARE_MAC_BUF(mac);
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
state = sta->ampdu_mlme.tid_state_tx[tid];
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
if (state == HT_AGG_STATE_IDLE &&
rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
@@ -662,7 +662,8 @@ static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
}
}
-static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
+static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
+ int rate_type)
{
u8 high = IWL_RATE_INVALID;
u8 low = IWL_RATE_INVALID;
@@ -763,7 +764,8 @@ static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
goto out;
}
- high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type);
+ high_low = rs_get_adjacent_rate(lq_sta->drv, scale_index, rate_mask,
+ tbl->lq_type);
low = high_low & 0xff;
if (low == IWL_RATE_INVALID)
@@ -990,7 +992,7 @@ out:
* These control how long we stay using same modulation mode before
* searching for a new mode.
*/
-static void rs_set_stay_in_table(u8 is_legacy,
+static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
struct iwl4965_lq_sta *lq_sta)
{
IWL_DEBUG_RATE("we are staying in the same table\n");
@@ -1079,7 +1081,8 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
new_rate = high = low = start_hi = IWL_RATE_INVALID;
for (; ;) {
- high_low = rs_get_adjacent_rate(rate, rate_mask, tbl->lq_type);
+ high_low = rs_get_adjacent_rate(priv, rate, rate_mask,
+ tbl->lq_type);
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
@@ -1565,7 +1568,9 @@ static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
int i;
int active_tbl;
int flush_interval_passed = 0;
+ struct iwl_priv *priv;
+ priv = lq_sta->drv;
active_tbl = lq_sta->active_tbl;
tbl = &(lq_sta->lq_info[active_tbl]);
@@ -1838,7 +1843,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
/* (Else) not in search of better modulation mode, try for better
* starting rate, while staying in this mode. */
- high_low = rs_get_adjacent_rate(index, rate_scale_index_msk,
+ high_low = rs_get_adjacent_rate(priv, index, rate_scale_index_msk,
tbl->lq_type);
low = high_low & 0xff;
high = (high_low >> 8) & 0xff;
@@ -1998,7 +2003,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
(lq_sta->action_counter >= 1)) {
lq_sta->action_counter = 0;
IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
- rs_set_stay_in_table(1, lq_sta);
+ rs_set_stay_in_table(priv, 1, lq_sta);
}
/* If we're in an HT mode, and all 3 mode switch actions
@@ -2015,7 +2020,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
}
#endif /*CONFIG_IWL4965_HT */
lq_sta->action_counter = 0;
- rs_set_stay_in_table(0, lq_sta);
+ rs_set_stay_in_table(priv, 0, lq_sta);
}
/*
@@ -2169,11 +2174,13 @@ out:
rcu_read_unlock();
}
-static void *rs_alloc_sta(void *priv, gfp_t gfp)
+static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
{
struct iwl4965_lq_sta *lq_sta;
+ struct iwl_priv *priv;
int i, j;
+ priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE("create station rate scale window\n");
lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp);
@@ -2443,10 +2450,12 @@ static void rs_clear(void *priv_rate)
IWL_DEBUG_RATE("leave\n");
}
-static void rs_free_sta(void *priv, void *priv_sta)
+static void rs_free_sta(void *priv_rate, void *priv_sta)
{
struct iwl4965_lq_sta *lq_sta = priv_sta;
+ struct iwl_priv *priv;
+ priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE("enter\n");
kfree(lq_sta);
IWL_DEBUG_RATE("leave\n");
@@ -2462,6 +2471,9 @@ static int open_file_generic(struct inode *inode, struct file *file)
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
u32 *rate_n_flags, int index)
{
+ struct iwl_priv *priv;
+
+ priv = lq_sta->drv;
if (lq_sta->dbg_fixed_rate) {
if (index < 12) {
*rate_n_flags = lq_sta->dbg_fixed_rate;
@@ -2481,10 +2493,12 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
struct iwl4965_lq_sta *lq_sta = file->private_data;
+ struct iwl_priv *priv;
char buf[64];
int buf_size;
u32 parsed_rate;
+ priv = lq_sta->drv;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 5d675e39bab8..17847f981e11 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -50,11 +50,10 @@ static struct iwl_mod_params iwl4965_mod_params = {
.num_of_queues = IWL49_NUM_QUEUES,
.enable_qos = 1,
.amsdu_size_8K = 1,
+ .restart_fw = 1,
/* the rest are 0 by default */
};
-static void iwl4965_hw_card_show_info(struct iwl_priv *priv);
-
#ifdef CONFIG_IWL4965_HT
static const u16 default_tid_to_tx_fifo[] = {
@@ -224,6 +223,102 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
return 0;
}
+/**
+ * iwl4965_set_ucode_ptrs - Set uCode address location
+ *
+ * Tell initialization uCode where to find runtime uCode.
+ *
+ * BSM registers initially contain pointers to initialization uCode.
+ * We need to replace them to load runtime uCode inst and data,
+ * and to save runtime data when powering down.
+ */
+static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
+{
+ dma_addr_t pinst;
+ dma_addr_t pdata;
+ unsigned long flags;
+ int ret = 0;
+
+ /* bits 35:4 for 4965 */
+ pinst = priv->ucode_code.p_addr >> 4;
+ pdata = priv->ucode_data_backup.p_addr >> 4;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Tell bootstrap uCode where to find image to load */
+ iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
+ iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
+ iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
+ priv->ucode_data.len);
+
+ /* Inst bytecount must be last to set up, bit 31 signals uCode
+ * that all new ptr/size info is in place */
+ iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
+ priv->ucode_code.len | BSM_DRAM_INST_LOAD);
+ iwl_release_nic_access(priv);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ IWL_DEBUG_INFO("Runtime uCode pointers are set.\n");
+
+ return ret;
+}
+
+/**
+ * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received
+ *
+ * Called after REPLY_ALIVE notification received from "initialize" uCode.
+ *
+ * The 4965 "initialize" ALIVE reply contains calibration data for:
+ * Voltage, temperature, and MIMO tx gain correction, now stored in priv
+ * (3945 does not contain this data).
+ *
+ * Tell "initialize" uCode to go ahead and load the runtime uCode.
+*/
+static void iwl4965_init_alive_start(struct iwl_priv *priv)
+{
+ /* Check alive response for "valid" sign from uCode */
+ if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
+ /* We had an error bringing up the hardware, so take it
+ * all the way back down so we can try again */
+ IWL_DEBUG_INFO("Initialize Alive failed.\n");
+ goto restart;
+ }
+
+ /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
+ * This is a paranoid check, because we would not have gotten the
+ * "initialize" alive if code weren't properly loaded. */
+ if (iwl_verify_ucode(priv)) {
+ /* Runtime instruction load was bad;
+ * take it all the way back down so we can try again */
+ IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n");
+ goto restart;
+ }
+
+ /* Calculate temperature */
+ priv->temperature = iwl4965_get_temperature(priv);
+
+ /* Send pointers to protocol/runtime uCode image ... init code will
+ * load and launch runtime uCode, which will send us another "Alive"
+ * notification. */
+ IWL_DEBUG_INFO("Initialization Alive received.\n");
+ if (iwl4965_set_ucode_ptrs(priv)) {
+ /* Runtime instruction load won't happen;
+ * take it all the way back down so we can try again */
+ IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n");
+ goto restart;
+ }
+ return;
+
+restart:
+ queue_work(priv->workqueue, &priv->restart);
+}
+
static int is_fat_channel(__le32 rxon_flags)
{
return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||
@@ -372,178 +467,31 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
return ret;
}
-static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl4965_rx_queue *rxq)
+static int iwl4965_disable_tx_fifo(struct iwl_priv *priv)
{
- int ret;
unsigned long flags;
- unsigned int rb_size;
+ int ret;
spin_lock_irqsave(&priv->lock, flags);
+
ret = iwl_grab_nic_access(priv);
- if (ret) {
+ if (unlikely(ret)) {
+ IWL_ERROR("Tx fifo reset failed");
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
- if (priv->cfg->mod_params->amsdu_size_8K)
- rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
- else
- rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
-
- /* Stop Rx DMA */
- iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
-
- /* Reset driver's Rx queue write index */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
-
- /* Tell device where to find RBD circular buffer in DRAM */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
- rxq->dma_addr >> 8);
-
- /* Tell device where in DRAM to update its Rx status */
- iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
- (priv->shared_phys +
- offsetof(struct iwl4965_shared, rb_closed)) >> 4);
-
- /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */
- iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
- FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
- FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
- rb_size |
- /* 0x10 << 4 | */
- (RX_QUEUE_SIZE_LOG <<
- FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT));
-
- /*
- * iwl_write32(priv,CSR_INT_COAL_REG,0);
- */
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
-/* Tell 4965 where to find the "keep warm" buffer */
-static int iwl4965_kw_init(struct iwl_priv *priv)
-{
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc)
- goto out;
-
- iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG,
- priv->kw.dma_addr >> 4);
+ iwl_write_prph(priv, IWL49_SCD_TXFACT, 0);
iwl_release_nic_access(priv);
-out:
spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
-}
-
-static int iwl4965_kw_alloc(struct iwl_priv *priv)
-{
- struct pci_dev *dev = priv->pci_dev;
- struct iwl4965_kw *kw = &priv->kw;
-
- kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */
- kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr);
- if (!kw->v_addr)
- return -ENOMEM;
return 0;
}
-/**
- * iwl4965_kw_free - Free the "keep warm" buffer
- */
-static void iwl4965_kw_free(struct iwl_priv *priv)
-{
- struct pci_dev *dev = priv->pci_dev;
- struct iwl4965_kw *kw = &priv->kw;
-
- if (kw->v_addr) {
- pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr);
- memset(kw, 0, sizeof(*kw));
- }
-}
-
-/**
- * iwl4965_txq_ctx_reset - Reset TX queue context
- * Destroys all DMA structures and initialise them again
- *
- * @param priv
- * @return error code
- */
-static int iwl4965_txq_ctx_reset(struct iwl_priv *priv)
-{
- int rc = 0;
- int txq_id, slots_num;
- unsigned long flags;
-
- iwl4965_kw_free(priv);
-
- /* Free all tx/cmd queues and keep-warm buffer */
- iwl4965_hw_txq_ctx_free(priv);
-
- /* Alloc keep-warm buffer */
- rc = iwl4965_kw_alloc(priv);
- if (rc) {
- IWL_ERROR("Keep Warm allocation failed");
- goto error_kw;
- }
-
- spin_lock_irqsave(&priv->lock, flags);
-
- rc = iwl_grab_nic_access(priv);
- if (unlikely(rc)) {
- IWL_ERROR("TX reset failed");
- spin_unlock_irqrestore(&priv->lock, flags);
- goto error_reset;
- }
-
- /* Turn off all Tx DMA channels */
- iwl_write_prph(priv, IWL49_SCD_TXFACT, 0);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Tell 4965 where to find the keep-warm buffer */
- rc = iwl4965_kw_init(priv);
- if (rc) {
- IWL_ERROR("kw_init failed\n");
- goto error_reset;
- }
-
- /* Alloc and init all (default 16) Tx queues,
- * including the command queue (#4) */
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
- slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
- TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
- txq_id);
- if (rc) {
- IWL_ERROR("Tx %d queue init failed\n", txq_id);
- goto error;
- }
- }
-
- return rc;
-
- error:
- iwl4965_hw_txq_ctx_free(priv);
- error_reset:
- iwl4965_kw_free(priv);
- error_kw:
- return rc;
-}
static int iwl4965_apm_init(struct iwl_priv *priv)
{
- unsigned long flags;
int ret = 0;
- spin_lock_irqsave(&priv->lock, flags);
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
@@ -575,7 +523,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
iwl_release_nic_access(priv);
out:
- spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
@@ -621,59 +568,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
}
-
-int iwl4965_hw_nic_init(struct iwl_priv *priv)
-{
- unsigned long flags;
- struct iwl4965_rx_queue *rxq = &priv->rxq;
- int ret;
-
- /* nic_init */
- priv->cfg->ops->lib->apm_ops.init(priv);
-
- spin_lock_irqsave(&priv->lock, flags);
- iwl_write32(priv, CSR_INT_COALESCING, 512 / 32);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
-
- priv->cfg->ops->lib->apm_ops.config(priv);
-
- iwl4965_hw_card_show_info(priv);
-
- /* end nic_init */
-
- /* Allocate the RX queue, or reset if it is already allocated */
- if (!rxq->bd) {
- ret = iwl4965_rx_queue_alloc(priv);
- if (ret) {
- IWL_ERROR("Unable to initialize Rx queue\n");
- return -ENOMEM;
- }
- } else
- iwl4965_rx_queue_reset(priv, rxq);
-
- iwl4965_rx_replenish(priv);
-
- iwl4965_rx_init(priv, rxq);
-
- spin_lock_irqsave(&priv->lock, flags);
-
- rxq->need_update = 1;
- iwl4965_rx_queue_update_write_ptr(priv, rxq);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Allocate and init all Tx and Command queues */
- ret = iwl4965_txq_ctx_reset(priv);
- if (ret)
- return ret;
-
- set_bit(STATUS_INIT, &priv->status);
-
- return 0;
-}
-
int iwl4965_hw_nic_stop_master(struct iwl_priv *priv)
{
int rc = 0;
@@ -734,7 +628,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv)
}
/* Deallocate memory for all Tx queues */
- iwl4965_hw_txq_ctx_free(priv);
+ iwl_hw_txq_ctx_free(priv);
}
int iwl4965_hw_nic_reset(struct iwl_priv *priv)
@@ -984,7 +878,7 @@ static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index)
* NOTE: Acquire priv->lock before calling this function !
*/
static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq,
+ struct iwl_tx_queue *txq,
int tx_fifo_id, int scd_retry)
{
int txq_id = txq->q.id;
@@ -1188,82 +1082,6 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
return 0;
}
-/**
- * iwl4965_hw_txq_ctx_free - Free TXQ Context
- *
- * Destroy all TX DMA queues and structures
- */
-void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv)
-{
- int txq_id;
-
- /* Tx queues */
- for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
- iwl4965_tx_queue_free(priv, &priv->txq[txq_id]);
-
- /* Keep-warm buffer */
- iwl4965_kw_free(priv);
-}
-
-/**
- * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq)
-{
- struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0];
- struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
- struct pci_dev *dev = priv->pci_dev;
- int i;
- int counter = 0;
- int index, is_odd;
-
- /* Host command buffers stay mapped in memory, nothing to clean */
- if (txq->q.id == IWL_CMD_QUEUE_NUM)
- return 0;
-
- /* Sanity check on number of chunks */
- counter = IWL_GET_BITS(*bd, num_tbs);
- if (counter > MAX_NUM_OF_TBS) {
- IWL_ERROR("Too many chunks: %i\n", counter);
- /* @todo issue fatal error, it is quite serious situation */
- return 0;
- }
-
- /* Unmap chunks, if any.
- * TFD info for odd chunks is different format than for even chunks. */
- for (i = 0; i < counter; i++) {
- index = i / 2;
- is_odd = i & 0x1;
-
- if (is_odd)
- pci_unmap_single(
- dev,
- IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
- (IWL_GET_BITS(bd->pa[index],
- tb2_addr_hi20) << 16),
- IWL_GET_BITS(bd->pa[index], tb2_len),
- PCI_DMA_TODEVICE);
-
- else if (i > 0)
- pci_unmap_single(dev,
- le32_to_cpu(bd->pa[index].tb1_addr),
- IWL_GET_BITS(bd->pa[index], tb1_len),
- PCI_DMA_TODEVICE);
-
- /* Free SKB, if any, for this chunk */
- if (txq->txb[txq->q.read_ptr].skb[i]) {
- struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i];
-
- dev_kfree_skb(skb);
- txq->txb[txq->q.read_ptr].skb[i] = NULL;
- }
- }
- return 0;
-}
-
/* set card power command */
static int iwl4965_set_power(struct iwl_priv *priv,
void *cmd)
@@ -2186,7 +2004,7 @@ void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
}
-int iwl4965_hw_get_rx_read(struct iwl_priv *priv)
+static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
{
struct iwl4965_shared *s = priv->shared_virt;
return le32_to_cpu(s->rb_closed) & 0xFFF;
@@ -2229,46 +2047,11 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
return (sizeof(*tx_beacon_cmd) + frame_size);
}
-/*
- * Tell 4965 where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq)
-{
- int rc;
- unsigned long flags;
- int txq_id = txq->q.id;
-
- spin_lock_irqsave(&priv->lock, flags);
- rc = iwl_grab_nic_access(priv);
- if (rc) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return rc;
- }
-
- /* Circular buffer (TFD queue in DRAM) physical base address */
- iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
- txq->q.dma_addr >> 8);
-
- /* Enable DMA channel, using same id as for TFD queue */
- iwl_write_direct32(
- priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id),
- FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
- FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL);
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
dma_addr_t addr, u16 len)
{
int index, is_odd;
- struct iwl4965_tfd_frame *tfd = ptr;
+ struct iwl_tfd_frame *tfd = ptr;
u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);
/* Each TFD can point to a maximum 20 Tx buffers */
@@ -2298,18 +2081,6 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
return 0;
}
-static void iwl4965_hw_card_show_info(struct iwl_priv *priv)
-{
- u16 hw_version = iwl_eeprom_query16(priv, EEPROM_4965_BOARD_REVISION);
-
- IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n",
- ((hw_version >> 8) & 0x0F),
- ((hw_version >> 8) >> 4), (hw_version & 0x00FF));
-
- IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n",
- &priv->eeprom[EEPROM_4965_BOARD_PBA]);
-}
-
static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
{
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
@@ -2320,6 +2091,8 @@ static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
memset(priv->shared_virt, 0, sizeof(struct iwl4965_shared));
+ priv->rb_closed_offset = offsetof(struct iwl4965_shared, rb_closed);
+
return 0;
}
@@ -2336,7 +2109,7 @@ static void iwl4965_free_shared_mem(struct iwl_priv *priv)
* iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
*/
static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
- struct iwl4965_tx_queue *txq,
+ struct iwl_tx_queue *txq,
u16 byte_cnt)
{
int len;
@@ -2516,9 +2289,10 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv)
priv->last_rx_noise);
}
-void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl4965_rx_mem_buffer *rxb)
+void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
+ struct iwl_rx_mem_buffer *rxb)
{
- struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data;
+ struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
int change;
s32 temp;
@@ -2588,7 +2362,7 @@ static void iwl4965_add_radiotap(struct iwl_priv *priv,
struct ieee80211_rx_status *stats,
u32 ampdu_status)
{
- s8 signal = stats->ssi;
+ s8 signal = stats->signal;
s8 noise = 0;
int rate = stats->rate_idx;
u64 tsf = stats->mactime;
@@ -2742,7 +2516,7 @@ static int iwl4965_set_decrypted_flag(struct iwl_p