提交 942e7b10 编写于 作者: D David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6

mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
Copyright (c) 2008, Jouni Malinen <j@w1.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
Introduction
mac80211_hwsim is a Linux kernel module that can be used to simulate
arbitrary number of IEEE 802.11 radios for mac80211. It can be used to
test most of the mac80211 functionality and user space tools (e.g.,
hostapd and wpa_supplicant) in a way that matches very closely with
the normal case of using real WLAN hardware. From the mac80211 view
point, mac80211_hwsim is yet another hardware driver, i.e., no changes
to mac80211 are needed to use this testing tool.
The main goal for mac80211_hwsim is to make it easier for developers
to test their code and work with new features to mac80211, hostapd,
and wpa_supplicant. The simulated radios do not have the limitations
of real hardware, so it is easy to generate an arbitrary test setup
and always reproduce the same setup for future tests. In addition,
since all radio operation is simulated, any channel can be used in
tests regardless of regulatory rules.
mac80211_hwsim kernel module has a parameter 'radios' that can be used
to select how many radios are simulated (default 2). This allows
configuration of both very simply setups (e.g., just a single access
point and a station) or large scale tests (multiple access points with
hundreds of stations).
mac80211_hwsim works by tracking the current channel of each virtual
radio and copying all transmitted frames to all other radios that are
currently enabled and on the same channel as the transmitting
radio. Software encryption in mac80211 is used so that the frames are
actually encrypted over the virtual air interface to allow more
complete testing of encryption.
A global monitoring netdev, hwsim#, is created independent of
mac80211. This interface can be used to monitor all transmitted frames
regardless of channel.
Simple example
This example shows how to use mac80211_hwsim to simulate two radios:
one to act as an access point and the other as a station that
associates with the AP. hostapd and wpa_supplicant are used to take
care of WPA2-PSK authentication. In addition, hostapd is also
processing access point side of association.
Please note that the current Linux kernel does not enable AP mode, so a
simple patch is needed to enable AP mode selection:
http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
# Build mac80211_hwsim as part of kernel configuration
# Load the module
modprobe mac80211_hwsim
# Run hostapd (AP) for wlan0
hostapd hostapd.conf
# Run wpa_supplicant (station) for wlan1
wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
interface=wlan0
driver=nl80211
hw_mode=g
channel=1
ssid=mac80211 test
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
wpa_passphrase=12345678
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="mac80211 test"
psk="12345678"
key_mgmt=WPA-PSK
proto=WPA2
pairwise=CCMP
group=CCMP
}
......@@ -673,6 +673,19 @@ config ADM8211
Thanks to Infineon-ADMtek for their support of this driver.
config MAC80211_HWSIM
tristate "Simulated radio testing tool for mac80211"
depends on MAC80211 && WLAN_80211
---help---
This driver is a developer testing tool that can be used to test
IEEE 802.11 networking stack (mac80211) functionality. This is not
needed for normal wireless LAN usage and is only for testing. See
Documentation/networking/mac80211_hwsim for more information on how
to use this tool.
To compile this driver as a module, choose M here: the module will be
called mac80211_hwsim. If unsure, say N.
source "drivers/net/wireless/p54/Kconfig"
source "drivers/net/wireless/ath5k/Kconfig"
source "drivers/net/wireless/iwlwifi/Kconfig"
......
......@@ -62,3 +62,5 @@ obj-$(CONFIG_RT2X00) += rt2x00/
obj-$(CONFIG_P54_COMMON) += p54/
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
......@@ -4561,22 +4561,13 @@ static ssize_t proc_read( struct file *file,
size_t len,
loff_t *offset )
{
loff_t pos = *offset;
struct proc_data *priv = (struct proc_data*)file->private_data;
struct proc_data *priv = file->private_data;
if (!priv->rbuffer)
return -EINVAL;
if (pos < 0)
return -EINVAL;
if (pos >= priv->readlen)
return 0;
if (len > priv->readlen - pos)
len = priv->readlen - pos;
if (copy_to_user(buffer, priv->rbuffer + pos, len))
return -EFAULT;
*offset = pos + len;
return len;
return simple_read_from_buffer(buffer, len, offset, priv->rbuffer,
priv->readlen);
}
/*
......
......@@ -14,15 +14,6 @@ config IWLWIFI_LEDS
bool
default n
config IWLWIFI_RUN_TIME_CALIB
bool
depends on IWLCORE
default n
---help---
This option will enable run time calibration for the iwlwifi driver.
These calibrations are Sensitivity and Chain Noise.
config IWLWIFI_RFKILL
boolean "IWLWIFI RF kill support"
depends on IWLCORE
......@@ -54,14 +45,6 @@ config IWL4965
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl4965.ko.
config IWL4965_HT
bool "Enable 802.11n HT features in iwl4965 driver"
depends on EXPERIMENTAL
depends on IWL4965
---help---
This option enables IEEE 802.11n High Throughput features
for the iwl4965 driver.
config IWL4965_LEDS
bool "Enable LEDS features in iwl4965 driver"
depends on IWL4965
......@@ -76,15 +59,6 @@ config IWL4965_SPECTRUM_MEASUREMENT
---help---
This option will enable spectrum measurement for the iwl4965 driver.
config IWL4965_RUN_TIME_CALIB
bool "Enable run time Calibration for 4965 NIC"
select IWLWIFI_RUN_TIME_CALIB
depends on IWL4965
default y
---help---
This option will enable run time calibration for the iwl4965 driver.
These calibrations are Sensitivity and Chain Noise. If unsure, say yes
config IWLWIFI_DEBUG
bool "Enable full debugging output in iwl4965 driver"
depends on IWL4965
......@@ -118,16 +92,6 @@ config IWL5000
This option enables support for Intel Wireless WiFi Link 5000AGN Family
Dependency on 4965 is temporary
config IWL5000_RUN_TIME_CALIB
bool "Enable run time Calibration for 5000 NIC"
select IWLWIFI_RUN_TIME_CALIB
depends on IWL5000
default y
---help---
This option will enable run time calibration for the iwl5000 driver.
These calibrations are Sensitivity and Chain Noise. If unsure, say yes
config IWLWIFI_DEBUGFS
bool "Iwlwifi debugfs support"
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
......
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-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
iwlcore-objs += iwl-scan.o
iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
iwlcore-$(CONFIG_IWLWIFI_RUN_TIME_CALIB) += iwl-calib.o
obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
......
......@@ -388,7 +388,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
u32 print_dump = 0; /* set to 1 to dump all frames' contents */
u32 hundred = 0;
u32 dataframe = 0;
u16 fc;
__le16 fc;
u16 seq_ctl;
u16 channel;
u16 phy_flags;
......@@ -407,7 +407,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
u8 *data = IWL_RX_DATA(pkt);
/* MAC header */
fc = le16_to_cpu(header->frame_control);
fc = header->frame_control;
seq_ctl = le16_to_cpu(header->seq_ctrl);
/* metadata */
......@@ -431,8 +431,8 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
/* 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)) {
if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
dataframe = 1;
if (!group100)
print_summary = 1; /* print each frame */
......@@ -455,13 +455,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
if (hundred)
title = "100Frames";
else if (fc & IEEE80211_FCTL_RETRY)
else if (ieee80211_has_retry(fc))
title = "Retry";
else if (ieee80211_is_assoc_response(fc))
else if (ieee80211_is_assoc_resp(fc))
title = "AscRsp";
else if (ieee80211_is_reassoc_response(fc))
else if (ieee80211_is_reassoc_resp(fc))
title = "RasRsp";
else if (ieee80211_is_probe_response(fc)) {
else if (ieee80211_is_probe_resp(fc)) {
title = "PrbRsp";
print_dump = 1; /* dump frame contents */
} else if (ieee80211_is_beacon(fc)) {
......@@ -490,14 +490,14 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
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],
title, le16_to_cpu(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],
title, le16_to_cpu(fc), header->addr1[5],
header->addr3[5], rssi,
tsf_low - priv->scan_start_tsf,
phy_flags, channel);
......@@ -971,7 +971,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
u8 rts_retry_limit;
u8 data_retry_limit;
__le32 tx_flags;
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
rate = iwl3945_rates[rate_index].plcp;
tx_flags = cmd->cmd.tx.tx_flags;
......@@ -996,7 +996,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
else
rts_retry_limit = 7;
if (ieee80211_is_probe_response(fc)) {
if (ieee80211_is_probe_resp(fc)) {
data_retry_limit = 3;
if (data_retry_limit < rts_retry_limit)
rts_retry_limit = data_retry_limit;
......@@ -1006,12 +1006,12 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
if (priv->data_retry_limit != -1)
data_retry_limit = priv->data_retry_limit;
if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
switch (fc & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_AUTH:
case IEEE80211_STYPE_DEAUTH:
case IEEE80211_STYPE_ASSOC_REQ:
case IEEE80211_STYPE_REASSOC_REQ:
if (ieee80211_is_mgmt(fc)) {
switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
case cpu_to_le16(IEEE80211_STYPE_AUTH):
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
if (tx_flags & TX_CMD_FLG_RTS_MSK) {
tx_flags &= ~TX_CMD_FLG_RTS_MSK;
tx_flags |= TX_CMD_FLG_CTS_MSK;
......
......@@ -82,7 +82,7 @@
*/
#define IWL_CMD_QUEUE_NUM 4
#define IWL_CMD_FIFO_NUM 4
#define IWL_BACK_QUEUE_FIRST_ID 7
#define IWL49_FIRST_AMPDU_QUEUE 7
/* Tx rates */
#define IWL_CCK_RATES 4
......@@ -793,19 +793,6 @@ enum {
/********************* END TXPOWER *****************************************/
static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags)
{
return le32_to_cpu(rate_n_flags) & 0xFF;
}
static inline u32 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags)
{
return le32_to_cpu(rate_n_flags) & 0x1FFFF;
}
static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags)
{
return cpu_to_le32(flags|(u16)rate);
}
/**
* Tx/Rx Queues
......
......@@ -38,6 +38,7 @@
#include "../net/mac80211/rate.h"
#include "iwl-dev.h"
#include "iwl-sta.h"
#include "iwl-core.h"
#include "iwl-helpers.h"
......@@ -105,8 +106,6 @@ struct iwl4965_scale_tbl_info {
struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
};
#ifdef CONFIG_IWL4965_HT
struct iwl4965_traffic_load {
unsigned long time_stamp; /* age of the oldest statistics */
u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
......@@ -118,8 +117,6 @@ struct iwl4965_traffic_load {
u8 head; /* start of the circular buffer */
};
#endif /* CONFIG_IWL4965_HT */
/**
* struct iwl4965_lq_sta -- driver's rate scaling private structure
*
......@@ -157,16 +154,12 @@ struct iwl4965_lq_sta {
struct iwl_link_quality_cmd lq;
struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
#ifdef CONFIG_IWL4965_HT
struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];
u8 tx_agg_tid_en;
#endif
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_scale_table_file;
struct dentry *rs_sta_dbgfs_stats_table_file;
#ifdef CONFIG_IWL4965_HT
struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
#endif
u32 dbg_fixed_rate;
#endif
struct iwl_priv *drv;
......@@ -256,7 +249,6 @@ static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
return ((ant_type & valid_antenna) == ant_type);
}
#ifdef CONFIG_IWL4965_HT
/*
* removes the old data from the statistics. All data that is older than
* TID_MAX_TIME_DIFF, will be deleted.
......@@ -282,21 +274,21 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
* increment traffic load value for tid and also remove
* any old values if passed the certain time period
*/
static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
struct ieee80211_hdr *hdr)
static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
struct ieee80211_hdr *hdr)
{
u32 curr_time = jiffies_to_msecs(jiffies);
u32 time_diff;
s32 index;
struct iwl4965_traffic_load *tl = NULL;
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
u8 tid;
if (ieee80211_is_qos_data(fc)) {
u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
if (ieee80211_is_data_qos(fc)) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
} else
return;
return MAX_TID_COUNT;
tl = &lq_data->load[tid];
......@@ -309,7 +301,7 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
tl->queue_count = 1;
tl->head = 0;
tl->packet_count[0] = 1;
return;
return MAX_TID_COUNT;
}
time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
......@@ -326,6 +318,8 @@ static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
if ((index + 1) > tl->queue_count)
tl->queue_count = index + 1;
return tid;
}
/*
......@@ -389,8 +383,6 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
}
#endif /* CONFIG_IWLWIFI_HT */
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
{
return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
......@@ -545,7 +537,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
u8 mcs;
*rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
*rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags);
if (*rate_idx == IWL_RATE_INVALID) {
*rate_idx = -1;
......@@ -626,7 +618,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
/* FIXME:RS: in 4965 we don't use greenfield at all */
/* FIXME:RS: don't use greenfield for now in TX */
/* #ifdef CONFIG_IWL4965_HT */
#if 0
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
{
......@@ -634,12 +625,11 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf
priv->current_ht_config.is_green_field &&
!priv->current_ht_config.non_GF_STA_present);
}
#else
#endif
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
{
return 0;
}
#endif /* CONFIG_IWL4965_HT */
/**
* rs_get_supported_rates - get the available rates
......@@ -804,7 +794,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
struct iwl4965_scale_tbl_info tbl_type;
struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
u8 active_index = 0;
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
s32 tpt = 0;
IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
......@@ -1050,7 +1040,6 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
tbl->expected_tpt = expected_tpt_G;
}
#ifdef CONFIG_IWL4965_HT
/*
* Find starting rate for new "search" high-throughput mode of modulation.
* Goal is to find lowest expected rate (under perfect conditions) that is
......@@ -1152,12 +1141,10 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
return new_rate;
}
#endif /* CONFIG_IWL4965_HT */
/*
* Set up search table for MIMO
*/
#ifdef CONFIG_IWL4965_HT
static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta,
struct ieee80211_conf *conf,
......@@ -1221,16 +1208,6 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
tbl->current_rate, is_green);
return 0;
}
#else
static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl4965_lq_sta *lq_sta,
struct ieee80211_conf *conf,
struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index)
{
return -1;
}
#endif /*CONFIG_IWL4965_HT */
/*
* Set up search table for SISO
......@@ -1241,7 +1218,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
struct sta_info *sta,
struct iwl4965_scale_tbl_info *tbl, int index)
{
#ifdef CONFIG_IWL4965_HT
u16 rate_mask;
u8 is_green = lq_sta->is_green;
s32 rate;
......@@ -1291,9 +1267,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n",
tbl->current_rate, is_green);
return 0;
#else
return -1;
#endif /*CONFIG_IWL4965_HT */
}
/*
......@@ -1678,7 +1651,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
int high_tpt = IWL_INVALID_VALUE;
u32 fail_count;
s8 scale_action = 0;
u16 fc, rate_mask;
__le16 fc;
u16 rate_mask;
u8 update_lq = 0;
struct iwl4965_lq_sta *lq_sta;
struct iwl4965_scale_tbl_info *tbl, *tbl1;
......@@ -1689,13 +1663,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
u8 done_search = 0;
u16 high_low;
s32 sr;
#ifdef CONFIG_IWL4965_HT
u8 tid = MAX_TID_COUNT;
#endif
IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
fc = le16_to_cpu(hdr->frame_control);
fc = hdr->frame_control;
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) {
/* Send management frames and broadcast/multicast data using
* lowest rate. */
......@@ -1712,9 +1684,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
}
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
#ifdef CONFIG_IWL4965_HT
rs_tl_add_packet(lq_sta, hdr);
#endif
tid = rs_tl_add_packet(lq_sta, hdr);
/*
* Select rate-scale / modulation-mode table to work with in
* the rest of this function: "search" if searching for better
......@@ -1842,8 +1813,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
tbl = &(lq_sta->lq_info[active_tbl]);
/* Revert to "active" rate and throughput info */
index = iwl4965_hwrate_to_plcp_idx(
tbl->current_rate);
index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
current_tpt = lq_sta->last_tpt;
/* Need to set up a new rate table in uCode */
......@@ -1997,8 +1967,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rs_rate_scale_clear_window(&(tbl->win[i]));
/* Use new "search" start rate */
index = iwl4965_hwrate_to_plcp_idx(
tbl->current_rate);
index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n",
tbl->current_rate, index);
......@@ -2013,9 +1982,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* before next round of mode comparisons. */
tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
if (is_legacy(tbl1->lq_type) &&
#ifdef CONFIG_IWL4965_HT
(!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) &&
#endif
(lq_sta->action_counter >= 1)) {
lq_sta->action_counter = 0;
IWL_DEBUG_RATE("LQ: STAY in legacy table\n");
......@@ -2027,14 +1994,12 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* mode for a while before next round of mode comparisons. */
if (lq_sta->enable_counter &&
(lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
#ifdef CONFIG_IWL4965_HT
if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
(lq_sta->tx_agg_tid_en & (1 << tid)) &&
(tid != MAX_TID_COUNT)) {
IWL_DEBUG_RATE("try to aggregate tid %d\n", tid);
rs_tl_turn_on_agg(priv, tid, lq_sta, sta);
}
#endif /*CONFIG_IWL4965_HT */
lq_sta->action_counter = 0;
rs_set_stay_in_table(priv, 0, lq_sta);
}
......@@ -2136,7 +2101,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
struct ieee80211_conf *conf = &local->hw.conf;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct sta_info *sta;
u16 fc;
__le16 fc;
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl4965_lq_sta *lq_sta;
......@@ -2148,7 +2113,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc = le16_to_cpu(hdr->frame_control);
fc = hdr->frame_control;
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
!sta || !sta->rate_ctrl_priv) {
sel->rate_idx = rate_lowest_index(local, sband, sta);
......@@ -2279,30 +2244,23 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
lq_sta->active_rate_basic = priv->active_rate_basic;
lq_sta->band = priv->band;
#ifdef CONFIG_IWL4965_HT
/*
* active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
* supp_rates[] does not; shift to convert format, force 9 MBits off.
*/
lq_sta->active_siso_rate =
priv->current_ht_config.supp_mcs_set[0] << 1;
lq_sta->active_siso_rate |=
priv->current_ht_config.supp_mcs_set[0] & 0x1;
lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1;
lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1;
lq_sta->active_siso_rate &= ~((u16)0x2);
lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
/* Same here */
lq_sta->active_mimo2_rate =
priv->current_ht_config.supp_mcs_set[1] << 1;
lq_sta->active_mimo2_rate |=
priv->current_ht_config.supp_mcs_set[1] & 0x1;
lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1;
lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1;
lq_sta->active_mimo2_rate &= ~((u16)0x2);
lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
lq_sta->active_mimo3_rate =
priv->current_ht_config.supp_mcs_set[2] << 1;
lq_sta->active_mimo3_rate |=
priv->current_ht_config.supp_mcs_set[2] & 0x1;
lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1;
lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1;
lq_sta->active_mimo3_rate &= ~((u16)0x2);
lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
......@@ -2317,7 +2275,6 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
/* as default allow aggregation for all tids */
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
#endif /*CONFIG_IWL4965_HT*/
#ifdef CONFIG_MAC80211_DEBUGFS
lq_sta->drv = priv;
#endif
......@@ -2635,11 +2592,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
#ifdef CONFIG_IWL4965_HT
lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
&lq_sta->tx_agg_tid_en);
#endif
}
......@@ -2648,9 +2603,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
struct iwl4965_lq_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
#ifdef CONFIG_IWL4965_HT
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
#endif
}
#endif
......
......@@ -286,8 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
return rate;
}
extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags);
/**
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
*
......
......@@ -81,7 +81,7 @@
#define IWL50_QUEUE_SIZE 256
#define IWL50_CMD_FIFO_NUM 7
#define IWL50_NUM_QUEUES 20
#define IWL50_BACK_QUEUE_FIRST_ID 10
#define IWL50_FIRST_AMPDU_QUEUE 10
#define IWL_sta_id_POS 12
#define IWL_sta_id_LEN 4
......
......@@ -41,6 +41,7 @@
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-5000-hw.h"
......@@ -300,8 +301,6 @@ static int iwl5000_eeprom_check_version(struct iwl_priv *priv)
}
#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
static void iwl5000_gain_computation(struct iwl_priv *priv,
u32 average_noise[NUM_RX_CHAINS],
u16 min_average_noise_antenna_i,
......@@ -354,7 +353,6 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
data->beacon_count = 0;
}
static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
{
struct iwl_chain_noise_data *data = &priv->chain_noise_data;
......@@ -393,10 +391,6 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = {
.nrg_th_ofdm = 95,
};
#endif /* CONFIG_IWL5000_RUN_TIME_CALIB */
static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
size_t offset)
{
......@@ -832,6 +826,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
}
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE;
priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto;
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
......@@ -847,9 +842,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) |
BIT(IEEE80211_BAND_5GHZ);
#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
priv->hw_params.sens = &iwl5000_sensitivity;
#endif
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_5100:
......@@ -984,6 +977,135 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
}
}
static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
u16 txq_id)
{
u32 tbl_dw_addr;
u32 tbl_dw;
u16 scd_q2ratid;
scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
tbl_dw_addr = priv->scd_base_addr +
IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
if (txq_id & 0x1)
tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
else
tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
return 0;
}
static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
{
/* Simply stop the queue, but don't change any configuration;
* the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
iwl_write_prph(priv,
IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
(0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
(1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
}
static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
int tx_fifo, int sta_id, int tid, u16 ssn_idx)
{
unsigned long flags;
int ret;
u16 ra_tid;
if (IWL50_FIRST_AMPDU_QUEUE > txq_id)
IWL_WARNING("queue number too small: %d, must be > %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE);
ra_tid = BUILD_RAxTID(sta_id, tid);
/* Modify device's station table to Tx this TID */
iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}
/* Stop this Tx queue before configuring it */
iwl5000_tx_queue_stop_scheduler(priv, txq_id);
/* Map receiver-address / traffic-ID to this queue */
iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
/* Set this queue as a chain-building queue */
iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
/* enable aggregations for the queue */
iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
/* Place first TFD at index corresponding to start sequence number.
* Assumes that ssn_idx is valid (!= 0xFFF) */
priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
/* Set up Tx window size and frame limit for this queue */
iwl_write_targ_mem(priv, priv->scd_base_addr +
IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
sizeof(u32),
((SCD_WIN_SIZE <<
IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
((SCD_FRAME_LIMIT <<
IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
}
static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo)
{
int ret;
if (IWL50_FIRST_AMPDU_QUEUE > txq_id) {
IWL_WARNING("queue number too small: %d, must be > %d\n",
txq_id, IWL50_FIRST_AMPDU_QUEUE);
return -EINVAL;
}
ret = iwl_grab_nic_access(priv);
if (ret)
return ret;
iwl5000_tx_queue_stop_scheduler(priv, txq_id);
iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
/* supposes that ssn_idx is valid (!= 0xFFF) */
iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
iwl_txq_ctx_deactivate(priv, txq_id);
iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
iwl_release_nic_access(priv);
return 0;
}
static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
......@@ -1004,23 +1126,21 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{
__le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status +
tx_resp->frame_count);
return le32_to_cpu(*scd_ssn) & MAX_SN;
return le32_to_cpup((__le32*)&tx_resp->status +
tx_resp->frame_count) & MAX_SN;
}
static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg,
struct iwl5000_tx_resp *tx_resp,
u16 start_idx)
int txq_id, u16 start_idx)
{
u16 status;
struct agg_tx_status *frame_status = &tx_resp->status;
struct ieee80211_tx_info *info = NULL;
struct ieee80211_hdr *hdr = NULL;
int i, sh;
int txq_id, idx;
u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
int i, sh, idx;
u16 seq;
if (agg->wait_for_ba)
......@@ -1028,16 +1148,14 @@ static int iwl5000_tx_status_reply_tx(struct iwl_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->rate_n_flags = rate_n_flags;
agg->bitmap = 0;
/* # frames attempted by Tx command */
if (agg->frame_count == 1) {
/* Only one frame was attempted; no block-ack will arrive */
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);
idx = start_idx;
/* FIXME: code repetition */
IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
......@@ -1048,15 +1166,13 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->flags |= iwl_is_tx_success(status)?
IEEE80211_TX_STAT_ACK : 0;
iwl4965_hwrate_to_tx_control(priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
/* FIXME: code repetition end */
IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n",
status & 0xff, tx_resp->failure_frame);
IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n",
iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags));
IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
agg->wait_for_ba = 0;
} else {
......@@ -1114,7 +1230,6 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
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%llx\n",
agg->frame_count, agg->start_idx,
(unsigned long long)agg->bitmap);
......@@ -1136,12 +1251,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
struct ieee80211_tx_info *info;
struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le16_to_cpu(tx_resp->status.status);
#ifdef CONFIG_IWL4965_HT
int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
u16 fc;
struct ieee80211_hdr *hdr;
u8 *qc = NULL;
#endif
if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
......@@ -1154,11 +1266,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
memset(&info->status, 0, sizeof(info->status));
#ifdef CONFIG_IWL4965_HT
hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
fc = le16_to_cpu(hdr->frame_control);
if (ieee80211_is_qos_data(fc)) {
qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
if (ieee80211_is_data_qos(hdr->frame_control)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
}
......@@ -1177,7 +1287,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
agg = &priv->stations[sta_id].tid[tid].agg;
iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index);
iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) {
/* TODO: send BAR */
......@@ -1195,7 +1305,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
txq_id >= 0 && priv->mac80211_registered &&
agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) {
/* calculate mac80211 ampdu sw queue to wake */
ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID +
ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE +
priv->hw->queues;
if (agg->state == IWL_AGG_OFF)
ieee80211_wake_queue(priv->hw, txq_id);
......@@ -1205,32 +1315,31 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
}
} else {
#endif /* CONFIG_IWL4965_HT */
info->status.retry_count = tx_resp->failure_frame;
info->flags = iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
info);
IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x "
"retries %d\n", txq_id, iwl_get_tx_fail_reason(status),
status, le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame);
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
#ifdef CONFIG_IWL4965_HT
if (index != -1) {
int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
if (tid != MAX_TID_COUNT)
info->status.retry_count = tx_resp->failure_frame;
info->flags =
iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0;
iwl_hwrate_to_tx_control(priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags "
"0x%x retries %d\n", txq_id,
iwl_get_tx_fail_reason(status),
status, le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame);
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
if (index != -1) {
int freed = iwl_tx_queue_reclaim(priv, txq_id, index);
if (tid != MAX_TID_COUNT)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
if (iwl_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)
if (tid != MAX_TID_COUNT)
iwl_txq_check_empty(priv, sta_id, tid, txq_id);
}
}
}
#endif /* CONFIG_IWL4965_HT */
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
......@@ -1242,6 +1351,12 @@ static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
return len;
}
static void iwl5000_setup_deferred_work(struct iwl_priv *priv)
{
/* in 5000 the tx power calibration is done in uCode */
priv->disable_tx_power_cal = 1;
}
static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
{
/* init calibration handlers */
......@@ -1305,6 +1420,19 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
return ret;
}
static int iwl5000_send_tx_power(struct iwl_priv *priv)
{
struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
/* half dBm need to multiply */
tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
tx_power_cmd.flags = 0;
tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO;
return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD,
sizeof(tx_power_cmd), &tx_power_cmd,
NULL);
}
static struct iwl_hcmd_ops iwl5000_hcmd = {
.rxon_assoc = iwl5000_send_rxon_assoc,
......@@ -1313,10 +1441,8 @@ static struct iwl_hcmd_ops iwl5000_hcmd = {
static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
.get_hcmd_size = iwl5000_get_hcmd_size,
.build_addsta_hcmd = iwl5000_build_addsta_hcmd,
#ifdef CONFIG_IWL5000_RUN_TIME_CALIB
.gain_computation = iwl5000_gain_computation,
.chain_noise_reset = iwl5000_chain_noise_reset,
#endif
};
static struct iwl_lib_ops iwl5000_lib = {
......@@ -1327,11 +1453,15 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwl5000_txq_set_sched,
.txq_agg_enable = iwl5000_txq_agg_enable,
.txq_agg_disable = iwl5000_txq_agg_disable,
.rx_handler_setup = iwl5000_rx_handler_setup,
.setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
.load_ucode = iwl5000_load_ucode,
.init_alive_start = iwl5000_init_alive_start,
.alive_notify = iwl5000_alive_notify,
.send_tx_power = iwl5000_send_tx_power,
.apm_ops = {
.init = iwl5000_apm_init,
.reset = iwl5000_apm_reset,
......
......@@ -60,13 +60,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include <linux/kernel.h>
#include <net/mac80211.h>
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-calib.h"
#include "iwl-eeprom.h"
/* "false alarms" are signals that our DSP tries to lock onto,
* but then determines that they are either noise, or transmissions
......@@ -435,8 +433,6 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
data = &(priv->sensitivity_data);
if (ranges == NULL)
/* can happen if IWLWIFI_RUN_TIME_CALIB is selected
* but no IWLXXXX_RUN_TIME_CALIB for specific is selected */
return;
memset(data, 0, sizeof(struct iwl_sensitivity_data));
......
......@@ -62,16 +62,10 @@
#ifndef __iwl_calib_h__
#define __iwl_calib_h__
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
#include "iwl-core.h"
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-commands.h"
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
void iwl_chain_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp);
void iwl_sensitivity_calibration(struct iwl_priv *priv,
......@@ -86,24 +80,5 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
priv->cfg->ops->utils->chain_noise_reset)
priv->cfg->ops->utils->chain_noise_reset(priv);
}
#else
static inline void iwl_chain_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp)
{
}
static inline void iwl_sensitivity_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *resp)
{
}
static inline void iwl_init_sensitivity(struct iwl_priv *priv)
{
}
static inline void iwl_chain_noise_reset(struct iwl_priv *priv)
{
}
static inline void iwl_reset_run_time_calib(struct iwl_priv *priv)
{
}
#endif
#endif /* __iwl_calib_h__ */
......@@ -126,6 +126,7 @@ enum {
/* Miscellaneous commands */
QUIET_NOTIFICATION = 0x96, /* not used */
REPLY_TX_PWR_TABLE_CMD = 0x97,
REPLY_TX_POWER_DBM_CMD = 0x98,
MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */
/* Bluetooth device coexistance config command */
......@@ -280,16 +281,7 @@ struct iwl_cmd_header {
#define RATE_MCS_ANT_C_MSK 0x10000
#define RATE_MCS_ANT_ABC_MSK 0x1C000
/**
* struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD
*
* Scan uses only one transmitter, so only one analog/dsp gain pair is needed.
*/
struct iwl4965_tx_power {
u8 tx_gain; /* gain for analog radio */
u8 dsp_atten; /* gain for DSP */
} __attribute__ ((packed));
#define RATE_MCS_ANT_INIT_IND 1
#define POWER_TABLE_NUM_ENTRIES 33
#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32
......@@ -339,6 +331,17 @@ struct iwl4965_tx_power_db {
struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
} __attribute__ ((packed));
/**
* Commad REPLY_TX_POWER_DBM_CMD = 0x98
* struct iwl5000_tx_power_dbm_cmd
*/
#define IWL50_TX_POWER_AUTO 0x7f
struct iwl5000_tx_power_dbm_cmd {
s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
u8 flags;
s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */
u8 reserved;
} __attribute__ ((packed));
/******************************************************************************
* (0a)
......@@ -990,6 +993,7 @@ struct iwl_wep_cmd {
#define WEP_KEY_WEP_TYPE 1
#define WEP_KEYS_MAX 4
#define WEP_INVALID_OFFSET 0xff
#define WEP_KEY_LEN_64 5
#define WEP_KEY_LEN_128 13
/******************************************************************************
......@@ -1481,21 +1485,10 @@ struct iwl4965_tx_resp {
* table entry used for all frames in the new agg.
* 31-16: Sequence # for this frame's Tx cmd (not SSN!)
*/
__le32 status; /* TX status (for aggregation status of 1st frame) */
} __attribute__ ((packed));
struct iwl4965_tx_resp_agg {
u8 frame_count; /* 1 no aggregation, >1 aggregation */
u8 reserved1;
u8 failure_rts;
u8 failure_frame;
__le32 rate_n_flags;
__le16 wireless_media_time;
__le16 reserved3;
__le32 pa_power1;
__le32 pa_power2;
struct agg_tx_status status; /* TX status (for aggregation status */
/* of 1st frame) */
union {
__le32 status;
struct agg_tx_status agg_status[0]; /* for each agg frame */
} u;
} __attribute__ ((packed));
struct iwl5000_tx_resp {
......@@ -2085,7 +2078,7 @@ struct iwl4965_card_state_notif {
#define RF_CARD_DISABLED 0x04
#define RXON_CARD_DISABLED 0x10
struct iwl4965_ct_kill_config {
struct iwl_ct_kill_config {
__le32 reserved;
__le32 critical_temperature_M;
__le32 critical_temperature_R;
......@@ -2098,7 +2091,7 @@ struct iwl4965_ct_kill_config {
*****************************************************************************/
/**
* struct iwl4965_scan_channel - entry in REPLY_SCAN_CMD channel table
* struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
*
* One for each channel in the scan list.
* Each channel can independently select:
......@@ -2108,7 +2101,7 @@ struct iwl4965_ct_kill_config {
* quiet_plcp_th, good_CRC_th)
*
* To avoid uCode errors, make sure the following are true (see comments
* under struct iwl4965_scan_cmd about max_out_time and quiet_time):
* under struct iwl_scan_cmd about max_out_time and quiet_time):
* 1) If using passive_dwell (i.e. passive_dwell != 0):
* active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
* 2) quiet_time <= active_dwell
......@@ -2116,7 +2109,7 @@ struct iwl4965_ct_kill_config {
* passive_dwell < max_out_time
* active_dwell < max_out_time
*/
struct iwl4965_scan_channel {
struct iwl_scan_channel {
/*
* type is defined as:
* 0:0 1 = active, 0 = passive
......@@ -2126,19 +2119,20 @@ struct iwl4965_scan_channel {
*/
u8 type;
u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */
struct iwl4965_tx_power tpc;
u8 tx_gain; /* gain for analog radio */
u8 dsp_atten; /* gain for DSP */
__le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));
/**
* struct iwl4965_ssid_ie - directed scan network information element
* struct iwl_ssid_ie - directed scan network information element
*
* Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field
* in struct iwl4965_scan_channel; each channel may select different ssids from
* among the 4 entries. SSID IEs get transmitted in reverse order of entry.
*/
struct iwl4965_ssid_ie {
struct iwl_ssid_ie {
u8 id;
u8 len;
u8 ssid[32];
......@@ -2199,9 +2193,9 @@ struct iwl4965_ssid_ie {
* Driver must use separate scan commands for 2.4 vs. 5 GHz bands.
*
* To avoid uCode errors, see timing restrictions described under
* struct iwl4965_scan_channel.
* struct iwl_scan_channel.
*/
struct iwl4965_scan_cmd {
struct iwl_scan_cmd {
__le16 len;
u8 reserved0;
u8 channel_count; /* # channels in channel list */
......@@ -2225,7 +2219,7 @@ struct iwl4965_scan_cmd {
struct iwl_tx_cmd tx_cmd;
/* For directed active scans (set to all-0s otherwise) */
struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX];
struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
/*
* Probe request frame, followed by channel list.
......@@ -2253,14 +2247,14 @@ struct iwl4965_scan_cmd {
/*
* REPLY_SCAN_CMD = 0x80 (response)
*/
struct iwl4965_scanreq_notification {
struct iwl_scanreq_notification {
__le32 status; /* 1: okay, 2: cannot fulfill request */
} __attribute__ ((packed));
/*
* SCAN_START_NOTIFICATION = 0x82 (notification only, not a command)
*/
struct iwl4965_scanstart_notification {
struct iwl_scanstart_notification {
__le32 tsf_low;
__le32 tsf_high;
__le32 beacon_timer;
......@@ -2277,7 +2271,7 @@ struct iwl4965_scanstart_notification {
/*
* SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command)
*/
struct iwl4965_scanresults_notification {
struct iwl_scanresults_notification {
u8 channel;
u8 band;
u8 reserved[2];
......@@ -2289,7 +2283,7 @@ struct iwl4965_scanresults_notification {
/*
* SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command)
*/
struct iwl4965_scancomplete_notification {
struct iwl_scancomplete_notification {
u8 scanned_channels;
u8 status;
u8 reserved;
......
......@@ -85,6 +85,63 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = {
};
EXPORT_SYMBOL(iwl_rates);
/**
* translate ucode response to mac80211 tx status control values
*/
void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *control)
{
int rate_index;
control->antenna_sel_tx =
((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
if (rate_n_flags & RATE_MCS_HT_MSK)
control->flags |= IEEE80211_TX_CTL_OFDM_HT;
if (rate_n_flags & RATE_MCS_GF_MSK)
control->flags |= IEEE80211_TX_CTL_GREEN_FIELD;
if (rate_n_flags & RATE_MCS_FAT_MSK)
control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH;
if (rate_n_flags & RATE_MCS_DUP_MSK)
control->flags |= IEEE80211_TX_CTL_DUP_DATA;
if (rate_n_flags & RATE_MCS_SGI_MSK)
control->flags |= IEEE80211_TX_CTL_SHORT_GI;
rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags);
if (control->band == IEEE80211_BAND_5GHZ)
rate_index -= IWL_FIRST_OFDM_RATE;
control->tx_rate_idx = rate_index;
}
EXPORT_SYMBOL(iwl_hwrate_to_tx_control);
int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
{
int idx = 0;
/* HT rate format */
if (rate_n_flags & RATE_MCS_HT_MSK) {
idx = (rate_n_flags & 0xff);
if (idx >= IWL_RATE_MIMO2_6M_PLCP)
idx = idx - IWL_RATE_MIMO2_6M_PLCP;
idx += IWL_FIRST_OFDM_RATE;
/* skip 9M not supported in ht*/
if (idx >= IWL_RATE_9M_INDEX)
idx += 1;
if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE))
return idx;
/* legacy rate format, search for match in table */
} else {
for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
return idx;
}
return -1;
}
EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx);
const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
EXPORT_SYMBOL(iwl_bcast_addr);
......@@ -321,7 +378,6 @@ void iwl_reset_qos(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_reset_qos);
#ifdef CONFIG_IWL4965_HT
#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */
#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
......@@ -374,13 +430,6 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2);
}
}
#else
static inline void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info,
enum ieee80211_band band)
{
}
#endif /* CONFIG_IWL4965_HT */
static void iwlcore_init_hw_rates(struct iwl_priv *priv,
struct ieee80211_rate *rates)
......@@ -486,28 +535,10 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
if (ch->flags & EEPROM_CHANNEL_RADAR)
geo_ch->flags |= IEEE80211_CHAN_RADAR;
switch (ch->fat_extension_channel) {
case HT_IE_EXT_CHANNEL_ABOVE:
/* only above is allowed, disable below */
geo_ch->flags |= IEEE80211_CHAN_NO_FAT_BELOW;
break;
case HT_IE_EXT_CHANNEL_BELOW:
/* only below is allowed, disable above */
geo_ch->flags |= IEEE80211_CHAN_NO_FAT_ABOVE;
break;
case HT_IE_EXT_CHANNEL_NONE:
/* fat not allowed: disable both*/
geo_ch->flags |= (IEEE80211_CHAN_NO_FAT_ABOVE |
IEEE80211_CHAN_NO_FAT_BELOW);
break;
case HT_IE_EXT_CHANNEL_MAX:
/* both above and below are permitted */
break;
}
geo_ch->flags |= ch->fat_extension_channel;
if (ch->max_power_avg > priv->max_channel_txpower_limit)
priv->max_channel_txpower_limit =
ch->max_power_avg;
if (ch->max_power_avg > priv->tx_power_channel_lmt)
priv->tx_power_channel_lmt = ch->max_power_avg;
} else {
geo_ch->flags |= IEEE80211_CHAN_DISABLED;
}
......@@ -515,7 +546,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
/* 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",
IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
ch->channel, geo_ch->center_freq,
is_channel_a_band(ch) ? "5.2" : "2.4",
geo_ch->flags & IEEE80211_CHAN_DISABLED ?
......@@ -553,7 +584,6 @@ static void iwlcore_free_geos(struct iwl_priv *priv)
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}
#ifdef CONFIG_IWL4965_HT
static u8 is_single_rx_stream(struct iwl_priv *priv)
{
return !priv->current_ht_config.is_ht ||
......@@ -561,6 +591,7 @@ static u8 is_single_rx_stream(struct iwl_priv *priv)
(priv->current_ht_config.supp_mcs_set[2] == 0)) ||
priv->ps_mode == IWL_MIMO_PS_STATIC;
}
static u8 iwl_is_channel_extension(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel, u8 extension_chan_offset)
......@@ -571,12 +602,12 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return 0;
if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)
return 0;
if ((ch_info->fat_extension_channel == extension_chan_offset) ||
(ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX))
return 1;
if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE)
return !(ch_info->fat_extension_channel &
IEEE80211_CHAN_NO_FAT_ABOVE);
else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW)
return !(ch_info->fat_extension_channel &
IEEE80211_CHAN_NO_FAT_BELOW);
return 0;
}
......@@ -588,7 +619,7 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
if ((!iwl_ht_conf->is_ht) ||
(iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
(iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE))
(iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE))
return 0;
if (sta_ht_inf) {
......@@ -622,19 +653,18 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
IWL_DEBUG_ASSOC("control diff than current %d %d\n",
le16_to_cpu(rxon->channel),
ht_info->control_channel);
rxon->channel = cpu_to_le16(ht_info->control_channel);
return;
}
/* Note: control channel is opposite of extension channel */
switch (ht_info->extension_chan_offset) {
case IWL_EXT_CHANNEL_OFFSET_ABOVE:
case IEEE80211_HT_IE_CHA_SEC_ABOVE:
rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
break;
case IWL_EXT_CHANNEL_OFFSET_BELOW:
case IEEE80211_HT_IE_CHA_SEC_BELOW:
rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
break;
case IWL_EXT_CHANNEL_OFFSET_NONE:
case IEEE80211_HT_IE_CHA_SEC_NONE:
default:
rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
break;
......@@ -660,13 +690,6 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
}
EXPORT_SYMBOL(iwl_set_rxon_ht);
#else
static inline u8 is_single_rx_stream(struct iwl_priv *priv)
{
return 1;
}
#endif /*CONFIG_IWL4965_HT */
/*
* Determine how many receiver/antenna chains to use.
* More provides better reception via diversity. Fewer saves power.
......@@ -791,10 +814,8 @@ int iwl_setup_mac(struct iwl_priv *priv)
IEEE80211_HW_NOISE_DBM;
/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
#ifdef CONFIG_IWL4965_HT
/* Enhanced value; more queues, to support 11n aggregation */
hw->ampdu_queues = 12;
#endif /* CONFIG_IWL4965_HT */
hw->conf.beacon_int = 100;
......@@ -853,6 +874,7 @@ int iwl_init_drv(struct iwl_priv *priv)
/* Choose which receivers/antennas to use */
iwl_set_rxon_chain(priv);
iwl_init_scan_params(priv);
if (priv->cfg->mod_params->enable_qos)
priv->qos_data.qos_enable = 1;
......@@ -867,7 +889,7 @@ int iwl_init_drv(struct iwl_priv *priv)
priv->rates_mask = IWL_RATES_MASK;
/* If power management is turned on, default to AC mode */
priv->power_mode = IWL_POWER_AC;
priv->user_txpower_limit = IWL_DEFAULT_TX_POWER;
priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX;
ret = iwl_init_channel_map(priv);
if (ret) {
......@@ -906,6 +928,34 @@ void iwl_free_calib_results(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_free_calib_results);
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
{
int ret = 0;
if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) {
IWL_WARNING("Requested user TXPOWER %d below limit.\n",
priv->tx_power_user_lmt);
return -EINVAL;
}
if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) {
IWL_WARNING("Requested user TXPOWER %d above limit.\n",
priv->tx_power_user_lmt);
return -EINVAL;
}
if (priv->tx_power_user_lmt != tx_power)
force = true;
priv->tx_power_user_lmt = tx_power;
if (force && priv->cfg->ops->lib->send_tx_power)
ret = priv->cfg->ops->lib->send_tx_power(priv);
return ret;
}
EXPORT_SYMBOL(iwl_set_tx_power);
void iwl_uninit_drv(struct iwl_priv *priv)
{
iwl_free_calib_results(priv);
......@@ -915,35 +965,6 @@ void iwl_uninit_drv(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_uninit_drv);
/* Low level driver call this function to update iwlcore with
* driver status.
*/
int iwlcore_low_level_notify(struct iwl_priv *priv,
enum iwlcore_card_notify notify)
{
int ret;
switch (notify) {
case IWLCORE_INIT_EVT:
ret = iwl_rfkill_init(priv);
if (ret)
IWL_ERROR("Unable to initialize RFKILL system. "
"Ignoring error: %d\n", ret);
iwl_power_initialize(priv);
break;
case IWLCORE_START_EVT:
iwl_power_update_mode(priv, 1);
break;
case IWLCORE_STOP_EVT:
break;
case IWLCORE_REMOVE_EVT:
iwl_rfkill_unregister(priv);
break;
}
return 0;
}
EXPORT_SYMBOL(iwlcore_low_level_notify);
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
u32 stat_flags = 0;
......@@ -1204,12 +1225,14 @@ void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
ptr += sizeof(u32);
time = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
if (mode == 0)
IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */
else {
if (mode == 0) {
/* data, ev */
IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev);
} else {
data = iwl_read_targ_mem(priv, ptr);
ptr += sizeof(u32);
IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev);
IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n",
time, data, ev);
}
}
}
......@@ -1272,4 +1295,114 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_dump_nic_event_log);
void iwl_rf_kill_ct_config(struct iwl_priv *priv)
{
struct iwl_ct_kill_config cmd;
unsigned long flags;
int ret = 0;
spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
spin_unlock_irqrestore(&priv->lock, flags);
cmd.critical_temperature_R =
cpu_to_le32(priv->hw_params.ct_kill_threshold);
ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
sizeof(cmd), &cmd);
if (ret)
IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
else
IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, "
"critical temperature is %d\n",
cmd.critical_temperature_R);
}
EXPORT_SYMBOL(iwl_rf_kill_ct_config);
/*
* CARD_STATE_CMD
*
* Use: Sets the device's internal card state to enable, disable, or halt
*
* When in the 'enable' state the card operates as normal.
* When in the 'disable' state, the card enters into a low power mode.
* When in the 'halt' state, the card is shut down and must be fully
* restarted to come back on.
*/
static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
{
struct iwl_host_cmd cmd = {
.id = REPLY_CARD_STATE_CMD,
.len = sizeof(u32),
.data = &flags,
.meta.flags = meta_flag,
};
return iwl_send_cmd(priv, &cmd);
}
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
{
unsigned long flags;
if (test_bit(STATUS_RF_KILL_SW, &priv->status))
return;
IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n");
iwl_scan_cancel(priv);
/* FIXME: This is a workaround for AP */
if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_SW_BIT_RFKILL);
spin_unlock_irqrestore(&priv->lock, flags);
/* call the host command only if no hw rf-kill set */
if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&
iwl_is_ready(priv))
iwl_send_card_state(priv,
CARD_STATE_CMD_DISABLE, 0);
set_bit(STATUS_RF_KILL_SW, &priv->status);
/* make sure mac80211 stop sending Tx frame */
if (priv->mac80211_registered)
ieee80211_stop_queues(priv->hw);
}
}
EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
{
unsigned long flags;
if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
return 0;
IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n");
spin_lock_irqsave(&priv->lock, flags);
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
clear_bit(STATUS_RF_KILL_SW, &priv->status);
spin_unlock_irqrestore(&priv->lock, flags);
/* wake up ucode */
msleep(10);
spin_lock_irqsave(&priv->lock, flags);
iwl_read32(priv, CSR_UCODE_DRV_GP1);
if (!iwl_grab_nic_access(priv))
iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
IWL_DEBUG_RF_KILL("Can not turn radio back on - "
"disabled by HW switch\n");
return 0;
}
if (priv->is_open)
queue_work(priv->workqueue, &priv->restart);
return 1;
}
EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
......@@ -88,13 +88,11 @@ struct iwl_hcmd_ops {
struct iwl_hcmd_utils_ops {
u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
void (*gain_computation)(struct iwl_priv *priv,
u32 *average_noise,
u16 min_average_noise_antennat_i,
u32 min_average_noise);
void (*chain_noise_reset)(struct iwl_priv *priv);
#endif
};
struct iwl_lib_ops {
......@@ -111,15 +109,17 @@ struct iwl_lib_ops {
void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
#ifdef CONFIG_IWL4965_HT
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
u8 tx_fifo);
#endif /* CONFIG_IWL4965_HT */
/* setup Rx handler */
void (*rx_handler_setup)(struct iwl_priv *priv);
/* setup deferred work */
void (*setup_deferred_work)(struct iwl_priv *priv);
/* cancel deferred work */
void (*cancel_deferred_work)(struct iwl_priv *priv);
/* alive notification after init uCode load */
void (*init_alive_start)(struct iwl_priv *priv);
/* alive notification */
......@@ -128,8 +128,6 @@ struct iwl_lib_ops {
int (*is_valid_rtc_data_addr)(u32 addr);
/* 1st ucode load */
int (*load_ucode)(struct iwl_priv *priv);
/* rfkill */
void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio);
/* power management */
struct {
int (*init)(struct iwl_priv *priv);
......@@ -140,6 +138,7 @@ struct iwl_lib_ops {
} apm_ops;
/* power */
int (*set_power)(struct iwl_priv *priv, void *cmd);
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
/* eeprom operations (as defined in iwl-eeprom.h) */
struct iwl_eeprom_ops eeprom_ops;
......@@ -233,11 +232,53 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
dma_addr_t addr, u16 len);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
#ifdef CONFIG_IWL4965_HT
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
#endif
/*****************************************************
* TX power
****************************************************/
int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
/*****************************************************
* RF -Kill - here and not in iwl-rfkill.h to be available when
* RF-kill subsystem is not compiled.
****************************************************/
void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
/*******************************************************************************
* Rate
******************************************************************************/
void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
{
return le32_to_cpu(rate_n_flags) & 0xFF;
}
static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags)
{
return le32_to_cpu(rate_n_flags) & 0x1FFFF;
}
static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
{
return cpu_to_le32(flags|(u32)rate);
}
/*******************************************************************************
* Scanning
******************************************************************************/
void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
const char *iwl_escape_essid(const char *essid, u8 essid_len);
int iwl_scan_initiate(struct iwl_priv *priv);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
......@@ -286,6 +327,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv);
#define STATUS_POWER_PMI 16
#define STATUS_FW_ERROR 17
#define STATUS_CONF_PENDING 18
#define STATUS_MODE_PENDING 19
static inline int iwl_is_ready(struct iwl_priv *priv)
......@@ -322,19 +364,10 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
return iwl_is_ready(priv);
}
enum iwlcore_card_notify {
IWLCORE_INIT_EVT = 0,
IWLCORE_START_EVT = 1,
IWLCORE_STOP_EVT = 2,
IWLCORE_REMOVE_EVT = 3,
};
int iwlcore_low_level_notify(struct iwl_priv *priv,
enum iwlcore_card_notify notify);
extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
int iwl_send_lq_cmd(struct iwl_priv *priv,
extern int iwl_send_lq_cmd(struct iwl_priv *priv,
struct iwl_link_quality_cmd *lq, u8 flags);
static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
......
......@@ -55,10 +55,9 @@ struct iwl_debugfs {
struct dentry *file_log_event;
} dbgfs_data_files;
struct dir_rf_files {
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct dentry *file_disable_sensitivity;
struct dentry *file_disable_chain_noise;
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
struct dentry *file_disable_tx_power;
} dbgfs_rf_files;
u32 sram_offset;
u32 sram_len;
......
......@@ -255,21 +255,18 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n");
pos += scnprintf(buf + pos, bufsz - pos,
"seq_num\t\ttxq_id");
#ifdef CONFIG_IWL4965_HT
pos += scnprintf(buf + pos, bufsz - pos,
"\tframe_count\twait_for_ba\t");
pos += scnprintf(buf + pos, bufsz - pos,
"start_idx\tbitmap0\t");
pos += scnprintf(buf + pos, bufsz - pos,
"bitmap1\trate_n_flags");
#endif
pos += scnprintf(buf + pos, bufsz - pos, "\n");
for (j = 0; j < MAX_TID_COUNT; j++) {
pos += scnprintf(buf + pos, bufsz - pos,
"[%d]:\t\t%u", j,
station->tid[j].seq_number);
#ifdef CONFIG_IWL4965_HT
pos += scnprintf(buf + pos, bufsz - pos,
"\t%u\t\t%u\t\t%u\t\t",
station->tid[j].agg.txq_id,
......@@ -280,7 +277,6 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
station->tid[j].agg.start_idx,
(unsigned long long)station->tid[j].agg.bitmap,
station->tid[j].agg.rate_n_flags);
#endif
pos += scnprintf(buf + pos, bufsz - pos, "\n");
}
pos += scnprintf(buf + pos, bufsz - pos, "\n");
......@@ -389,11 +385,10 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(stations, data);
DEBUGFS_ADD_FILE(rx_statistics, data);
DEBUGFS_ADD_FILE(tx_statistics, data);
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
&priv->disable_chain_noise_cal);
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal);
return 0;
err:
......@@ -419,10 +414,9 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
DEBUGFS_REMOVE(priv->dbgfs->dir_data);
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power);
DEBUGFS_REMOVE(priv->dbgfs->dir_rf);
DEBUGFS_REMOVE(priv->dbgfs->dir_drv);
kfree(priv->dbgfs);
......
......@@ -29,8 +29,8 @@
* Please use iwl-4965-hw.h for hardware-related definitions.
*/
#ifndef __iwl_4965_h__
#define __iwl_4965_h__
#ifndef __iwl_dev_h__
#define __iwl_dev_h__
#include <linux/pci.h> /* for struct pci_device_id */
#include <linux/kernel.h>
......@@ -157,44 +157,11 @@ struct iwl4965_channel_tgh_info {
s64 last_radar_time;
};
/* current Tx power values to use, one for each rate for each channel.
* requested power is limited by:
* -- regulatory EEPROM limits for this channel
* -- hardware capabilities (clip-powers)
* -- spectrum management
* -- user preference (e.g. iwconfig)
* when requested power is set, base power index must also be set. */
struct iwl4965_channel_power_info {
struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */
s8 power_table_index; /* actual (compenst'd) index into gain table */
s8 base_power_index; /* gain index for power at factory temp. */
s8 requested_power; /* power (dBm) requested for this chnl/rate */
};
/* current scan Tx power values to use, one for each scan rate for each
* channel. */
struct iwl4965_scan_power_info {
struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */
s8 power_table_index; /* actual (compenst'd) index into gain table */
s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */
};
/* For fat_extension_channel */
enum {
HT_IE_EXT_CHANNEL_NONE = 0,
HT_IE_EXT_CHANNEL_ABOVE,
HT_IE_EXT_CHANNEL_INVALID,
HT_IE_EXT_CHANNEL_BELOW,
HT_IE_EXT_CHANNEL_MAX
};
/*
* One for each channel, holds all channel setup data
* Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
* with one another!
*/
#define IWL4965_MAX_RATE (33)
struct iwl_channel_info {
struct iwl4965_channel_tgd_info tgd;
struct iwl4965_channel_tgh_info tgh;
......@@ -213,11 +180,6 @@ struct iwl_channel_info {
u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */
enum ieee80211_band band;
/* Radio/DSP gain settings for each "normal" data Tx rate.
* These include, in addition to RF and DSP gain, a few fields for
* remembering/modifying gain settings (indexes). */
struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE];
/* FAT channel info */
s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */
s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */
......@@ -225,9 +187,6 @@ struct iwl_channel_info {
s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */
u8 fat_flags; /* flags copied from EEPROM */
u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */
/* Radio/DSP gain settings for each scan rate, for directed scans. */
struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
};
struct iwl4965_clip_group {
......@@ -401,7 +360,6 @@ struct iwl_rx_queue {
#define IWL_INVALID_RATE 0xFF
#define IWL_INVALID_VALUE -1
#ifdef CONFIG_IWL4965_HT
/**
* struct iwl_ht_agg -- aggregation status while waiting for block-ack
* @txq_id: Tx queue used for Tx attempt
......@@ -430,14 +388,11 @@ struct iwl_ht_agg {
u8 state;
};
#endif /* CONFIG_IWL4965_HT */
struct iwl_tid_data {
u16 seq_number;
u16 tfds_in_queue;
#ifdef CONFIG_IWL4965_HT
struct iwl_ht_agg agg;
#endif /* CONFIG_IWL4965_HT */
};
struct iwl_hw_key {
......@@ -525,7 +480,7 @@ struct fw_desc {
};
/* uCode file layout */
struct iwl4965_ucode {
struct iwl_ucode {
__le32 ver; /* major/minor/subminor */
__le32 inst_size; /* bytes of runtime instructions */
__le32 data_size; /* bytes of runtime data */
......@@ -587,6 +542,7 @@ struct iwl_sensitivity_ranges {
* @max_xxx_size: for ucode uses
* @ct_kill_threshold: temperature threshold
* @struct iwl_sensitivity_ranges: range of sensitivity values
* @first_ampdu_q: first HW queue available for ampdu
*/
struct iwl_hw_params {
u16 max_txq_num;
......@@ -606,9 +562,8 @@ struct iwl_hw_params {
u32 max_data_size;
u32 max_bsm_size;
u32 ct_kill_threshold; /* value in hw-dependent units */
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
const struct iwl_sensitivity_ranges *sens;
#endif
u8 first_ampdu_q;
};
#define HT_SHORT_GI_20MHZ (1 << 0)
......@@ -638,15 +593,8 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
u8 flags, struct ieee80211_ht_info *ht_info);
extern int iwl4965_is_network_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header);
extern int iwl4965_power_init_handle(struct iwl_priv *priv);
extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb,
void *data, short len,
struct ieee80211_rx_status *stats,
u16 phy_flags);
extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv,
struct ieee80211_hdr *header);
extern int iwl4965_calc_db_from_ratio(int sig_ratio);
extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);
extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
......@@ -654,18 +602,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
int iwl4965_init_geos(struct iwl_priv *priv);
void iwl4965_free_geos(struct iwl_priv *priv);
extern const u8 iwl_bcast_addr[ETH_ALEN];
int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
/*
* Currently used by iwl-3945-rs... look at restructuring so that it doesn't
* call this... todo... fix that.
*/
extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
/******************************************************************************
*
......@@ -683,38 +620,16 @@ extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id,
* iwl4965_mac_ <-- mac80211 callback
*
****************************************************************************/
extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv);
extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv);
extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);
extern int iwl_rxq_stop(struct iwl_priv *priv);
extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
extern int iwl4965_hw_get_temperature(struct iwl_priv *priv);
extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate);
extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
struct iwl_cmd *cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
int sta_id, int tx_id);
extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv);
extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl4965_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
extern void iwl4965_rx_reply_rx(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
/**
* iwl_find_station - Find station id for a given BSSID
* @bssid: MAC address of station ID to find
*
* NOTE: This should not be hardware specific but the code has
* not yet been merged into a single common layer for managing the
* station tables.
*/
extern u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);
extern int iwl_queue_space(const struct iwl_queue *q);
static inline int iwl_queue_used(const struct iwl_queue *q, int i)
......@@ -738,37 +653,17 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
struct iwl_priv;
extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);
/*
* Forward declare iwl-4965.c functions for iwl-base.c
*/
extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv,
struct iwl_tx_queue *txq,
u16 byte_cnt);
extern int iwl4965_alive_notify(struct iwl_priv *priv);
extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode);
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
u32 rate_n_flags,
struct ieee80211_tx_info *info);
#ifdef CONFIG_IWL4965_HT
extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info,
enum ieee80211_band band);
void iwl4965_set_rxon_ht(struct iwl_priv *priv,
struct iwl_ht_info *ht_info);
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
enum ieee80211_ampdu_mlme_action action,
const u8 *addr, u16 tid, u16 *ssn);
int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
u8 tid, int txq_id);
#else
static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
struct ieee80211_ht_info *ht_info,
enum ieee80211_band band) {}
#endif /*CONFIG_IWL4965_HT */
/* Structures, enum, and defines specific to the 4965 */
#define IWL_KW_SIZE 0x1000 /*4k */
......@@ -792,11 +687,6 @@ struct iwl_kw {
#define IWL_OPERATION_MODE_MIXED 2
#define IWL_OPERATION_MODE_20MHZ 3
#define IWL_EXT_CHANNEL_OFFSET_NONE 0
#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1
#define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2
#define IWL_EXT_CHANNEL_OFFSET_BELOW 3
#define IWL_TX_CRC_SIZE 4
#define IWL_TX_DELIMITER_SIZE 4
......@@ -892,7 +782,6 @@ enum ucode_type {
UCODE_RT
};
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
/* Sensitivity calib data */
struct iwl_sensitivity_data {
u32 auto_corr_ofdm;
......@@ -934,7 +823,6 @@ struct iwl_chain_noise_data {
u8 delta_gain_code[NUM_RX_CHAINS];
u8 radio_write;
};
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
......@@ -1006,7 +894,8 @@ struct iwl_priv {
int one_direct_scan;
u8 direct_ssid_len;
u8 direct_ssid[IW_ESSID_MAX_SIZE];
struct iwl4965_scan_cmd *scan;
struct iwl_scan_cmd *scan;
u32 scan_tx_ant[IEEE80211_NUM_BANDS];
/* spinlock */
spinlock_t lock; /* protect general shared data */
......@@ -1067,15 +956,11 @@ struct iwl_priv {
u8 assoc_station_added;
u8 use_ant_b_for_management_frame; /* Tx antenna selection */
u8 start_calib;
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct iwl_sensitivity_data sensitivity_data;
struct iwl_chain_noise_data chain_noise_data;
__le16 sensitivity_tbl[HD_TABLE_SIZE];
#endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/
#ifdef CONFIG_IWL4965_HT
struct iwl_ht_info current_ht_config;
#endif
u8 last_phy_res[100];
/* Rate scaling data */
......@@ -1197,15 +1082,11 @@ struct iwl_priv {
struct delayed_work init_alive_start;
struct delayed_work alive_start;
struct delayed_work activity_timer;
struct delayed_work thermal_periodic;
struct delayed_work gather_stats;
struct delayed_work scan_check;
struct delayed_work post_associate;
#define IWL_DEFAULT_TX_POWER 0x0F
s8 user_txpower_limit;
s8 max_channel_txpower_limit;
/* TX Power */
s8 tx_power_user_lmt;
s8 tx_power_channel_lmt;
#ifdef CONFIG_PM
u32 pm_state[16];
......@@ -1223,13 +1104,10 @@ struct iwl_priv {
#endif /* CONFIG_IWLWIFI_DEBUG */
struct work_struct txpower_work;
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
u32 disable_sens_cal;
u32 disable_chain_noise_cal;
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
struct work_struct sensitivity_work;
#endif /* CONFIG_IWL4965_RUN_TIME_CALIB */
u32 disable_tx_power_cal;
struct work_struct run_time_calib_work;
struct timer_list statistics_periodic;
}; /*iwl_priv */
......@@ -1250,18 +1128,6 @@ static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; }
#endif
#ifdef CONFIG_IWL4965_HT
static inline int iwl_get_ra_sta_id(struct iwl_priv *priv,
struct ieee80211_hdr *hdr)
{
if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
return IWL_AP_ID;
} else {
u8 *da = ieee80211_get_DA(hdr);
return iwl_find_station(priv, da);
}
}
static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
int txq_id, int idx)
{
......@@ -1270,7 +1136,6 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
txb[idx].skb[0]->data;
return NULL;
}
#endif
static inline int iwl_is_associated(struct iwl_priv *priv)
......@@ -1332,4 +1197,4 @@ extern const struct iwl_channel_info *iwl_get_channel_info(
/* Requires full declaration of iwl_priv before including */
#endif /* __iwl4965_4965_h__ */
#endif /* __iwl_dev_h__ */
......@@ -382,8 +382,8 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv,
if (!is_channel_valid(ch_info))
return -1;
IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x"
" %ddBm): Ad-Hoc %ssupported\n",
IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %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",
......@@ -470,6 +470,11 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* Copy the run-time flags so they are there even on
* invalid channels */
ch_info->flags = eeprom_ch_info[ch].flags;
/* First write that fat is not enabled, and then enable
* one by one */
ch_info->fat_extension_channel =
(IEEE80211_CHAN_NO_FAT_ABOVE |
IEEE80211_CHAN_NO_FAT_BELOW);
if (!(is_channel_valid(ch_info))) {
IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
......@@ -488,8 +493,8 @@ int iwl_init_channel_map(struct iwl_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"
" %ddBm): Ad-Hoc %ssupported\n",
IWL_DEBUG_INFO("Ch. %d [%sGHz] %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",
......@@ -510,8 +515,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
/* Set the user_txpower_limit to the highest power
* supported by any channel */
if (eeprom_ch_info[ch].max_power_avg >
priv->user_txpower_limit)
priv->user_txpower_limit =
priv->tx_power_user_lmt)
priv->tx_power_user_lmt =
eeprom_ch_info[ch].max_power_avg;
ch_info++;
......@@ -534,12 +539,14 @@ int iwl_init_channel_map(struct iwl_priv *priv)
for (ch = 0; ch < eeprom_ch_count; ch++) {
if ((band == 6) &&
((eeprom_ch_index[ch] == 5) ||
(eeprom_ch_index[ch] == 6) ||
(eeprom_ch_index[ch] == 7)))
fat_extension_chan = HT_IE_EXT_CHANNEL_MAX;
((eeprom_ch_index[ch] == 5) ||
(eeprom_ch_index[ch] == 6) ||
(eeprom_ch_index[ch] == 7)))
/* both are allowed: above and below */
fat_extension_chan = 0;
else
fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE;
fat_extension_chan =
IEEE80211_CHAN_NO_FAT_BELOW;
/* Set up driver's info for lower half */
iwl_set_fat_chan_info(priv, ieeeband,
......@@ -551,7 +558,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
iwl_set_fat_chan_info(priv, ieeeband,
(eeprom_ch_index[ch] + 4),
&(eeprom_ch_info[ch]),
HT_IE_EXT_CHANNEL_BELOW);
IEEE80211_CHAN_NO_FAT_ABOVE);
}
}
......
......@@ -139,123 +139,12 @@ static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val)
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
#define IEEE80211_CHAN_W_RADAR_DETECT 0x00000010
static inline struct ieee80211_conf *ieee80211_get_hw_conf(
struct ieee80211_hw *hw)
{
return &hw->conf;
}
#define QOS_CONTROL_LEN 2
static inline int ieee80211_is_management(u16 fc)
{
return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT;
}
static inline int ieee80211_is_control(u16 fc)
{
return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL;
}
static inline int ieee80211_is_data(u16 fc)
{
return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA;
}
static inline int ieee80211_is_back_request(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ);
}
static inline int ieee80211_is_probe_response(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP);
}
static inline int ieee80211_is_probe_request(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_REQ);
}
static inline int ieee80211_is_beacon(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON);
}
static inline int ieee80211_is_atim(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ATIM);
}
static inline int ieee80211_is_assoc_request(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
}
static inline int ieee80211_is_assoc_response(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_RESP);
}
static inline int ieee80211_is_auth(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
}
static inline int ieee80211_is_deauth(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
}
static inline int ieee80211_is_disassoc(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ);
}
static inline int ieee80211_is_reassoc_request(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ);
}
static inline int ieee80211_is_reassoc_response(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP);
}
static inline int ieee80211_is_qos_data(u16 fc)
{
return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA);
}
/**
* ieee80211_get_qos_ctrl - get pointer to the QoS control field
*
* This function returns the pointer to 802.11 header QoS field (2 bytes)
* This function doesn't check whether hdr is a QoS hdr, use with care
* @hdr: struct ieee80211_hdr *hdr
* @hdr_len: header length
*/
static inline u8 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr, int hdr_len)
{
return ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN);
}
static inline int iwl_check_bits(unsigned long field, unsigned long mask)
{
return ((field & mask) == mask) ? 1 : 0;
......
......@@ -55,13 +55,13 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
switch (state) {
case RFKILL_STATE_ON:
priv->cfg->ops->lib->radio_kill_sw(priv, 0);
iwl_radio_kill_sw_enable_radio(priv);
/* if HW rf-kill is set dont allow ON state */
if (iwl_is_rfkill(priv))
err = -EBUSY;
break;
case RFKILL_STATE_OFF:
priv->cfg->ops->lib->radio_kill_sw(priv, 1);
iwl_radio_kill_sw_disable_radio(priv);
if (!iwl_is_rfkill(priv))
err = -EBUSY;
break;
......
......@@ -33,7 +33,6 @@ struct iwl_priv;
#include <linux/rfkill.h>
#include <linux/input.h>
#ifdef CONFIG_IWLWIFI_RFKILL
struct iwl_rfkill_mngr {
struct rfkill *rfkill;
......
......@@ -451,7 +451,6 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
struct iwl4965_missed_beacon_notif *missed_beacon;
......@@ -465,6 +464,5 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
if (!test_bit(STATUS_SCANNING, &priv->status))
iwl_init_sensitivity(priv);
}
#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */
}
EXPORT_SYMBOL(iwl_rx_missed_beacon_notif);
此差异已折叠。
......@@ -30,11 +30,9 @@
#include <net/mac80211.h>
#include <linux/etherdevice.h>
#include "iwl-eeprom.h"
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-sta.h"
#include "iwl-io.h"
#include "iwl-helpers.h"
......@@ -74,6 +72,17 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
}
EXPORT_SYMBOL(iwl_find_station);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
{
if (priv->iw_mode == IEEE80211_IF_TYPE_STA) {
return IWL_AP_ID;
} else {
u8 *da = ieee80211_get_DA(hdr);
return iwl_find_station(priv, da);
}
}
EXPORT_SYMBOL(iwl_get_ra_sta_id);
static int iwl_add_sta_callback(struct iwl_priv *priv,
struct iwl_cmd *cmd, struct sk_buff *skb)
{
......@@ -105,8 +114,6 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
return 1;
}
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
......@@ -156,8 +163,6 @@ int iwl_send_add_sta(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_send_add_sta);
#ifdef CONFIG_IWL4965_HT
static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_ht_info *sta_ht_inf)
{
......@@ -202,12 +207,6 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
done:
return;
}
#else
static inline void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_ht_info *sta_ht_info)
{
}
#endif
/**
* iwl_add_station_flags - Add station to tables in driver and device
......@@ -280,7 +279,6 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
}
EXPORT_SYMBOL(iwl_add_station_flags);
static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
{
unsigned long flags;
......@@ -384,9 +382,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
return ret;
}
/**
* iwl_remove_station - Remove driver's knowledge of station.
*
*/
u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
{
......@@ -426,7 +424,7 @@ u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
return 0;
}
EXPORT_SYMBOL(iwl_remove_station);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
static int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
int i;
......@@ -496,6 +494,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
priv->default_wep_key--;
memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
ret = iwl_send_static_wepkey_cmd(priv, 1);
IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n",
keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
......@@ -508,6 +508,12 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
int ret;
unsigned long flags;
if (keyconf->keylen != WEP_KEY_LEN_128 &&
keyconf->keylen != WEP_KEY_LEN_64) {
IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen);
return -EINVAL;
}
keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
keyconf->hw_key_idx = HW_KEY_DEFAULT;
priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP;
......@@ -524,6 +530,8 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
keyconf->keylen);
ret = iwl_send_static_wepkey_cmd(priv, 0);
IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
keyconf->keylen, keyconf->keyidx, ret);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
......@@ -670,6 +678,9 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags);
keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n",
keyconf->keyidx, sta_id);
if (keyconf->keyidx != keyidx) {
/* We need to remove a key with index different that the one
* in the uCode. This means that the key we need to remove has
......@@ -694,7 +705,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
......@@ -724,6 +734,10 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
ret = -EINVAL;
}
IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n",
keyconf->alg, keyconf->keylen, keyconf->keyidx,
sta_id, ret);
return ret;
}
EXPORT_SYMBOL(iwl_set_dynamic_key);
......@@ -816,7 +830,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
link_cmd.rs_table[i].rate_n_flags =
iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
r = iwl4965_get_prev_ieee_rate(r);
}
......@@ -842,7 +856,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
u8 sta_id;
/* Add station to device's station table */
#ifdef CONFIG_IWL4965_HT
struct ieee80211_conf *conf = &priv->hw->conf;
struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf;
......@@ -852,7 +865,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
sta_id = iwl_add_station_flags(priv, addr, is_ap,
0, cur_ht_config);
else
#endif /* CONFIG_IWL4965_HT */
sta_id = iwl_add_station_flags(priv, addr, is_ap,
0, NULL);
......@@ -863,7 +875,6 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
}
EXPORT_SYMBOL(iwl_rxon_add_station);
/**
* iwl_get_sta_id - Find station's index within station table
*
......@@ -921,7 +932,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
}
EXPORT_SYMBOL(iwl_get_sta_id);
/**
* iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table
*/
......@@ -940,4 +950,3 @@ void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid)
}
EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx);
......@@ -32,18 +32,24 @@
#define HW_KEY_DYNAMIC 0
#define HW_KEY_DEFAULT 1
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
/**
* iwl_find_station - Find station id for a given BSSID
* @bssid: MAC address of station ID to find
*/
u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty);
int iwl_remove_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key);
struct ieee80211_key_conf *key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key);
struct ieee80211_key_conf *key);
int iwl_set_dynamic_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key, u8 sta_id);
struct ieee80211_key_conf *key, u8 sta_id);
int iwl_remove_dynamic_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key, u8 sta_id);
struct ieee80211_key_conf *key, u8 sta_id);
int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
#endif /* __iwl_sta_h__ */
......@@ -36,8 +36,6 @@
#include "iwl-io.h"
#include "iwl-helpers.h"
#ifdef CONFIG_IWL4965_HT
static const u16 default_tid_to_tx_fifo[] = {
IWL_TX_FIFO_AC1,
IWL_TX_FIFO_AC0,
......@@ -58,9 +56,6 @@ static const u16 default_tid_to_tx_fifo[] = {
IWL_TX_FIFO_AC3
};
#endif /*CONFIG_IWL4965_HT */
/**
* iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
......@@ -574,15 +569,15 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
int is_unicast, u8 std_id)
{
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
__le32 tx_flags = tx_cmd->tx_flags;
tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
tx_flags |= TX_CMD_FLG_ACK_MSK;
if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
if (ieee80211_is_mgmt(fc))
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
if (ieee80211_is_probe_response(fc) &&
if (ieee80211_is_probe_resp(fc) &&
!(le16_to_cpu(hdr->seq_ctrl) & 0xf))
tx_flags |= TX_CMD_FLG_TSF_MSK;
} else {
......@@ -590,16 +585,16 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
}
if (ieee80211_is_back_request(fc))
if (ieee80211_is_back_req(fc))
tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
tx_cmd->sta_id = std_id;
if (ieee80211_get_morefrag(hdr))
if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
if (ieee80211_is_qos_data(fc)) {
u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
if (ieee80211_is_data_qos(fc)) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
tx_cmd->tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
......@@ -618,9 +613,8 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
(fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
if (ieee80211_is_mgmt(fc)) {
if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
else
tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
......@@ -639,7 +633,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv,
static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
struct iwl_tx_cmd *tx_cmd,
struct ieee80211_tx_info *info,
u16 fc, int sta_id,
__le16 fc, int sta_id,
int is_hcca)
{
u8 rts_retry_limit = 0;
......@@ -660,7 +654,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
rate_flags |= RATE_MCS_CCK_MSK;
if (ieee80211_is_probe_response(fc)) {
if (ieee80211_is_probe_resp(fc)) {
data_retry_limit = 3;
if (data_retry_limit < rts_retry_limit)
rts_retry_limit = data_retry_limit;
......@@ -675,11 +669,11 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
tx_cmd->initial_rate_index = 0;
tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
} else {
switch (fc & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_AUTH:
case IEEE80211_STYPE_DEAUTH:
case IEEE80211_STYPE_ASSOC_REQ:
case IEEE80211_STYPE_REASSOC_REQ:
switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
case cpu_to_le16(IEEE80211_STYPE_AUTH):
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) {
tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK;
......@@ -701,7 +695,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv,
tx_cmd->rts_retry_limit = rts_retry_limit;
tx_cmd->data_retry_limit = data_retry_limit;
tx_cmd->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags);
}
static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
......@@ -776,7 +770,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
u16 seq_number = 0;
u8 id, hdr_len, unicast;
u8 sta_id;
u16 fc;
__le16 fc;
u8 wait_write_ptr = 0;
u8 tid = 0;
u8 *qc = NULL;
......@@ -803,19 +797,19 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
unicast = !is_multicast_ether_addr(hdr->addr1);
id = 0;
fc = le16_to_cpu(hdr->frame_control);
fc = hdr->frame_control;
#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
IWL_DEBUG_TX("Sending AUTH frame\n");
else if (ieee80211_is_assoc_request(fc))
else if (ieee80211_is_assoc_req(fc))
IWL_DEBUG_TX("Sending ASSOC frame\n");
else if (ieee80211_is_reassoc_request(fc))
else if (ieee80211_is_reassoc_req(fc))
IWL_DEBUG_TX("Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
if (ieee80211_is_data(fc) &&
(!iwl_is_associated(priv) ||
((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) ||
!priv->assoc_station_added)) {
......@@ -825,7 +819,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
spin_unlock_irqrestore(&priv->lock, flags);
hdr_len = ieee80211_get_hdrlen(fc);
hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
/* Find (or create) index into station table for destination station */
sta_id = iwl_get_sta_id(priv, hdr);
......@@ -839,8 +833,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
IWL_DEBUG_TX("station Id %d\n", sta_id);
if (ieee80211_is_qos_data(fc)) {
qc = ieee80211_get_qos_ctrl(hdr, hdr_len);
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
seq_number = priv->stations[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
......@@ -848,12 +842,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
(hdr->seq_ctrl &
__constant_cpu_to_le16(IEEE80211_SCTL_FRAG));
seq_number += 0x10;
#ifdef CONFIG_IWL4965_HT
/* aggregation is on for this <sta,tid> */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;
priv->stations[sta_id].tid[tid].tfds_in_queue++;
#endif /* CONFIG_IWL4965_HT */
}
/* Descriptor for chosen Tx queue */
......@@ -945,14 +937,14 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* set is_hcca to 0; it probably will never be implemented */
iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
iwl_update_tx_stats(priv, fc, len);
iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
offsetof(struct iwl_tx_cmd, scratch);
tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys);
if (!ieee80211_get_morefrag(hdr)) {
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc)
priv->stations[sta_id].tid[tid].seq_number = seq_number;
......@@ -1196,8 +1188,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
}
EXPORT_SYMBOL(iwl_tx_cmd_complete);
#ifdef CONFIG_IWL4965_HT
/*
* Find first available (lowest unused) Tx Queue, mark it "active".
* Called only when finding queue for aggregation.
......@@ -1359,7 +1349,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id)
return 0;
}
EXPORT_SYMBOL(iwl_txq_check_empty);
#endif /* CONFIG_IWL4965_HT */
#ifdef CONFIG_IWLWIF_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
......
......@@ -2431,15 +2431,15 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
struct ieee80211_hdr *hdr,
int is_unicast, u8 std_id)
{
u16 fc = le16_to_cpu(hdr->frame_control);
__le16 fc = hdr->frame_control;
__le32 tx_flags = cmd->cmd.tx.tx_flags;
cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
tx_flags |= TX_CMD_FLG_ACK_MSK;
if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
if (ieee80211_is_mgmt(fc))
tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
if (ieee80211_is_probe_response(fc) &&
if (ieee80211_is_probe_resp(fc) &&
!(le16_to_cpu(hdr->seq_ctrl) & 0xf))
tx_flags |= TX_CMD_FLG_TSF_MSK;
} else {
......@@ -2448,11 +2448,11 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
}
cmd->cmd.tx.sta_id = std_id;
if (ieee80211_get_morefrag(hdr))
if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
if (ieee80211_is_qos_data(fc)) {
u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc));
if (ieee80211_is_data_qos(fc)) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
cmd->cmd.tx.tid_tspec = qc[0] & 0xf;
tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
} else {
......@@ -2471,9 +2471,8 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv,
tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK;
tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ ||
(fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
if (ieee80211_is_mgmt(fc)) {
if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3);
else
cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2);
......@@ -2564,7 +2563,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
u8 sta_id;
u8 tid = 0;
u16 seq_number = 0;
u16 fc;
__le16 fc;
u8 wait_write_ptr = 0;
u8 *qc = NULL;
unsigned long flags;
......@@ -2589,28 +2588,28 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
unicast = !is_multicast_ether_addr(hdr->addr1);
id = 0;
fc = le16_to_cpu(hdr->frame_control);
fc = hdr->frame_control;
#ifdef CONFIG_IWL3945_DEBUG
if (ieee80211_is_auth(fc))
IWL_DEBUG_TX("Sending AUTH frame\n");
else if (ieee80211_is_assoc_request(fc))
else if (ieee80211_is_assoc_req(fc))
IWL_DEBUG_TX("Sending ASSOC frame\n");
else if (ieee80211_is_reassoc_request(fc))
else if (ieee80211_is_reassoc_req(fc))
IWL_DEBUG_TX("Sending REASSOC frame\n");
#endif
/* drop all data frame if we are not associated */
if ((!iwl3945_is_associated(priv) ||
((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
ieee80211_is_data(fc)) {
IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
goto drop_unlock;
}
spin_unlock_irqrestore(&priv->lock, flags);
hdr_len = ieee80211_get_hdrlen(fc);
hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc));
/* Find (or create) index into station table for destination station */
sta_id = iwl3945_get_sta_id(priv, hdr);
......@@ -2624,8 +2623,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
IWL_DEBUG_RATE("station Id %d\n", sta_id);
if (ieee80211_is_qos_data(fc)) {
qc = ieee80211_get_qos_ctrl(hdr, hdr_len);
if (ieee80211_is_data_qos(fc)) {
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
seq_number = priv->stations[sta_id].tid[tid].seq_number &
IEEE80211_SCTL_SEQ;
......@@ -2732,7 +2731,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
if (!ieee80211_get_morefrag(hdr)) {
if (!ieee80211_has_morefrags(hdr->frame_control)) {
txq->need_update = 1;
if (qc) {
priv->stations[sta_id].tid[tid].seq_number = seq_number;
......@@ -2746,7 +2745,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
sizeof(out_cmd->cmd.tx));
iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr,
ieee80211_get_hdrlen(fc));
ieee80211_get_hdrlen(le16_to_cpu(fc)));
/* Tell device the write index *just past* this latest filled TFD */
q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
......@@ -2875,7 +2874,8 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio)
return;
}
queue_work(priv->workqueue, &priv->restart);
if (priv->is_open)
queue_work(priv->workqueue, &priv->restart);
return;
}
......
此差异已折叠。
此差异已折叠。
......@@ -277,6 +277,17 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev,
return 0;
}
static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev,
struct rt2x00_led *led,
enum led_type type)
{
led->rt2x00dev = rt2x00dev;
led->type = type;
led->led_dev.brightness_set = rt2400pci_brightness_set;
led->led_dev.blink_set = rt2400pci_blink_set;
led->flags = LED_INITIALIZED;
}
#endif /* CONFIG_RT2400PCI_LEDS */
/*
......@@ -781,25 +792,32 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
return 0;
}
static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u16 eeprom;
u8 reg_id;
u8 value;
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2400pci_bbp_read(rt2x00dev, 0, &value);
if ((value != 0xff) && (value != 0x00))
goto continue_csr_init;
NOTICE(rt2x00dev, "Waiting for BBP register.\n");
return 0;
udelay(REGISTER_BUSY_DELAY);
}
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
return -EACCES;
}
static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev)
{
unsigned int i;
u16 eeprom;
u8 reg_id;
u8 value;
if (unlikely(rt2400pci_wait_bbp_ready(rt2x00dev)))
return -EACCES;
continue_csr_init:
rt2400pci_bbp_write(rt2x00dev, 1, 0x00);
rt2400pci_bbp_write(rt2x00dev, 3, 0x27);
rt2400pci_bbp_write(rt2x00dev, 4, 0x08);
......@@ -838,7 +856,8 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
rt2x00pci_register_read(rt2x00dev, RXCSR0, &reg);
rt2x00_set_field32(&reg, RXCSR0_DISABLE_RX,
state == STATE_RADIO_RX_OFF);
(state == STATE_RADIO_RX_OFF) ||
(state == STATE_RADIO_RX_OFF_LINK));
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
......@@ -875,17 +894,10 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all registers.
*/
if (rt2400pci_init_queues(rt2x00dev) ||
rt2400pci_init_registers(rt2x00dev) ||
rt2400pci_init_bbp(rt2x00dev)) {
ERROR(rt2x00dev, "Register initialization failed.\n");
if (unlikely(rt2400pci_init_queues(rt2x00dev) ||
rt2400pci_init_registers(rt2x00dev) ||
rt2400pci_init_bbp(rt2x00dev)))
return -EIO;
}
/*
* Enable interrupts.
*/
rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
return 0;
}
......@@ -907,11 +919,6 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev)
rt2x00pci_register_read(rt2x00dev, TXCSR0, &reg);
rt2x00_set_field32(&reg, TXCSR0_ABORT, 1);
rt2x00pci_register_write(rt2x00dev, TXCSR0, reg);
/*
* Disable interrupts.
*/
rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);
}
static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
......@@ -946,10 +953,6 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev,
msleep(10);
}
NOTICE(rt2x00dev, "Device failed to enter state %d, "
"current device state: bbp %d and rf %d.\n",
state, bbp_state, rf_state);
return -EBUSY;
}
......@@ -967,11 +970,13 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
case STATE_RADIO_RX_ON:
case STATE_RADIO_RX_ON_LINK:
rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
break;
case STATE_RADIO_RX_OFF:
case STATE_RADIO_RX_OFF_LINK:
rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
rt2400pci_toggle_rx(rt2x00dev, state);
break;
case STATE_RADIO_IRQ_ON:
case STATE_RADIO_IRQ_OFF:
rt2400pci_toggle_irq(rt2x00dev, state);
break;
case STATE_DEEP_SLEEP:
case STATE_SLEEP:
......@@ -984,6 +989,10 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
break;
}
if (unlikely(retval))
ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
state, retval);
return retval;
}
......@@ -1007,8 +1016,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
rt2x00_desc_write(entry_priv->desc, 1, word);
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skbdesc->data_len);
rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len);
rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len);
rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
......@@ -1300,23 +1309,10 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
#ifdef CONFIG_RT2400PCI_LEDS
value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE);
rt2x00dev->led_radio.rt2x00dev = rt2x00dev;
rt2x00dev->led_radio.type = LED_TYPE_RADIO;
rt2x00dev->led_radio.led_dev.brightness_set =
rt2400pci_brightness_set;
rt2x00dev->led_radio.led_dev.blink_set =
rt2400pci_blink_set;
rt2x00dev->led_radio.flags = LED_INITIALIZED;
if (value == LED_MODE_TXRX_ACTIVITY) {
rt2x00dev->led_qual.rt2x00dev = rt2x00dev;
rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY;
rt2x00dev->led_qual.led_dev.brightness_set =
rt2400pci_brightness_set;
rt2x00dev->led_qual.led_dev.blink_set =
rt2400pci_blink_set;
rt2x00dev->led_qual.flags = LED_INITIALIZED;
}
rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
if (value == LED_MODE_TXRX_ACTIVITY)
rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual,
LED_TYPE_ACTIVITY);
#endif /* CONFIG_RT2400PCI_LEDS */
/*
......@@ -1511,9 +1507,6 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
*/
skbdesc = get_skb_frame_desc(skb);
memset(skbdesc, 0, sizeof(*skbdesc));
skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED;
skbdesc->data = skb->data;
skbdesc->data_len = skb->len;
skbdesc->desc = entry_priv->desc;
skbdesc->desc_len = intf->beacon->queue->desc_size;
skbdesc->entry = intf->beacon;
......
......@@ -37,8 +37,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
#define MAX_SIGNAL 100
#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 100
/*
......
......@@ -48,8 +48,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
#define MAX_SIGNAL 100
#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 121
/*
......
......@@ -48,8 +48,6 @@
* Signal information.
* Defaul offset is required for RSSI <-> dBm conversion.
*/
#define MAX_SIGNAL 100
#define MAX_RX_SSI -1
#define DEFAULT_RSSI_OFFSET 120
/*
......
......@@ -44,7 +44,7 @@
/*
* Module information.
*/
#define DRV_VERSION "2.1.6"
#define DRV_VERSION "2.1.7"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
......@@ -546,8 +546,7 @@ struct rt2x00lib_ops {
void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb,
struct txentry_desc *txdesc);
int (*write_tx_data) (struct rt2x00_dev *rt2x00dev,
struct data_queue *queue, struct sk_buff *skb);
int (*write_tx_data) (struct queue_entry *entry);
int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev,
struct sk_buff *skb);
void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev,
......@@ -827,7 +826,7 @@ struct rt2x00_dev {
* The Beacon array also contains the Atim queue
* if that is supported by the device.
*/
int data_queues;
unsigned int data_queues;
struct data_queue *rx;
struct data_queue *tx;
struct data_queue *bcn;
......@@ -930,6 +929,12 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate)
return ((size * 8 * 10) % rate);
}
/**
* rt2x00queue_alloc_rxskb - allocate a skb for RX purposes.
* @queue: The queue for which the skb will be applicable.
*/
struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue);
/**
* rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input
* @entry: The entry which will be used to transfer the TX frame.
......
......@@ -101,6 +101,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
/*
* Queue handlers.
*/
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb);
void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev);
void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev);
int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册