#include "iwl-calib.h"
#include "iwl-sta.h"
+static int iwl4965_send_tx_power(struct iwl_priv *priv);
+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
+
/* module parameters */
static struct iwl_mod_params iwl4965_mod_params = {
.num_of_queues = IWL49_NUM_QUEUES,
}
/* Calculate temperature */
- priv->temperature = iwl4965_get_temperature(priv);
+ priv->temperature = iwl4965_hw_get_temperature(priv);
/* Send pointers to protocol/runtime uCode image ... init code will
* load and launch runtime uCode, which will send us another "Alive"
(rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
}
-int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
-{
- int idx = 0;
-
- /* 4965 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;
-
- /* 4965 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;
-}
-
-/**
- * translate ucode response to mac80211 tx status control values
- */
-void iwl4965_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 = iwl4965_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;
-}
-
/*
* EEPROM handlers
*/
#define REG_RECALIB_PERIOD (60)
-void iwl4965_rf_kill_ct_config(struct iwl_priv *priv)
-{
- struct iwl4965_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);
-}
-
/* Reset differential Rx gains in NIC to prepare for chain noise calibration.
* Called after every association, but this runs only once!
* ... once chain noise is calibrated the first time, it's good forever. */
/* Regardless of if we are assocaited, we must reconfigure the
* TX power since frames can be sent on non-radar channels while
* not associated */
- iwl4965_hw_reg_send_txpower(priv);
+ iwl4965_send_tx_power(priv);
/* Update last_temperature to keep is_calib_needed from running
* when it isn't needed... */
IWL_TX_FIFO_HCCA_2
};
-int iwl4965_alive_notify(struct iwl_priv *priv)
+static int iwl4965_alive_notify(struct iwl_priv *priv)
{
u32 a;
int i = 0;
*
* Called when initializing driver
*/
-int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
+static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
{
if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) ||
cmd, NULL);
return ret;
}
-int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
-{
- IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n");
- return -EINVAL;
-}
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
{
return comp;
}
-static const struct iwl_channel_info *
-iwl4965_get_channel_txpower_info(struct iwl_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- const struct iwl_channel_info *ch_info;
-
- ch_info = iwl_get_channel_info(priv, band, channel);
-
- if (!is_channel_valid(ch_info))
- return NULL;
-
- return ch_info;
-}
-
static s32 iwl4965_get_tx_atten_grp(u16 channel)
{
if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH &&
s32 factory_actual_pwr[2];
s32 power_index;
- /* Sanity check requested level (dBm) */
- if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) {
- IWL_WARNING("Requested user TXPOWER %d below limit.\n",
- priv->user_txpower_limit);
- return -EINVAL;
- }
- if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) {
- IWL_WARNING("Requested user TXPOWER %d above limit.\n",
- priv->user_txpower_limit);
- return -EINVAL;
- }
-
/* user_txpower_limit is in dBm, convert to half-dBm (half-dB units
* are used for indexing into txpower table) */
- user_target_power = 2 * priv->user_txpower_limit;
+ user_target_power = 2 * priv->tx_power_user_lmt;
/* Get current (RXON) channel, band, width */
- ch_info =
- iwl4965_get_channel_txpower_info(priv, priv->band, channel);
-
IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band,
is_fat);
- if (!ch_info)
+ ch_info = iwl_get_channel_info(priv, priv->band, channel);
+
+ if (!is_channel_valid(ch_info))
return -EINVAL;
/* get txatten group, used to select 1) thermal txpower adjustment
}
/**
- * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit
+ * iwl4965_send_tx_power - Configure the TXPOWER level user limit
*
* Uses the active RXON for channel, band, and characteristics (fat, high)
- * The power limit is taken from priv->user_txpower_limit.
+ * The power limit is taken from priv->tx_power_user_lmt.
*/
-int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv)
+static int iwl4965_send_tx_power(struct iwl_priv *priv)
{
struct iwl4965_txpowertable_cmd cmd = { 0 };
int ret;
return le32_to_cpu(s->rb_closed) & 0xFFF;
}
-int iwl4965_hw_get_temperature(struct iwl_priv *priv)
-{
- return priv->temperature;
-}
-
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
struct iwl_frame *frame, u8 rate)
{
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
tx_beacon_cmd->tx.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
+ iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
else
tx_beacon_cmd->tx.rate_n_flags =
- iwl4965_hw_set_rate_n_flags(rate, 0);
+ iwl_hw_set_rate_n_flags(rate, 0);
tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
}
/**
- * iwl4965_get_temperature - return the calibrated temperature (in Kelvin)
+ * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
* @statistics: Provides the temperature reading from the uCode
*
* A return of <0 indicates bogus data in the statistics
*/
-int iwl4965_get_temperature(const struct iwl_priv *priv)
+static int iwl4965_hw_get_temperature(const struct iwl_priv *priv)
{
s32 temperature;
s32 vt;
vt = sign_extend(
le32_to_cpu(priv->statistics.general.temperature), 23);
- IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n",
- R1, R2, R3, vt);
+ IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
if (R3 == R1) {
IWL_ERROR("Calibration conflict R1 == R3\n");
* Add offset to center the adjustment around 0 degrees Centigrade. */
temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
temperature /= (R3 - R1);
- temperature = (temperature * 97) / 100 +
- TEMPERATURE_CALIB_KELVIN_OFFSET;
+ temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
- IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", temperature,
- KELVIN_TO_CELSIUS(temperature));
+ IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n",
+ temperature, KELVIN_TO_CELSIUS(temperature));
return temperature;
}
if (!change)
return;
- temp = iwl4965_get_temperature(priv);
+ temp = iwl4965_hw_get_temperature(priv);
if (temp < 0)
return;
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;
return;
/* MAC header */
- fc = le16_to_cpu(header->frame_control);
+ fc = header->frame_control;
seq_ctl = le16_to_cpu(header->seq_ctrl);
/* metadata */
/* 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 */
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)) {
else
title = "Frame";
- rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym);
+ rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
if (unlikely(rate_idx == -1))
bitrate = 0;
else
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, bitrate);
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);
rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
rx_status.rate_idx =
- iwl4965_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
+ iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
if (rx_status.band == IEEE80211_BAND_5GHZ)
rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
info->flags |= IEEE80211_TX_STAT_AMPDU;
info->status.ampdu_ack_map = successes;
info->status.ampdu_ack_len = agg->frame_count;
- iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
+ iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
static inline u32 iwl4965_get_scd_ssn(struct iwl4965_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(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
}
/**
*/
static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
struct iwl_ht_agg *agg,
- struct iwl4965_tx_resp_agg *tx_resp,
- u16 start_idx)
+ struct iwl4965_tx_resp *tx_resp,
+ int txq_id, u16 start_idx)
{
u16 status;
- struct agg_tx_status *frame_status = &tx_resp->status;
+ struct agg_tx_status *frame_status = tx_resp->u.agg_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)
IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n");
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",
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 {
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);
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct ieee80211_tx_info *info;
struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
- u32 status = le32_to_cpu(tx_resp->status);
+ u32 status = le32_to_cpu(tx_resp->u.status);
int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION;
- u16 fc;
+ __le16 fc;
struct ieee80211_hdr *hdr;
u8 *qc = NULL;
memset(&info->status, 0, sizeof(info->status));
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));
+ fc = hdr->frame_control;
+ if (ieee80211_is_data_qos(fc)) {
+ qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
}
agg = &priv->stations[sta_id].tid[tid].agg;
- iwl4965_tx_status_reply_tx(priv, agg,
- (struct iwl4965_tx_resp_agg *)tx_resp, index);
+ iwl4965_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 */
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,
+ iwl_hwrate_to_tx_control(priv,
le32_to_cpu(tx_resp->rate_n_flags),
info);
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)
.check_version = iwl4965_eeprom_check_version,
.query_addr = iwlcore_eeprom_query_addr,
},
- .radio_kill_sw = iwl4965_radio_kill_sw,
.set_power = iwl4965_set_power,
+ .send_tx_power = iwl4965_send_tx_power,
.update_chain_flags = iwl4965_update_chain_flags,
};