Commit 857485c0 authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville

iwlwifi: move host command sending functions to core module

1. Host command sending functions moved from iwl4965-base.c to iwl-hcmd.c
in iwlcore module
2. enqueue_hcmd function currently stays in iwl4965-base.c. It is invoked
   through the new 'utils' field in priv's ops.
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarAssaf Krauss <assaf.krauss@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8622e705
obj-$(CONFIG_IWLCORE) += iwlcore.o obj-$(CONFIG_IWLCORE) += iwlcore.o
iwlcore-objs = iwl-core.o iwl-eeprom.o iwlcore-objs = iwl-core.o iwl-eeprom.o iwl-hcmd.o
ifeq ($(CONFIG_IWLWIFI_DEBUGFS),y) ifeq ($(CONFIG_IWLWIFI_DEBUGFS),y)
iwlcore-objs += iwl-debugfs.o iwlcore-objs += iwl-debugfs.o
......
...@@ -139,7 +139,7 @@ enum { ...@@ -139,7 +139,7 @@ enum {
REPLY_PHY_CALIBRATION_CMD = 0xb0, REPLY_PHY_CALIBRATION_CMD = 0xb0,
REPLY_RX_PHY_CMD = 0xc0, REPLY_RX_PHY_CMD = 0xc0,
REPLY_RX_MPDU_CMD = 0xc1, REPLY_RX_MPDU_CMD = 0xc1,
REPLY_4965_RX = 0xc3, REPLY_RX = 0xc3,
REPLY_COMPRESSED_BA = 0xc5, REPLY_COMPRESSED_BA = 0xc5,
REPLY_MAX = 0xff REPLY_MAX = 0xff
}; };
...@@ -151,16 +151,16 @@ enum { ...@@ -151,16 +151,16 @@ enum {
* *
*****************************************************************************/ *****************************************************************************/
/* iwl4965_cmd_header flags value */ /* iwl_cmd_header flags value */
#define IWL_CMD_FAILED_MSK 0x40 #define IWL_CMD_FAILED_MSK 0x40
/** /**
* struct iwl4965_cmd_header * struct iwl_cmd_header
* *
* This header format appears in the beginning of each command sent from the * This header format appears in the beginning of each command sent from the
* driver, and each response/notification received from uCode. * driver, and each response/notification received from uCode.
*/ */
struct iwl4965_cmd_header { struct iwl_cmd_header {
u8 cmd; /* Command ID: REPLY_RXON, etc. */ u8 cmd; /* Command ID: REPLY_RXON, etc. */
u8 flags; /* IWL_CMD_* */ u8 flags; /* IWL_CMD_* */
/* /*
...@@ -194,7 +194,7 @@ struct iwl4965_cmd_header { ...@@ -194,7 +194,7 @@ struct iwl4965_cmd_header {
* 4965 rate_n_flags bit fields * 4965 rate_n_flags bit fields
* *
* rate_n_flags format is used in following 4965 commands: * rate_n_flags format is used in following 4965 commands:
* REPLY_4965_RX (response only) * REPLY_RX (response only)
* REPLY_TX (both command and response) * REPLY_TX (both command and response)
* REPLY_TX_LINK_QUALITY_CMD * REPLY_TX_LINK_QUALITY_CMD
* *
...@@ -939,7 +939,7 @@ struct iwl4965_rx_non_cfg_phy { ...@@ -939,7 +939,7 @@ struct iwl4965_rx_non_cfg_phy {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* /*
* REPLY_4965_RX = 0xc3 (response only, not a command) * REPLY_RX = 0xc3 (response only, not a command)
* Used only for legacy (non 11n) frames. * Used only for legacy (non 11n) frames.
*/ */
#define RX_RES_PHY_CNT 14 #define RX_RES_PHY_CNT 14
...@@ -2664,7 +2664,7 @@ struct iwl4965_led_cmd { ...@@ -2664,7 +2664,7 @@ struct iwl4965_led_cmd {
struct iwl4965_rx_packet { struct iwl4965_rx_packet {
__le32 len; __le32 len;
struct iwl4965_cmd_header hdr; struct iwl_cmd_header hdr;
union { union {
struct iwl4965_alive_resp alive_frame; struct iwl4965_alive_resp alive_frame;
struct iwl4965_rx_frame rx_frame; struct iwl4965_rx_frame rx_frame;
......
...@@ -113,9 +113,6 @@ ...@@ -113,9 +113,6 @@
#define TFD_TX_CMD_SLOTS 256 #define TFD_TX_CMD_SLOTS 256
#define TFD_CMD_SLOTS 32 #define TFD_CMD_SLOTS 32
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl4965_cmd) - \
sizeof(struct iwl4965_cmd_meta))
/* /*
* RX related structures and functions * RX related structures and functions
*/ */
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "../net/mac80211/ieee80211_rate.h" #include "../net/mac80211/ieee80211_rate.h"
#include "iwl-4965.h" #include "iwl-4965.h"
#include "iwl-core.h"
#include "iwl-helpers.h" #include "iwl-helpers.h"
#define RS_NAME "iwl-4965-rs" #define RS_NAME "iwl-4965-rs"
...@@ -230,7 +231,7 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = { ...@@ -230,7 +231,7 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
}; };
static int iwl4965_lq_sync_callback(struct iwl_priv *priv, static int iwl4965_lq_sync_callback(struct iwl_priv *priv,
struct iwl4965_cmd *cmd, struct sk_buff *skb) struct iwl_cmd *cmd, struct sk_buff *skb)
{ {
/*We didn't cache the SKB; let the caller free it */ /*We didn't cache the SKB; let the caller free it */
return 1; return 1;
...@@ -247,7 +248,7 @@ static int rs_send_lq_cmd(struct iwl_priv *priv, ...@@ -247,7 +248,7 @@ static int rs_send_lq_cmd(struct iwl_priv *priv,
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
int i; int i;
#endif #endif
struct iwl4965_host_cmd cmd = { struct iwl_host_cmd cmd = {
.id = REPLY_TX_LINK_QUALITY_CMD, .id = REPLY_TX_LINK_QUALITY_CMD,
.len = sizeof(struct iwl4965_link_quality_cmd), .len = sizeof(struct iwl4965_link_quality_cmd),
.meta.flags = flags, .meta.flags = flags,
...@@ -276,7 +277,7 @@ static int rs_send_lq_cmd(struct iwl_priv *priv, ...@@ -276,7 +277,7 @@ static int rs_send_lq_cmd(struct iwl_priv *priv,
if (iwl4965_is_associated(priv) && priv->assoc_station_added && if (iwl4965_is_associated(priv) && priv->assoc_station_added &&
priv->lq_mngr.lq_ready) priv->lq_mngr.lq_ready)
return iwl4965_send_cmd(priv, &cmd); return iwl_send_cmd(priv, &cmd);
return 0; return 0;
} }
......
...@@ -861,7 +861,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) ...@@ -861,7 +861,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
u32 temp_th; u32 temp_th;
u32 crit_temperature; u32 crit_temperature;
unsigned long flags; unsigned long flags;
int rc = 0; int ret = 0;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR,
...@@ -882,9 +882,9 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) ...@@ -882,9 +882,9 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
crit_temperature = ((temp_th * (R3-R1))/CT_LIMIT_CONST) + R2; crit_temperature = ((temp_th * (R3-R1))/CT_LIMIT_CONST) + R2;
cmd.critical_temperature_R = cpu_to_le32(crit_temperature); cmd.critical_temperature_R = cpu_to_le32(crit_temperature);
rc = iwl4965_send_cmd_pdu(priv, ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
REPLY_CT_KILL_CONFIG_CMD, sizeof(cmd), &cmd); sizeof(cmd), &cmd);
if (rc) if (ret)
IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n");
else else
IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded\n"); IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded\n");
...@@ -1157,7 +1157,7 @@ static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv, ...@@ -1157,7 +1157,7 @@ static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv,
} }
static int iwl4965_sensitivity_callback(struct iwl_priv *priv, static int iwl4965_sensitivity_callback(struct iwl_priv *priv,
struct iwl4965_cmd *cmd, struct sk_buff *skb) struct iwl_cmd *cmd, struct sk_buff *skb)
{ {
/* We didn't cache the SKB; let the caller free it */ /* We didn't cache the SKB; let the caller free it */
return 1; return 1;
...@@ -1166,15 +1166,15 @@ static int iwl4965_sensitivity_callback(struct iwl_priv *priv, ...@@ -1166,15 +1166,15 @@ static int iwl4965_sensitivity_callback(struct iwl_priv *priv,
/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags) static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
{ {
int rc = 0;
struct iwl4965_sensitivity_cmd cmd ; struct iwl4965_sensitivity_cmd cmd ;
struct iwl4965_sensitivity_data *data = NULL; struct iwl4965_sensitivity_data *data = NULL;
struct iwl4965_host_cmd cmd_out = { struct iwl_host_cmd cmd_out = {
.id = SENSITIVITY_CMD, .id = SENSITIVITY_CMD,
.len = sizeof(struct iwl4965_sensitivity_cmd), .len = sizeof(struct iwl4965_sensitivity_cmd),
.meta.flags = flags, .meta.flags = flags,
.data = &cmd, .data = &cmd,
}; };
int ret;
data = &(priv->sensitivity_data); data = &(priv->sensitivity_data);
...@@ -1232,20 +1232,18 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags) ...@@ -1232,20 +1232,18 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags)
memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]),
sizeof(u16)*HD_TABLE_SIZE); sizeof(u16)*HD_TABLE_SIZE);
rc = iwl4965_send_cmd(priv, &cmd_out); ret = iwl_send_cmd(priv, &cmd_out);
if (!rc) { if (ret)
IWL_DEBUG_CALIB("SENSITIVITY_CMD succeeded\n"); IWL_ERROR("SENSITIVITY_CMD failed\n");
return rc;
}
return 0; return ret;
} }
void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force) void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
{ {
int rc = 0;
int i;
struct iwl4965_sensitivity_data *data = NULL; struct iwl4965_sensitivity_data *data = NULL;
int i;
int ret = 0;
IWL_DEBUG_CALIB("Start iwl4965_init_sensitivity\n"); IWL_DEBUG_CALIB("Start iwl4965_init_sensitivity\n");
...@@ -1289,8 +1287,8 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force) ...@@ -1289,8 +1287,8 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
memset(&(priv->sensitivity_tbl[0]), 0, memset(&(priv->sensitivity_tbl[0]), 0,
sizeof(u16)*HD_TABLE_SIZE); sizeof(u16)*HD_TABLE_SIZE);
rc |= iwl4965_sensitivity_write(priv, flags); ret |= iwl4965_sensitivity_write(priv, flags);
IWL_DEBUG_CALIB("<<return 0x%X\n", rc); IWL_DEBUG_CALIB("<<return 0x%X\n", ret);
return; return;
} }
...@@ -1302,7 +1300,6 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force) ...@@ -1302,7 +1300,6 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force)
void iwl4965_chain_noise_reset(struct iwl_priv *priv) void iwl4965_chain_noise_reset(struct iwl_priv *priv)
{ {
struct iwl4965_chain_noise_data *data = NULL; struct iwl4965_chain_noise_data *data = NULL;
int rc = 0;
data = &(priv->chain_noise_data); data = &(priv->chain_noise_data);
if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl4965_is_associated(priv)) { if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl4965_is_associated(priv)) {
...@@ -1313,7 +1310,7 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv) ...@@ -1313,7 +1310,7 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv)
cmd.diff_gain_a = 0; cmd.diff_gain_a = 0;
cmd.diff_gain_b = 0; cmd.diff_gain_b = 0;
cmd.diff_gain_c = 0; cmd.diff_gain_c = 0;
rc = iwl4965_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd); sizeof(cmd), &cmd);
msleep(4); msleep(4);
data->state = IWL_CHAIN_NOISE_ACCUMULATE; data->state = IWL_CHAIN_NOISE_ACCUMULATE;
...@@ -1332,7 +1329,7 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv, ...@@ -1332,7 +1329,7 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *stat_resp) struct iwl4965_notif_statistics *stat_resp)
{ {
struct iwl4965_chain_noise_data *data = NULL; struct iwl4965_chain_noise_data *data = NULL;
int rc = 0; int ret = 0;
u32 chain_noise_a; u32 chain_noise_a;
u32 chain_noise_b; u32 chain_noise_b;
...@@ -1538,9 +1535,9 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv, ...@@ -1538,9 +1535,9 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv,
cmd.diff_gain_a = data->delta_gain_code[0]; cmd.diff_gain_a = data->delta_gain_code[0];
cmd.diff_gain_b = data->delta_gain_code[1]; cmd.diff_gain_b = data->delta_gain_code[1];
cmd.diff_gain_c = data->delta_gain_code[2]; cmd.diff_gain_c = data->delta_gain_code[2];
rc = iwl4965_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd); sizeof(cmd), &cmd);
if (rc) if (ret)
IWL_DEBUG_CALIB("fail sending cmd " IWL_DEBUG_CALIB("fail sending cmd "
"REPLY_PHY_CALIBRATION_CMD \n"); "REPLY_PHY_CALIBRATION_CMD \n");
...@@ -1564,7 +1561,6 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv, ...@@ -1564,7 +1561,6 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv,
static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
struct iwl4965_notif_statistics *resp) struct iwl4965_notif_statistics *resp)
{ {
int rc = 0;
u32 rx_enable_time; u32 rx_enable_time;
u32 fa_cck; u32 fa_cck;
u32 fa_ofdm; u32 fa_ofdm;
...@@ -1577,6 +1573,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, ...@@ -1577,6 +1573,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
struct statistics_rx *statistics = &(resp->rx); struct statistics_rx *statistics = &(resp->rx);
unsigned long flags; unsigned long flags;
struct statistics_general_data statis; struct statistics_general_data statis;
int ret;
data = &(priv->sensitivity_data); data = &(priv->sensitivity_data);
...@@ -1661,7 +1658,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, ...@@ -1661,7 +1658,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv,
iwl4965_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time); iwl4965_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
iwl4965_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis); iwl4965_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
rc |= iwl4965_sensitivity_write(priv, CMD_ASYNC); ret = iwl4965_sensitivity_write(priv, CMD_ASYNC);
return; return;
} }
...@@ -1789,7 +1786,7 @@ int iwl4965_alive_notify(struct iwl_priv *priv) ...@@ -1789,7 +1786,7 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
u32 a; u32 a;
int i = 0; int i = 0;
unsigned long flags; unsigned long flags;
int rc; int ret;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -1802,10 +1799,10 @@ int iwl4965_alive_notify(struct iwl_priv *priv) ...@@ -1802,10 +1799,10 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
priv->chain_noise_data.delta_gain_code[i] = priv->chain_noise_data.delta_gain_code[i] =
CHAIN_NOISE_DELTA_GAIN_INIT_VAL; CHAIN_NOISE_DELTA_GAIN_INIT_VAL;
#endif /* CONFIG_IWL4965_SENSITIVITY*/ #endif /* CONFIG_IWL4965_SENSITIVITY*/
rc = iwl4965_grab_nic_access(priv); ret = iwl4965_grab_nic_access(priv);
if (rc) { if (ret) {
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
return rc; return ret;
} }
/* Clear 4965's internal Tx Scheduler data base */ /* Clear 4965's internal Tx Scheduler data base */
...@@ -1868,7 +1865,7 @@ int iwl4965_alive_notify(struct iwl_priv *priv) ...@@ -1868,7 +1865,7 @@ int iwl4965_alive_notify(struct iwl_priv *priv)
iwl4965_release_nic_access(priv); iwl4965_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
return 0; return ret;
} }
/** /**
...@@ -2719,7 +2716,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -2719,7 +2716,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv) int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv)
{ {
struct iwl4965_txpowertable_cmd cmd = { 0 }; struct iwl4965_txpowertable_cmd cmd = { 0 };
int rc = 0; int ret;
u8 band = 0; u8 band = 0;
u8 is_fat = 0; u8 is_fat = 0;
u8 ctrl_chan_high = 0; u8 ctrl_chan_high = 0;
...@@ -2743,14 +2740,16 @@ int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv) ...@@ -2743,14 +2740,16 @@ int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv)
cmd.band = band; cmd.band = band;
cmd.channel = priv->active_rxon.channel; cmd.channel = priv->active_rxon.channel;
rc = iwl4965_fill_txpower_tbl(priv, band, ret = iwl4965_fill_txpower_tbl(priv, band,
le16_to_cpu(priv->active_rxon.channel), le16_to_cpu(priv->active_rxon.channel),
is_fat, ctrl_chan_high, &cmd.tx_power); is_fat, ctrl_chan_high, &cmd.tx_power);
if (rc) if (ret)
return rc; goto out;
rc = iwl4965_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); ret = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd);
return rc;
out:
return ret;
} }
int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
...@@ -2790,7 +2789,7 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) ...@@ -2790,7 +2789,7 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
return rc; return rc;
} }
rc = iwl4965_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
return rc; return rc;
} }
...@@ -2798,7 +2797,7 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel) ...@@ -2798,7 +2797,7 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
#define RTS_DFAULT_RETRY_LIMIT 60 #define RTS_DFAULT_RETRY_LIMIT 60
void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
struct iwl4965_cmd *cmd, struct iwl_cmd *cmd,
struct ieee80211_tx_control *ctrl, struct ieee80211_tx_control *ctrl,
struct ieee80211_hdr *hdr, int sta_id, struct ieee80211_hdr *hdr, int sta_id,
int is_hcca) int is_hcca)
...@@ -3863,7 +3862,7 @@ static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv, ...@@ -3863,7 +3862,7 @@ static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv,
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
/* Called for REPLY_4965_RX (legacy ABG frames), or /* Called for REPLY_RX (legacy ABG frames), or
* REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
static void iwl4965_rx_reply_rx(struct iwl_priv *priv, static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
struct iwl4965_rx_mem_buffer *rxb) struct iwl4965_rx_mem_buffer *rxb)
...@@ -3874,7 +3873,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, ...@@ -3874,7 +3873,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
/* Use phy data (Rx signal strength, etc.) contained within /* Use phy data (Rx signal strength, etc.) contained within
* this rx packet for legacy frames, * this rx packet for legacy frames,
* or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
int include_phy = (pkt->hdr.cmd == REPLY_4965_RX); int include_phy = (pkt->hdr.cmd == REPLY_RX);
struct iwl4965_rx_phy_res *rx_start = (include_phy) ? struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
(struct iwl4965_rx_phy_res *)&priv->last_phy_res[1]; (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
...@@ -4562,7 +4561,7 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) ...@@ -4562,7 +4561,7 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
/* Update the rate scaling for control frame Tx to AP */ /* Update the rate scaling for control frame Tx to AP */
link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id; link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id;
iwl4965_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd), iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd),
&link_cmd); &link_cmd);
} }
...@@ -4915,7 +4914,7 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, ...@@ -4915,7 +4914,7 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
void iwl4965_hw_rx_handler_setup(struct iwl_priv *priv) void iwl4965_hw_rx_handler_setup(struct iwl_priv *priv)
{ {
/* Legacy Rx frames */ /* Legacy Rx frames */
priv->rx_handlers[REPLY_4965_RX] = iwl4965_rx_reply_rx; priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx;
/* High-throughput (HT) Rx frames */ /* High-throughput (HT) Rx frames */
priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy; priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy;
...@@ -4948,6 +4947,10 @@ void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv) ...@@ -4948,6 +4947,10 @@ void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv)
cancel_delayed_work(&priv->init_alive_start); cancel_delayed_work(&priv->init_alive_start);
} }
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.enqueue_hcmd = iwl4965_enqueue_hcmd,
};
static struct iwl_lib_ops iwl4965_lib = { static struct iwl_lib_ops iwl4965_lib = {
.init_drv = iwl4965_init_drv, .init_drv = iwl4965_init_drv,
.eeprom_ops = { .eeprom_ops = {
...@@ -4959,6 +4962,7 @@ static struct iwl_lib_ops iwl4965_lib = { ...@@ -4959,6 +4962,7 @@ static struct iwl_lib_ops iwl4965_lib = {
static struct iwl_ops iwl4965_ops = { static struct iwl_ops iwl4965_ops = {
.lib = &iwl4965_lib, .lib = &iwl4965_lib,
.utils = &iwl4965_hcmd_utils,
}; };
static struct iwl_cfg iwl4965_agn_cfg = { static struct iwl_cfg iwl4965_agn_cfg = {
......
...@@ -140,7 +140,7 @@ struct iwl4965_tx_info { ...@@ -140,7 +140,7 @@ struct iwl4965_tx_info {
struct iwl4965_tx_queue { struct iwl4965_tx_queue {
struct iwl4965_queue q; struct iwl4965_queue q;
struct iwl4965_tfd_frame *bd; struct iwl4965_tfd_frame *bd;
struct iwl4965_cmd *cmd; struct iwl_cmd *cmd;
dma_addr_t dma_addr_cmd; dma_addr_t dma_addr_cmd;
struct iwl4965_tx_info *txb; struct iwl4965_tx_info *txb;
int need_update; int need_update;
...@@ -312,15 +312,15 @@ enum { ...@@ -312,15 +312,15 @@ enum {
CMD_WANT_SKB = (1 << 2), CMD_WANT_SKB = (1 << 2),
}; };
struct iwl4965_cmd; struct iwl_cmd;
struct iwl_priv; struct iwl_priv;
struct iwl4965_cmd_meta { struct iwl_cmd_meta {
struct iwl4965_cmd_meta *source; struct iwl_cmd_meta *source;
union { union {
struct sk_buff *skb; struct sk_buff *skb;
int (*callback)(struct iwl_priv *priv, int (*callback)(struct iwl_priv *priv,
struct iwl4965_cmd *cmd, struct sk_buff *skb); struct iwl_cmd *cmd, struct sk_buff *skb);
} __attribute__ ((packed)) u; } __attribute__ ((packed)) u;
/* The CMD_SIZE_HUGE flag bit indicates that the command /* The CMD_SIZE_HUGE flag bit indicates that the command
...@@ -330,15 +330,15 @@ struct iwl4965_cmd_meta { ...@@ -330,15 +330,15 @@ struct iwl4965_cmd_meta {
} __attribute__ ((packed)); } __attribute__ ((packed));
/** /**
* struct iwl4965_cmd * struct iwl_cmd
* *
* For allocation of the command and tx queues, this establishes the overall * For allocation of the command and tx queues, this establishes the overall
* size of the largest command we send to uCode, except for a scan command * size of the largest command we send to uCode, except for a scan command
* (which is relatively huge; space is allocated separately). * (which is relatively huge; space is allocated separately).
*/ */
struct iwl4965_cmd { struct iwl_cmd {
struct iwl4965_cmd_meta meta; /* driver data */ struct iwl_cmd_meta meta; /* driver data */
struct iwl4965_cmd_header hdr; /* uCode API */ struct iwl_cmd_header hdr; /* uCode API */
union { union {
struct iwl4965_addsta_cmd addsta; struct iwl4965_addsta_cmd addsta;
struct iwl4965_led_cmd led; struct iwl4965_led_cmd led;
...@@ -358,15 +358,15 @@ struct iwl4965_cmd { ...@@ -358,15 +358,15 @@ struct iwl4965_cmd {
} __attribute__ ((packed)) cmd; } __attribute__ ((packed)) cmd;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct iwl4965_host_cmd { struct iwl_host_cmd {
u8 id; u8 id;
u16 len; u16 len;
struct iwl4965_cmd_meta meta; struct iwl_cmd_meta meta;
const void *data; const void *data;
}; };
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl4965_cmd) - \ #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \
sizeof(struct iwl4965_cmd_meta)) sizeof(struct iwl_cmd_meta))
/* /*
* RX related structures and functions * RX related structures and functions
...@@ -656,10 +656,6 @@ extern int iwl4965_tx_queue_init(struct iwl_priv *priv, ...@@ -656,10 +656,6 @@ extern int iwl4965_tx_queue_init(struct iwl_priv *priv,
struct iwl4965_tx_queue *txq, int count, u32 id); struct iwl4965_tx_queue *txq, int count, u32 id);
extern void iwl4965_rx_replenish(void *data); extern void iwl4965_rx_replenish(void *data);
extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq);
extern int iwl4965_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
const void *data);
extern int __must_check iwl4965_send_cmd(struct iwl_priv *priv,
struct iwl4965_host_cmd *cmd);
extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
const u8 *dest, int left); const u8 *dest, int left);
...@@ -674,6 +670,7 @@ int iwl4965_init_geos(struct iwl_priv *priv); ...@@ -674,6 +670,7 @@ int iwl4965_init_geos(struct iwl_priv *priv);
void iwl4965_free_geos(struct iwl_priv *priv); void iwl4965_free_geos(struct iwl_priv *priv);
extern const u8 iwl4965_broadcast_addr[ETH_ALEN]; extern const u8 iwl4965_broadcast_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 * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
...@@ -718,7 +715,7 @@ extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, ...@@ -718,7 +715,7 @@ extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl4965_frame *frame, u8 rate); struct iwl4965_frame *frame, u8 rate);
extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv); extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv);
extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
struct iwl4965_cmd *cmd, struct iwl_cmd *cmd,
struct ieee80211_tx_control *ctrl, struct ieee80211_tx_control *ctrl,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
int sta_id, int tx_id); int sta_id, int tx_id);
......
...@@ -63,6 +63,13 @@ ...@@ -63,6 +63,13 @@
#ifndef __iwl_core_h__ #ifndef __iwl_core_h__
#define __iwl_core_h__ #define __iwl_core_h__
/************************
* forward declarations *
************************/
struct iwl_host_cmd;
struct iwl_cmd;
#define IWLWIFI_VERSION "1.2.26k" #define IWLWIFI_VERSION "1.2.26k"
#define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation" #define DRV_COPYRIGHT "Copyright(c) 2003-2008 Intel Corporation"
...@@ -75,6 +82,10 @@ ...@@ -75,6 +82,10 @@
#define IWL_SKU_A 0x2 #define IWL_SKU_A 0x2
#define IWL_SKU_N 0x8 #define IWL_SKU_N 0x8
struct iwl_hcmd_utils_ops {
int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
};
struct iwl_lib_ops { struct iwl_lib_ops {
/* iwlwifi driver (priv) init */ /* iwlwifi driver (priv) init */
int (*init_drv)(struct iwl_priv *priv); int (*init_drv)(struct iwl_priv *priv);
...@@ -84,6 +95,7 @@ struct iwl_lib_ops { ...@@ -84,6 +95,7 @@ struct iwl_lib_ops {
struct iwl_ops { struct iwl_ops {
const struct iwl_lib_ops *lib; const struct iwl_lib_ops *lib;
const struct iwl_hcmd_utils_ops *utils;
}; };
struct iwl_mod_params { struct iwl_mod_params {
...@@ -120,4 +132,18 @@ int iwlcore_set_rxon_channel(struct iwl_priv *priv, ...@@ -120,4 +132,18 @@ int iwlcore_set_rxon_channel(struct iwl_priv *priv,
int iwl_setup(struct iwl_priv *priv); int iwl_setup(struct iwl_priv *priv);
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/
const char *get_cmd_string(u8 cmd);
int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data);
int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
const void *data,
int (*callback)(struct iwl_priv *priv,
struct iwl_cmd *cmd,
struct sk_buff *skb));
#endif /* __iwl_core_h__ */ #endif /* __iwl_core_h__ */
/******************************************************************************
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
* USA
*
* The full GNU General Public License is included in this distribution
* in the file called LICENSE.GPL.
*
* Contact Information:
* Tomas Winkler <tomas.winkler@intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <net/mac80211.h>
#include "iwl-4965.h" /* FIXME: remove */
#include "iwl-debug.h"
#include "iwl-eeprom.h"
#include "iwl-core.h"
#define IWL_CMD(x) case x : return #x
const char *get_cmd_string(u8 cmd)
{
switch (cmd) {
IWL_CMD(REPLY_ALIVE);
IWL_CMD(REPLY_ERROR);
IWL_CMD(REPLY_RXON);
IWL_CMD(REPLY_RXON_ASSOC);
IWL_CMD(REPLY_QOS_PARAM);
IWL_CMD(REPLY_RXON_TIMING);
IWL_CMD(REPLY_ADD_STA);
IWL_CMD(REPLY_REMOVE_STA);
IWL_CMD(REPLY_REMOVE_ALL_STA);
IWL_CMD(REPLY_TX);
IWL_CMD(REPLY_RATE_SCALE);
IWL_CMD(REPLY_LEDS_CMD);
IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
IWL_CMD(RADAR_NOTIFICATION);
IWL_CMD(REPLY_QUIET_CMD);
IWL_CMD(REPLY_CHANNEL_SWITCH);
IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
IWL_CMD(POWER_TABLE_CMD);
IWL_CMD(PM_SLEEP_NOTIFICATION);
IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
IWL_CMD(REPLY_SCAN_CMD);
IWL_CMD(REPLY_SCAN_ABORT_CMD);
IWL_CMD(SCAN_START_NOTIFICATION);
IWL_CMD(SCAN_RESULTS_NOTIFICATION);
IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
IWL_CMD(BEACON_NOTIFICATION);
IWL_CMD(REPLY_TX_BEACON);
IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
IWL_CMD(QUIET_NOTIFICATION);
IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
IWL_CMD(MEASURE_ABORT_NOTIFICATION);
IWL_CMD(REPLY_BT_CONFIG);
IWL_CMD(REPLY_STATISTICS_CMD);
IWL_CMD(STATISTICS_NOTIFICATION);
IWL_CMD(REPLY_CARD_STATE_CMD);
IWL_CMD(CARD_STATE_NOTIFICATION);
IWL_CMD(MISSED_BEACONS_NOTIFICATION);
IWL_CMD(REPLY_CT_KILL_CONFIG_CMD);
IWL_CMD(SENSITIVITY_CMD);
IWL_CMD(REPLY_PHY_CALIBRATION_CMD);
IWL_CMD(REPLY_RX_PHY_CMD);
IWL_CMD(REPLY_RX_MPDU_CMD);
IWL_CMD(REPLY_RX);
IWL_CMD(REPLY_COMPRESSED_BA);
default:
return "UNKNOWN";
}
}
EXPORT_SYMBOL(get_cmd_string);
#define HOST_COMPLETE_TIMEOUT (HZ / 2)
static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
int ret;
BUG_ON(!(cmd->meta.flags & CMD_ASYNC));
/* An asynchronous command can not expect an SKB to be set. */
BUG_ON(cmd->meta.flags & CMD_WANT_SKB);
/* An asynchronous command MUST have a callback. */
BUG_ON(!cmd->meta.u.callback);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return -EBUSY;
ret = priv->cfg->ops->utils->enqueue_hcmd(priv, cmd);
if (ret < 0) {
IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
return ret;
}
return 0;
}
int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
int cmd_idx;
int ret;
static atomic_t entry = ATOMIC_INIT(0); /* reentrance protection */
BUG_ON(cmd->meta.flags & CMD_ASYNC);
/* A synchronous command can not have a callback set. */
BUG_ON(cmd->meta.u.callback != NULL);
if (atomic_xchg(&entry, 1)) {
IWL_ERROR("Error sending %s: Already sending a host command\n",
get_cmd_string(cmd->id));
return -EBUSY;
}
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
if (cmd->meta.flags & CMD_WANT_SKB)
cmd->meta.source = &cmd->meta;
cmd_idx = priv->cfg->ops->utils->enqueue_hcmd(priv, cmd);
if (cmd_idx < 0) {
ret = cmd_idx;
IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
get_cmd_string(cmd->id), ret);
goto out;
}
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
!test_bit(STATUS_HCMD_ACTIVE, &priv->status),
HOST_COMPLETE_TIMEOUT);
if (!ret) {
if (test_bit(STATUS_HCMD_ACTIVE, &priv->status)) {
IWL_ERROR("Error sending %s: time out after %dms.\n",
get_cmd_string(cmd->id),
jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
ret = -ETIMEDOUT;
goto cancel;
}
}
if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
IWL_DEBUG_INFO("Command %s aborted: RF KILL Switch\n",
get_cmd_string(cmd->id));
ret = -ECANCELED;
goto fail;
}
if (test_bit(STATUS_FW_ERROR, &priv->status)) {
IWL_DEBUG_INFO("Command %s failed: FW Error\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto fail;
}
if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) {
IWL_ERROR("Error: Response NULL in '%s'\n",
get_cmd_string(cmd->id));
ret = -EIO;
goto out;
}
ret = 0;
goto out;
cancel:
if (cmd->meta.flags & CMD_WANT_SKB) {
struct iwl_cmd *qcmd;
/* Cancel the CMD_WANT_SKB flag for the cmd in the
* TX cmd queue. Otherwise in case the cmd comes
* in later, it will possibly set an invalid
* address (cmd->meta.source). */
qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
qcmd->meta.flags &= ~CMD_WANT_SKB;
}
fail:
if (cmd->meta.u.skb) {
dev_kfree_skb_any(cmd->meta.u.skb);
cmd->meta.u.skb = NULL;
}
out:
atomic_set(&entry, 0);
return ret;
}
EXPORT_SYMBOL(iwl_send_cmd_sync);
int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
{
if (cmd->meta.flags & CMD_ASYNC)
return iwl_send_cmd_async(priv, cmd);
return iwl_send_cmd_sync(priv, cmd);
}
EXPORT_SYMBOL(iwl_send_cmd);
int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data)
{
struct iwl_host_cmd cmd = {
.id = id,
.len = len,
.data = data,
};
return iwl_send_cmd_sync(priv, &cmd);
}
EXPORT_SYMBOL(iwl_send_cmd_pdu);
int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
u8 id, u16 len, const void *data,
int (*callback)(struct iwl_priv *priv,
struct iwl_cmd *cmd,
struct sk_buff *skb))
{
struct iwl_host_cmd cmd = {
.id = id,
.len = len,
.data = data,
};
cmd.meta.flags |= CMD_ASYNC;
cmd.meta.u.callback = callback;
return iwl_send_cmd_async(priv, &cmd);
}
EXPORT_SYMBOL(iwl_send_cmd_pdu_async);
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment