Merge branch 'wireless-next-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6
This commit is contained in:
commit
a2c9fc971d
|
@ -129,8 +129,8 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
|
|||
priv->cfg->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
|
||||
|
||||
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
|
||||
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
|
||||
|
@ -226,6 +226,8 @@ static struct iwl_lib_ops iwl1000_lib = {
|
|||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl1000_ops = {
|
||||
|
|
|
@ -179,8 +179,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
|
|||
priv->cfg->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
|
||||
|
||||
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
|
||||
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
|
||||
|
@ -226,8 +226,8 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
|
|||
priv->cfg->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
|
||||
|
||||
priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
|
||||
priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
|
||||
|
@ -402,6 +402,8 @@ static struct iwl_lib_ops iwl5000_lib = {
|
|||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl5150_lib = {
|
||||
|
@ -465,6 +467,8 @@ static struct iwl_lib_ops iwl5150_lib = {
|
|||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl5000_ops = {
|
||||
|
|
|
@ -160,8 +160,8 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
|
|||
priv->cfg->num_of_queues *
|
||||
sizeof(struct iwlagn_scd_bc_tbl);
|
||||
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
|
||||
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
|
||||
priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
|
||||
priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID;
|
||||
|
||||
priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
|
||||
priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
|
||||
|
@ -327,6 +327,8 @@ static struct iwl_lib_ops iwl6000_lib = {
|
|||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
.check_ack_health = iwl_good_ack_health,
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl6000_ops = {
|
||||
|
|
|
@ -409,10 +409,50 @@ static int iwl_sens_auto_corr_ofdm(struct iwl_priv *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_prepare_legacy_sensitivity_tbl(struct iwl_priv *priv,
|
||||
struct iwl_sensitivity_data *data,
|
||||
__le16 *tbl)
|
||||
{
|
||||
tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm);
|
||||
tbl[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
|
||||
tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm_x1);
|
||||
tbl[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
|
||||
|
||||
tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_cck);
|
||||
tbl[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_cck_mrc);
|
||||
|
||||
tbl[HD_MIN_ENERGY_CCK_DET_INDEX] =
|
||||
cpu_to_le16((u16)data->nrg_th_cck);
|
||||
tbl[HD_MIN_ENERGY_OFDM_DET_INDEX] =
|
||||
cpu_to_le16((u16)data->nrg_th_ofdm);
|
||||
|
||||
tbl[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16(data->barker_corr_th_min);
|
||||
tbl[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16(data->barker_corr_th_min_mrc);
|
||||
tbl[HD_OFDM_ENERGY_TH_IN_INDEX] =
|
||||
cpu_to_le16(data->nrg_th_cca);
|
||||
|
||||
IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
|
||||
data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
|
||||
data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
|
||||
data->nrg_th_ofdm);
|
||||
|
||||
IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
|
||||
data->auto_corr_cck, data->auto_corr_cck_mrc,
|
||||
data->nrg_th_cck);
|
||||
}
|
||||
|
||||
/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
|
||||
static int iwl_sensitivity_write(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_sensitivity_cmd cmd ;
|
||||
struct iwl_sensitivity_cmd cmd;
|
||||
struct iwl_sensitivity_data *data = NULL;
|
||||
struct iwl_host_cmd cmd_out = {
|
||||
.id = SENSITIVITY_CMD,
|
||||
|
@ -425,40 +465,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
|
|||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm);
|
||||
cmd.table[HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm_mrc);
|
||||
cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm_x1);
|
||||
cmd.table[HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_ofdm_mrc_x1);
|
||||
|
||||
cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_cck);
|
||||
cmd.table[HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16((u16)data->auto_corr_cck_mrc);
|
||||
|
||||
cmd.table[HD_MIN_ENERGY_CCK_DET_INDEX] =
|
||||
cpu_to_le16((u16)data->nrg_th_cck);
|
||||
cmd.table[HD_MIN_ENERGY_OFDM_DET_INDEX] =
|
||||
cpu_to_le16((u16)data->nrg_th_ofdm);
|
||||
|
||||
cmd.table[HD_BARKER_CORR_TH_ADD_MIN_INDEX] =
|
||||
cpu_to_le16(data->barker_corr_th_min);
|
||||
cmd.table[HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX] =
|
||||
cpu_to_le16(data->barker_corr_th_min_mrc);
|
||||
cmd.table[HD_OFDM_ENERGY_TH_IN_INDEX] =
|
||||
cpu_to_le16(data->nrg_th_cca);
|
||||
|
||||
IWL_DEBUG_CALIB(priv, "ofdm: ac %u mrc %u x1 %u mrc_x1 %u thresh %u\n",
|
||||
data->auto_corr_ofdm, data->auto_corr_ofdm_mrc,
|
||||
data->auto_corr_ofdm_x1, data->auto_corr_ofdm_mrc_x1,
|
||||
data->nrg_th_ofdm);
|
||||
|
||||
IWL_DEBUG_CALIB(priv, "cck: ac %u mrc %u thresh %u\n",
|
||||
data->auto_corr_cck, data->auto_corr_cck_mrc,
|
||||
data->nrg_th_cck);
|
||||
iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.table[0]);
|
||||
|
||||
/* Update uCode's "work" table, and copy it to DSP */
|
||||
cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
|
||||
|
@ -477,6 +484,70 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
|
|||
return iwl_send_cmd(priv, &cmd_out);
|
||||
}
|
||||
|
||||
/* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */
|
||||
static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_enhance_sensitivity_cmd cmd;
|
||||
struct iwl_sensitivity_data *data = NULL;
|
||||
struct iwl_host_cmd cmd_out = {
|
||||
.id = SENSITIVITY_CMD,
|
||||
.len = sizeof(struct iwl_enhance_sensitivity_cmd),
|
||||
.flags = CMD_ASYNC,
|
||||
.data = &cmd,
|
||||
};
|
||||
|
||||
data = &(priv->sensitivity_data);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
|
||||
|
||||
cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
|
||||
HD_INA_NON_SQUARE_DET_OFDM_DATA;
|
||||
cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
|
||||
HD_INA_NON_SQUARE_DET_CCK_DATA;
|
||||
cmd.enhance_table[HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX] =
|
||||
HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA;
|
||||
cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
|
||||
HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA;
|
||||
cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
|
||||
HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
|
||||
cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX] =
|
||||
HD_OFDM_NON_SQUARE_DET_SLOPE_DATA;
|
||||
cmd.enhance_table[HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX] =
|
||||
HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA;
|
||||
cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX] =
|
||||
HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA;
|
||||
cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX] =
|
||||
HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA;
|
||||
cmd.enhance_table[HD_CCK_NON_SQUARE_DET_SLOPE_INDEX] =
|
||||
HD_CCK_NON_SQUARE_DET_SLOPE_DATA;
|
||||
cmd.enhance_table[HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX] =
|
||||
HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA;
|
||||
|
||||
/* Update uCode's "work" table, and copy it to DSP */
|
||||
cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE;
|
||||
|
||||
/* Don't send command to uCode if nothing has changed */
|
||||
if (!memcmp(&cmd.enhance_table[0], &(priv->sensitivity_tbl[0]),
|
||||
sizeof(u16)*HD_TABLE_SIZE) &&
|
||||
!memcmp(&cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX],
|
||||
&(priv->enhance_sensitivity_tbl[0]),
|
||||
sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES)) {
|
||||
IWL_DEBUG_CALIB(priv, "No change in SENSITIVITY_CMD\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy table for comparison next time */
|
||||
memcpy(&(priv->sensitivity_tbl[0]), &(cmd.enhance_table[0]),
|
||||
sizeof(u16)*HD_TABLE_SIZE);
|
||||
memcpy(&(priv->enhance_sensitivity_tbl[0]),
|
||||
&(cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX]),
|
||||
sizeof(u16)*ENHANCE_HD_TABLE_ENTRIES);
|
||||
|
||||
return iwl_send_cmd(priv, &cmd_out);
|
||||
}
|
||||
|
||||
void iwl_init_sensitivity(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -527,7 +598,10 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
|
|||
data->last_bad_plcp_cnt_cck = 0;
|
||||
data->last_fa_cnt_cck = 0;
|
||||
|
||||
ret |= iwl_sensitivity_write(priv);
|
||||
if (priv->enhance_sensitivity_table)
|
||||
ret |= iwl_enhance_sensitivity_write(priv);
|
||||
else
|
||||
ret |= iwl_sensitivity_write(priv);
|
||||
IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
|
||||
}
|
||||
|
||||
|
@ -633,7 +707,10 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
|
|||
|
||||
iwl_sens_auto_corr_ofdm(priv, norm_fa_ofdm, rx_enable_time);
|
||||
iwl_sens_energy_cck(priv, norm_fa_cck, rx_enable_time, &statis);
|
||||
iwl_sensitivity_write(priv);
|
||||
if (priv->enhance_sensitivity_table)
|
||||
iwl_enhance_sensitivity_write(priv);
|
||||
else
|
||||
iwl_sensitivity_write(priv);
|
||||
}
|
||||
|
||||
static inline u8 find_first_chain(u8 mask)
|
||||
|
|
|
@ -205,7 +205,9 @@ void iwl_check_abort_status(struct iwl_priv *priv,
|
|||
u8 frame_count, u32 status)
|
||||
{
|
||||
if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
|
||||
IWL_ERR(priv, "TODO: Implement Tx flush command!!!\n");
|
||||
IWL_ERR(priv, "Tx flush command to flush out all frames\n");
|
||||
if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
queue_work(priv->workqueue, &priv->tx_flush);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1435,3 +1437,81 @@ void iwl_free_tfds_in_queue(struct iwl_priv *priv,
|
|||
priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define IWL_FLUSH_WAIT_MS 2000
|
||||
|
||||
int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_tx_queue *txq;
|
||||
struct iwl_queue *q;
|
||||
int cnt;
|
||||
unsigned long now = jiffies;
|
||||
int ret = 0;
|
||||
|
||||
/* waiting for all the tx frames complete might take a while */
|
||||
for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
|
||||
if (cnt == IWL_CMD_QUEUE_NUM)
|
||||
continue;
|
||||
txq = &priv->txq[cnt];
|
||||
q = &txq->q;
|
||||
while (q->read_ptr != q->write_ptr && !time_after(jiffies,
|
||||
now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
|
||||
msleep(1);
|
||||
|
||||
if (q->read_ptr != q->write_ptr) {
|
||||
IWL_ERR(priv, "fail to flush all tx fifo queues\n");
|
||||
ret = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define IWL_TX_QUEUE_MSK 0xfffff
|
||||
|
||||
/**
|
||||
* iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode
|
||||
*
|
||||
* pre-requirements:
|
||||
* 1. acquire mutex before calling
|
||||
* 2. make sure rf is on and not in exit state
|
||||
*/
|
||||
int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
||||
{
|
||||
struct iwl_txfifo_flush_cmd flush_cmd;
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REPLY_TXFIFO_FLUSH,
|
||||
.len = sizeof(struct iwl_txfifo_flush_cmd),
|
||||
.flags = CMD_SYNC,
|
||||
.data = &flush_cmd,
|
||||
};
|
||||
|
||||
might_sleep();
|
||||
|
||||
memset(&flush_cmd, 0, sizeof(flush_cmd));
|
||||
flush_cmd.fifo_control = IWL_TX_FIFO_VO_MSK | IWL_TX_FIFO_VI_MSK |
|
||||
IWL_TX_FIFO_BE_MSK | IWL_TX_FIFO_BK_MSK;
|
||||
if (priv->cfg->sku & IWL_SKU_N)
|
||||
flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
|
||||
flush_cmd.fifo_control);
|
||||
flush_cmd.flush_control = cpu_to_le16(flush_control);
|
||||
|
||||
return iwl_send_cmd(priv, &cmd);
|
||||
}
|
||||
|
||||
void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
||||
{
|
||||
mutex_lock(&priv->mutex);
|
||||
ieee80211_stop_queues(priv->hw);
|
||||
if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
|
||||
IWL_ERR(priv, "flush request fail\n");
|
||||
goto done;
|
||||
}
|
||||
IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
|
||||
iwlagn_wait_tx_queue_empty(priv);
|
||||
done:
|
||||
ieee80211_wake_queues(priv->hw);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
|
|
@ -859,6 +859,24 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_bg_tx_flush(struct work_struct *work)
|
||||
{
|
||||
struct iwl_priv *priv =
|
||||
container_of(work, struct iwl_priv, tx_flush);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
/* do nothing if rf-kill is on */
|
||||
if (!iwl_is_ready_rf(priv))
|
||||
return;
|
||||
|
||||
if (priv->cfg->ops->lib->txfifo_flush) {
|
||||
IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n");
|
||||
iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_setup_rx_handlers - Initialize Rx handler callbacks
|
||||
*
|
||||
|
@ -1806,12 +1824,21 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
|||
const u8 *data;
|
||||
int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
|
||||
u64 alternatives;
|
||||
u32 tlv_len;
|
||||
enum iwl_ucode_tlv_type tlv_type;
|
||||
const u8 *tlv_data;
|
||||
int ret = 0;
|
||||
|
||||
if (len < sizeof(*ucode))
|
||||
if (len < sizeof(*ucode)) {
|
||||
IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC))
|
||||
if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) {
|
||||
IWL_ERR(priv, "invalid uCode magic: 0X%x\n",
|
||||
le32_to_cpu(ucode->magic));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check which alternatives are present, and "downgrade"
|
||||
|
@ -1836,11 +1863,9 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
|||
|
||||
len -= sizeof(*ucode);
|
||||
|
||||
while (len >= sizeof(*tlv)) {
|
||||
u32 tlv_len;
|
||||
enum iwl_ucode_tlv_type tlv_type;
|
||||
while (len >= sizeof(*tlv) && !ret) {
|
||||
u16 tlv_alt;
|
||||
const u8 *tlv_data;
|
||||
u32 fixed_tlv_size = 4;
|
||||
|
||||
len -= sizeof(*tlv);
|
||||
tlv = (void *)data;
|
||||
|
@ -1850,8 +1875,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
|||
tlv_alt = le16_to_cpu(tlv->alternative);
|
||||
tlv_data = tlv->data;
|
||||
|
||||
if (len < tlv_len)
|
||||
if (len < tlv_len) {
|
||||
IWL_ERR(priv, "invalid TLV len: %zd/%u\n",
|
||||
len, tlv_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
len -= ALIGN(tlv_len, 4);
|
||||
data += sizeof(*tlv) + ALIGN(tlv_len, 4);
|
||||
|
||||
|
@ -1885,56 +1913,77 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
|||
pieces->boot_size = tlv_len;
|
||||
break;
|
||||
case IWL_UCODE_TLV_PROBE_MAX_LEN:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
capa->max_probe_length =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
capa->max_probe_length =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
pieces->init_evtlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->init_evtlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
pieces->init_evtlog_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->init_evtlog_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
pieces->init_errlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->init_errlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
pieces->inst_evtlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->inst_evtlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
pieces->inst_evtlog_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->inst_evtlog_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
|
||||
if (tlv_len != 4)
|
||||
return -EINVAL;
|
||||
pieces->inst_errlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->inst_errlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
|
||||
if (tlv_len)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
priv->enhance_sensitivity_table = true;
|
||||
break;
|
||||
default:
|
||||
IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len)
|
||||
return -EINVAL;
|
||||
if (len) {
|
||||
IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
|
||||
iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
|
||||
ret = -EINVAL;
|
||||
} else if (ret) {
|
||||
IWL_ERR(priv, "TLV %d has invalid size: %u\n",
|
||||
tlv_type, tlv_len);
|
||||
iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3614,6 +3663,44 @@ out_exit:
|
|||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
|
||||
static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
/* do not support "flush" */
|
||||
if (!priv->cfg->ops->lib->txfifo_flush)
|
||||
goto done;
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
IWL_DEBUG_TX(priv, "Aborting flush due to device shutdown\n");
|
||||
goto done;
|
||||
}
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
IWL_DEBUG_TX(priv, "Aborting flush due to RF Kill\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* mac80211 will not push any more frames for transmit
|
||||
* until the flush is completed
|
||||
*/
|
||||
if (drop) {
|
||||
IWL_DEBUG_MAC80211(priv, "send flush command\n");
|
||||
if (priv->cfg->ops->lib->txfifo_flush(priv, IWL_DROP_ALL)) {
|
||||
IWL_ERR(priv, "flush request fail\n");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
|
||||
iwlagn_wait_tx_queue_empty(priv);
|
||||
done:
|
||||
mutex_unlock(&priv->mutex);
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* driver setup and teardown
|
||||
|
@ -3630,6 +3717,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
|||
INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
|
||||
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
|
||||
INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
|
||||
INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
|
||||
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
|
||||
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
|
||||
|
||||
|
@ -3787,6 +3875,7 @@ static struct ieee80211_ops iwl_hw_ops = {
|
|||
.sta_add = iwlagn_mac_sta_add,
|
||||
.sta_remove = iwl_mac_sta_remove,
|
||||
.channel_switch = iwl_mac_channel_switch,
|
||||
.flush = iwl_mac_flush,
|
||||
};
|
||||
|
||||
static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
|
|
@ -147,6 +147,9 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv,
|
|||
void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
|
||||
int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
|
||||
int iwlagn_hw_nic_init(struct iwl_priv *priv);
|
||||
int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
|
||||
int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
|
||||
void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
|
||||
|
||||
/* rx */
|
||||
void iwlagn_rx_queue_restock(struct iwl_priv *priv);
|
||||
|
|
|
@ -97,6 +97,7 @@ enum {
|
|||
REPLY_ADD_STA = 0x18,
|
||||
REPLY_REMOVE_STA = 0x19,
|
||||
REPLY_REMOVE_ALL_STA = 0x1a, /* not used */
|
||||
REPLY_TXFIFO_FLUSH = 0x1e,
|
||||
|
||||
/* Security */
|
||||
REPLY_WEPKEY = 0x20,
|
||||
|
@ -957,8 +958,8 @@ struct iwl_qosparam_cmd {
|
|||
#define IWL3945_STATION_COUNT 25
|
||||
#define IWL4965_BROADCAST_ID 31
|
||||
#define IWL4965_STATION_COUNT 32
|
||||
#define IWL5000_BROADCAST_ID 15
|
||||
#define IWL5000_STATION_COUNT 16
|
||||
#define IWLAGN_BROADCAST_ID 15
|
||||
#define IWLAGN_STATION_COUNT 16
|
||||
|
||||
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
|
||||
#define IWL_INVALID_STATION 255
|
||||
|
@ -1209,6 +1210,43 @@ struct iwl_rem_sta_cmd {
|
|||
u8 reserved2[2];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define IWL_TX_FIFO_BK_MSK cpu_to_le32(BIT(0))
|
||||
#define IWL_TX_FIFO_BE_MSK cpu_to_le32(BIT(1))
|
||||
#define IWL_TX_FIFO_VI_MSK cpu_to_le32(BIT(2))
|
||||
#define IWL_TX_FIFO_VO_MSK cpu_to_le32(BIT(3))
|
||||
#define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00)
|
||||
|
||||
#define IWL_DROP_SINGLE 0
|
||||
#define IWL_DROP_SELECTED 1
|
||||
#define IWL_DROP_ALL 2
|
||||
|
||||
/*
|
||||
* REPLY_TXFIFO_FLUSH = 0x1e(command and response)
|
||||
*
|
||||
* When using full FIFO flush this command checks the scheduler HW block WR/RD
|
||||
* pointers to check if all the frames were transferred by DMA into the
|
||||
* relevant TX FIFO queue. Only when the DMA is finished and the queue is
|
||||
* empty the command can finish.
|
||||
* This command is used to flush the TXFIFO from transmit commands, it may
|
||||
* operate on single or multiple queues, the command queue can't be flushed by
|
||||
* this command. The command response is returned when all the queue flush
|
||||
* operations are done. Each TX command flushed return response with the FLUSH
|
||||
* status set in the TX response status. When FIFO flush operation is used,
|
||||
* the flush operation ends when both the scheduler DMA done and TXFIFO empty
|
||||
* are set.
|
||||
*
|
||||
* @fifo_control: bit mask for which queues to flush
|
||||
* @flush_control: flush controls
|
||||
* 0: Dump single MSDU
|
||||
* 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable.
|
||||
* 2: Dump all FIFO
|
||||
*/
|
||||
struct iwl_txfifo_flush_cmd {
|
||||
__le32 fifo_control;
|
||||
__le16 flush_control;
|
||||
__le16 reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* REPLY_WEP_KEY = 0x20
|
||||
*/
|
||||
|
@ -3452,6 +3490,41 @@ struct iwl_missed_beacon_notif {
|
|||
#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9)
|
||||
#define HD_OFDM_ENERGY_TH_IN_INDEX (10)
|
||||
|
||||
/*
|
||||
* Additional table entries in enhance SENSITIVITY_CMD
|
||||
*/
|
||||
#define HD_INA_NON_SQUARE_DET_OFDM_INDEX (11)
|
||||
#define HD_INA_NON_SQUARE_DET_CCK_INDEX (12)
|
||||
#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_INDEX (13)
|
||||
#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_INDEX (14)
|
||||
#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (15)
|
||||
#define HD_OFDM_NON_SQUARE_DET_SLOPE_INDEX (16)
|
||||
#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_INDEX (17)
|
||||
#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_INDEX (18)
|
||||
#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_INDEX (19)
|
||||
#define HD_CCK_NON_SQUARE_DET_SLOPE_INDEX (20)
|
||||
#define HD_CCK_NON_SQUARE_DET_INTERCEPT_INDEX (21)
|
||||
#define HD_RESERVED (22)
|
||||
|
||||
/* number of entries for enhanced tbl */
|
||||
#define ENHANCE_HD_TABLE_SIZE (23)
|
||||
|
||||
/* number of additional entries for enhanced tbl */
|
||||
#define ENHANCE_HD_TABLE_ENTRIES (ENHANCE_HD_TABLE_SIZE - HD_TABLE_SIZE)
|
||||
|
||||
#define HD_INA_NON_SQUARE_DET_OFDM_DATA cpu_to_le16(0)
|
||||
#define HD_INA_NON_SQUARE_DET_CCK_DATA cpu_to_le16(0)
|
||||
#define HD_CORR_11_INSTEAD_OF_CORR_9_EN_DATA cpu_to_le16(0)
|
||||
#define HD_OFDM_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(668)
|
||||
#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4)
|
||||
#define HD_OFDM_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(486)
|
||||
#define HD_OFDM_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(37)
|
||||
#define HD_CCK_NON_SQUARE_DET_SLOPE_MRC_DATA cpu_to_le16(853)
|
||||
#define HD_CCK_NON_SQUARE_DET_INTERCEPT_MRC_DATA cpu_to_le16(4)
|
||||
#define HD_CCK_NON_SQUARE_DET_SLOPE_DATA cpu_to_le16(476)
|
||||
#define HD_CCK_NON_SQUARE_DET_INTERCEPT_DATA cpu_to_le16(99)
|
||||
|
||||
|
||||
/* Control field in struct iwl_sensitivity_cmd */
|
||||
#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE cpu_to_le16(0)
|
||||
#define SENSITIVITY_CMD_CONTROL_WORK_TABLE cpu_to_le16(1)
|
||||
|
@ -3468,6 +3541,14 @@ struct iwl_sensitivity_cmd {
|
|||
__le16 table[HD_TABLE_SIZE]; /* use HD_* as index */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
struct iwl_enhance_sensitivity_cmd {
|
||||
__le16 control; /* always use "1" */
|
||||
__le16 enhance_table[ENHANCE_HD_TABLE_SIZE]; /* use HD_* as index */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/**
|
||||
* REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response)
|
||||
|
|
|
@ -2627,7 +2627,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
|
|||
}
|
||||
|
||||
|
||||
int iwl_force_reset(struct iwl_priv *priv, int mode)
|
||||
int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
|
||||
{
|
||||
struct iwl_force_reset *force_reset;
|
||||
|
||||
|
@ -2640,12 +2640,14 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
|
|||
}
|
||||
force_reset = &priv->force_reset[mode];
|
||||
force_reset->reset_request_count++;
|
||||
if (force_reset->last_force_reset_jiffies &&
|
||||
time_after(force_reset->last_force_reset_jiffies +
|
||||
force_reset->reset_duration, jiffies)) {
|
||||
IWL_DEBUG_INFO(priv, "force reset rejected\n");
|
||||
force_reset->reset_reject_count++;
|
||||
return -EAGAIN;
|
||||
if (!external) {
|
||||
if (force_reset->last_force_reset_jiffies &&
|
||||
time_after(force_reset->last_force_reset_jiffies +
|
||||
force_reset->reset_duration, jiffies)) {
|
||||
IWL_DEBUG_INFO(priv, "force reset rejected\n");
|
||||
force_reset->reset_reject_count++;
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
force_reset->reset_success_count++;
|
||||
force_reset->last_force_reset_jiffies = jiffies;
|
||||
|
@ -2655,6 +2657,19 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
|
|||
iwl_force_rf_reset(priv);
|
||||
break;
|
||||
case IWL_FW_RESET:
|
||||
/*
|
||||
* if the request is from external(ex: debugfs),
|
||||
* then always perform the request in regardless the module
|
||||
* parameter setting
|
||||
* if the request is from internal (uCode error or driver
|
||||
* detect failure), then fw_restart module parameter
|
||||
* need to be check before performing firmware reload
|
||||
*/
|
||||
if (!external && !priv->cfg->mod_params->restart_fw) {
|
||||
IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
|
||||
"module parameter setting\n");
|
||||
break;
|
||||
}
|
||||
IWL_ERR(priv, "On demand firmware reload\n");
|
||||
/* Set the FW error flag -- cleared on iwl_down */
|
||||
set_bit(STATUS_FW_ERROR, &priv->status);
|
||||
|
@ -2713,7 +2728,7 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
|
|||
"queue %d stuck %d time. Fw reload.\n",
|
||||
q->id, q->repeat_same_read_ptr);
|
||||
q->repeat_same_read_ptr = 0;
|
||||
iwl_force_reset(priv, IWL_FW_RESET);
|
||||
iwl_force_reset(priv, IWL_FW_RESET, false);
|
||||
} else {
|
||||
q->repeat_same_read_ptr++;
|
||||
IWL_DEBUG_RADIO(priv,
|
||||
|
|
|
@ -205,6 +205,9 @@ struct iwl_lib_ops {
|
|||
/* check for ack health */
|
||||
bool (*check_ack_health)(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt);
|
||||
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
|
||||
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
|
||||
|
||||
struct iwl_debugfs_ops debugfs_ops;
|
||||
};
|
||||
|
||||
|
@ -525,7 +528,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
|
|||
struct cfg80211_scan_request *req);
|
||||
void iwl_bg_start_internal_scan(struct work_struct *work);
|
||||
void iwl_internal_short_hw_scan(struct iwl_priv *priv);
|
||||
int iwl_force_reset(struct iwl_priv *priv, int mode);
|
||||
int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
|
||||
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
|
||||
const u8 *ta, const u8 *ie, int ie_len, int left);
|
||||
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
|
||||
|
|
|
@ -1487,7 +1487,7 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
|
|||
switch (reset) {
|
||||
case IWL_RF_RESET:
|
||||
case IWL_FW_RESET:
|
||||
ret = iwl_force_reset(priv, reset);
|
||||
ret = iwl_force_reset(priv, reset, true);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
@ -1495,6 +1495,30 @@ static ssize_t iwl_dbgfs_force_reset_write(struct file *file,
|
|||
return ret ? ret : count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos) {
|
||||
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
char buf[8];
|
||||
int buf_size;
|
||||
int flush;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buf_size = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, buf_size))
|
||||
return -EFAULT;
|
||||
if (sscanf(buf, "%d", &flush) != 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
return -EFAULT;
|
||||
|
||||
priv->cfg->ops->lib->dev_txfifo_flush(priv, IWL_DROP_ALL);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
DEBUGFS_READ_FILE_OPS(rx_statistics);
|
||||
DEBUGFS_READ_FILE_OPS(tx_statistics);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
|
||||
|
@ -1516,6 +1540,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
|
|||
DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
|
||||
DEBUGFS_READ_FILE_OPS(rxon_flags);
|
||||
DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
|
||||
DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
|
||||
|
||||
/*
|
||||
* Create the debugfs files and directories
|
||||
|
@ -1574,6 +1599,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
|||
DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
|
||||
if (priv->cfg->ops->lib->dev_txfifo_flush)
|
||||
DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
|
||||
|
||||
if (priv->cfg->sensitivity_calib_by_driver)
|
||||
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
|
||||
|
|
|
@ -570,6 +570,7 @@ enum iwl_ucode_tlv_type {
|
|||
IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11,
|
||||
IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
|
||||
IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
|
||||
IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
|
||||
};
|
||||
|
||||
struct iwl_ucode_tlv {
|
||||
|
@ -1193,7 +1194,9 @@ struct iwl_priv {
|
|||
u8 start_calib;
|
||||
struct iwl_sensitivity_data sensitivity_data;
|
||||
struct iwl_chain_noise_data chain_noise_data;
|
||||
bool enhance_sensitivity_table;
|
||||
__le16 sensitivity_tbl[HD_TABLE_SIZE];
|
||||
__le16 enhance_sensitivity_tbl[ENHANCE_HD_TABLE_ENTRIES];
|
||||
|
||||
struct iwl_ht_config current_ht_config;
|
||||
|
||||
|
@ -1345,6 +1348,7 @@ struct iwl_priv {
|
|||
struct work_struct ct_enter;
|
||||
struct work_struct ct_exit;
|
||||
struct work_struct start_internal_scan;
|
||||
struct work_struct tx_flush;
|
||||
|
||||
struct tasklet_struct irq_tasklet;
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ const char *get_cmd_string(u8 cmd)
|
|||
IWL_CMD(REPLY_ADD_STA);
|
||||
IWL_CMD(REPLY_REMOVE_STA);
|
||||
IWL_CMD(REPLY_REMOVE_ALL_STA);
|
||||
IWL_CMD(REPLY_TXFIFO_FLUSH);
|
||||
IWL_CMD(REPLY_WEPKEY);
|
||||
IWL_CMD(REPLY_3945_RX);
|
||||
IWL_CMD(REPLY_TX);
|
||||
|
|
|
@ -238,7 +238,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
|
|||
*/
|
||||
IWL_ERR(priv, "low ack count detected, "
|
||||
"restart firmware\n");
|
||||
if (!iwl_force_reset(priv, IWL_FW_RESET))
|
||||
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
|
|||
* high plcp error detected
|
||||
* reset Radio
|
||||
*/
|
||||
iwl_force_reset(priv, IWL_RF_RESET);
|
||||
iwl_force_reset(priv, IWL_RF_RESET, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue