From 9ed333e0298c8f12cf7f3b4aec4258e81ef588a0 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:33 -0800 Subject: iwlwifi: fix clear statistics counter command When receive reply statistics command with "clear" mask, just reset the accumulated statistics counters, but not the current statistics counters, so the accumulated statistics counter can provide the correct information. Signed-off-by: Wey-Yi Guy Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 6f36b6e79f5..10db9732745 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -638,8 +638,6 @@ void iwl_reply_statistics(struct iwl_priv *priv, struct iwl_rx_packet *pkt = rxb_addr(rxb); if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) { - memset(&priv->statistics, 0, - sizeof(struct iwl_notif_statistics)); #ifdef CONFIG_IWLWIFI_DEBUG memset(&priv->accum_statistics, 0, sizeof(struct iwl_notif_statistics)); -- cgit v1.2.3 From e3ef2164386a13a37714ec033e30811d052c7999 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:34 -0800 Subject: iwlwifi: format and show statistics counter from uCode To help debug uCode related problem, adding "delta" and "max" information in debugfs statistics counters display. Those information show the delta between two statistics report from uCode, user can monitor the counters for any "un-normal" behavior. Signed-off-by: Wey-Yi Guy Signed-off-by: Jay Sternberg Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 850 ++++++++++++++++++----------- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 + drivers/net/wireless/iwlwifi/iwl-rx.c | 19 +- 3 files changed, 545 insertions(+), 326 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 4a2ac9311ba..2264cbd95a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1081,6 +1081,12 @@ static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, return p; } +static const char ucode_stats_header[] = + "%-32s current acumulative delta max\n"; +static const char ucode_stats_short_format[] = + " %-30s %10u\n"; +static const char ucode_stats_format[] = + " %-30s %10u %10u %10u %10u\n"; static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf, @@ -1089,14 +1095,15 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, struct iwl_priv *priv = file->private_data; int pos = 0; char *buf; - int bufsz = sizeof(struct statistics_rx_phy) * 20 + - sizeof(struct statistics_rx_non_phy) * 20 + - sizeof(struct statistics_rx_ht_phy) * 20 + 400; + int bufsz = sizeof(struct statistics_rx_phy) * 40 + + sizeof(struct statistics_rx_non_phy) * 40 + + sizeof(struct statistics_rx_ht_phy) * 40 + 400; ssize_t ret; - struct statistics_rx_phy *ofdm, *accum_ofdm; - struct statistics_rx_phy *cck, *accum_cck; + struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; + struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; struct statistics_rx_non_phy *general, *accum_general; - struct statistics_rx_ht_phy *ht, *accum_ht; + struct statistics_rx_non_phy *delta_general, *max_general; + struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; if (!iwl_is_alive(priv)) return -EAGAIN; @@ -1129,267 +1136,401 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, accum_cck = &priv->accum_statistics.rx.cck; accum_general = &priv->accum_statistics.rx.general; accum_ht = &priv->accum_statistics.rx.ofdm_ht; + delta_ofdm = &priv->delta_statistics.rx.ofdm; + delta_cck = &priv->delta_statistics.rx.cck; + delta_general = &priv->delta_statistics.rx.general; + delta_ht = &priv->delta_statistics.rx.ofdm_ht; + max_ofdm = &priv->max_delta.rx.ofdm; + max_cck = &priv->max_delta.rx.cck; + max_general = &priv->max_delta.rx.general; + max_ht = &priv->max_delta.rx.ofdm_ht; + pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - "overrun_err:\t\t%u\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header, + "Statistics_Rx - OFDM:"); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), + accum_ofdm->ina_cnt, + delta_ofdm->ina_cnt, max_ofdm->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "fina_cnt:", + le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, + delta_ofdm->fina_cnt, max_ofdm->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "plcp_err:", + le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, + delta_ofdm->plcp_err, max_ofdm->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "crc32_err:", + le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, + delta_ofdm->crc32_err, max_ofdm->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "overrun_err:", le32_to_cpu(ofdm->overrun_err), - accum_ofdm->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - "early_overrun_err:\t%u\t\t\t%u\n", + accum_ofdm->overrun_err, + delta_ofdm->overrun_err, max_ofdm->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "early_overrun_err:", le32_to_cpu(ofdm->early_overrun_err), - accum_ofdm->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", + accum_ofdm->early_overrun_err, + delta_ofdm->early_overrun_err, + max_ofdm->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "crc32_good:", le32_to_cpu(ofdm->crc32_good), - accum_ofdm->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - "false_alarm_cnt:\t%u\t\t\t%u\n", + accum_ofdm->crc32_good, + delta_ofdm->crc32_good, max_ofdm->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "false_alarm_cnt:", le32_to_cpu(ofdm->false_alarm_cnt), - accum_ofdm->false_alarm_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "fina_sync_err_cnt:\t%u\t\t\t%u\n", + accum_ofdm->false_alarm_cnt, + delta_ofdm->false_alarm_cnt, + max_ofdm->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "fina_sync_err_cnt:", le32_to_cpu(ofdm->fina_sync_err_cnt), - accum_ofdm->fina_sync_err_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "sfd_timeout:\t\t%u\t\t\t%u\n", + accum_ofdm->fina_sync_err_cnt, + delta_ofdm->fina_sync_err_cnt, + max_ofdm->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sfd_timeout:", le32_to_cpu(ofdm->sfd_timeout), - accum_ofdm->sfd_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "fina_timeout:\t\t%u\t\t\t%u\n", + accum_ofdm->sfd_timeout, + delta_ofdm->sfd_timeout, + max_ofdm->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "fina_timeout:", le32_to_cpu(ofdm->fina_timeout), - accum_ofdm->fina_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "unresponded_rts:\t%u\t\t\t%u\n", + accum_ofdm->fina_timeout, + delta_ofdm->fina_timeout, + max_ofdm->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "unresponded_rts:", le32_to_cpu(ofdm->unresponded_rts), - accum_ofdm->unresponded_rts); - pos += scnprintf(buf + pos, bufsz - pos, - "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", + accum_ofdm->unresponded_rts, + delta_ofdm->unresponded_rts, + max_ofdm->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "rxe_frame_lmt_ovrun:", le32_to_cpu(ofdm->rxe_frame_limit_overrun), - accum_ofdm->rxe_frame_limit_overrun); - pos += scnprintf(buf + pos, bufsz - pos, - "sent_ack_cnt:\t\t%u\t\t\t%u\n", + accum_ofdm->rxe_frame_limit_overrun, + delta_ofdm->rxe_frame_limit_overrun, + max_ofdm->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sent_ack_cnt:", le32_to_cpu(ofdm->sent_ack_cnt), - accum_ofdm->sent_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "sent_cts_cnt:\t\t%u\t\t\t%u\n", + accum_ofdm->sent_ack_cnt, + delta_ofdm->sent_ack_cnt, + max_ofdm->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sent_cts_cnt:", le32_to_cpu(ofdm->sent_cts_cnt), - accum_ofdm->sent_cts_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", + accum_ofdm->sent_cts_cnt, + delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sent_ba_rsp_cnt:", le32_to_cpu(ofdm->sent_ba_rsp_cnt), - accum_ofdm->sent_ba_rsp_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "dsp_self_kill:\t\t%u\t\t\t%u\n", + accum_ofdm->sent_ba_rsp_cnt, + delta_ofdm->sent_ba_rsp_cnt, + max_ofdm->sent_ba_rsp_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "dsp_self_kill:", le32_to_cpu(ofdm->dsp_self_kill), - accum_ofdm->dsp_self_kill); - pos += scnprintf(buf + pos, bufsz - pos, - "mh_format_err:\t\t%u\t\t\t%u\n", + accum_ofdm->dsp_self_kill, + delta_ofdm->dsp_self_kill, + max_ofdm->dsp_self_kill); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "mh_format_err:", le32_to_cpu(ofdm->mh_format_err), - accum_ofdm->mh_format_err); - pos += scnprintf(buf + pos, bufsz - pos, - "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", + accum_ofdm->mh_format_err, + delta_ofdm->mh_format_err, + max_ofdm->mh_format_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "re_acq_main_rssi_sum:", le32_to_cpu(ofdm->re_acq_main_rssi_sum), - accum_ofdm->re_acq_main_rssi_sum); - - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); - pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - "overrun_err:\t\t%u\t\t\t%u\n", + accum_ofdm->re_acq_main_rssi_sum, + delta_ofdm->re_acq_main_rssi_sum, + max_ofdm->re_acq_main_rssi_sum); + + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header, + "Statistics_Rx - CCK:"); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "ina_cnt:", + le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, + delta_cck->ina_cnt, max_cck->ina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "fina_cnt:", + le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, + delta_cck->fina_cnt, max_cck->fina_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "plcp_err:", + le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, + delta_cck->plcp_err, max_cck->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "crc32_err:", + le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, + delta_cck->crc32_err, max_cck->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "overrun_err:", le32_to_cpu(cck->overrun_err), - accum_cck->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - "early_overrun_err:\t%u\t\t\t%u\n", + accum_cck->overrun_err, + delta_cck->overrun_err, max_cck->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "early_overrun_err:", le32_to_cpu(cck->early_overrun_err), - accum_cck->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", - le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - "false_alarm_cnt:\t%u\t\t\t%u\n", + accum_cck->early_overrun_err, + delta_cck->early_overrun_err, + max_cck->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "crc32_good:", + le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, + delta_cck->crc32_good, + max_cck->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "false_alarm_cnt:", le32_to_cpu(cck->false_alarm_cnt), - accum_cck->false_alarm_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "fina_sync_err_cnt:\t%u\t\t\t%u\n", + accum_cck->false_alarm_cnt, + delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "fina_sync_err_cnt:", le32_to_cpu(cck->fina_sync_err_cnt), - accum_cck->fina_sync_err_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "sfd_timeout:\t\t%u\t\t\t%u\n", + accum_cck->fina_sync_err_cnt, + delta_cck->fina_sync_err_cnt, + max_cck->fina_sync_err_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sfd_timeout:", le32_to_cpu(cck->sfd_timeout), - accum_cck->sfd_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "fina_timeout:\t\t%u\t\t\t%u\n", + accum_cck->sfd_timeout, + delta_cck->sfd_timeout, max_cck->sfd_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "fina_timeout:", le32_to_cpu(cck->fina_timeout), - accum_cck->fina_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "unresponded_rts:\t%u\t\t\t%u\n", + accum_cck->fina_timeout, + delta_cck->fina_timeout, max_cck->fina_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "unresponded_rts:", le32_to_cpu(cck->unresponded_rts), - accum_cck->unresponded_rts); - pos += scnprintf(buf + pos, bufsz - pos, - "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", + accum_cck->unresponded_rts, + delta_cck->unresponded_rts, + max_cck->unresponded_rts); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "rxe_frame_lmt_ovrun:", le32_to_cpu(cck->rxe_frame_limit_overrun), - accum_cck->rxe_frame_limit_overrun); - pos += scnprintf(buf + pos, bufsz - pos, - "sent_ack_cnt:\t\t%u\t\t\t%u\n", + accum_cck->rxe_frame_limit_overrun, + delta_cck->rxe_frame_limit_overrun, + max_cck->rxe_frame_limit_overrun); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sent_ack_cnt:", le32_to_cpu(cck->sent_ack_cnt), - accum_cck->sent_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "sent_cts_cnt:\t\t%u\t\t\t%u\n", + accum_cck->sent_ack_cnt, + delta_cck->sent_ack_cnt, + max_cck->sent_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sent_cts_cnt:", le32_to_cpu(cck->sent_cts_cnt), - accum_cck->sent_cts_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", + accum_cck->sent_cts_cnt, + delta_cck->sent_cts_cnt, + max_cck->sent_cts_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sent_ba_rsp_cnt:", le32_to_cpu(cck->sent_ba_rsp_cnt), - accum_cck->sent_ba_rsp_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "dsp_self_kill:\t\t%u\t\t\t%u\n", + accum_cck->sent_ba_rsp_cnt, + delta_cck->sent_ba_rsp_cnt, + max_cck->sent_ba_rsp_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "dsp_self_kill:", le32_to_cpu(cck->dsp_self_kill), - accum_cck->dsp_self_kill); - pos += scnprintf(buf + pos, bufsz - pos, - "mh_format_err:\t\t%u\t\t\t%u\n", + accum_cck->dsp_self_kill, + delta_cck->dsp_self_kill, + max_cck->dsp_self_kill); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "mh_format_err:", le32_to_cpu(cck->mh_format_err), - accum_cck->mh_format_err); - pos += scnprintf(buf + pos, bufsz - pos, - "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", + accum_cck->mh_format_err, + delta_cck->mh_format_err, max_cck->mh_format_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "re_acq_main_rssi_sum:", le32_to_cpu(cck->re_acq_main_rssi_sum), - accum_cck->re_acq_main_rssi_sum); - - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", + accum_cck->re_acq_main_rssi_sum, + delta_cck->re_acq_main_rssi_sum, + max_cck->re_acq_main_rssi_sum); + + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header, + "Statistics_Rx - GENERAL:"); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "bogus_cts:", le32_to_cpu(general->bogus_cts), - accum_general->bogus_cts); - pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", + accum_general->bogus_cts, + delta_general->bogus_cts, max_general->bogus_cts); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "bogus_ack:", le32_to_cpu(general->bogus_ack), - accum_general->bogus_ack); - pos += scnprintf(buf + pos, bufsz - pos, - "non_bssid_frames:\t%u\t\t\t%u\n", + accum_general->bogus_ack, + delta_general->bogus_ack, max_general->bogus_ack); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "non_bssid_frames:", le32_to_cpu(general->non_bssid_frames), - accum_general->non_bssid_frames); - pos += scnprintf(buf + pos, bufsz - pos, - "filtered_frames:\t%u\t\t\t%u\n", + accum_general->non_bssid_frames, + delta_general->non_bssid_frames, + max_general->non_bssid_frames); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "filtered_frames:", le32_to_cpu(general->filtered_frames), - accum_general->filtered_frames); - pos += scnprintf(buf + pos, bufsz - pos, - "non_channel_beacons:\t%u\t\t\t%u\n", + accum_general->filtered_frames, + delta_general->filtered_frames, + max_general->filtered_frames); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "non_channel_beacons:", le32_to_cpu(general->non_channel_beacons), - accum_general->non_channel_beacons); - pos += scnprintf(buf + pos, bufsz - pos, - "channel_beacons:\t%u\t\t\t%u\n", + accum_general->non_channel_beacons, + delta_general->non_channel_beacons, + max_general->non_channel_beacons); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "channel_beacons:", le32_to_cpu(general->channel_beacons), - accum_general->channel_beacons); - pos += scnprintf(buf + pos, bufsz - pos, - "num_missed_bcon:\t%u\t\t\t%u\n", + accum_general->channel_beacons, + delta_general->channel_beacons, + max_general->channel_beacons); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "num_missed_bcon:", le32_to_cpu(general->num_missed_bcon), - accum_general->num_missed_bcon); - pos += scnprintf(buf + pos, bufsz - pos, - "adc_rx_saturation_time:\t%u\t\t\t%u\n", + accum_general->num_missed_bcon, + delta_general->num_missed_bcon, + max_general->num_missed_bcon); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "adc_rx_saturation_time:", le32_to_cpu(general->adc_rx_saturation_time), - accum_general->adc_rx_saturation_time); - pos += scnprintf(buf + pos, bufsz - pos, - "ina_detect_search_tm:\t%u\t\t\t%u\n", + accum_general->adc_rx_saturation_time, + delta_general->adc_rx_saturation_time, + max_general->adc_rx_saturation_time); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "ina_detect_search_tm:", le32_to_cpu(general->ina_detection_search_time), - accum_general->ina_detection_search_time); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_silence_rssi_a:\t%u\t\t\t%u\n", + accum_general->ina_detection_search_time, + delta_general->ina_detection_search_time, + max_general->ina_detection_search_time); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_silence_rssi_a:", le32_to_cpu(general->beacon_silence_rssi_a), - accum_general->beacon_silence_rssi_a); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_silence_rssi_b:\t%u\t\t\t%u\n", + accum_general->beacon_silence_rssi_a, + delta_general->beacon_silence_rssi_a, + max_general->beacon_silence_rssi_a); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_silence_rssi_b:", le32_to_cpu(general->beacon_silence_rssi_b), - accum_general->beacon_silence_rssi_b); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_silence_rssi_c:\t%u\t\t\t%u\n", + accum_general->beacon_silence_rssi_b, + delta_general->beacon_silence_rssi_b, + max_general->beacon_silence_rssi_b); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_silence_rssi_c:", le32_to_cpu(general->beacon_silence_rssi_c), - accum_general->beacon_silence_rssi_c); - pos += scnprintf(buf + pos, bufsz - pos, - "interference_data_flag:\t%u\t\t\t%u\n", + accum_general->beacon_silence_rssi_c, + delta_general->beacon_silence_rssi_c, + max_general->beacon_silence_rssi_c); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "interference_data_flag:", le32_to_cpu(general->interference_data_flag), - accum_general->interference_data_flag); - pos += scnprintf(buf + pos, bufsz - pos, - "channel_load:\t\t%u\t\t\t%u\n", + accum_general->interference_data_flag, + delta_general->interference_data_flag, + max_general->interference_data_flag); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "channel_load:", le32_to_cpu(general->channel_load), - accum_general->channel_load); - pos += scnprintf(buf + pos, bufsz - pos, - "dsp_false_alarms:\t%u\t\t\t%u\n", + accum_general->channel_load, + delta_general->channel_load, + max_general->channel_load); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "dsp_false_alarms:", le32_to_cpu(general->dsp_false_alarms), - accum_general->dsp_false_alarms); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_rssi_a:\t\t%u\t\t\t%u\n", + accum_general->dsp_false_alarms, + delta_general->dsp_false_alarms, + max_general->dsp_false_alarms); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_rssi_a:", le32_to_cpu(general->beacon_rssi_a), - accum_general->beacon_rssi_a); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_rssi_b:\t\t%u\t\t\t%u\n", + accum_general->beacon_rssi_a, + delta_general->beacon_rssi_a, + max_general->beacon_rssi_a); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_rssi_b:", le32_to_cpu(general->beacon_rssi_b), - accum_general->beacon_rssi_b); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_rssi_c:\t\t%u\t\t\t%u\n", + accum_general->beacon_rssi_b, + delta_general->beacon_rssi_b, + max_general->beacon_rssi_b); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_rssi_c:", le32_to_cpu(general->beacon_rssi_c), - accum_general->beacon_rssi_c); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_energy_a:\t%u\t\t\t%u\n", + accum_general->beacon_rssi_c, + delta_general->beacon_rssi_c, + max_general->beacon_rssi_c); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_energy_a:", le32_to_cpu(general->beacon_energy_a), - accum_general->beacon_energy_a); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_energy_b:\t%u\t\t\t%u\n", + accum_general->beacon_energy_a, + delta_general->beacon_energy_a, + max_general->beacon_energy_a); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_energy_b:", le32_to_cpu(general->beacon_energy_b), - accum_general->beacon_energy_b); - pos += scnprintf(buf + pos, bufsz - pos, - "beacon_energy_c:\t%u\t\t\t%u\n", + accum_general->beacon_energy_b, + delta_general->beacon_energy_b, + max_general->beacon_energy_b); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "beacon_energy_c:", le32_to_cpu(general->beacon_energy_c), - accum_general->beacon_energy_c); + accum_general->beacon_energy_c, + delta_general->beacon_energy_c, + max_general->beacon_energy_c); pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); - pos += scnprintf(buf + pos, bufsz - pos, - "overrun_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, - "early_overrun_err:\t%u\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header, + "Statistics_Rx - OFDM_HT:"); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "plcp_err:", + le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, + delta_ht->plcp_err, max_ht->plcp_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "overrun_err:", + le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, + delta_ht->overrun_err, max_ht->overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "early_overrun_err:", le32_to_cpu(ht->early_overrun_err), - accum_ht->early_overrun_err); - pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", - le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", - le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); - pos += scnprintf(buf + pos, bufsz - pos, - "mh_format_err:\t\t%u\t\t\t%u\n", + accum_ht->early_overrun_err, + delta_ht->early_overrun_err, + max_ht->early_overrun_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "crc32_good:", + le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, + delta_ht->crc32_good, max_ht->crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "crc32_err:", + le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, + delta_ht->crc32_err, max_ht->crc32_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "mh_format_err:", le32_to_cpu(ht->mh_format_err), - accum_ht->mh_format_err); - pos += scnprintf(buf + pos, bufsz - pos, - "agg_crc32_good:\t\t%u\t\t\t%u\n", + accum_ht->mh_format_err, + delta_ht->mh_format_err, max_ht->mh_format_err); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg_crc32_good:", le32_to_cpu(ht->agg_crc32_good), - accum_ht->agg_crc32_good); - pos += scnprintf(buf + pos, bufsz - pos, - "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", + accum_ht->agg_crc32_good, + delta_ht->agg_crc32_good, max_ht->agg_crc32_good); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg_mpdu_cnt:", le32_to_cpu(ht->agg_mpdu_cnt), - accum_ht->agg_mpdu_cnt); - pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", - le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); - pos += scnprintf(buf + pos, bufsz - pos, "unsupport_mcs:\t\t%u\t\t\t%u\n", + accum_ht->agg_mpdu_cnt, + delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg_cnt:", + le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, + delta_ht->agg_cnt, max_ht->agg_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "unsupport_mcs:", le32_to_cpu(ht->unsupport_mcs), - accum_ht->unsupport_mcs); + accum_ht->unsupport_mcs, + delta_ht->unsupport_mcs, max_ht->unsupport_mcs); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -1403,9 +1544,9 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, struct iwl_priv *priv = file->private_data; int pos = 0; char *buf; - int bufsz = (sizeof(struct statistics_tx) * 24) + 250; + int bufsz = (sizeof(struct statistics_tx) * 48) + 250; ssize_t ret; - struct statistics_tx *tx, *accum_tx; + struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; if (!iwl_is_alive(priv)) return -EAGAIN; @@ -1432,106 +1573,148 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, */ tx = &priv->statistics.tx; accum_tx = &priv->accum_statistics.tx; + delta_tx = &priv->delta_statistics.tx; + max_tx = &priv->max_delta.tx; pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header, + "Statistics_Tx:"); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "preamble:", le32_to_cpu(tx->preamble_cnt), - accum_tx->preamble_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "rx_detected_cnt:\t\t%u\t\t\t%u\n", + accum_tx->preamble_cnt, + delta_tx->preamble_cnt, max_tx->preamble_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "rx_detected_cnt:", le32_to_cpu(tx->rx_detected_cnt), - accum_tx->rx_detected_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", + accum_tx->rx_detected_cnt, + delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "bt_prio_defer_cnt:", le32_to_cpu(tx->bt_prio_defer_cnt), - accum_tx->bt_prio_defer_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", + accum_tx->bt_prio_defer_cnt, + delta_tx->bt_prio_defer_cnt, + max_tx->bt_prio_defer_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "bt_prio_kill_cnt:", le32_to_cpu(tx->bt_prio_kill_cnt), - accum_tx->bt_prio_kill_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", + accum_tx->bt_prio_kill_cnt, + delta_tx->bt_prio_kill_cnt, + max_tx->bt_prio_kill_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "few_bytes_cnt:", le32_to_cpu(tx->few_bytes_cnt), - accum_tx->few_bytes_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "cts_timeout:\t\t\t%u\t\t\t%u\n", - le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "ack_timeout:\t\t\t%u\t\t\t%u\n", + accum_tx->few_bytes_cnt, + delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "cts_timeout:", + le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, + delta_tx->cts_timeout, max_tx->cts_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "ack_timeout:", le32_to_cpu(tx->ack_timeout), - accum_tx->ack_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "expected_ack_cnt:\t\t%u\t\t\t%u\n", + accum_tx->ack_timeout, + delta_tx->ack_timeout, max_tx->ack_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "expected_ack_cnt:", le32_to_cpu(tx->expected_ack_cnt), - accum_tx->expected_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", + accum_tx->expected_ack_cnt, + delta_tx->expected_ack_cnt, + max_tx->expected_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "actual_ack_cnt:", le32_to_cpu(tx->actual_ack_cnt), - accum_tx->actual_ack_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", + accum_tx->actual_ack_cnt, + delta_tx->actual_ack_cnt, + max_tx->actual_ack_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "dump_msdu_cnt:", le32_to_cpu(tx->dump_msdu_cnt), - accum_tx->dump_msdu_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "abort_nxt_frame_mismatch:" - "\t%u\t\t\t%u\n", + accum_tx->dump_msdu_cnt, + delta_tx->dump_msdu_cnt, + max_tx->dump_msdu_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "abort_nxt_frame_mismatch:", le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), - accum_tx->burst_abort_next_frame_mismatch_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "abort_missing_nxt_frame:" - "\t%u\t\t\t%u\n", + accum_tx->burst_abort_next_frame_mismatch_cnt, + delta_tx->burst_abort_next_frame_mismatch_cnt, + max_tx->burst_abort_next_frame_mismatch_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "abort_missing_nxt_frame:", le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), - accum_tx->burst_abort_missing_next_frame_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "cts_timeout_collision:\t\t%u\t\t\t%u\n", + accum_tx->burst_abort_missing_next_frame_cnt, + delta_tx->burst_abort_missing_next_frame_cnt, + max_tx->burst_abort_missing_next_frame_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "cts_timeout_collision:", le32_to_cpu(tx->cts_timeout_collision), - accum_tx->cts_timeout_collision); - pos += scnprintf(buf + pos, bufsz - pos, - "ack_ba_timeout_collision:\t%u\t\t\t%u\n", + accum_tx->cts_timeout_collision, + delta_tx->cts_timeout_collision, + max_tx->cts_timeout_collision); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "ack_ba_timeout_collision:", le32_to_cpu(tx->ack_or_ba_timeout_collision), - accum_tx->ack_or_ba_timeout_collision); - pos += scnprintf(buf + pos, bufsz - pos, - "agg ba_timeout:\t\t\t%u\t\t\t%u\n", + accum_tx->ack_or_ba_timeout_collision, + delta_tx->ack_or_ba_timeout_collision, + max_tx->ack_or_ba_timeout_collision); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg ba_timeout:", le32_to_cpu(tx->agg.ba_timeout), - accum_tx->agg.ba_timeout); - pos += scnprintf(buf + pos, bufsz - pos, - "agg ba_resched_frames:\t\t%u\t\t\t%u\n", + accum_tx->agg.ba_timeout, + delta_tx->agg.ba_timeout, + max_tx->agg.ba_timeout); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg ba_resched_frames:", le32_to_cpu(tx->agg.ba_reschedule_frames), - accum_tx->agg.ba_reschedule_frames); - pos += scnprintf(buf + pos, bufsz - pos, - "agg scd_query_agg_frame:\t%u\t\t\t%u\n", + accum_tx->agg.ba_reschedule_frames, + delta_tx->agg.ba_reschedule_frames, + max_tx->agg.ba_reschedule_frames); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg scd_query_agg_frame:", le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), - accum_tx->agg.scd_query_agg_frame_cnt); - pos += scnprintf(buf + pos, bufsz - pos, - "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", + accum_tx->agg.scd_query_agg_frame_cnt, + delta_tx->agg.scd_query_agg_frame_cnt, + max_tx->agg.scd_query_agg_frame_cnt); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg scd_query_no_agg:", le32_to_cpu(tx->agg.scd_query_no_agg), - accum_tx->agg.scd_query_no_agg); - pos += scnprintf(buf + pos, bufsz - pos, - "agg scd_query_agg:\t\t%u\t\t\t%u\n", + accum_tx->agg.scd_query_no_agg, + delta_tx->agg.scd_query_no_agg, + max_tx->agg.scd_query_no_agg); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg scd_query_agg:", le32_to_cpu(tx->agg.scd_query_agg), - accum_tx->agg.scd_query_agg); - pos += scnprintf(buf + pos, bufsz - pos, - "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", + accum_tx->agg.scd_query_agg, + delta_tx->agg.scd_query_agg, + max_tx->agg.scd_query_agg); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg scd_query_mismatch:", le32_to_cpu(tx->agg.scd_query_mismatch), - accum_tx->agg.scd_query_mismatch); - pos += scnprintf(buf + pos, bufsz - pos, - "agg frame_not_ready:\t\t%u\t\t\t%u\n", + accum_tx->agg.scd_query_mismatch, + delta_tx->agg.scd_query_mismatch, + max_tx->agg.scd_query_mismatch); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg frame_not_ready:", le32_to_cpu(tx->agg.frame_not_ready), - accum_tx->agg.frame_not_ready); - pos += scnprintf(buf + pos, bufsz - pos, - "agg underrun:\t\t\t%u\t\t\t%u\n", + accum_tx->agg.frame_not_ready, + delta_tx->agg.frame_not_ready, + max_tx->agg.frame_not_ready); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg underrun:", le32_to_cpu(tx->agg.underrun), - accum_tx->agg.underrun); - pos += scnprintf(buf + pos, bufsz - pos, - "agg bt_prio_kill:\t\t%u\t\t\t%u\n", + accum_tx->agg.underrun, + delta_tx->agg.underrun, max_tx->agg.underrun); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg bt_prio_kill:", le32_to_cpu(tx->agg.bt_prio_kill), - accum_tx->agg.bt_prio_kill); - pos += scnprintf(buf + pos, bufsz - pos, - "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", + accum_tx->agg.bt_prio_kill, + delta_tx->agg.bt_prio_kill, + max_tx->agg.bt_prio_kill); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "agg rx_ba_rsp_cnt:", le32_to_cpu(tx->agg.rx_ba_rsp_cnt), - accum_tx->agg.rx_ba_rsp_cnt); + accum_tx->agg.rx_ba_rsp_cnt, + delta_tx->agg.rx_ba_rsp_cnt, + max_tx->agg.rx_ba_rsp_cnt); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); @@ -1545,11 +1728,12 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, struct iwl_priv *priv = file->private_data; int pos = 0; char *buf; - int bufsz = sizeof(struct statistics_general) * 4 + 250; + int bufsz = sizeof(struct statistics_general) * 8 + 250; ssize_t ret; struct statistics_general *general, *accum_general; - struct statistics_dbg *dbg, *accum_dbg; - struct statistics_div *div, *accum_div; + struct statistics_general *delta_general, *max_general; + struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; + struct statistics_div *div, *accum_div, *delta_div, *max_div; if (!iwl_is_alive(priv)) return -EAGAIN; @@ -1578,52 +1762,72 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, dbg = &priv->statistics.general.dbg; div = &priv->statistics.general.div; accum_general = &priv->accum_statistics.general; + delta_general = &priv->delta_statistics.general; + max_general = &priv->max_delta.general; accum_dbg = &priv->accum_statistics.general.dbg; + delta_dbg = &priv->delta_statistics.general.dbg; + max_dbg = &priv->max_delta.general.dbg; accum_div = &priv->accum_statistics.general.div; + delta_div = &priv->delta_statistics.general.div; + max_div = &priv->max_delta.general.div; pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); - pos += scnprintf(buf + pos, bufsz - pos, - "\t\t\tcurrent\t\t\taccumulative\n"); - pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_header, + "Statistics_General:"); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format, + "temperature:", le32_to_cpu(general->temperature)); - pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_short_format, + "temperature_m:", le32_to_cpu(general->temperature_m)); - pos += scnprintf(buf + pos, bufsz - pos, - "burst_check:\t\t\t%u\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "burst_check:", le32_to_cpu(dbg->burst_check), - accum_dbg->burst_check); - pos += scnprintf(buf + pos, bufsz - pos, - "burst_count:\t\t\t%u\t\t\t%u\n", + accum_dbg->burst_check, + delta_dbg->burst_check, max_dbg->burst_check); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "burst_count:", le32_to_cpu(dbg->burst_count), - accum_dbg->burst_count); - pos += scnprintf(buf + pos, bufsz - pos, - "sleep_time:\t\t\t%u\t\t\t%u\n", + accum_dbg->burst_count, + delta_dbg->burst_count, max_dbg->burst_count); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "sleep_time:", le32_to_cpu(general->sleep_time), - accum_general->sleep_time); - pos += scnprintf(buf + pos, bufsz - pos, - "slots_out:\t\t\t%u\t\t\t%u\n", + accum_general->sleep_time, + delta_general->sleep_time, max_general->sleep_time); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "slots_out:", le32_to_cpu(general->slots_out), - accum_general->slots_out); - pos += scnprintf(buf + pos, bufsz - pos, - "slots_idle:\t\t\t%u\t\t\t%u\n", + accum_general->slots_out, + delta_general->slots_out, max_general->slots_out); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "slots_idle:", le32_to_cpu(general->slots_idle), - accum_general->slots_idle); + accum_general->slots_idle, + delta_general->slots_idle, max_general->slots_idle); pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", le32_to_cpu(general->ttl_timestamp)); - pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", - le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); - pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", - le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); - pos += scnprintf(buf + pos, bufsz - pos, - "exec_time:\t\t\t%u\t\t\t%u\n", - le32_to_cpu(div->exec_time), accum_div->exec_time); - pos += scnprintf(buf + pos, bufsz - pos, - "probe_time:\t\t\t%u\t\t\t%u\n", - le32_to_cpu(div->probe_time), accum_div->probe_time); - pos += scnprintf(buf + pos, bufsz - pos, - "rx_enable_counter:\t\t%u\t\t\t%u\n", + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "tx_on_a:", + le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, + delta_div->tx_on_a, max_div->tx_on_a); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "tx_on_b:", + le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, + delta_div->tx_on_b, max_div->tx_on_b); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "exec_time:", + le32_to_cpu(div->exec_time), accum_div->exec_time, + delta_div->exec_time, max_div->exec_time); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "probe_time:", + le32_to_cpu(div->probe_time), accum_div->probe_time, + delta_div->probe_time, max_div->probe_time); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "rx_enable_counter:", le32_to_cpu(general->rx_enable_counter), - accum_general->rx_enable_counter); + accum_general->rx_enable_counter, + delta_general->rx_enable_counter, + max_general->rx_enable_counter); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 70f0e79c8e4..63e45cd3f63 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1162,6 +1162,8 @@ struct iwl_priv { struct iwl_notif_statistics statistics; #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_notif_statistics accum_statistics; + struct iwl_notif_statistics delta_statistics; + struct iwl_notif_statistics max_delta; #endif /* context information */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 10db9732745..5bbe5f1f749 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -564,15 +564,24 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, int i; __le32 *prev_stats; u32 *accum_stats; + u32 *delta, *max_delta; prev_stats = (__le32 *)&priv->statistics; accum_stats = (u32 *)&priv->accum_statistics; + delta = (u32 *)&priv->delta_statistics; + max_delta = (u32 *)&priv->max_delta; for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics); - i += sizeof(__le32), stats++, prev_stats++, accum_stats++) - if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) - *accum_stats += (le32_to_cpu(*stats) - + i += sizeof(__le32), stats++, prev_stats++, delta++, + max_delta++, accum_stats++) { + if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) { + *delta = (le32_to_cpu(*stats) - le32_to_cpu(*prev_stats)); + *accum_stats += *delta; + if (*delta > *max_delta) + *max_delta = *delta; + } + } /* reset accumulative statistics for "no-counter" type statistics */ priv->accum_statistics.general.temperature = @@ -641,6 +650,10 @@ void iwl_reply_statistics(struct iwl_priv *priv, #ifdef CONFIG_IWLWIFI_DEBUG memset(&priv->accum_statistics, 0, sizeof(struct iwl_notif_statistics)); + memset(&priv->delta_statistics, 0, + sizeof(struct iwl_notif_statistics)); + memset(&priv->max_delta, 0, + sizeof(struct iwl_notif_statistics)); #endif IWL_DEBUG_RX(priv, "Statistics have been cleared\n"); } -- cgit v1.2.3 From 11fc524941248dc717f1af5dfa844eceb7c0217f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:35 -0800 Subject: iwlwifi: add num_of_sos_stats to statistics counter When uCode detects number of beacon missed consecutively above the internal missed beacon threshold (set by uCode), it will reset and re-tune the radio in order to get out of bad PHY state. This "num_of_sos_states" counter monitors number of time uCode encounters this bad condition and has to re-tune the radio. Signed-off-by: Wey-Yi Guy Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 7 ++++++- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 3320cce3d57..8dc34a3d4f7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3095,7 +3095,12 @@ struct statistics_general { __le32 ttl_timestamp; struct statistics_div div; __le32 rx_enable_counter; - __le32 reserved1; + /* + * num_of_sos_states: + * count the number of times we have to re-tune + * in order to get out of bad PHY status + */ + __le32 num_of_sos_states; __le32 reserved2; __le32 reserved3; } __attribute__ ((packed)); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 2264cbd95a0..19c7fab4793 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1728,7 +1728,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, struct iwl_priv *priv = file->private_data; int pos = 0; char *buf; - int bufsz = sizeof(struct statistics_general) * 8 + 250; + int bufsz = sizeof(struct statistics_general) * 10 + 300; ssize_t ret; struct statistics_general *general, *accum_general; struct statistics_general *delta_general, *max_general; @@ -1828,6 +1828,12 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, accum_general->rx_enable_counter, delta_general->rx_enable_counter, max_general->rx_enable_counter); + pos += scnprintf(buf + pos, bufsz - pos, ucode_stats_format, + "num_of_sos_states:", + le32_to_cpu(general->num_of_sos_states), + accum_general->num_of_sos_states, + delta_general->num_of_sos_states, + max_general->num_of_sos_states); ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); return ret; -- cgit v1.2.3 From 937c397eb633b804d9a806d08c395ecfc42b1fec Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:36 -0800 Subject: iwlwifi: correct return code for log_event When dumping event log in debugfs, iwl_dump_nic_event_log() should return the correct error code instead of let the calling function makes it own assumption. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c78063312ea..eaa309d8bee 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1965,7 +1965,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, IWL_ERR(priv, "Invalid event log pointer 0x%08X for %s uCode\n", base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); - return pos; + return -EINVAL; } /* event log header */ @@ -2013,7 +2013,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, bufsz = size * 48; *buf = kmalloc(bufsz, GFP_KERNEL); if (!*buf) - return pos; + return -ENOMEM; } if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { /* diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 19c7fab4793..a7ca06d21d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -429,8 +429,9 @@ static ssize_t iwl_dbgfs_log_event_read(struct file *file, int pos = 0; ssize_t ret = -ENOMEM; - pos = priv->cfg->ops->lib->dump_nic_event_log(priv, true, &buf, true); - if (pos && buf) { + ret = pos = priv->cfg->ops->lib->dump_nic_event_log( + priv, true, &buf, true); + if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); kfree(buf); } diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 10b0aa8024c..8bbcc5487aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1644,7 +1644,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, base = le32_to_cpu(priv->card_alive.log_event_table_ptr); if (!iwl3945_hw_valid_rtc_data_addr(base)) { IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base); - return pos; + return -EINVAL; } /* event log header */ @@ -1693,7 +1693,7 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, bufsz = size * 48; *buf = kmalloc(bufsz, GFP_KERNEL); if (!*buf) - return pos; + return -ENOMEM; } if ((iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) || full_log) { /* if uCode has wrapped back to top of log, -- cgit v1.2.3 From 2be76703a3afb281155894ac52d34f7f5d736633 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:37 -0800 Subject: iwlwifi: set interrupt coalescing timer range and default For interrupt coalescing timer, the CSR_INT_COALESCING is an 8 bit register in 32-usec unit, the range can go from 0x00 - 0xFF. set the range and default timeout value for both calibration mode and operation mode. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-dev.h | 15 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-rx.c | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 5b56307a381..29eb7b4dc7d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -257,8 +257,8 @@ int iwl_hw_nic_init(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); priv->cfg->ops->lib->apm_ops.init(priv); - /* Set interrupt coalescing timer to 512 usecs */ - iwl_write8(priv, CSR_INT_COALESCING, 512 / 32); + /* Set interrupt coalescing calibration timer to default (512 usecs) */ + iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); spin_unlock_irqrestore(&priv->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 63e45cd3f63..251eb737860 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1011,6 +1011,21 @@ struct iwl_event_log { int wraps_more_count; }; +/* + * host interrupt timeout value + * used with setting interrupt coalescing timer + * the CSR_INT_COALESCING is an 8 bit register in 32-usec unit + * + * default interrupt coalescing timer is 64 x 32 = 2048 usecs + * default interrupt coalescing calibration timer is 16 x 32 = 512 usecs + */ +#define IWL_HOST_INT_TIMEOUT_MAX (0xFF) +#define IWL_HOST_INT_TIMEOUT_DEF (0x40) +#define IWL_HOST_INT_TIMEOUT_MIN (0x0) +#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF) +#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) +#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) + struct iwl_priv { /* ieee device used by generic ieee processing code */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 5bbe5f1f749..07bdba93c17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -473,8 +473,8 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); - /* Set interrupt coalescing timer to 64 x 32 = 2048 usecs */ - iwl_write8(priv, CSR_INT_COALESCING, 0x40); + /* Set interrupt coalescing timer to default (2048 usecs) */ + iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); return 0; } -- cgit v1.2.3 From 2a11df6ee58d1b1fc7e5ecd7593a04d7555dc522 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:38 -0800 Subject: iwlwifi: software w/a for h/w bug cause Rx bit get clear This is a w/a for a hardware bug. the h/w bug may cause the Rx bit (bit 15 before shifting it to 31) to clear when using interrupt coalescing. This does not mean frames are lost - their processing is just delayed until next interrupt arrives. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 29eb7b4dc7d..9d6c144d070 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1803,6 +1803,16 @@ irqreturn_t iwl_isr_ict(int irq, void *data) if (val == 0xffffffff) val = 0; + /* + * this is a w/a for a h/w bug. the h/w bug may cause the Rx bit + * (bit 15 before shifting it to 31) to clear when using interrupt + * coalescing. fortunately, bits 18 and 19 stay set when this happens + * so we use them to decide on the real state of the Rx bit. + * In order words, bit 15 is set if bit 18 or bit 19 are set. + */ + if (val & 0xC0000) + val |= 0x8000; + inta = (0xff & val) | ((0xff00 & val) << 16); IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n", inta, inta_mask, val); -- cgit v1.2.3 From 1b3eb8236ad9369ae519216b61a3d22806370115 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:39 -0800 Subject: iwlwifi: display flowhandler register when sw error or on-demand Flowhandler handle the communication between driver and uCode, when any uCode error happen, we also like to know what is the status of the flowhandler; it can help to debug flowhandler related problem. Also adding debugfs file to dump current value of flowhandler registers. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 1 + drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + drivers/net/wireless/iwlwifi/iwl-core.c | 65 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-debug.h | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 24 +++++++++++ drivers/net/wireless/iwlwifi/iwl-fh.h | 19 +++++++++ 8 files changed, 114 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 0db1fda94a6..506429f00c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -106,6 +106,7 @@ static struct iwl_lib_ops iwl1000_lib = { .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, + .dump_fh = iwl_dump_fh, .init_alive_start = iwl5000_init_alive_start, .alive_notify = iwl5000_alive_notify, .send_tx_power = iwl5000_send_tx_power, diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c6120f0b8f9..500c410f524 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1467,6 +1467,7 @@ struct iwl_lib_ops iwl5000_lib = { .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, + .dump_fh = iwl_dump_fh, .load_ucode = iwl5000_load_ucode, .init_alive_start = iwl5000_init_alive_start, .alive_notify = iwl5000_alive_notify, diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index a5a0ed4817a..c5f244f3d74 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -216,6 +216,7 @@ static struct iwl_lib_ops iwl6000_lib = { .dump_nic_event_log = iwl_dump_nic_event_log, .dump_nic_error_log = iwl_dump_nic_error_log, .dump_csr = iwl_dump_csr, + .dump_fh = iwl_dump_fh, .init_alive_start = iwl5000_init_alive_start, .alive_notify = iwl5000_alive_notify, .send_tx_power = iwl5000_send_tx_power, diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 9d6c144d070..28d97f5f8cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1353,6 +1353,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv) priv->cfg->ops->lib->dump_nic_error_log(priv); if (priv->cfg->ops->lib->dump_csr) priv->cfg->ops->lib->dump_csr(priv); + if (priv->cfg->ops->lib->dump_fh) + priv->cfg->ops->lib->dump_fh(priv, NULL, false); priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) @@ -3278,6 +3280,69 @@ void iwl_dump_csr(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_dump_csr); +const static char *get_fh_string(int cmd) +{ + switch (cmd) { + IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); + IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); + IWL_CMD(FH_RSCSR_CHNL0_WPTR); + IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); + IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); + IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); + IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); + IWL_CMD(FH_TSSR_TX_STATUS_REG); + IWL_CMD(FH_TSSR_TX_ERROR_REG); + default: + return "UNKNOWN"; + + } +} + +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) +{ + int i; +#ifdef CONFIG_IWLWIFI_DEBUG + int pos = 0; + size_t bufsz = 0; +#endif + u32 fh_tbl[] = { + FH_RSCSR_CHNL0_STTS_WPTR_REG, + FH_RSCSR_CHNL0_RBDCB_BASE_REG, + FH_RSCSR_CHNL0_WPTR, + FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_MEM_RSSR_SHARED_CTRL_REG, + FH_MEM_RSSR_RX_STATUS_REG, + FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, + FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_ERROR_REG + }; +#ifdef CONFIG_IWLWIFI_DEBUG + if (display) { + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + pos += scnprintf(*buf + pos, bufsz - pos, + "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + pos += scnprintf(*buf + pos, bufsz - pos, + " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(priv, fh_tbl[i])); + } + return pos; + } +#endif + IWL_ERR(priv, "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + IWL_ERR(priv, " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(priv, fh_tbl[i])); + } + return 0; +} +EXPORT_SYMBOL(iwl_dump_fh); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 8deb83bfe18..666b0e0728b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -171,6 +171,7 @@ struct iwl_lib_ops { bool full_log, char **buf, bool display); void (*dump_nic_error_log)(struct iwl_priv *priv); void (*dump_csr)(struct iwl_priv *priv); + int (*dump_fh)(struct iwl_priv *priv, char **buf, bool display); int (*set_channel_switch)(struct iwl_priv *priv, u16 channel); /* power management */ struct iwl_apm_ops apm_ops; @@ -582,6 +583,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv); int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, char **buf, bool display); void iwl_dump_csr(struct iwl_priv *priv); +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv); #else diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 58e0462cafa..1d1e655317a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -111,6 +111,7 @@ struct iwl_debugfs { struct dentry *file_clear_traffic_statistics; struct dentry *file_csr; struct dentry *file_ucode_tracing; + struct dentry *file_fh_reg; } dbgfs_debug_files; u32 sram_offset; u32 sram_len; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index a7ca06d21d5..a3d461ff4a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2151,6 +2151,27 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + char *buf; + int pos = 0; + ssize_t ret = -EFAULT; + + if (priv->cfg->ops->lib->dump_fh) { + ret = pos = priv->cfg->ops->lib->dump_fh(priv, &buf, true); + if (buf) { + ret = simple_read_from_buffer(user_buf, + count, ppos, buf, pos); + kfree(buf); + } + } + + return ret; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -2167,6 +2188,7 @@ DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); DEBUGFS_WRITE_FILE_OPS(csr); DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); +DEBUGFS_READ_FILE_OPS(fh_reg); /* * Create the debugfs files and directories @@ -2218,6 +2240,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); + DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); @@ -2277,6 +2300,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. file_clear_traffic_statistics); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); + DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. file_ucode_rx_stats); diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 65fa8a69fd5..1342cf40297 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -379,6 +379,25 @@ #define FH_TSSR_TX_STATUS_REG (FH_TSSR_LOWER_BOUND + 0x010) +/** + * Bit fields for TSSR(Tx Shared Status & Control) error status register: + * 31: Indicates an address error when accessed to internal memory + * uCode/driver must write "1" in order to clear this flag + * 30: Indicates that Host did not send the expected number of dwords to FH + * uCode/driver must write "1" in order to clear this flag + * 16-9:Each status bit is for one channel. Indicates that an (Error) ActDMA + * command was received from the scheduler while the TRB was already full + * with previous command + * uCode/driver must write "1" in order to clear this flag + * 7-0: Each status bit indicates a channel's TxCredit error. When an error + * bit is set, it indicates that the FH has received a full indication + * from the RTC TxFIFO and the current value of the TxCredit counter was + * not equal to zero. This mean that the credit mechanism was not + * synchronized to the TxFIFO status + * uCode/driver must write "1" in order to clear this flag + */ +#define FH_TSSR_TX_ERROR_REG (FH_TSSR_LOWER_BOUND + 0x018) + #define FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) ((1 << (_chnl)) << 24) #define FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl) ((1 << (_chnl)) << 16) -- cgit v1.2.3 From 4e9772b0a94c7d3a5f7062ba94afdbb9e692275d Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 15 Jan 2010 13:43:40 -0800 Subject: iwlwifi: remove extra statistics request from debugfs When reading current ucode statistics information from debugfs, in current implementation, it will always send a new "statistics request" to uCode. In normal operation, uCode should report the statistics per beacon interval. Remove this extra request to reduce the additional command exchanges between driver and uCode. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 41 ------------------------------ 1 file changed, 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index a3d461ff4a9..38e2f9f9f1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -1109,16 +1109,6 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, if (!iwl_is_alive(priv)) return -EAGAIN; - /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->mutex); - ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->mutex); - - if (ret) { - IWL_ERR(priv, - "Error sending statistics request: %zd\n", ret); - return -EAGAIN; - } buf = kzalloc(bufsz, GFP_KERNEL); if (!buf) { IWL_ERR(priv, "Can not allocate Buffer\n"); @@ -1552,16 +1542,6 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, if (!iwl_is_alive(priv)) return -EAGAIN; - /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->mutex); - ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->mutex); - - if (ret) { - IWL_ERR(priv, - "Error sending statistics request: %zd\n", ret); - return -EAGAIN; - } buf = kzalloc(bufsz, GFP_KERNEL); if (!buf) { IWL_ERR(priv, "Can not allocate Buffer\n"); @@ -1739,16 +1719,6 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, if (!iwl_is_alive(priv)) return -EAGAIN; - /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->mutex); - ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->mutex); - - if (ret) { - IWL_ERR(priv, - "Error sending statistics request: %zd\n", ret); - return -EAGAIN; - } buf = kzalloc(bufsz, GFP_KERNEL); if (!buf) { IWL_ERR(priv, "Can not allocate Buffer\n"); @@ -1986,23 +1956,12 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file, struct iwl_priv *priv = file->private_data; char buf[128]; int pos = 0; - ssize_t ret; const size_t bufsz = sizeof(buf); struct statistics_tx *tx; if (!iwl_is_alive(priv)) pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); else { - /* make request to uCode to retrieve statistics information */ - mutex_lock(&priv->mutex); - ret = iwl_send_statistics_request(priv, CMD_SYNC, false); - mutex_unlock(&priv->mutex); - - if (ret) { - IWL_ERR(priv, "Error sending statistics request: %zd\n", - ret); - return -EAGAIN; - } tx = &priv->statistics.tx; if (tx->tx_power.ant_a || tx->tx_power.ant_b || -- cgit v1.2.3 From 1f44780827c6bbbcd1f12d5c6b6ce84f49a96bc0 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 15 Jan 2010 13:43:41 -0800 Subject: iwlwifi: update copyright year to 2010 Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-3945-fh.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-3945-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-3945-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +- drivers/net/wireless/iwlwifi/iwl-3945.h | 2 +- drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000-hw.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-calib.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-calib.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 6 +++--- drivers/net/wireless/iwlwifi/iwl-csr.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-debug.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-fh.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-hcmd.c | 2 +- drivers/net/wireless/iwlwifi/iwl-helpers.h | 2 +- drivers/net/wireless/iwlwifi/iwl-io.h | 2 +- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.h | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwlwifi/iwl-spectrum.c | 2 +- drivers/net/wireless/iwlwifi/iwl-spectrum.h | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +- drivers/net/wireless/iwlwifi/iwl-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++-- 47 files changed, 63 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 506429f00c1..d5c6edbbc95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h index 08ce259a0e6..042f6bc0df1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-fh.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 6fd10d443ba..3a876a8ece3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index a871d09d598..abe2b739c4d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.h b/drivers/net/wireless/iwlwifi/iwl-3945-led.h index 5a1033ca7aa..ce990adc51e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index d4b49883b30..47909f94271 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 28ffe4c826d..6472910b72d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 3ec2fe370b5..db4137d9a3a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index c606366b582..67ef562e8db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 6a004abb597..8159a0fcf5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index bc056e9ab85..714e032f621 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 500c410f524..aab6cf23c2b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h index 90185777d98..ddba3999999 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index c5f244f3d74..4dab7f12e72 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008-2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.c b/drivers/net/wireless/iwlwifi/iwl-agn-led.c index 3bccba20f6d..1a24946bc20 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-led.h b/drivers/net/wireless/iwlwifi/iwl-agn-led.h index ab55f92a161..a594e4fdc6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index b93e4915819..6aebcedaca8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index affc0c5a2f2..2f0094a4326 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index eaa309d8bee..8db86239bd6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c index dc61906290e..845831ac053 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-calib.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-calib.h index b6cef989a79..2b7b1df83ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-calib.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 8dc34a3d4f7..cee5fb2187c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 28d97f5f8cc..bb3ed25f843 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 666b0e0728b..785331a98aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,7 +71,7 @@ struct iwl_cmd; #define IWLWIFI_VERSION "in-tree:" -#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" #define DRV_AUTHOR "" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 1ec8cb4d5ea..1e00720bf8b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 1d1e655317a..0facaca9b40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 38e2f9f9f1d..af00ad2afa1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 251eb737860..c6310b0b2f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 4a30969689f..fd37152abae 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 0cd9c02ee04..4e1ba824dc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 1342cf40297..113c3669b9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 87d684efe11..86783c27d97 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index bd0b12efb5c..45af5bbc1c5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index e552d4c4bdb..c719baf2585 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 46c7a95b88f..a6f9c918aab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index f47f053f02e..49a70baa3fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 8ccc0bb1d9e..8599444bef0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 310c32e8f69..5db91c10dcc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 6d95832db06..d2d2a917490 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 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 @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 07bdba93c17..eb45f8be074 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index fa1c89ba645..ceb91f969e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2010 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 diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c index 1ea5cd345fe..da166d1d1b1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.h b/drivers/net/wireless/iwlwifi/iwl-spectrum.h index a77c1e61906..af6babee289 100644 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.h +++ b/drivers/net/wireless/iwlwifi/iwl-spectrum.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ieee80211 subsystem header files. * diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index cde09a890b7..8afa39b4b48 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 8d052de2d40..8c6850d03e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 87ce2bd292c..d365d13e329 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 8bbcc5487aa..c46f988d0a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. @@ -77,7 +77,7 @@ #endif #define DRV_VERSION IWLWIFI_VERSION VD VS -#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" #define DRV_AUTHOR "" MODULE_DESCRIPTION(DRV_DESCRIPTION); -- cgit v1.2.3 From 026816fce48390807859508cd5172e9c79901ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:03:28 +0100 Subject: b43: N-PHY: implement RX PHY cleanup and setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 82 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 4a817e3da16..a1dd381c6c6 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -480,6 +480,88 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write, } } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhyCleanup */ +static void b43_nphy_rx_cal_phy_cleanup(struct b43_wldev *dev, u8 core) +{ + u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; + + b43_phy_write(dev, B43_NPHY_RFSEQCA, regs[0]); + if (core == 0) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[1]); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); + } else { + b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); + } + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[3]); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[4]); + b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO1, regs[5]); + b43_phy_write(dev, B43_NPHY_RFCTL_RSSIO2, regs[6]); + b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, regs[7]); + b43_phy_write(dev, B43_NPHY_RFCTL_OVER, regs[8]); + b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); + b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCalPhySetup */ +static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) +{ + u8 rxval, txval; + u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; + + regs[0] = b43_phy_read(dev, B43_NPHY_RFSEQCA); + if (core == 0) { + regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); + regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); + } else { + regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); + regs[2] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); + } + regs[3] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); + regs[4] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); + regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); + regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); + regs[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S1); + regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); + regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); + regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); + + b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); + b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); + + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, (u16)~B43_NPHY_RFSEQCA_RXDIS, + ((1 - core) << B43_NPHY_RFSEQCA_RXDIS_SHIFT)); + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN, + ((1 - core) << B43_NPHY_RFSEQCA_TXEN_SHIFT)); + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN, + (core << B43_NPHY_RFSEQCA_RXEN_SHIFT)); + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXDIS, + (core << B43_NPHY_RFSEQCA_TXDIS_SHIFT)); + + if (core == 0) { + b43_phy_mask(dev, B43_NPHY_AFECTL_C1, ~0x0007); + b43_phy_set(dev, B43_NPHY_AFECTL_OVER1, 0x0007); + } else { + b43_phy_mask(dev, B43_NPHY_AFECTL_C2, ~0x0007); + b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0007); + } + + /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */ + /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */ + /* TODO: Call N PHY RF Seq with 0 as argument */ + + if (core == 0) { + rxval = 1; + txval = 8; + } else { + rxval = 4; + txval = 2; + } + + /* TODO: Call N PHY RF Ctrl Intc Override with 1, rxval, (core + 1) */ + /* TODO: Call N PHY RF Ctrl Intc Override with 1, txval, (2 - core) */ +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) { -- cgit v1.2.3 From e53de67449bbcaf5551f54e506a4dff62fc6a49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:03:32 +0100 Subject: b43: N-PHY: implement TX PHY cleanup and setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 112 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index a1dd381c6c6..fd93b2a6b49 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1505,6 +1505,114 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) return target; } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhyCleanup */ +static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev) +{ + u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; + + if (dev->phy.rev >= 3) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, regs[0]); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, regs[1]); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]); + b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]); + /* TODO: Write an N PHY Table with ID 8, length 1, offset 3, + width 16, and data from regs[5] */ + /* TODO: Write an N PHY Table with ID 8, length 1, offset 19, + width 16, and data from regs[6] */ + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]); + b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); + b43_phy_write(dev, B43_NPHY_PAPD_EN1, regs[10]); + b43_nphy_reset_cca(dev); + } else { + b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]); + b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]); + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); + /* TODO: Write an N PHY Table with ID 8, length 1, offset 2, + width 16, and data from regs[3] */ + /* TODO: Write an N PHY Table with ID 8, length 1, offset 18, + width 16, and data from regs[4] */ + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]); + } +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalPhySetup */ +static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) +{ + u16 *regs = dev->phy.n->tx_rx_cal_phy_saveregs; + u16 tmp; + + regs[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); + regs[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); + if (dev->phy.rev >= 3) { + b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0xF0FF, 0x0A00); + b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0xF0FF, 0x0A00); + + tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); + regs[2] = tmp; + b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, tmp | 0x0600); + + tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); + regs[3] = tmp; + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600); + + regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); + b43_phy_mask(dev, B43_NPHY_BBCFG, ~B43_NPHY_BBCFG_RSTRX); + + /* TODO: Read an N PHY Table with ID 8, length 1, offset 3, + width 16, and data pointing to tmp */ + regs[5] = tmp; + + /* TODO: Write an N PHY Table with ID 8, length 1, offset 3, + width 16, and data 0 */ + /* TODO: Read an N PHY Table with ID 8, length 1, offset 19, + width 16, and data pointing to tmp */ + regs[6] = tmp; + + /* TODO: Write an N PHY Table with ID 8, length 1, offset 19, + width 16, and data 0 */ + regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); + regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); + + /* TODO: Call N PHY RF Ctrl Intc Override with 2, 1, 3 */ + /* TODO: Call N PHY RF Ctrl Intc Override with 1, 2, 1 */ + /* TODO: Call N PHY RF Ctrl Intc Override with 1, 8, 2 */ + + regs[9] = b43_phy_read(dev, B43_NPHY_PAPD_EN0); + regs[10] = b43_phy_read(dev, B43_NPHY_PAPD_EN1); + b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x0001); + b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x0001); + } else { + b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, 0xA000); + b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, 0xA000); + tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); + regs[2] = tmp; + b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000); + /* TODO: Read an N PHY Table with ID 8, length 1, offset 2, + width 16, and data pointing to tmp */ + regs[3] = tmp; + tmp |= 0x2000; + /* TODO: Write an N PHY Table with ID 8, length 1, offset 2, + width 16, and data pointer tmp */ + /* TODO: Read an N PHY Table with ID 8, length 1, offset 18, + width 16, and data pointer tmp */ + regs[4] = tmp; + tmp |= 0x2000; + /* TODO: Write an N PHY Table with ID 8, length 1, offset 18, + width 16, and data pointer tmp */ + regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); + regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) + tmp = 0x0180; + else + tmp = 0x0120; + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp); + } +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */ static void b43_nphy_restore_cal(struct b43_wldev *dev) { @@ -1617,7 +1725,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, width 16, and data pointer gain */ b43_nphy_tx_cal_radio_setup(dev); - /* TODO: Call N PHY TX Cal PHY Setup */ + b43_nphy_tx_cal_phy_setup(dev); phy6or5x = dev->phy.rev >= 6 || (dev->phy.rev == 5 && nphy->ipa2g_on && @@ -1788,7 +1896,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); } - /* TODO: Call N PHY TX Cal PHY Cleanup */ + b43_nphy_tx_cal_phy_cleanup(dev); /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, width 16, and data from save */ -- cgit v1.2.3 From ad9716e8e8bc39664a0d41ec94f9bffbf748b45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:03:40 +0100 Subject: b43: N-PHY: implement MIMO config update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 16 +++++++++++++++- drivers/net/wireless/b43/phy_n.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index fd93b2a6b49..1996843eac1 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -424,6 +424,20 @@ static void b43_nphy_reset_cca(struct b43_wldev *dev) /* TODO: N PHY Force RF Seq with argument 2 */ } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ +static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) +{ + u16 mimocfg = b43_phy_read(dev, B43_NPHY_MIMOCFG); + + mimocfg |= B43_NPHY_MIMOCFG_AUTO; + if (preamble == 1) + mimocfg |= B43_NPHY_MIMOCFG_GFMIX; + else + mimocfg &= ~B43_NPHY_MIMOCFG_GFMIX; + + b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est, u16 samps, u8 time, bool wait) @@ -2180,7 +2194,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50); b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); - /* TODO MIMO-Config */ + b43_nphy_update_mimo_config(dev, nphy->preamble_override); /* TODO Update TX/RX chain */ if (phy->rev < 2) { diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 4572866756f..ae00e3f2d61 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -973,6 +973,7 @@ struct b43_phy_n { bool hang_avoid; bool mute; u16 papd_epsilon_offset[2]; + s32 preamble_override; u8 mphase_cal_phase_id; u16 mphase_txcal_cmdidx; -- cgit v1.2.3 From 53ae8e8c92b2715f27c95e8e7169bca9a8909856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:03:48 +0100 Subject: b43: N-PHY: implement stopping playback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 34 +++++++++++++++++++++++++++++++--- drivers/net/wireless/b43/phy_n.h | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 1996843eac1..229f2d0364f 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -749,6 +749,34 @@ static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable) } } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/stop-playback */ +static void b43_nphy_stop_playback(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + u16 tmp; + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 1); + + tmp = b43_phy_read(dev, B43_NPHY_SAMP_STAT); + if (tmp & 0x1) + b43_phy_set(dev, B43_NPHY_SAMP_CMD, B43_NPHY_SAMP_CMD_STOP); + else if (tmp & 0x2) + b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, (u16)~0x8000); + + b43_phy_mask(dev, B43_NPHY_SAMP_CMD, ~0x0004); + + if (nphy->bb_mult_save & 0x80000000) { + tmp = nphy->bb_mult_save & 0xFFFF; + /* TODO: Write an N PHY Table with ID 15, length 1, offset 87, + width 16 and data from tmp */ + nphy->bb_mult_save = 0; + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 0); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) { @@ -1906,7 +1934,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, nphy->mphase_txcal_bestcoeffs */ } - /* TODO: Call N PHY Stop Playback */ + b43_nphy_stop_playback(dev); b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); } @@ -2053,7 +2081,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], 3, 0 as arguments */ /* TODO: Call N PHY Force RF Seq with 2 as argument */ - /* TODO: Call N PHT Stop Playback */ + b43_nphy_stop_playback(dev); if (playtone) { /* TODO: Call N PHY TX Tone with 4000, @@ -2080,7 +2108,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, } else { b43_nphy_calc_rx_iq_comp(dev, 1 << i); } - /* TODO: Call N PHY Stop Playback */ + b43_nphy_stop_playback(dev); } if (ret != 0) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index ae00e3f2d61..d6c92a81d3c 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -974,6 +974,7 @@ struct b43_phy_n { bool mute; u16 papd_epsilon_offset[2]; s32 preamble_override; + u32 bb_mult_save; u8 mphase_cal_phase_id; u16 mphase_txcal_cmdidx; -- cgit v1.2.3 From 4f4ab6cd1486fcb0ab8d689d625ac7691198f36b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:03:55 +0100 Subject: b43: N-PHY: implement chain selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 30 +++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_n.h | 1 + 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 229f2d0364f..90a49cfaa96 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -438,6 +438,34 @@ static void b43_nphy_update_mimo_config(struct b43_wldev *dev, s32 preamble) b43_phy_write(dev, B43_NPHY_MIMOCFG, mimocfg); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Chains */ +static void b43_nphy_update_txrx_chain(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + bool override = false; + u16 chain = 0x33; + + if (nphy->txrx_chain == 0) { + chain = 0x11; + override = true; + } else if (nphy->txrx_chain == 1) { + chain = 0x22; + override = true; + } + + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, + ~(B43_NPHY_RFSEQCA_TXEN | B43_NPHY_RFSEQCA_RXEN), + chain); + + if (override) + b43_phy_set(dev, B43_NPHY_RFSEQMODE, + B43_NPHY_RFSEQMODE_CAOVER); + else + b43_phy_mask(dev, B43_NPHY_RFSEQMODE, + ~B43_NPHY_RFSEQMODE_CAOVER); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */ static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est, u16 samps, u8 time, bool wait) @@ -2223,7 +2251,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30); b43_nphy_update_mimo_config(dev, nphy->preamble_override); - /* TODO Update TX/RX chain */ + b43_nphy_update_txrx_chain(dev); if (phy->rev < 2) { b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index d6c92a81d3c..f5a27661f65 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -987,6 +987,7 @@ struct b43_phy_n { bool txiqlocal_coeffsvalid; struct b43_phy_n_txpwrindex txpwrindex[2]; + u8 txrx_chain; u16 tx_rx_cal_phy_saveregs[11]; u16 tx_rx_cal_radio_saveregs[22]; -- cgit v1.2.3 From 67c0d6e2d1abb9cbff9235143a8faaef89119628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:04:02 +0100 Subject: b43: N-PHY: move RF sequence declarations top, add missing calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 90a49cfaa96..99024b02bdb 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -55,6 +55,18 @@ struct nphy_iq_est { u32 q1_pwr; }; +enum b43_nphy_rf_sequence { + B43_RFSEQ_RX2TX, + B43_RFSEQ_TX2RX, + B43_RFSEQ_RESET2RX, + B43_RFSEQ_UPDATE_GAINH, + B43_RFSEQ_UPDATE_GAINL, + B43_RFSEQ_UPDATE_GAINU, +}; + +static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, + enum b43_nphy_rf_sequence seq); + void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) {//TODO } @@ -421,7 +433,7 @@ static void b43_nphy_reset_cca(struct b43_wldev *dev) udelay(1); b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA); b43_nphy_bmac_clock_fgc(dev, 0); - /* TODO: N PHY Force RF Seq with argument 2 */ + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MIMOConfig */ @@ -590,7 +602,7 @@ static void b43_nphy_rx_cal_phy_setup(struct b43_wldev *dev, u8 core) /* TODO: Call N PHY RF Ctrl Intc Override with 2, 0, 3 as arguments */ /* TODO: Call N PHY RF Intc Override with 8, 0, 3, 0 as arguments */ - /* TODO: Call N PHY RF Seq with 0 as argument */ + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); if (core == 0) { rxval = 1; @@ -872,15 +884,7 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, false); } -enum b43_nphy_rf_sequence { - B43_RFSEQ_RX2TX, - B43_RFSEQ_TX2RX, - B43_RFSEQ_RESET2RX, - B43_RFSEQ_UPDATE_GAINH, - B43_RFSEQ_UPDATE_GAINL, - B43_RFSEQ_UPDATE_GAINU, -}; - +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, enum b43_nphy_rf_sequence seq) { @@ -2156,7 +2160,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, } /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ - /* TODO: Call N PHY Force RF Seq with 2 as argument */ + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, width 16, and data from gain_save */ -- cgit v1.2.3 From c57199bc32ebcd914253496486d2e09b1c9a3de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Jan 2010 13:04:08 +0100 Subject: b43: N-PHY: store seq mode for proper restoring (follow specs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 99024b02bdb..95190d42372 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -897,6 +897,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, }; int i; + u16 seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); @@ -910,8 +911,7 @@ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, } b43err(dev->wl, "RF sequence status timeout\n"); ok: - b43_phy_mask(dev, B43_NPHY_RFSEQMODE, - ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); + b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); } static void b43_nphy_bphy_init(struct b43_wldev *dev) -- cgit v1.2.3 From 27032059677b98f33634ceb90488812db432cbc9 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 17 Jan 2010 21:08:50 +0100 Subject: ath9k: fix RTS/CTS handling The Tx DMA descriptor has two kinds of flags that select RTS/CTS usage. The first one (global for the frame) selects whether RTS/CTS or CTS-to-self should be used, the second one enables RTS/CTS or CTS-to-self usage for an individual multi-rate-retry entry. Previously the code preparing the descriptor only enabled the global flag, if the first MRR series selected the local one. Fix this by enabling the global flag if any of the MRR entries need it. With this patch, rate control can properly select the use of RTS/CTS for all MRR entries except the first one, which is the default behavior. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/xmit.c | 37 +++++++++++++++-------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a821bb687b3..a6893cf0c43 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1498,26 +1498,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ctsrate |= rate->hw_value_short; - /* - * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. - * Check the first rate in the series to decide whether RTS/CTS - * or CTS-to-self has to be used. - */ - if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) - flags = ATH9K_TXDESC_CTSENA; - else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) - flags = ATH9K_TXDESC_RTSENA; - - /* FIXME: Handle aggregation protection */ - if (sc->config.ath_aggr_prot && - (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) { - flags = ATH9K_TXDESC_RTSENA; - } - - /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ - if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) - flags &= ~(ATH9K_TXDESC_RTSENA); - for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; int phy; @@ -1529,8 +1509,15 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) series[i].Tries = rates[i].count; series[i].ChSel = common->tx_chainmask; - if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) + if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) || + (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) { series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; + flags |= ATH9K_TXDESC_RTSENA; + } else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { + series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS; + flags |= ATH9K_TXDESC_CTSENA; + } + if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) series[i].RateFlags |= ATH9K_RATESERIES_2040; if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) @@ -1568,6 +1555,14 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) phy, rate->bitrate * 100, bf->bf_frmlen, rix, is_sp); } + /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ + if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit)) + flags &= ~ATH9K_TXDESC_RTSENA; + + /* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */ + if (flags & ATH9K_TXDESC_RTSENA) + flags &= ~ATH9K_TXDESC_CTSENA; + /* set dur_update_en for l-sig computation except for PS-Poll frames */ ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc, bf->bf_lastbf->bf_desc, -- cgit v1.2.3 From 288c8ce8047695fd8872dd5db3ef21a9679c402f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 17 Jan 2010 23:17:29 +0100 Subject: p54pci: handle dma mapping errors This patch adds error-paths to handle pci_dma_mapping errors. Cc: Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54pci.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index a72f7c2577d..4bf4c213bae 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -157,6 +157,14 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev, skb_tail_pointer(skb), priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE); + + if (pci_dma_mapping_error(priv->pdev, mapping)) { + dev_kfree_skb_any(skb); + dev_err(&priv->pdev->dev, + "RX DMA Mapping error\n"); + break; + } + desc->host_addr = cpu_to_le32(mapping); desc->device_addr = 0; // FIXME: necessary? desc->len = cpu_to_le16(priv->common.rx_mtu + 32); @@ -325,14 +333,20 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) u32 device_idx, idx, i; spin_lock_irqsave(&priv->lock, flags); - device_idx = le32_to_cpu(ring_control->device_idx[1]); idx = le32_to_cpu(ring_control->host_idx[1]); i = idx % ARRAY_SIZE(ring_control->tx_data); - priv->tx_buf_data[i] = skb; mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); + if (pci_dma_mapping_error(priv->pdev, mapping)) { + spin_unlock_irqrestore(&priv->lock, flags); + p54_free_skb(dev, skb); + dev_err(&priv->pdev->dev, "TX DMA mapping error\n"); + return ; + } + priv->tx_buf_data[i] = skb; + desc = &ring_control->tx_data[i]; desc->host_addr = cpu_to_le32(mapping); desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; -- cgit v1.2.3 From d713804c6032b95cd3035014e16fadebb9655c6f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 17 Jan 2010 23:19:25 +0100 Subject: p54pci: move tx cleanup into tasklet This patch moves the tx cleanup routines out of the critical interrupt context and into the (previously known as rx) tasklet. The main goal of this operation is to remove the extensive usage of spin_lock_irqsaves in the generic p54common library. The next step would be to modify p54usb to do the rx processing inside a tasklet (just like usbnet). Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54pci.c | 56 ++++++++++++++++++++------------------- drivers/net/wireless/p54/p54pci.h | 6 ++--- 2 files changed, 32 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 4bf4c213bae..48cae48ed6e 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -234,25 +234,26 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index, p54p_refill_rx_ring(dev, ring_index, ring, ring_limit, rx_buf); } -/* caller must hold priv->lock */ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, int ring_index, struct p54p_desc *ring, u32 ring_limit, - void **tx_buf) + struct sk_buff **tx_buf) { + unsigned long flags; struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; struct p54p_desc *desc; + struct sk_buff *skb; u32 idx, i; i = (*index) % ring_limit; (*index) = idx = le32_to_cpu(ring_control->device_idx[1]); idx %= ring_limit; + spin_lock_irqsave(&priv->lock, flags); while (i != idx) { desc = &ring[i]; - if (tx_buf[i]) - if (FREE_AFTER_TX((struct sk_buff *) tx_buf[i])) - p54_free_skb(dev, tx_buf[i]); + + skb = tx_buf[i]; tx_buf[i] = NULL; pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), @@ -263,17 +264,32 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, desc->len = 0; desc->flags = 0; + if (skb && FREE_AFTER_TX(skb)) { + spin_unlock_irqrestore(&priv->lock, flags); + p54_free_skb(dev, skb); + spin_lock_irqsave(&priv->lock, flags); + } + i++; i %= ring_limit; } + spin_unlock_irqrestore(&priv->lock, flags); } -static void p54p_rx_tasklet(unsigned long dev_id) +static void p54p_tasklet(unsigned long dev_id) { struct ieee80211_hw *dev = (struct ieee80211_hw *)dev_id; struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; + p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, 3, ring_control->tx_mgmt, + ARRAY_SIZE(ring_control->tx_mgmt), + priv->tx_buf_mgmt); + + p54p_check_tx_ring(dev, &priv->tx_idx_data, 1, ring_control->tx_data, + ARRAY_SIZE(ring_control->tx_data), + priv->tx_buf_data); + p54p_check_rx_ring(dev, &priv->rx_idx_mgmt, 2, ring_control->rx_mgmt, ARRAY_SIZE(ring_control->rx_mgmt), priv->rx_buf_mgmt); @@ -288,38 +304,24 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) { struct ieee80211_hw *dev = dev_id; struct p54p_priv *priv = dev->priv; - struct p54p_ring_control *ring_control = priv->ring_control; __le32 reg; spin_lock(&priv->lock); reg = P54P_READ(int_ident); if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { - spin_unlock(&priv->lock); - return IRQ_HANDLED; + goto out; } - P54P_WRITE(int_ack, reg); reg &= P54P_READ(int_enable); - if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) { - p54p_check_tx_ring(dev, &priv->tx_idx_mgmt, - 3, ring_control->tx_mgmt, - ARRAY_SIZE(ring_control->tx_mgmt), - priv->tx_buf_mgmt); - - p54p_check_tx_ring(dev, &priv->tx_idx_data, - 1, ring_control->tx_data, - ARRAY_SIZE(ring_control->tx_data), - priv->tx_buf_data); - - tasklet_schedule(&priv->rx_tasklet); - - } else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)) + if (reg & cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)) + tasklet_schedule(&priv->tasklet); + else if (reg & cpu_to_le32(ISL38XX_INT_IDENT_INIT)) complete(&priv->boot_comp); +out: spin_unlock(&priv->lock); - return reg ? IRQ_HANDLED : IRQ_NONE; } @@ -368,7 +370,7 @@ static void p54p_stop(struct ieee80211_hw *dev) unsigned int i; struct p54p_desc *desc; - tasklet_kill(&priv->rx_tasklet); + tasklet_kill(&priv->tasklet); P54P_WRITE(int_enable, cpu_to_le32(0)); P54P_READ(int_enable); @@ -559,7 +561,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev, priv->common.tx = p54p_tx; spin_lock_init(&priv->lock); - tasklet_init(&priv->rx_tasklet, p54p_rx_tasklet, (unsigned long)dev); + tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev); err = request_firmware(&priv->firmware, "isl3886pci", &priv->pdev->dev); diff --git a/drivers/net/wireless/p54/p54pci.h b/drivers/net/wireless/p54/p54pci.h index fbb683953fb..2feead617a3 100644 --- a/drivers/net/wireless/p54/p54pci.h +++ b/drivers/net/wireless/p54/p54pci.h @@ -92,7 +92,7 @@ struct p54p_priv { struct p54_common common; struct pci_dev *pdev; struct p54p_csr __iomem *map; - struct tasklet_struct rx_tasklet; + struct tasklet_struct tasklet; const struct firmware *firmware; spinlock_t lock; struct p54p_ring_control *ring_control; @@ -101,8 +101,8 @@ struct p54p_priv { u32 rx_idx_mgmt, tx_idx_mgmt; struct sk_buff *rx_buf_data[8]; struct sk_buff *rx_buf_mgmt[4]; - void *tx_buf_data[32]; - void *tx_buf_mgmt[4]; + struct sk_buff *tx_buf_data[32]; + struct sk_buff *tx_buf_mgmt[4]; struct completion boot_comp; }; -- cgit v1.2.3 From d41a3552f96673480d7913c170cab31fa00b7697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 18 Jan 2010 00:21:17 +0100 Subject: b43: N-PHY: add writing one element tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 95190d42372..32f837049ef 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -808,8 +808,7 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) if (nphy->bb_mult_save & 0x80000000) { tmp = nphy->bb_mult_save & 0xFFFF; - /* TODO: Write an N PHY Table with ID 15, length 1, offset 87, - width 16 and data from tmp */ + b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); nphy->bb_mult_save = 0; } @@ -1486,13 +1485,11 @@ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core) for (i = 0; i < 18; i++) { scale = (ladder_lo[i].percent * tmp) / 100; entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env; - /* TODO: Write an N PHY Table with ID 15, length 1, - offset i, width 16, and data entry */ + b43_ntab_write(dev, B43_NTAB16(15, i), entry); scale = (ladder_iq[i].percent * tmp) / 100; entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env; - /* TODO: Write an N PHY Table with ID 15, length 1, - offset i + 32, width 16, and data entry */ + b43_ntab_write(dev, B43_NTAB16(15, i + 32), entry); } } @@ -1590,10 +1587,8 @@ static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, regs[2]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[3]); b43_phy_write(dev, B43_NPHY_BBCFG, regs[4]); - /* TODO: Write an N PHY Table with ID 8, length 1, offset 3, - width 16, and data from regs[5] */ - /* TODO: Write an N PHY Table with ID 8, length 1, offset 19, - width 16, and data from regs[6] */ + b43_ntab_write(dev, B43_NTAB16(8, 3), regs[5]); + b43_ntab_write(dev, B43_NTAB16(8, 19), regs[6]); b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[7]); b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[8]); b43_phy_write(dev, B43_NPHY_PAPD_EN0, regs[9]); @@ -1603,10 +1598,8 @@ static void b43_nphy_tx_cal_phy_cleanup(struct b43_wldev *dev) b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, regs[0]); b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, regs[1]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, regs[2]); - /* TODO: Write an N PHY Table with ID 8, length 1, offset 2, - width 16, and data from regs[3] */ - /* TODO: Write an N PHY Table with ID 8, length 1, offset 18, - width 16, and data from regs[4] */ + b43_ntab_write(dev, B43_NTAB16(8, 2), regs[3]); + b43_ntab_write(dev, B43_NTAB16(8, 18), regs[4]); b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs[5]); b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs[6]); } @@ -1638,15 +1631,11 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) /* TODO: Read an N PHY Table with ID 8, length 1, offset 3, width 16, and data pointing to tmp */ regs[5] = tmp; - - /* TODO: Write an N PHY Table with ID 8, length 1, offset 3, - width 16, and data 0 */ + b43_ntab_write(dev, B43_NTAB16(8, 3), 0); /* TODO: Read an N PHY Table with ID 8, length 1, offset 19, width 16, and data pointing to tmp */ regs[6] = tmp; - - /* TODO: Write an N PHY Table with ID 8, length 1, offset 19, - width 16, and data 0 */ + b43_ntab_write(dev, B43_NTAB16(8, 19), 0); regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); regs[8] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); @@ -1668,14 +1657,12 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) width 16, and data pointing to tmp */ regs[3] = tmp; tmp |= 0x2000; - /* TODO: Write an N PHY Table with ID 8, length 1, offset 2, - width 16, and data pointer tmp */ + b43_ntab_write(dev, B43_NTAB16(8, 2), tmp); /* TODO: Read an N PHY Table with ID 8, length 1, offset 18, width 16, and data pointer tmp */ regs[4] = tmp; tmp |= 0x2000; - /* TODO: Write an N PHY Table with ID 8, length 1, offset 18, - width 16, and data pointer tmp */ + b43_ntab_write(dev, B43_NTAB16(8, 18), tmp); regs[5] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); regs[6] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) @@ -1900,9 +1887,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, width 16, and data pointer buffer */ diq_start = buffer[0]; buffer[0] = 0; - /* TODO: Write an N PHY Table with ID 15, - length 1, offset 69 + core, width 16, - and data of 0 */ + b43_ntab_write(dev, B43_NTAB16(15, 69 + core), + 0); } b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); -- cgit v1.2.3 From 2581b1434ccba6960e0b671927d87c83b5152c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 18 Jan 2010 00:21:21 +0100 Subject: b43: N-PHY: implement and add multi-dimensional table writing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 58 +++++++++++++++------------------- drivers/net/wireless/b43/tables_nphy.c | 40 +++++++++++++++++++++++ drivers/net/wireless/b43/tables_nphy.h | 2 ++ 3 files changed, 67 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 32f837049ef..671fbcfdc0e 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1699,8 +1699,7 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) loft = &nphy->cal_cache.txcal_coeffs_5G[5]; } - /* TODO: Write an N PHY table with ID 15, length 4, offset 80, - width 16, and data from table */ + b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 4, table); for (i = 0; i < 4; i++) { if (dev->phy.rev >= 3) @@ -1709,12 +1708,9 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) coef[i] = 0; } - /* TODO: Write an N PHY table with ID 15, length 4, offset 88, - width 16, and data from coef */ - /* TODO: Write an N PHY table with ID 15, length 2, offset 85, - width 16 and data from loft */ - /* TODO: Write an N PHY table with ID 15, length 2, offset 93, - width 16 and data from loft */ + b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, coef); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, loft); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, loft); if (dev->phy.rev < 2) b43_nphy_tx_iq_workaround(dev); @@ -1782,8 +1778,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_nphy_iq_cal_gain_params(dev, i, target, ¶ms[i]); gain[i] = params[i].cal_gain; } - /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, - width 16, and data pointer gain */ + + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain); b43_nphy_tx_cal_radio_setup(dev); b43_nphy_tx_cal_phy_setup(dev); @@ -1833,8 +1829,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, } } - /* TODO: Write an N PHY Table with ID 15, length from above, - offset 64, width 16, and the data pointer from above */ + b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, table); if (full) { if (dev->phy.rev >= 3) @@ -1902,9 +1897,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, /* TODO: Read an N PHY Table with ID 15, length table_length, offset 96, width 16, and data pointer buffer */ - /* TODO: Write an N PHY Table with ID 15, - length table_length, offset 64, width 16, - and data pointer buffer */ + b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, + buffer); if (type == 1 || type == 3 || type == 4) buffer[0] = diq_start; @@ -1916,8 +1910,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, last = (dev->phy.rev < 3) ? 6 : 7; if (!mphase || nphy->mphase_cal_phase_id == last) { - /* TODO: Write an N PHY Table with ID 15, length 4, - offset 96, width 16, and data pointer buffer */ + b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer); /* TODO: Read an N PHY Table with ID 15, length 4, offset 80, width 16, and data pointer buffer */ if (dev->phy.rev < 3) { @@ -1926,14 +1919,14 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, buffer[2] = 0; buffer[3] = 0; } - /* TODO: Write an N PHY Table with ID 15, length 4, - offset 88, width 16, and data pointer buffer */ - /* TODO: Read an N PHY Table with ID 15, length 2, - offset 101, width 16, and data pointer buffer*/ - /* TODO: Write an N PHY Table with ID 15, length 2, - offset 85, width 16, and data pointer buffer */ - /* TODO: Write an N PHY Table with ID 15, length 2, - offset 93, width 16, and data pointer buffer */ + b43_ntab_write_bulk(dev, B43_NTAB16(15, 88), 4, + buffer); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 101), 2, + buffer); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 85), 2, + buffer); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 93), 2, + buffer); length = 11; if (dev->phy.rev < 3) length -= 2; @@ -1957,8 +1950,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, } b43_nphy_tx_cal_phy_cleanup(dev); - /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, - width 16, and data from save */ + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, save); if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) b43_nphy_tx_iq_workaround(dev); @@ -2008,8 +2000,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); cal_gain[i] = cal_params[i].cal_gain; } - /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, - width 16, and data from cal_gain */ + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, cal_gain); for (i = 0; i < 2; i++) { if (i == 0) { @@ -2147,8 +2138,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); - /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, - width 16, and data from gain_save */ + b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); b43_nphy_stay_in_carrier_search(dev, 0); @@ -2290,8 +2280,10 @@ int b43_phy_initn(struct b43_wldev *dev) if (phy->rev >= 3) { /* TODO */ } else { - /* TODO Write an N PHY table with ID 26, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ - /* TODO Write an N PHY table with ID 27, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */ + b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, + b43_ntab_tx_gain_rev0_1_2); + b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, + b43_ntab_tx_gain_rev0_1_2); } if (nphy->phyrxchain != 3) diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 7dff853ab96..fc08be0b976 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2952,6 +2952,46 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) assert_ntab_array_sizes(); } +void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, const void *_data) +{ + u32 type, value; + const u8 *data = _data; + unsigned int i; + + type = offset & B43_NTAB_TYPEMASK; + offset &= ~B43_NTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); + + for (i = 0; i < nr_elements; i++) { + switch (type) { + case B43_NTAB_8BIT: + value = *data; + data++; + B43_WARN_ON(value & ~0xFF); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value); + break; + case B43_NTAB_16BIT: + value = *((u16 *)data); + data += 2; + B43_WARN_ON(value & ~0xFFFF); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, value); + break; + case B43_NTAB_32BIT: + value = *((u32 *)data); + data += 4; + b43_phy_write(dev, B43_NPHY_TABLE_DATAHI, value >> 16); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + value & 0xFFFF); + break; + default: + B43_WARN_ON(1); + } + } +} + #define ntab_upload(dev, offset, data) do { \ unsigned int i; \ for (i = 0; i < (offset##_SIZE); i++) \ diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 51636d02f8b..d5605df5d6b 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -143,6 +143,8 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); +void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, const void *_data); void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); -- cgit v1.2.3 From c643a66ef5ccfd4d359327fb8afa9949f1abbfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 18 Jan 2010 00:21:27 +0100 Subject: b43: N-PHY: implement and add reading one element tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 18 +++++++----------- drivers/net/wireless/b43/tables_nphy.c | 31 +++++++++++++++++++++++++++++++ drivers/net/wireless/b43/tables_nphy.h | 1 + 3 files changed, 39 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 671fbcfdc0e..7eac0ae2b15 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1628,12 +1628,11 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); b43_phy_mask(dev, B43_NPHY_BBCFG, ~B43_NPHY_BBCFG_RSTRX); - /* TODO: Read an N PHY Table with ID 8, length 1, offset 3, - width 16, and data pointing to tmp */ + tmp = b43_ntab_read(dev, B43_NTAB16(8, 3)); regs[5] = tmp; b43_ntab_write(dev, B43_NTAB16(8, 3), 0); - /* TODO: Read an N PHY Table with ID 8, length 1, offset 19, - width 16, and data pointing to tmp */ + + tmp = b43_ntab_read(dev, B43_NTAB16(8, 19)); regs[6] = tmp; b43_ntab_write(dev, B43_NTAB16(8, 19), 0); regs[7] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); @@ -1653,13 +1652,11 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) tmp = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); regs[2] = tmp; b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x3000); - /* TODO: Read an N PHY Table with ID 8, length 1, offset 2, - width 16, and data pointing to tmp */ + tmp = b43_ntab_read(dev, B43_NTAB16(8, 2)); regs[3] = tmp; tmp |= 0x2000; b43_ntab_write(dev, B43_NTAB16(8, 2), tmp); - /* TODO: Read an N PHY Table with ID 8, length 1, offset 18, - width 16, and data pointer tmp */ + tmp = b43_ntab_read(dev, B43_NTAB16(8, 18)); regs[4] = tmp; tmp |= 0x2000; b43_ntab_write(dev, B43_NTAB16(8, 18), tmp); @@ -1877,9 +1874,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); if (type == 1 || type == 3 || type == 4) { - /* TODO: Read an N PHY Table with ID 15, - length 1, offset 69 + core, - width 16, and data pointer buffer */ + buffer[0] = b43_ntab_read(dev, + B43_NTAB16(15, 69 + core)); diq_start = buffer[0]; buffer[0] = 0; b43_ntab_write(dev, B43_NTAB16(15, 69 + core), diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index fc08be0b976..b8aed456da1 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2919,6 +2919,37 @@ static inline void assert_ntab_array_sizes(void) #undef check } +u32 b43_ntab_read(struct b43_wldev *dev, u32 offset) +{ + u32 type, value; + + type = offset & B43_NTAB_TYPEMASK; + offset &= ~B43_NTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + switch (type) { + case B43_NTAB_8BIT: + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF; + break; + case B43_NTAB_16BIT: + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + break; + case B43_NTAB_32BIT: + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); + value = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI); + value <<= 16; + value |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + break; + default: + B43_WARN_ON(1); + value = 0; + } + + return value; +} + void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) { u32 type; diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index d5605df5d6b..64e990a14de 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -142,6 +142,7 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10 #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 +u32 b43_ntab_read(struct b43_wldev *dev, u32 offset); void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, unsigned int nr_elements, const void *_data); -- cgit v1.2.3 From 9145834e84805f5efcca4706edfd641047af1d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 18 Jan 2010 00:21:35 +0100 Subject: b43: N-PHY: implement and add multi-dimensional table reading MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 30 +++++++++++------------------ drivers/net/wireless/b43/tables_nphy.c | 35 ++++++++++++++++++++++++++++++++++ drivers/net/wireless/b43/tables_nphy.h | 2 ++ 3 files changed, 48 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 7eac0ae2b15..1359267a35f 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -829,8 +829,7 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, true); - /* TODO: Read an N PHY Table with ID 15, length 7, offset 80, - width 16, and data pointer buffer */ + b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); for (i = 0; i < 2; i++) { tmp = ((buffer[i * 2] & 0x3FF) << 10) | @@ -1507,8 +1506,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, true); - /* TODO: Read an N PHY Table with ID 7, length 2, - offset 0x110, width 16, and curr_gain */ + b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, curr_gain); if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, false); @@ -1768,8 +1766,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, nphy->hang_avoid = 0; } - /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, - width 16, and data pointer save */ + b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, save); for (i = 0; i < 2; i++) { b43_nphy_iq_cal_gain_params(dev, i, target, ¶ms[i]); @@ -1890,9 +1887,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, udelay(10); } - /* TODO: Read an N PHY Table with ID 15, - length table_length, offset 96, width 16, - and data pointer buffer */ + b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, + buffer); b43_ntab_write_bulk(dev, B43_NTAB16(15, 64), length, buffer); @@ -1907,8 +1903,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, if (!mphase || nphy->mphase_cal_phase_id == last) { b43_ntab_write_bulk(dev, B43_NTAB16(15, 96), 4, buffer); - /* TODO: Read an N PHY Table with ID 15, length 4, - offset 80, width 16, and data pointer buffer */ + b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 4, buffer); if (dev->phy.rev < 3) { buffer[0] = 0; buffer[1] = 0; @@ -1926,9 +1921,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, length = 11; if (dev->phy.rev < 3) length -= 2; - /* TODO: Read an N PHY Table with ID 15, length length, - offset 96, width 16, and data pointer - nphy->txiqlocal_bestc */ + b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, + nphy->txiqlocal_bestc); nphy->txiqlocal_coeffsvalid = true; /* TODO: Set nphy->txiqlocal_chanspec to the current channel */ @@ -1936,9 +1930,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, length = 11; if (dev->phy.rev < 3) length -= 2; - /* TODO: Read an N PHY Table with ID 5, length length, - offset 96, width 16, and data pointer - nphy->mphase_txcal_bestcoeffs */ + b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, + nphy->mphase_txcal_bestcoeffs); } b43_nphy_stop_playback(dev); @@ -1990,8 +1983,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, if (dev->phy.rev < 2) ;/* TODO: Call N PHY Reapply TX Cal Coeffs */ - /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, - width 16, and data gain_save */ + b43_ntab_read_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); for (i = 0; i < 2; i++) { b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]); cal_gain[i] = cal_params[i].cal_gain; diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index b8aed456da1..b8c9fc619ab 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2950,6 +2950,41 @@ u32 b43_ntab_read(struct b43_wldev *dev, u32 offset) return value; } +void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, void *_data) +{ + u32 type; + u8 *data = _data; + unsigned int i; + + type = offset & B43_NTAB_TYPEMASK; + offset &= ~B43_NTAB_TYPEMASK; + B43_WARN_ON(offset > 0xFFFF); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, offset); + + for (i = 0; i < nr_elements; i++) { + switch (type) { + case B43_NTAB_8BIT: + *data = b43_phy_read(dev, B43_NPHY_TABLE_DATALO) & 0xFF; + data++; + break; + case B43_NTAB_16BIT: + *((u16 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + data += 2; + break; + case B43_NTAB_32BIT: + *((u32 *)data) = b43_phy_read(dev, B43_NPHY_TABLE_DATAHI); + *((u32 *)data) <<= 16; + *((u32 *)data) |= b43_phy_read(dev, B43_NPHY_TABLE_DATALO); + data += 4; + break; + default: + B43_WARN_ON(1); + } + } +} + void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value) { u32 type; diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 64e990a14de..6bbef894010 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -143,6 +143,8 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel); #define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12 u32 b43_ntab_read(struct b43_wldev *dev, u32 offset); +void b43_ntab_read_bulk(struct b43_wldev *dev, u32 offset, + unsigned int nr_elements, void *_data); void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, unsigned int nr_elements, const void *_data); -- cgit v1.2.3 From de9a47f92795f697964f662415cb27816c2d9b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 18 Jan 2010 00:21:49 +0100 Subject: b43: N-PHY: silence warnings, add missing call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 1359267a35f..e77f1f24d10 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1624,7 +1624,7 @@ static void b43_nphy_tx_cal_phy_setup(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp | 0x0600); regs[4] = b43_phy_read(dev, B43_NPHY_BBCFG); - b43_phy_mask(dev, B43_NPHY_BBCFG, ~B43_NPHY_BBCFG_RSTRX); + b43_phy_mask(dev, B43_NPHY_BBCFG, (u16)~B43_NPHY_BBCFG_RSTRX); tmp = b43_ntab_read(dev, B43_NTAB16(8, 3)); regs[5] = tmp; @@ -1970,7 +1970,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, u16 lna[3] = { 3, 3, 1 }; u16 hpf1[3] = { 7, 2, 0 }; u16 hpf2[3] = { 2, 0, 0 }; - u32 power[3]; + u32 power[3] = { }; u16 gain_save[2]; u16 cal_gain[2]; struct nphy_iqcal_params cal_params[2]; @@ -2077,7 +2077,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, (cur_lna << 2)); /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], 3, 0 as arguments */ - /* TODO: Call N PHY Force RF Seq with 2 as argument */ + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); b43_nphy_stop_playback(dev); if (playtone) { -- cgit v1.2.3 From 1625c148cde23a8b4180e171ed4a17e17521b995 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 19 Jan 2010 00:19:21 +0100 Subject: libertas: Set/clear WPA keys before the WEP ones With the v10 firmware running on 8688 HW, clearing WPA keys after setting the WEP key prevents us from being able to associate with WEP APs. Swapping the calling order for assoc_helper_wpa_keys() and assoc_helper_wep_keys fixes that issue. Signed-off-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/assoc.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 5e650f35841..fb3dff0fdfa 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -2052,13 +2052,6 @@ void lbs_association_worker(struct work_struct *work) goto out; } - if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) - || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { - ret = assoc_helper_wep_keys(priv, assoc_req); - if (ret) - goto out; - } - if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { ret = assoc_helper_secinfo(priv, assoc_req); if (ret) @@ -2078,6 +2071,14 @@ void lbs_association_worker(struct work_struct *work) goto out; } + if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) + || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { + ret = assoc_helper_wep_keys(priv, assoc_req); + if (ret) + goto out; + } + + /* SSID/BSSID should be the _last_ config option set, because they * trigger the association attempt. */ -- cgit v1.2.3 From c9f6a6567f3e8dd69dd3f80a67e73d7d10884bea Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 19 Jan 2010 14:04:19 -0500 Subject: ath9k: make tx power config changes take effect immediatley Users wishing to tweak tx power want it to happen immediately, try to respect that. This was tested by Lorenzo by measuring the received signal strength from an AP with ath9k and the patch. Changing the tx power on the AP produced these results: 1) iwconfig wlan0 txpower 20 ---> Rx power -37dbm 2) iwconfig wlan0 txpower 15 ---> Rx power -41dbm 3) iwconfig wlan0 txpower 10 ---> Rx power -45dbm 4) iwconfig wlan0 txpower 5 ---> Rx power -51dbm 5) iwconfig wlan0 txpower 0 ---> Rx power -37dbm The result with 0 is an anomoly and would need to be addressed through a separate patch. Signed-off-by: Luis R. Rodriguez Tested-by: Lorenzo Bianconi Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index c0c571c2e8c..6f3e71c5071 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1624,8 +1624,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } skip_chan_change: - if (changed & IEEE80211_CONF_CHANGE_POWER) + if (changed & IEEE80211_CONF_CHANGE_POWER) { sc->config.txpowlimit = 2 * conf->power_level; + ath_update_txpow(sc); + } spin_lock_bh(&sc->wiphy_lock); disable_radio = ath9k_all_wiphys_idle(sc); -- cgit v1.2.3 From 64147c729732ba9c9e50966971bdfbd503c888bb Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 19 Jan 2010 17:07:41 -0500 Subject: libertas/assoc.c: rearrange some strange line breaks Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/assoc.c | 62 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index fb3dff0fdfa..0979b07799a 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -1160,11 +1160,11 @@ int lbs_adhoc_stop(struct lbs_private *priv) static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, struct bss_descriptor *match_bss) { - if (!secinfo->wep_enabled && !secinfo->WPAenabled - && !secinfo->WPA2enabled - && match_bss->wpa_ie[0] != WLAN_EID_GENERIC - && match_bss->rsn_ie[0] != WLAN_EID_RSN - && !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) + if (!secinfo->wep_enabled && + !secinfo->WPAenabled && !secinfo->WPA2enabled && + match_bss->wpa_ie[0] != WLAN_EID_GENERIC && + match_bss->rsn_ie[0] != WLAN_EID_RSN && + !(match_bss->capability & WLAN_CAPABILITY_PRIVACY)) return 1; else return 0; @@ -1173,9 +1173,9 @@ static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, struct bss_descriptor *match_bss) { - if (secinfo->wep_enabled && !secinfo->WPAenabled - && !secinfo->WPA2enabled - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) + if (secinfo->wep_enabled && + !secinfo->WPAenabled && !secinfo->WPA2enabled && + (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) return 1; else return 0; @@ -1184,8 +1184,8 @@ static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, struct bss_descriptor *match_bss) { - if (!secinfo->wep_enabled && secinfo->WPAenabled - && (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) + if (!secinfo->wep_enabled && secinfo->WPAenabled && + (match_bss->wpa_ie[0] == WLAN_EID_GENERIC) /* privacy bit may NOT be set in some APs like LinkSys WRT54G && (match_bss->capability & WLAN_CAPABILITY_PRIVACY) */ ) @@ -1210,11 +1210,11 @@ static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, struct bss_descriptor *match_bss) { - if (!secinfo->wep_enabled && !secinfo->WPAenabled - && !secinfo->WPA2enabled - && (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) - && (match_bss->rsn_ie[0] != WLAN_EID_RSN) - && (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) + if (!secinfo->wep_enabled && + !secinfo->WPAenabled && !secinfo->WPA2enabled && + (match_bss->wpa_ie[0] != WLAN_EID_GENERIC) && + (match_bss->rsn_ie[0] != WLAN_EID_RSN) && + (match_bss->capability & WLAN_CAPABILITY_PRIVACY)) return 1; else return 0; @@ -1525,8 +1525,8 @@ static int assoc_helper_associate(struct lbs_private *priv, /* If we're given and 'any' BSSID, try associating based on SSID */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - if (compare_ether_addr(bssid_any, assoc_req->bssid) - && compare_ether_addr(bssid_off, assoc_req->bssid)) { + if (compare_ether_addr(bssid_any, assoc_req->bssid) && + compare_ether_addr(bssid_off, assoc_req->bssid)) { ret = assoc_helper_bssid(priv, assoc_req); done = 1; } @@ -1612,11 +1612,9 @@ static int assoc_helper_channel(struct lbs_private *priv, goto restore_mesh; } - if ( assoc_req->secinfo.wep_enabled - && (assoc_req->wep_keys[0].len - || assoc_req->wep_keys[1].len - || assoc_req->wep_keys[2].len - || assoc_req->wep_keys[3].len)) { + if (assoc_req->secinfo.wep_enabled && + (assoc_req->wep_keys[0].len || assoc_req->wep_keys[1].len || + assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len)) { /* Make sure WEP keys are re-sent to firmware */ set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); } @@ -1983,14 +1981,14 @@ void lbs_association_worker(struct work_struct *work) assoc_req->secinfo.auth_mode); /* If 'any' SSID was specified, find an SSID to associate with */ - if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) - && !assoc_req->ssid_len) + if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) && + !assoc_req->ssid_len) find_any_ssid = 1; /* But don't use 'any' SSID if there's a valid locked BSSID to use */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - if (compare_ether_addr(assoc_req->bssid, bssid_any) - && compare_ether_addr(assoc_req->bssid, bssid_off)) + if (compare_ether_addr(assoc_req->bssid, bssid_any) && + compare_ether_addr(assoc_req->bssid, bssid_off)) find_any_ssid = 0; } @@ -2064,15 +2062,15 @@ void lbs_association_worker(struct work_struct *work) goto out; } - if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) - || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { + if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || + test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { ret = assoc_helper_wpa_keys(priv, assoc_req); if (ret) goto out; } - if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) - || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { + if (test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) || + test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { ret = assoc_helper_wep_keys(priv, assoc_req); if (ret) goto out; @@ -2082,8 +2080,8 @@ void lbs_association_worker(struct work_struct *work) /* SSID/BSSID should be the _last_ config option set, because they * trigger the association attempt. */ - if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) - || test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { + if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags) || + test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { int success = 1; ret = assoc_helper_associate(priv, assoc_req); -- cgit v1.2.3 From b3fbdcf49f940d0703c356441e0daf045e64e076 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2010 11:40:47 +0100 Subject: mac80211: pass vif and station to update_tkip_key When a TKIP key is updated, we should pass the station pointer instead of just the address, since drivers can use that to store their own data. We also need to pass the virtual interface pointer. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 11 ++++++++--- drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c238468bca7..c699e46534d 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -844,8 +844,10 @@ static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32, } static void b43_op_update_tkip_key(struct ieee80211_hw *hw, - struct ieee80211_key_conf *keyconf, const u8 *addr, - u32 iv32, u16 *phase1key) + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev; @@ -863,7 +865,10 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw, keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ rx_tkip_phase1_write(dev, index, iv32, phase1key); - keymac_write(dev, index, addr); + /* only pairwise TKIP keys are supported right now */ + if (WARN_ON(!sta)) + goto out_unlock; + keymac_write(dev, index, sta->addr); out_unlock: mutex_unlock(&wl->mutex); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8db86239bd6..62b6939df52 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2839,14 +2839,18 @@ void iwl_config_ap(struct iwl_priv *priv) } static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, - struct ieee80211_key_conf *keyconf, const u8 *addr, - u32 iv32, u16 *phase1key) + struct ieee80211_vif *vif, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, + u32 iv32, u16 *phase1key) { struct iwl_priv *priv = hw->priv; IWL_DEBUG_MAC80211(priv, "enter\n"); - iwl_update_tkip_key(priv, keyconf, addr, iv32, phase1key); + iwl_update_tkip_key(priv, keyconf, + sta ? sta->addr : iwl_bcast_addr, + iv32, phase1key); IWL_DEBUG_MAC80211(priv, "leave\n"); } -- cgit v1.2.3 From ef15aac6073b27fd4f70007784d2d52ed394bf43 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jan 2010 12:02:33 +0100 Subject: cfg80211: export multiple MAC addresses in sysfs If a device has multiple MAC addresses, userspace will need to know about that. Similarly, if it allows the MAC addresses to vary by a bitmask. If a driver exports multiple addresses, it is assumed that it will be able to deal with that many different addresses, which need not necessarily match the ones programmed into the device; if a mask is set then the device should deal addresses within that mask based on an arbitrary "base address". To test it all and show how it is used, add support to hwsim even though it can't actually deal with addresses different from the default. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/mac80211_hwsim.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 84df3fcf37b..0dbda8dfbd9 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -281,6 +281,8 @@ struct mac80211_hwsim_data { struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; + struct mac_address addresses[2]; + struct ieee80211_channel *channel; unsigned long beacon_int; /* in jiffies unit */ unsigned int rx_filter; @@ -1154,7 +1156,11 @@ static int __init init_mac80211_hwsim(void) SET_IEEE80211_DEV(hw, data->dev); addr[3] = i >> 8; addr[4] = i; - SET_IEEE80211_PERM_ADDR(hw, addr); + memcpy(data->addresses[0].addr, addr, ETH_ALEN); + memcpy(data->addresses[1].addr, addr, ETH_ALEN); + data->addresses[1].addr[0] |= 0x40; + hw->wiphy->n_addresses = 2; + hw->wiphy->addresses = data->addresses; hw->channel_change_time = 1; hw->queues = 4; -- cgit v1.2.3 From 5d6ce628f986d1a3c523cbb0a5a52095c48cc332 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 20 Jan 2010 23:51:03 -0500 Subject: ath5k: dont use external sleep clock in AP mode When using the external sleep clock in AP mode, the TSF increments too quickly, causing beacon interval to be much lower than it is supposed to be, resulting in lots of beacon-not-ready interrupts. This fixes http://bugzilla.kernel.org/show_bug.cgi?id=14802. Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/reset.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 6690923fd78..a35a7db0fc4 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -1374,8 +1374,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * Set clocks to 32KHz operation and use an * external 32KHz crystal when sleeping if one * exists */ - if (ah->ah_version == AR5K_AR5212) - ath5k_hw_set_sleep_clock(ah, true); + if (ah->ah_version == AR5K_AR5212 && + ah->ah_op_mode != NL80211_IFTYPE_AP) + ath5k_hw_set_sleep_clock(ah, true); /* * Disable beacons and reset the register -- cgit v1.2.3 From a951ae2176b982574ffa197455db6c89359fd5eb Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 20 Jan 2010 23:51:04 -0500 Subject: ath5k: fix setup for CAB queue The beacon sent gating doesn't seem to work with any combination of flags. Thus, buffered frames tend to stay buffered forever, using up tx descriptors. Instead, use the DBA gating and hold transmission of the buffered frames until 80% of the beacon interval has elapsed using the ready time. This fixes the following error in AP mode: ath5k phy0: no further txbuf available, dropping packet Add a comment to acknowledge that this isn't the best solution. Signed-off-by: Bob Copeland Acked-by: Nick Kossifidis Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath/ath5k/base.c | 22 +++++++++++++++++++--- drivers/net/wireless/ath/ath5k/qcu.c | 5 +++-- 3 files changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 66bcb506a11..ad4d446f026 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -535,7 +535,7 @@ struct ath5k_txq_info { u32 tqi_cbr_period; /* Constant bit rate period */ u32 tqi_cbr_overflow_limit; u32 tqi_burst_time; - u32 tqi_ready_time; /* Not used */ + u32 tqi_ready_time; /* Time queue waits after an event */ }; /* diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index b5015376d4b..535a6afb94e 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1516,7 +1516,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); if (ret) - return ret; + goto err; + if (sc->opmode == NL80211_IFTYPE_AP || sc->opmode == NL80211_IFTYPE_MESH_POINT) { /* @@ -1543,10 +1544,25 @@ ath5k_beaconq_config(struct ath5k_softc *sc) if (ret) { ATH5K_ERR(sc, "%s: unable to update parameters for beacon " "hardware queue!\n", __func__); - return ret; + goto err; } + ret = ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */ + if (ret) + goto err; - return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */; + /* reconfigure cabq with ready time to 80% of beacon_interval */ + ret = ath5k_hw_get_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); + if (ret) + goto err; + + qi.tqi_ready_time = (sc->bintval * 80) / 100; + ret = ath5k_hw_set_tx_queueprops(ah, AR5K_TX_QUEUE_ID_CAB, &qi); + if (ret) + goto err; + + ret = ath5k_hw_reset_tx_queue(ah, AR5K_TX_QUEUE_ID_CAB); +err: + return ret; } static void diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index abe36c0d139..9122a8556f4 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -408,12 +408,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) break; case AR5K_TX_QUEUE_CAB: + /* XXX: use BCN_SENT_GT, if we can figure out how */ AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_FRSHED_BCN_SENT_GT | + AR5K_QCU_MISC_FRSHED_DBA_GT | AR5K_QCU_MISC_CBREXP_DIS | AR5K_QCU_MISC_CBREXP_BCN_DIS); - ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - + ath5k_hw_reg_write(ah, ((tq->tqi_ready_time - (AR5K_TUNE_SW_BEACON_RESP - AR5K_TUNE_DMA_BEACON_RESP) - AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | -- cgit v1.2.3 From 58da1318ee92ad3fe7917278d596768bbe441850 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 21 Jan 2010 11:17:27 +0530 Subject: ath9k: Fix wifi disconnection when collocated bt scan is active As all bt packets are priority traffic during bt scan, wifi will get disconnected when bt scan lasts for few seconds. Fix this by allocating 10% of bt period time (4.5ms) to wifi fully. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 ++ drivers/net/wireless/ath/ath9k/btcoex.h | 2 ++ drivers/net/wireless/ath/ath9k/gpio.c | 30 ++++++++++++++++++++++-------- drivers/net/wireless/ath/ath9k/reg.h | 6 +++--- 4 files changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index bf3d4c4bfa5..bdbcc70df07 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -364,6 +364,7 @@ struct ath_btcoex { int bt_stomp_type; /* Types of BT stomping */ u32 btcoex_no_stomp; /* in usec */ u32 btcoex_period; /* in usec */ + u32 btscan_no_stomp; /* in usec */ struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ }; @@ -429,6 +430,7 @@ void ath_deinit_leds(struct ath_softc *sc); #define SC_OP_SCANNING BIT(10) #define SC_OP_TSF_RESET BIT(11) #define SC_OP_BT_PRIORITY_DETECTED BIT(12) +#define SC_OP_BT_SCAN BIT(13) /* Powersave flags */ #define PS_WAIT_FOR_BEACON BIT(0) diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 1ba31a73317..1ee5a15ccbb 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h @@ -25,10 +25,12 @@ #define ATH_BTCOEX_DEF_BT_PERIOD 45 #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 +#define ATH_BTCOEX_BTSCAN_DUTY_CYCLE 90 #define ATH_BTCOEX_BMISS_THRESH 50 #define ATH_BT_PRIORITY_TIME_THRESHOLD 1000 /* ms */ #define ATH_BT_CNT_THRESHOLD 3 +#define ATH_BT_CNT_SCAN_THRESHOLD 15 enum ath_btcoex_scheme { ATH_BTCOEX_CFG_NONE, diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index e204bd25ff6..deab8beb068 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -230,12 +230,17 @@ static void ath_detect_bt_priority(struct ath_softc *sc) if (time_after(jiffies, btcoex->bt_priority_time + msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { - if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { + sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); + /* Detect if colocated bt started scanning */ + if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { + ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, + "BT scan detected"); + sc->sc_flags |= (SC_OP_BT_SCAN | + SC_OP_BT_PRIORITY_DETECTED); + } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX, "BT priority traffic detected"); sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; - } else { - sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; } btcoex->bt_priority_cnt = 0; @@ -316,12 +321,17 @@ static void ath_btcoex_period_timer(unsigned long data) struct ath_softc *sc = (struct ath_softc *) data; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + u32 timer_period; + bool is_btscan; ath_detect_bt_priority(sc); + is_btscan = sc->sc_flags & SC_OP_BT_SCAN; + spin_lock_bh(&btcoex->btcoex_lock); - ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type); + ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL : + btcoex->bt_stomp_type); spin_unlock_bh(&btcoex->btcoex_lock); @@ -329,11 +339,12 @@ static void ath_btcoex_period_timer(unsigned long data) if (btcoex->hw_timer_enabled) ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); + timer_period = is_btscan ? btcoex->btscan_no_stomp : + btcoex->btcoex_no_stomp; ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, (ath9k_hw_gettsf32(ah) + - btcoex->btcoex_no_stomp), - btcoex->btcoex_no_stomp * 10); + timer_period), timer_period * 10); btcoex->hw_timer_enabled = true; } @@ -350,13 +361,14 @@ static void ath_btcoex_no_stomp_timer(void *arg) struct ath_softc *sc = (struct ath_softc *)arg; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, "no stomp timer running \n"); spin_lock_bh(&btcoex->btcoex_lock); - if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW) + if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); @@ -371,6 +383,8 @@ int ath_init_btcoex_timer(struct ath_softc *sc) btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * btcoex->btcoex_period / 100; + btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * + btcoex->btcoex_period / 100; setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, (unsigned long) sc); @@ -405,7 +419,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) btcoex->bt_priority_cnt = 0; btcoex->bt_priority_time = jiffies; - sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED; + sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); mod_timer(&btcoex->period_timer, jiffies); } diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 8e653fb937a..72cfa8ebd9a 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1547,9 +1547,9 @@ enum { #define AR_BT_COEX_WEIGHT 0x8174 #define AR_BT_COEX_WGHT 0xff55 -#define AR_STOMP_ALL_WLAN_WGHT 0xffcc -#define AR_STOMP_LOW_WLAN_WGHT 0xaaa8 -#define AR_STOMP_NONE_WLAN_WGHT 0xaa00 +#define AR_STOMP_ALL_WLAN_WGHT 0xfcfc +#define AR_STOMP_LOW_WLAN_WGHT 0xa8a8 +#define AR_STOMP_NONE_WLAN_WGHT 0x0000 #define AR_BTCOEX_BT_WGHT 0x0000ffff #define AR_BTCOEX_BT_WGHT_S 0 #define AR_BTCOEX_WL_WGHT 0xffff0000 -- cgit v1.2.3 From aa4c7b2a2547db95388f795f092ea286fbdd98a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 22 Jan 2010 01:53:12 +0100 Subject: b43: check band width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 6 ++++++ drivers/net/wireless/b43/phy_common.h | 3 +++ drivers/net/wireless/b43/phy_n.c | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index c699e46534d..6d7cf3c2f7b 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3576,6 +3576,12 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) dev = wl->current_dev; phy = &dev->phy; + if (conf_is_ht(conf)) + phy->is_40mhz = + (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf)); + else + phy->is_40mhz = false; + b43_mac_suspend(dev); if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 9edd4e8e0c8..f635f9e4f83 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -212,6 +212,9 @@ struct b43_phy { bool supports_2ghz; bool supports_5ghz; + /* HT info */ + bool is_40mhz; + /* GMODE bit enabled? */ bool gmode; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e77f1f24d10..2cdf32e5fd9 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1787,7 +1787,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); - if (1 /* FIXME: the band width is 20 MHz */) + if (!dev->phy.is_40mhz) freq = 2500; else freq = 5000; -- cgit v1.2.3 From 75377b2476d85d90c0db07e780ee95741cff3a2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 22 Jan 2010 01:53:13 +0100 Subject: b43: N-PHY: implement overriding RF control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 82 ++++++++++++++++++++++++++++++++-- drivers/net/wireless/b43/tables_nphy.c | 37 +++++++++++++++ drivers/net/wireless/b43/tables_nphy.h | 21 +++++++++ 3 files changed, 137 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 2cdf32e5fd9..d3c9783b76b 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -912,6 +912,82 @@ ok: b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RFCtrlOverride */ +static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, + u16 value, u8 core, bool off) +{ + int i; + u8 index = fls(field); + u8 addr, en_addr, val_addr; + /* we expect only one bit set */ + B43_WARN_ON(field & (~(1 << index))); + + if (dev->phy.rev >= 3) { + const struct nphy_rf_control_override_rev3 *rf_ctrl; + for (i = 0; i < 2; i++) { + if (index == 0 || index == 16) { + b43err(dev->wl, + "Unsupported RF Ctrl Override call\n"); + return; + } + + rf_ctrl = &tbl_rf_control_override_rev3[index - 1]; + en_addr = B43_PHY_N((i == 0) ? + rf_ctrl->en_addr0 : rf_ctrl->en_addr1); + val_addr = B43_PHY_N((i == 0) ? + rf_ctrl->val_addr0 : rf_ctrl->val_addr1); + + if (off) { + b43_phy_mask(dev, en_addr, ~(field)); + b43_phy_mask(dev, val_addr, + ~(rf_ctrl->val_mask)); + } else { + if (core == 0 || ((1 << core) & i) != 0) { + b43_phy_set(dev, en_addr, field); + b43_phy_maskset(dev, val_addr, + ~(rf_ctrl->val_mask), + (value << rf_ctrl->val_shift)); + } + } + } + } else { + const struct nphy_rf_control_override_rev2 *rf_ctrl; + if (off) { + b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, ~(field)); + value = 0; + } else { + b43_phy_set(dev, B43_NPHY_RFCTL_OVER, field); + } + + for (i = 0; i < 2; i++) { + if (index <= 1 || index == 16) { + b43err(dev->wl, + "Unsupported RF Ctrl Override call\n"); + return; + } + + if (index == 2 || index == 10 || + (index >= 13 && index <= 15)) { + core = 1; + } + + rf_ctrl = &tbl_rf_control_override_rev2[index - 2]; + addr = B43_PHY_N((i == 0) ? + rf_ctrl->addr0 : rf_ctrl->addr1); + + if ((core & (1 << i)) != 0) + b43_phy_maskset(dev, addr, ~(rf_ctrl->bmask), + (value << rf_ctrl->shift)); + + b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_CMD_START); + udelay(1); + b43_phy_mask(dev, B43_NPHY_RFCTL_OVER, 0xFFFE); + } + } +} + static void b43_nphy_bphy_init(struct b43_wldev *dev) { unsigned int i; @@ -2075,8 +2151,8 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) | (cur_lna << 2)); - /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0], - 3, 0 as arguments */ + b43_nphy_rf_control_override(dev, 0x400, tmp[0], 3, + false); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); b43_nphy_stop_playback(dev); @@ -2124,7 +2200,7 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, break; } - /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/ + b43_nphy_rf_control_override(dev, 0x400, 0, 3, true); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); b43_ntab_write_bulk(dev, B43_NTAB16(7, 0x110), 2, gain_save); diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index b8c9fc619ab..dd9687d611d 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2883,6 +2883,43 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { 0x9084, 0x9267, 0x9056, 0x9234 }; +/* addr0, addr1, bmask, shift */ +const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = { + { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */ + { 0x7A, 0x7D, 0x0001, 0 }, /* for field == 0x0004 (fls == 3) */ + { 0x7A, 0x7D, 0x0002, 1 }, /* for field == 0x0008 (fls == 4) */ + { 0x7A, 0x7D, 0x0004, 2 }, /* for field == 0x0010 (fls == 5) */ + { 0x7A, 0x7D, 0x0030, 4 }, /* for field == 0x0020 (fls == 6) */ + { 0x7A, 0x7D, 0x00C0, 6 }, /* for field == 0x0040 (fls == 7) */ + { 0x7A, 0x7D, 0x0100, 8 }, /* for field == 0x0080 (fls == 8) */ + { 0x7A, 0x7D, 0x0200, 9 }, /* for field == 0x0100 (fls == 9) */ + { 0x78, 0x78, 0x0004, 2 }, /* for field == 0x0200 (fls == 10) */ + { 0x7B, 0x7E, 0x01FF, 0 }, /* for field == 0x0400 (fls == 11) */ + { 0x7C, 0x7F, 0x01FF, 0 }, /* for field == 0x0800 (fls == 12) */ + { 0x78, 0x78, 0x0100, 8 }, /* for field == 0x1000 (fls == 13) */ + { 0x78, 0x78, 0x0200, 9 }, /* for field == 0x2000 (fls == 14) */ + { 0x78, 0x78, 0xF000, 12 } /* for field == 0x4000 (fls == 15) */ +}; + +/* val_mask, val_shift, en_addr0, val_addr0, en_addr1, val_addr1 */ +const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { + { 0x8000, 15, 0xE5, 0xF9, 0xE6, 0xFB }, /* field == 0x0001 (fls 1) */ + { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ + { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ + { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ + { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ + { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ + { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ + { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ + { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ + { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ + { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ + { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ + { 0xFFFF, 0, 0xE7, 0x7B, 0xEC, 0x7E }, /* field == 0x1000 (fls 13) */ + { 0xFFFF, 0, 0xE7, 0x7C, 0xEC, 0x7F }, /* field == 0x2000 (fls 14) */ + { 0x00C0, 6, 0xE7, 0xF9, 0xEC, 0xFB } /* field == 0x4000 (fls 15) */ +}; + static inline void assert_ntab_array_sizes(void) { #undef check diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 6bbef894010..5d38172a152 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -51,6 +51,22 @@ struct nphy_txiqcal_ladder { u8 g_env; }; +struct nphy_rf_control_override_rev2 { + u8 addr0; + u8 addr1; + u16 bmask; + u8 shift; +}; + +struct nphy_rf_control_override_rev3 { + u16 val_mask; + u8 val_shift; + u8 en_addr0; + u8 val_addr0; + u8 en_addr1; + u8 val_addr1; +}; + /* Upload the default register value table. * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz * table is uploaded. If "ignore_uploadflag" is true, we upload any value @@ -178,4 +194,9 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; +extern const struct nphy_rf_control_override_rev2 + tbl_rf_control_override_rev2[]; +extern const struct nphy_rf_control_override_rev3 + tbl_rf_control_override_rev3[]; + #endif /* B43_TABLES_NPHY_H_ */ -- cgit v1.2.3 From 10a798733e0f47923a1050231d8d39609c62be70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 22 Jan 2010 01:53:14 +0100 Subject: b43: N-PHY: add running samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 68 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d3c9783b76b..f5900f04ff5 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -816,6 +816,66 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ +static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, + u16 wait, bool iqmode, bool dac_test) +{ + struct b43_phy_n *nphy = dev->phy.n; + int i; + u16 seq_mode; + u32 tmp; + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + if ((nphy->bb_mult_save & 0x80000000) == 0) { + tmp = b43_ntab_read(dev, B43_NTAB16(15, 87)); + nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; + } + + if (!dev->phy.is_40mhz) + tmp = 0x6464; + else + tmp = 0x4747; + b43_ntab_write(dev, B43_NTAB16(15, 87), tmp); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); + + b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); + + if (loops != 0xFFFF) + b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, (loops - 1)); + else + b43_phy_write(dev, B43_NPHY_SAMP_LOOPCNT, loops); + + b43_phy_write(dev, B43_NPHY_SAMP_WAITCNT, wait); + + seq_mode = b43_phy_read(dev, B43_NPHY_RFSEQMODE); + + b43_phy_set(dev, B43_NPHY_RFSEQMODE, B43_NPHY_RFSEQMODE_CAOVER); + if (iqmode) { + b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); + b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000); + } else { + if (dac_test) + b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5); + else + b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1); + } + for (i = 0; i < 100; i++) { + if (b43_phy_read(dev, B43_NPHY_RFSEQST) & 1) { + i = 0; + break; + } + udelay(10); + } + if (i) + b43err(dev->wl, "run samples timeout\n"); + + b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) { @@ -1869,8 +1929,8 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, freq = 5000; if (nphy->mphase_cal_phase_id > 2) - ;/* TODO: Call N PHY Run Samples with (band width * 8), - 0xFFFF, 0, 1, 0 as arguments */ + b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8, + 0xFFFF, 0, true, false); else ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments and save result as error */ @@ -2162,8 +2222,8 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, as arguments and save result as ret */ playtone = false; } else { - /* TODO: Call N PHY Run Samples with 160, - 0xFFFF, 0, 0, 0 as arguments */ + b43_nphy_run_samples(dev, 160, 0xFFFF, 0, + false, false); } if (ret == 0) { -- cgit v1.2.3 From 45ca697e60eb5d3cac4530ae3a88f96c297efb09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 22 Jan 2010 01:53:15 +0100 Subject: b43: N-PHY: add setting power amplifier filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 41 ++++++++++++++++++++++++++++++++-- drivers/net/wireless/b43/tables_nphy.c | 24 ++++++++++++++++++++ drivers/net/wireless/b43/tables_nphy.h | 1 + 3 files changed, 64 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f5900f04ff5..97a44e43d05 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1628,6 +1628,43 @@ static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core) } } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ExtPaSetTxDigiFilts */ +static void b43_nphy_ext_pa_set_tx_dig_filters(struct b43_wldev *dev) +{ + int i; + for (i = 0; i < 15; i++) + b43_phy_write(dev, B43_PHY_N(0x2C5 + i), + tbl_tx_filter_coef_rev4[2][i]); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IpaSetTxDigiFilts */ +static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev) +{ + int i, j; + /* B43_NPHY_TXF_20CO_S0A1, B43_NPHY_TXF_40CO_S0A1, unknown */ + u16 offset[] = { 0x186, 0x195, 0x2C5 }; + + for (i = 0; i < 3; i++) + for (j = 0; j < 15; j++) + b43_phy_write(dev, B43_PHY_N(offset[i] + j), + tbl_tx_filter_coef_rev4[i][j]); + + if (dev->phy.is_40mhz) { + for (j = 0; j < 15; j++) + b43_phy_write(dev, B43_PHY_N(offset[0] + j), + tbl_tx_filter_coef_rev4[3][j]); + } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + for (j = 0; j < 15; j++) + b43_phy_write(dev, B43_PHY_N(offset[0] + j), + tbl_tx_filter_coef_rev4[5][j]); + } + + if (dev->phy.channel == 14) + for (j = 0; j < 15; j++) + b43_phy_write(dev, B43_PHY_N(offset[0] + j), + tbl_tx_filter_coef_rev4[6][j]); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) { @@ -2371,9 +2408,9 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1); b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F, nphy->papd_epsilon_offset[1] << 7); - /* TODO N PHY IPA Set TX Dig Filters */ + b43_nphy_int_pa_set_tx_dig_filters(dev); } else if (phy->rev >= 5) { - /* TODO N PHY Ext PA Set TX Dig Filters */ + b43_nphy_ext_pa_set_tx_dig_filters(dev); } b43_nphy_workarounds(dev); diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index dd9687d611d..a00d509150f 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2883,6 +2883,30 @@ const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { 0x9084, 0x9267, 0x9056, 0x9234 }; +const s16 tbl_tx_filter_coef_rev4[7][15] = { + { -377, 137, -407, 208, -1527, + 956, 93, 186, 93, 230, + -44, 230, 20, -191, 201 }, + { -77, 20, -98, 49, -93, + 60, 56, 111, 56, 26, + -5, 26, 34, -32, 34 }, + { -360, 164, -376, 164, -1533, + 576, 308, -314, 308, 121, + -73, 121, 91, 124, 91 }, + { -295, 200, -363, 142, -1391, + 826, 151, 301, 151, 151, + 301, 151, 602, -752, 602 }, + { -92, 58, -96, 49, -104, + 44, 17, 35, 17, 12, + 25, 12, 13, 27, 13 }, + { -375, 136, -399, 209, -1479, + 949, 130, 260, 130, 230, + -44, 230, 201, -191, 201 }, + { 0xed9, 0xc8, 0xe95, 0x8e, 0xa91, + 0x33a, 0x97, 0x12d, 0x97, 0x97, + 0x12d, 0x97, 0x25a, 0xd10, 0x25a } +}; + /* addr0, addr1, bmask, shift */ const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[] = { { 0x78, 0x78, 0x0038, 3 }, /* for field == 0x0002 (fls == 2) */ diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 5d38172a152..9c1c6ecd367 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -193,6 +193,7 @@ extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[]; extern const u16 tbl_tx_iqlo_cal_cmds_recal[]; extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[]; extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[]; +extern const s16 tbl_tx_filter_coef_rev4[7][15]; extern const struct nphy_rf_control_override_rev2 tbl_rf_control_override_rev2[]; -- cgit v1.2.3 From 59af099b1956086b06c0d0f32ea99ce136b415b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 22 Jan 2010 01:53:16 +0100 Subject: b43: N-PHY: add TX tone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 60 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 97a44e43d05..a45a1f3ced4 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -816,6 +816,43 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ +static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, + bool test) +{ + int i; + u16 bw, len, num, rot, angle; + /* TODO: *buffer; */ + + bw = (dev->phy.is_40mhz) ? 40 : 20; + len = bw << 3; + + if (test) { + if (b43_phy_read(dev, B43_NPHY_BBCFG) & B43_NPHY_BBCFG_RSTRX) + bw = 82; + else + bw = 80; + + if (dev->phy.is_40mhz) + bw <<= 1; + + len = bw << 1; + } + + /* TODO: buffer = kzalloc(len * sizeof(u32), GFP_KERNEL); */ + num = len; + rot = (((freq * 36) / bw) << 16) / 100; + angle = 0; + + for (i = 0; i < num; i++) { + /* TODO */ + } + + /* TODO: Call N PHY Load Sample Table with buffer, num as arguments */ + /* TODO: kfree(buffer); */ + return num; +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, u16 wait, bool iqmode, bool dac_test) @@ -876,6 +913,20 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, b43_phy_write(dev, B43_NPHY_RFSEQMODE, seq_mode); } +/* + * Transmits a known value for LO calibration + * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone + */ +static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val, + bool iqmode, bool dac_test) +{ + u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test); + if (samp == 0) + return -1; + b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test); + return 0; +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) { @@ -1969,8 +2020,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8, 0xFFFF, 0, true, false); else - ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments - and save result as error */ + error = b43_nphy_tx_tone(dev, freq, 250, true, false); if (error == 0) { if (nphy->mphase_cal_phase_id > 2) { @@ -2254,9 +2304,9 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev, b43_nphy_stop_playback(dev); if (playtone) { - /* TODO: Call N PHY TX Tone with 4000, - (nphy_rxcalparams & 0xffff), 0, 0 - as arguments and save result as ret */ + ret = b43_nphy_tx_tone(dev, 4000, + (nphy->rxcalparams & 0xFFFF), + false, false); playtone = false; } else { b43_nphy_run_samples(dev, 160, 0xFFFF, 0, -- cgit v1.2.3 From b92f7d30830a319148df2943b7565989494e5ad1 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 22 Jan 2010 08:01:11 +0100 Subject: p54pci: revise tx locking This patch continues the effort which began with: "[PATCH] p54pci: move tx cleanup into tasklet". Thanks to these changes, p54pci's interrupt & tx cleanup routines can be made lock-less. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54pci.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 48cae48ed6e..bda29c00f3e 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -238,7 +238,6 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, int ring_index, struct p54p_desc *ring, u32 ring_limit, struct sk_buff **tx_buf) { - unsigned long flags; struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; struct p54p_desc *desc; @@ -249,7 +248,6 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, (*index) = idx = le32_to_cpu(ring_control->device_idx[1]); idx %= ring_limit; - spin_lock_irqsave(&priv->lock, flags); while (i != idx) { desc = &ring[i]; @@ -264,16 +262,12 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, desc->len = 0; desc->flags = 0; - if (skb && FREE_AFTER_TX(skb)) { - spin_unlock_irqrestore(&priv->lock, flags); + if (skb && FREE_AFTER_TX(skb)) p54_free_skb(dev, skb); - spin_lock_irqsave(&priv->lock, flags); - } i++; i %= ring_limit; } - spin_unlock_irqrestore(&priv->lock, flags); } static void p54p_tasklet(unsigned long dev_id) @@ -306,7 +300,6 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) struct p54p_priv *priv = dev->priv; __le32 reg; - spin_lock(&priv->lock); reg = P54P_READ(int_ident); if (unlikely(reg == cpu_to_le32(0xFFFFFFFF))) { goto out; @@ -321,15 +314,14 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) complete(&priv->boot_comp); out: - spin_unlock(&priv->lock); return reg ? IRQ_HANDLED : IRQ_NONE; } static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { + unsigned long flags; struct p54p_priv *priv = dev->priv; struct p54p_ring_control *ring_control = priv->ring_control; - unsigned long flags; struct p54p_desc *desc; dma_addr_t mapping; u32 device_idx, idx, i; @@ -370,14 +362,14 @@ static void p54p_stop(struct ieee80211_hw *dev) unsigned int i; struct p54p_desc *desc; - tasklet_kill(&priv->tasklet); - P54P_WRITE(int_enable, cpu_to_le32(0)); P54P_READ(int_enable); udelay(10); free_irq(priv->pdev->irq, dev); + tasklet_kill(&priv->tasklet); + P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); for (i = 0; i < ARRAY_SIZE(priv->rx_buf_data); i++) { -- cgit v1.2.3 From a13d276f1e49ae0bc4ad18ce8ea3c90656c9e8d4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 22 Jan 2010 14:22:42 -0800 Subject: iwlwifi: configure missed beacon threshold Add support to configure missed beacon threshold, by default, if receive "missed beacon" notification from uCode and has more than 5 consecutive beacon missed, then perform sensitivity calibration; with this change, allow user to adjust the missed beacon threshold from debugfs in case more sensitivity calibration required for better performance in noisy environment The default value (=5) should be good enough for the normal condition, but for very noisy environment, more sensitivity calibration could help improve the throughput, so by setting the missed beacon threshold to lower number, user might experience better performance result. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + drivers/net/wireless/iwlwifi/iwl-commands.h | 25 +++++++++++++--- drivers/net/wireless/iwlwifi/iwl-debug.h | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 46 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-rx.c | 5 ++-- drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 + 7 files changed, 74 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 62b6939df52..e9f786443d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3372,6 +3372,7 @@ static int iwl_init_drv(struct iwl_priv *priv) priv->iw_mode = NL80211_IFTYPE_STATION; priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; + priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; /* Choose which receivers/antennas to use */ if (priv->cfg->ops->hcmd->set_rxon_chain) diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index cee5fb2187c..8823d18b9f4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -3165,13 +3165,30 @@ struct iwl_notif_statistics { /* * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) + * + * uCode send MISSED_BEACONS_NOTIFICATION to driver when detect beacon missed + * in regardless of how many missed beacons, which mean when driver receive the + * notification, inside the command, it can find all the beacons information + * which include number of total missed beacons, number of consecutive missed + * beacons, number of beacons received and number of beacons expected to + * receive. + * + * If uCode detected consecutive_missed_beacons > 5, it will reset the radio + * in order to bring the radio/PHY back to working state; which has no relation + * to when driver will perform sensitivity calibration. + * + * Driver should set it own missed_beacon_threshold to decide when to perform + * sensitivity calibration based on number of consecutive missed beacons in + * order to improve overall performance, especially in noisy environment. + * */ -/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, - * then this notification will be sent. */ -#define CONSECUTIVE_MISSED_BCONS_TH 20 + +#define IWL_MISSED_BEACON_THRESHOLD_MIN (1) +#define IWL_MISSED_BEACON_THRESHOLD_DEF (5) +#define IWL_MISSED_BEACON_THRESHOLD_MAX IWL_MISSED_BEACON_THRESHOLD_DEF struct iwl_missed_beacon_notif { - __le32 consequtive_missed_beacons; + __le32 consecutive_missed_beacons; __le32 total_missed_becons; __le32 num_expected_beacons; __le32 num_recvd_beacons; diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 0facaca9b40..36b558f2332 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -112,6 +112,7 @@ struct iwl_debugfs { struct dentry *file_csr; struct dentry *file_ucode_tracing; struct dentry *file_fh_reg; + struct dentry *file_missed_beacon; } dbgfs_debug_files; u32 sram_offset; u32 sram_len; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index af00ad2afa1..02f80bc2130 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2131,6 +2131,49 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, return ret; } +static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + int pos = 0; + char buf[12]; + const size_t bufsz = sizeof(buf); + ssize_t ret; + + pos += scnprintf(buf + pos, bufsz - pos, "%d\n", + priv->missed_beacon_threshold); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + return ret; +} + +static ssize_t iwl_dbgfs_missed_beacon_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 missed; + + 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", &missed) != 1) + return -EINVAL; + + if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN || + missed > IWL_MISSED_BEACON_THRESHOLD_MAX) + priv->missed_beacon_threshold = + IWL_MISSED_BEACON_THRESHOLD_DEF; + else + priv->missed_beacon_threshold = missed; + + return count; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -2148,6 +2191,7 @@ DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); DEBUGFS_WRITE_FILE_OPS(csr); DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_FILE_OPS(fh_reg); +DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); /* * Create the debugfs files and directories @@ -2200,6 +2244,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); + DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); @@ -2260,6 +2305,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) file_clear_traffic_statistics); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); + DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. file_ucode_rx_stats); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index c6310b0b2f1..5e06e666f17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1053,6 +1053,7 @@ struct iwl_priv { #endif /* ucode beacon time */ u32 ucode_beacon_time; + int missed_beacon_threshold; /* we allocate array of iwl4965_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index eb45f8be074..dc06c7bb0f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -499,9 +499,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, struct iwl_missed_beacon_notif *missed_beacon; missed_beacon = &pkt->u.missed_beacon; - if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { + if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) > + priv->missed_beacon_threshold) { IWL_DEBUG_CALIB(priv, "missed bcn cnsq %d totl %d rcd %d expctd %d\n", - le32_to_cpu(missed_beacon->consequtive_missed_beacons), + le32_to_cpu(missed_beacon->consecutive_missed_beacons), le32_to_cpu(missed_beacon->total_missed_becons), le32_to_cpu(missed_beacon->num_recvd_beacons), le32_to_cpu(missed_beacon->num_expected_beacons)); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index c46f988d0a5..9c0b6ebbdc5 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3881,6 +3881,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) priv->band = IEEE80211_BAND_2GHZ; priv->iw_mode = NL80211_IFTYPE_STATION; + priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; iwl_reset_qos(priv); -- cgit v1.2.3 From afbdd69af0e6a0c40676d4d4b94a0a4414708eaa Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 22 Jan 2010 14:22:43 -0800 Subject: iwlwifi: add function to reset/tune radio if needed Adding "radio reset" function to help reset and stabilize the radio. During normal operation, sometime for unknown reason, radio encounter problem and can not recover by itself; the best way to recover from it is to reset and re-tune the radio. Currently, there is no RF reset command available, but since radio will get reset when switching channel, use internal hw scan request to force radio reset and get back to normal operation state. The internal hw scan will only perform passive scan on the first available channel (not the channel being used) in associated state. The request should be ignored if already performing scan operation or STA is not in associated state. Also include an "internal_scan" debugfs file to help trigger the internal scan from user mode. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-core.c | 24 +++++ drivers/net/wireless/iwlwifi/iwl-core.h | 2 + drivers/net/wireless/iwlwifi/iwl-debug.h | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 24 +++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-scan.c | 155 ++++++++++++++++++++++++++--- 6 files changed, 193 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index bb3ed25f843..645bc133577 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -3343,6 +3343,30 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) } EXPORT_SYMBOL(iwl_dump_fh); +void iwl_force_rf_reset(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_is_associated(priv)) { + IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); + return; + } + /* + * There is no easy and better way to force reset the radio, + * the only known method is switching channel which will force to + * reset and tune the radio. + * Use internal short scan (single channel) operation to should + * achieve this objective. + * Driver should reset the radio when number of consecutive missed + * beacon, or any other uCode error condition detected. + */ + IWL_DEBUG_INFO(priv, "perform radio reset.\n"); + iwl_internal_short_hw_scan(priv); + return; +} +EXPORT_SYMBOL(iwl_force_rf_reset); + #ifdef CONFIG_PM int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 785331a98aa..6de83d1e1eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -494,6 +494,8 @@ 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); int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req); +int iwl_internal_short_hw_scan(struct iwl_priv *priv); +void iwl_force_rf_reset(struct iwl_priv *priv); u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, const u8 *ie, int ie_len, int left); void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 36b558f2332..d81b4f39bb1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -113,6 +113,7 @@ struct iwl_debugfs { struct dentry *file_ucode_tracing; struct dentry *file_fh_reg; struct dentry *file_missed_beacon; + struct dentry *file_internal_scan; } dbgfs_debug_files; u32 sram_offset; u32 sram_len; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 02f80bc2130..4944fdb31ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2174,6 +2174,27 @@ static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_internal_scan_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 scan; + + 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", &scan) != 1) + return -EINVAL; + + iwl_internal_short_hw_scan(priv); + + return count; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -2192,6 +2213,7 @@ DEBUGFS_WRITE_FILE_OPS(csr); DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); +DEBUGFS_WRITE_FILE_OPS(internal_scan); /* * Create the debugfs files and directories @@ -2245,6 +2267,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); + DEBUGFS_ADD_FILE(internal_scan, debug, S_IWUSR); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); @@ -2306,6 +2329,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); + DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_internal_scan); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. file_ucode_rx_stats); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 5e06e666f17..502d7a6b090 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1080,6 +1080,7 @@ struct iwl_priv { void *scan; int scan_bands; struct cfg80211_scan_request *scan_request; + bool is_internal_short_scan; u8 scan_tx_ant[IEEE80211_NUM_BANDS]; u8 mgmt_tx_ant; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index ceb91f969e4..fd6bafbddfc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -314,6 +314,72 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_get_passive_dwell_time); +static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, + enum ieee80211_band band, + struct iwl_scan_channel *scan_ch) +{ + const struct ieee80211_supported_band *sband; + const struct iwl_channel_info *ch_info; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int i, added = 0; + u16 channel = 0; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) { + IWL_ERR(priv, "invalid band\n"); + return added; + } + + active_dwell = iwl_get_active_dwell_time(priv, band, 0); + passive_dwell = iwl_get_passive_dwell_time(priv, band); + + if (passive_dwell <= active_dwell) + passive_dwell = active_dwell + 1; + + /* only scan single channel, good enough to reset the RF */ + /* pick the first valid not in-use channel */ + if (band == IEEE80211_BAND_5GHZ) { + for (i = 14; i < priv->channel_count; i++) { + if (priv->channel_info[i].channel != + le16_to_cpu(priv->staging_rxon.channel)) { + channel = priv->channel_info[i].channel; + ch_info = iwl_get_channel_info(priv, + band, channel); + if (is_channel_valid(ch_info)) + break; + } + } + } else { + for (i = 0; i < 14; i++) { + if (priv->channel_info[i].channel != + le16_to_cpu(priv->staging_rxon.channel)) { + channel = + priv->channel_info[i].channel; + ch_info = iwl_get_channel_info(priv, + band, channel); + if (is_channel_valid(ch_info)) + break; + } + } + } + if (channel) { + scan_ch->channel = cpu_to_le16(channel); + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + /* Set txpower levels to defaults */ + scan_ch->dsp_atten = 110; + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; + else + scan_ch->tx_gain = ((1 << 5) | (5 << 3)); + added++; + } else + IWL_ERR(priv, "no valid channel found\n"); + return added; +} + static int iwl_get_channels_for_scan(struct iwl_priv *priv, enum ieee80211_band band, u8 is_active, u8 n_probes, @@ -421,6 +487,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, "Starting scan...\n"); set_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = false; priv->scan_start = jiffies; priv->scan_pass_start = priv->scan_start; @@ -488,6 +555,45 @@ out_unlock: } EXPORT_SYMBOL(iwl_mac_hw_scan); +/* + * internal short scan, this function should only been called while associated. + * It will reset and tune the radio to prevent possible RF related problem + */ +int iwl_internal_short_hw_scan(struct iwl_priv *priv) +{ + int ret = 0; + + if (!iwl_is_ready_rf(priv)) { + ret = -EIO; + IWL_DEBUG_SCAN(priv, "not ready or exit pending\n"); + goto out; + } + if (test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); + ret = -EAGAIN; + goto out; + } + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); + ret = -EAGAIN; + goto out; + } + priv->scan_bands = 0; + if (priv->band == IEEE80211_BAND_5GHZ) + priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); + else + priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); + + IWL_DEBUG_SCAN(priv, "Start internal short scan...\n"); + set_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = true; + queue_work(priv->workqueue, &priv->request_scan); + +out: + return ret; +} +EXPORT_SYMBOL(iwl_internal_short_hw_scan); + #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) void iwl_bg_scan_check(struct work_struct *data) @@ -551,7 +657,8 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, if (WARN_ON(left < ie_len)) return len; - memcpy(pos, ies, ie_len); + if (ies) + memcpy(pos, ies, ie_len); len += ie_len; left -= ie_len; @@ -654,7 +761,6 @@ static void iwl_bg_request_scan(struct work_struct *data) unsigned long flags; IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); - spin_lock_irqsave(&priv->lock, flags); interval = priv->beacon_int; spin_unlock_irqrestore(&priv->lock, flags); @@ -672,7 +778,9 @@ static void iwl_bg_request_scan(struct work_struct *data) scan_suspend_time, interval); } - if (priv->scan_request->n_ssids) { + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n"); + } else if (priv->scan_request->n_ssids) { int i, p = 0; IWL_DEBUG_SCAN(priv, "Kicking off active scan\n"); for (i = 0; i < priv->scan_request->n_ssids; i++) { @@ -753,24 +861,38 @@ static void iwl_bg_request_scan(struct work_struct *data) rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS; rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS; scan->rx_chain = cpu_to_le16(rx_chain); - cmd_len = iwl_fill_probe_req(priv, - (struct ieee80211_mgmt *)scan->data, - priv->scan_request->ie, - priv->scan_request->ie_len, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); + if (!priv->is_internal_short_scan) { + cmd_len = iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + priv->scan_request->ie, + priv->scan_request->ie_len, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + } else { + cmd_len = iwl_fill_probe_req(priv, + (struct ieee80211_mgmt *)scan->data, + NULL, 0, + IWL_MAX_SCAN_SIZE - sizeof(*scan)); + } scan->tx_cmd.len = cpu_to_le16(cmd_len); - if (iwl_is_monitor_mode(priv)) scan->filter_flags = RXON_FILTER_PROMISC_MSK; scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | RXON_FILTER_BCON_AWARE_MSK); - scan->channel_count = - iwl_get_channels_for_scan(priv, band, is_active, n_probes, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); - + if (priv->is_internal_short_scan) { + scan->channel_count = + iwl_get_single_channel_for_scan(priv, band, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } else { + scan->channel_count = + iwl_get_channels_for_scan(priv, band, + is_active, n_probes, + (void *)&scan->data[le16_to_cpu( + scan->tx_cmd.len)]); + } if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); goto done; @@ -831,7 +953,12 @@ void iwl_bg_scan_completed(struct work_struct *work) cancel_delayed_work(&priv->scan_check); - ieee80211_scan_completed(priv->hw, false); + if (!priv->is_internal_short_scan) + ieee80211_scan_completed(priv->hw, false); + else { + priv->is_internal_short_scan = false; + IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); + } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; -- cgit v1.2.3 From 220575f78fb0b8d2a1c41cd28115d52ae8d132ee Mon Sep 17 00:00:00 2001 From: Henry Zhangh Date: Fri, 22 Jan 2010 14:22:44 -0800 Subject: iwlwifi: Fix A band scanning when associated This patch allows A band to be scanned when driver is associated to AP. Scan mechanism is that mac80211/cfg80211 requests driver to scan G band first and then immediately to scan A band. Original code require driver to wait for 2 seconds after any scan before another scan will be performed. This caused driver to service G band scan request from mac80211/cfg80211 but deny the A band scan request. Signed-off-by: Henry Zhangh Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-scan.c | 17 ++--------------- 2 files changed, 2 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 502d7a6b090..42cf1810b45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1072,7 +1072,6 @@ struct iwl_priv { struct iwl_calib_result calib_results[IWL_CALIB_MAX]; /* Scan related variables */ - unsigned long last_scan_jiffies; unsigned long next_scan_jiffies; unsigned long scan_start; unsigned long scan_pass_start; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index fd6bafbddfc..07fabbbfd56 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -192,18 +192,15 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, IWL_DEBUG_SCAN(priv, "Scan ch.res: " "%d [802.11%s] " "(TSF: 0x%08X:%08X) - %d " - "elapsed=%lu usec (%dms since last)\n", + "elapsed=%lu usec\n", notif->channel, notif->band ? "bg" : "a", le32_to_cpu(notif->tsf_high), le32_to_cpu(notif->tsf_low), le32_to_cpu(notif->statistics[0]), - le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, - jiffies_to_msecs(elapsed_jiffies - (priv->last_scan_jiffies, jiffies))); + le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf); #endif - priv->last_scan_jiffies = jiffies; priv->next_scan_jiffies = 0; } @@ -250,7 +247,6 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, goto reschedule; } - priv->last_scan_jiffies = jiffies; priv->next_scan_jiffies = 0; IWL_DEBUG_INFO(priv, "Setting scan to off\n"); @@ -528,15 +524,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, goto out_unlock; } - /* if we just finished scan ask for delay */ - if (iwl_is_associated(priv) && priv->last_scan_jiffies && - time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) { - IWL_DEBUG_SCAN(priv, "scan rejected: within previous scan period\n"); - queue_work(priv->workqueue, &priv->scan_completed); - ret = 0; - goto out_unlock; - } - priv->scan_bands = 0; for (i = 0; i < req->n_channels; i++) priv->scan_bands |= BIT(req->channels[i]->band); -- cgit v1.2.3 From d4d59e88cb746165c6fe33eacb6f582d525c6ef1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 22 Jan 2010 14:22:45 -0800 Subject: iwlwifi: Logic to control how frequent radio should be reset if needed Add additional logic for internal scan routine to control how frequent this function should be performed. The intent of this function is to reset/re-tune the radio and bring the RF/PHY back to normal state, it does not make sense calling it too frequent, if reset the radio can not bring it back to normal state, it indicate there are other reason to cause the radio not operate correctly. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 + drivers/net/wireless/iwlwifi/iwl-scan.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 42cf1810b45..86d38ae2ec7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1076,6 +1076,7 @@ struct iwl_priv { unsigned long scan_start; unsigned long scan_pass_start; unsigned long scan_start_tsf; + unsigned long last_internal_scan_jiffies; void *scan; int scan_bands; struct cfg80211_scan_request *scan_request; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 07fabbbfd56..08faafae849 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -201,7 +201,8 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf); #endif - priv->next_scan_jiffies = 0; + if (!priv->is_internal_short_scan) + priv->next_scan_jiffies = 0; } /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ @@ -247,7 +248,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, goto reschedule; } - priv->next_scan_jiffies = 0; + if (!priv->is_internal_short_scan) + priv->next_scan_jiffies = 0; + else + priv->last_internal_scan_jiffies = jiffies; + IWL_DEBUG_INFO(priv, "Setting scan to off\n"); clear_bit(STATUS_SCANNING, &priv->status); @@ -546,6 +551,8 @@ EXPORT_SYMBOL(iwl_mac_hw_scan); * internal short scan, this function should only been called while associated. * It will reset and tune the radio to prevent possible RF related problem */ +#define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1) + int iwl_internal_short_hw_scan(struct iwl_priv *priv) { int ret = 0; @@ -565,6 +572,13 @@ int iwl_internal_short_hw_scan(struct iwl_priv *priv) ret = -EAGAIN; goto out; } + if (priv->last_internal_scan_jiffies && + time_after(priv->last_internal_scan_jiffies + + IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) { + IWL_DEBUG_SCAN(priv, "internal scan rejected\n"); + goto out; + } + priv->scan_bands = 0; if (priv->band == IEEE80211_BAND_5GHZ) priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); -- cgit v1.2.3 From 3e4fb5faefb57824f2e42305b3d5907845af978c Mon Sep 17 00:00:00 2001 From: Trieu 'Andrew' Nguyen Date: Fri, 22 Jan 2010 14:22:46 -0800 Subject: iwlwifi: Tune radio to prevent unexpected behavior We have seen the throughput dropped due to external noisy environment and the radio is out of tune. There are lot of plcp errors indicating this condition. Eventually the station can get de-authenticated by the Access Point. By resetting and tuning the radio, the plcp errors are reduced or eliminated and the throughput starts to rise. To prevent unexpected behavior such as drop in throughput or deauthentication, - The change provides the driver feature to monitor and tune the radio base on the statistics notification from the uCode. - It also allows the setting of the plcp error rate threshold via the plcp_delta under debugfs interface. Signed-off-by: Trieu 'Andrew' Nguyen Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-3945.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 7 ++++ drivers/net/wireless/iwlwifi/iwl-6000.c | 6 ++++ drivers/net/wireless/iwlwifi/iwl-core.h | 3 ++ drivers/net/wireless/iwlwifi/iwl-debug.h | 1 + drivers/net/wireless/iwlwifi/iwl-debugfs.c | 44 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-dev.h | 12 +++++++ drivers/net/wireless/iwlwifi/iwl-rx.c | 54 ++++++++++++++++++++++++++++++ 10 files changed, 132 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index d5c6edbbc95..85162e2c35d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -175,6 +175,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct iwl_cfg iwl1000_bg_cfg = { @@ -201,6 +202,7 @@ struct iwl_cfg iwl1000_bg_cfg = { .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 6472910b72d..764479f74c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -2830,6 +2830,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { .ht_greenfield_support = false, .led_compensation = 64, .broken_powersave = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; static struct iwl_cfg iwl3945_abg_cfg = { @@ -2847,6 +2848,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { .ht_greenfield_support = false, .led_compensation = 64, .broken_powersave = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct pci_device_id iwl3945_hw_card_ids[] = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 8159a0fcf5a..c36fef99b4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2239,6 +2239,7 @@ struct iwl_cfg iwl4965_agn_cfg = { .broken_powersave = true, .led_compensation = 61, .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; /* Module firmware */ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index aab6cf23c2b..cbbc0e4f2c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1603,6 +1603,7 @@ struct iwl_cfg iwl5300_agn_cfg = { .led_compensation = 51, .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; struct iwl_cfg iwl5100_bgn_cfg = { @@ -1627,6 +1628,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { .led_compensation = 51, .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; struct iwl_cfg iwl5100_abg_cfg = { @@ -1649,6 +1651,7 @@ struct iwl_cfg iwl5100_abg_cfg = { .use_bsm = false, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; struct iwl_cfg iwl5100_agn_cfg = { @@ -1673,6 +1676,7 @@ struct iwl_cfg iwl5100_agn_cfg = { .led_compensation = 51, .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; struct iwl_cfg iwl5350_agn_cfg = { @@ -1697,6 +1701,7 @@ struct iwl_cfg iwl5350_agn_cfg = { .led_compensation = 51, .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; struct iwl_cfg iwl5150_agn_cfg = { @@ -1721,6 +1726,7 @@ struct iwl_cfg iwl5150_agn_cfg = { .led_compensation = 51, .use_rts_for_ht = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; struct iwl_cfg iwl5150_abg_cfg = { @@ -1743,6 +1749,7 @@ struct iwl_cfg iwl5150_abg_cfg = { .use_bsm = false, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, }; MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 4dab7f12e72..b191c634ad9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -308,6 +308,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct iwl_cfg iwl6000i_2abg_cfg = { @@ -337,6 +338,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct iwl_cfg iwl6000i_2bg_cfg = { @@ -366,6 +368,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct iwl_cfg iwl6050_2agn_cfg = { @@ -396,6 +399,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct iwl_cfg iwl6050_2abg_cfg = { @@ -425,6 +429,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; struct iwl_cfg iwl6000_3agn_cfg = { @@ -455,6 +460,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { .supports_idle = true, .adv_thermal_throttle = true, .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 6de83d1e1eb..661918347d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -232,6 +232,8 @@ struct iwl_mod_params { * @adv_thermal_throttle: support advance thermal throttle * @support_ct_kill_exit: support ct kill exit condition * @support_wimax_coexist: support wimax/wifi co-exist + * @plcp_delta_threshold: plcp error rate threshold used to trigger + * radio tuning when there is a high receiving plcp error rate * * We enable the driver to be backward compatible wrt API version. The * driver specifies which APIs it supports (with @ucode_api_max being the @@ -288,6 +290,7 @@ struct iwl_cfg { bool adv_thermal_throttle; bool support_ct_kill_exit; const bool support_wimax_coexist; + u8 plcp_delta_threshold; }; /*************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index d81b4f39bb1..aff1dc0756f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -114,6 +114,7 @@ struct iwl_debugfs { struct dentry *file_fh_reg; struct dentry *file_missed_beacon; struct dentry *file_internal_scan; + struct dentry *file_plcp_delta; } dbgfs_debug_files; u32 sram_offset; u32 sram_len; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 4944fdb31ba..3f9c0399849 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2195,6 +2195,47 @@ static ssize_t iwl_dbgfs_internal_scan_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + char buf[12]; + const size_t bufsz = sizeof(buf); + ssize_t ret; + + pos += scnprintf(buf + pos, bufsz - pos, "%u\n", + priv->cfg->plcp_delta_threshold); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + return ret; +} + +static ssize_t iwl_dbgfs_plcp_delta_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 plcp; + + 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", &plcp) != 1) + return -EINVAL; + if ((plcp <= IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || + (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) + priv->cfg->plcp_delta_threshold = + IWL_MAX_PLCP_ERR_THRESHOLD_DEF; + else + priv->cfg->plcp_delta_threshold = plcp; + return count; +} + DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -2214,6 +2255,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); DEBUGFS_WRITE_FILE_OPS(internal_scan); +DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); /* * Create the debugfs files and directories @@ -2268,6 +2310,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); DEBUGFS_ADD_FILE(internal_scan, debug, S_IWUSR); + DEBUGFS_ADD_FILE(plcp_delta, debug, S_IWUSR | S_IRUSR); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); @@ -2330,6 +2373,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_internal_scan); + DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_plcp_delta); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. file_ucode_rx_stats); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 86d38ae2ec7..a1f3ecb69ed 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1026,6 +1026,15 @@ struct iwl_event_log { #define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10) #define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0) +/* + * This is the threshold value of plcp error rate per 100mSecs. It is + * used to set and check for the validity of plcp_delta. + */ +#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0) +#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50) +#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100) +#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255) + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1055,6 +1064,9 @@ struct iwl_priv { u32 ucode_beacon_time; int missed_beacon_threshold; + /* storing the jiffies when the plcp error rate is received */ + unsigned long plcp_jiffies; + /* we allocate array of iwl4965_channel_info for NIC's valid channels. * Access via channel # using indirect index array */ struct iwl_channel_info *channel_info; /* channel info array */ diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index dc06c7bb0f5..ea309f42a78 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -602,11 +602,15 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, #define REG_RECALIB_PERIOD (60) +#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n" void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); + int combined_plcp_delta; + unsigned int plcp_msec; + unsigned long plcp_received_jiffies; IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", (int)sizeof(priv->statistics), @@ -621,6 +625,56 @@ void iwl_rx_statistics(struct iwl_priv *priv, #ifdef CONFIG_IWLWIFI_DEBUG iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats); #endif + /* + * check for plcp_err and trigger radio reset if it exceeds + * the plcp error threshold plcp_delta. + */ + plcp_received_jiffies = jiffies; + plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies - + (long) priv->plcp_jiffies); + priv->plcp_jiffies = plcp_received_jiffies; + /* + * check to make sure plcp_msec is not 0 to prevent division + * by zero. + */ + if (plcp_msec) { + combined_plcp_delta = + (le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) - + le32_to_cpu(priv->statistics.rx.ofdm.plcp_err)) + + (le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) - + le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); + + if ((combined_plcp_delta > 0) && + ((combined_plcp_delta * 100) / plcp_msec) > + priv->cfg->plcp_delta_threshold) { + /* + * if plcp_err exceed the threshold, the following + * data is printed in csv format: + * Text: plcp_err exceeded %d, + * Received ofdm.plcp_err, + * Current ofdm.plcp_err, + * Received ofdm_ht.plcp_err, + * Current ofdm_ht.plcp_err, + * combined_plcp_delta, + * plcp_msec + */ + IWL_DEBUG_RADIO(priv, PLCP_MSG, + priv->cfg->plcp_delta_threshold, + le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), + le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), + le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), + le32_to_cpu( + priv->statistics.rx.ofdm_ht.plcp_err), + combined_plcp_delta, plcp_msec); + + /* + * Reset the RF radio due to the high plcp + * error rate + */ + iwl_force_rf_reset(priv); + } + } + memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); set_bit(STATUS_STATISTICS, &priv->status); -- cgit v1.2.3 From 07f33f92e8e1e6ed2ec9d4de048142e7a1d96856 Mon Sep 17 00:00:00 2001 From: Abhijeet Kolekar Date: Fri, 22 Jan 2010 14:22:47 -0800 Subject: iwlwifi: enable DC calibration From: Abhijeet Kolekar For 6X50 DC calibration needs to be initialized else uCode will run an endless loop. Enbale DC calibration in hw config. Signed-off-by: Abhijeet Kolekar Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-6000.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index b191c634ad9..f89ef4aa78f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -158,11 +158,25 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) /* Set initial sensitivity parameters */ /* Set initial calibration set */ priv->hw_params.sens = &iwl6000_sensitivity; - priv->hw_params.calib_init_cfg = + switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { + case CSR_HW_REV_TYPE_6x50: + priv->hw_params.calib_init_cfg = BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_DC) | BIT(IWL_CALIB_LO) | BIT(IWL_CALIB_TX_IQ) | BIT(IWL_CALIB_BASE_BAND); + + break; + default: + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_BASE_BAND); + break; + } + return 0; } -- cgit v1.2.3 From 1fa97aaeb7fb5111f69abfdb8db656ce19e4951e Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 22 Jan 2010 14:22:48 -0800 Subject: iwlwifi: cleanup station adding code The work done when a station is added is very similar whether the station is added synchronously or asynchronously. Centralize this work. At the same time increase the status flags being checked for when the command returns with accompanying debug messages. Also increase checking when setting the "ucode active" state with accompanying debugging. This work is done in preparation for station notification support. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sta.c | 114 ++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 8afa39b4b48..842f1565323 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -80,46 +80,103 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) } EXPORT_SYMBOL(iwl_get_ra_sta_id); +/* priv->sta_lock must be held */ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) { - unsigned long flags; - - spin_lock_irqsave(&priv->sta_lock, flags); if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) - IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", - sta_id); + IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u addr %pM\n", + sta_id, priv->stations[sta_id].sta.sta.addr); - priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; - IWL_DEBUG_ASSOC(priv, "Added STA to Ucode: %pM\n", - priv->stations[sta_id].sta.sta.addr); - - spin_unlock_irqrestore(&priv->sta_lock, flags); + if (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) { + IWL_DEBUG_ASSOC(priv, + "STA id %u addr %pM already present in uCode (according to driver)\n", + sta_id, priv->stations[sta_id].sta.sta.addr); + } else { + priv->stations[sta_id].used |= IWL_STA_UCODE_ACTIVE; + IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n", + sta_id, priv->stations[sta_id].sta.sta.addr); + } } -static void iwl_add_sta_callback(struct iwl_priv *priv, - struct iwl_device_cmd *cmd, - struct iwl_rx_packet *pkt) +static void iwl_process_add_sta_resp(struct iwl_priv *priv, + struct iwl_addsta_cmd *addsta, + struct iwl_rx_packet *pkt, + bool sync) { - struct iwl_addsta_cmd *addsta = - (struct iwl_addsta_cmd *)cmd->cmd.payload; u8 sta_id = addsta->sta.sta_id; + unsigned long flags; if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", - pkt->hdr.flags); + pkt->hdr.flags); return; } + IWL_DEBUG_INFO(priv, "Processing response for adding station %u\n", + sta_id); + + spin_lock_irqsave(&priv->sta_lock, flags); + switch (pkt->u.add_sta.status) { case ADD_STA_SUCCESS_MSK: + IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); iwl_sta_ucode_activate(priv, sta_id); - /* fall through */ + break; + case ADD_STA_NO_ROOM_IN_TABLE: + IWL_ERR(priv, "Adding station %d failed, no room in table.\n", + sta_id); + break; + case ADD_STA_NO_BLOCK_ACK_RESOURCE: + IWL_ERR(priv, "Adding station %d failed, no block ack resource.\n", + sta_id); + break; + case ADD_STA_MODIFY_NON_EXIST_STA: + IWL_ERR(priv, "Attempting to modify non-existing station %d \n", + sta_id); + break; default: - IWL_DEBUG_HC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", - pkt->u.add_sta.status); + IWL_DEBUG_ASSOC(priv, "Received REPLY_ADD_STA:(0x%08X)\n", + pkt->u.add_sta.status); break; } + + IWL_DEBUG_INFO(priv, "%s station id %u addr %pM\n", + priv->stations[sta_id].sta.mode == + STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", + sta_id, priv->stations[sta_id].sta.sta.addr); + + /* + * XXX: The MAC address in the command buffer is often changed from + * the original sent to the device. That is, the MAC address + * written to the command buffer often is not the same MAC adress + * read from the command buffer when the command returns. This + * issue has not yet been resolved and this debugging is left to + * observe the problem. + */ + IWL_DEBUG_INFO(priv, "%s station according to cmd buffer %pM\n", + priv->stations[sta_id].sta.mode == + STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", + addsta->sta.addr); + + /* + * Determine if we wanted to modify or add a station, + * if adding a station succeeded we have some more initialization + * to do when using station notification. TODO + */ + + spin_unlock_irqrestore(&priv->sta_lock, flags); +} + +static void iwl_add_sta_callback(struct iwl_priv *priv, + struct iwl_device_cmd *cmd, + struct iwl_rx_packet *pkt) +{ + struct iwl_addsta_cmd *addsta = + (struct iwl_addsta_cmd *)cmd->cmd.payload; + + iwl_process_add_sta_resp(priv, addsta, pkt, false); + } int iwl_send_add_sta(struct iwl_priv *priv, @@ -145,24 +202,9 @@ int iwl_send_add_sta(struct iwl_priv *priv, if (ret || (flags & CMD_ASYNC)) return ret; - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", - pkt->hdr.flags); - ret = -EIO; - } - if (ret == 0) { - switch (pkt->u.add_sta.status) { - case ADD_STA_SUCCESS_MSK: - iwl_sta_ucode_activate(priv, sta->sta.sta_id); - IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); - break; - default: - ret = -EIO; - IWL_WARN(priv, "REPLY_ADD_STA failed\n"); - break; - } + pkt = (struct iwl_rx_packet *)cmd.reply_page; + iwl_process_add_sta_resp(priv, sta, pkt, true); } iwl_free_pages(priv, cmd.reply_page); -- cgit v1.2.3 From 3459ab5a1c92eaf8b76e9fa1b6ca529cf83066f3 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 22 Jan 2010 14:22:49 -0800 Subject: iwlwifi: make broadcast station addition generic Add function pointer for broadcast station addition so that we can call it in from iwlcore at a later time. We only distinguish between iwlagn and iwl3945 broadcast station addition. For the iwl3945 station addition we add that function to iwlcore since that is where most station functionality resides, making it part of iwl3945 will require significant code reorganization that will dilute station management functionality. This seems to be an efficient solution. It may seem as though we are removing error checking when adding the 3945 broadcast station but this error checking was never really necessary since the function returns the station id and the broadcast station id is always set. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 1 + drivers/net/wireless/iwlwifi/iwl-3945.c | 7 ++----- drivers/net/wireless/iwlwifi/iwl-4965.c | 1 + drivers/net/wireless/iwlwifi/iwl-5000.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-6000.c | 1 + drivers/net/wireless/iwlwifi/iwl-agn.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-sta.c | 11 +++++++++++ drivers/net/wireless/iwlwifi/iwl-sta.h | 1 + 9 files changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 85162e2c35d..4281999cfaa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -140,6 +140,7 @@ static struct iwl_lib_ops iwl1000_lib = { .temperature = iwl5000_temperature, .set_ct_kill = iwl1000_set_ct_threshold, }, + .add_bcast_station = iwl_add_bcast_station, }; static const struct iwl_ops iwl1000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 764479f74c8..57194bbd276 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -1951,11 +1951,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) } /* Add the broadcast address so we can send broadcast frames */ - if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) == - IWL_INVALID_STATION) { - IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); - return -EIO; - } + priv->cfg->ops->lib->add_bcast_station(priv); /* If we have set the ASSOC_MSK and we are in BSS mode then * add the IWL_AP_ID to the station rate table */ @@ -2796,6 +2792,7 @@ static struct iwl_lib_ops iwl3945_lib = { .post_associate = iwl3945_post_associate, .isr = iwl_isr_legacy, .config_ap = iwl3945_config_ap, + .add_bcast_station = iwl3945_add_bcast_station, }; static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index c36fef99b4b..aebe8c51d3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -2206,6 +2206,7 @@ static struct iwl_lib_ops iwl4965_lib = { .temperature = iwl4965_temperature_calib, .set_ct_kill = iwl4965_set_ct_threshold, }, + .add_bcast_station = iwl_add_bcast_station, }; static const struct iwl_ops iwl4965_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index cbbc0e4f2c7..6027e2a658d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1503,6 +1503,7 @@ struct iwl_lib_ops iwl5000_lib = { .temperature = iwl5000_temperature, .set_ct_kill = iwl5000_set_ct_threshold, }, + .add_bcast_station = iwl_add_bcast_station, }; static struct iwl_lib_ops iwl5150_lib = { @@ -1556,6 +1557,7 @@ static struct iwl_lib_ops iwl5150_lib = { .temperature = iwl5150_temperature, .set_ct_kill = iwl5150_set_ct_threshold, }, + .add_bcast_station = iwl_add_bcast_station, }; static const struct iwl_ops iwl5000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index f89ef4aa78f..81e03e33ec7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -266,6 +266,7 @@ static struct iwl_lib_ops iwl6000_lib = { .temperature = iwl5000_temperature, .set_ct_kill = iwl6000_set_ct_threshold, }, + .add_bcast_station = iwl_add_bcast_station, }; static const struct iwl_ops iwl6000_ops = { diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index e9f786443d1..bed5dda8d6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -203,7 +203,8 @@ int iwl_commit_rxon(struct iwl_priv *priv) priv->start_calib = 0; /* Add the broadcast address so we can send broadcast frames */ - iwl_add_bcast_station(priv); + priv->cfg->ops->lib->add_bcast_station(priv); + /* If we have set the ASSOC_MSK and we are in BSS mode then * add the IWL_AP_ID to the station rate table */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 661918347d4..e14e32976b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -188,6 +188,8 @@ struct iwl_lib_ops { /* temperature */ struct iwl_temp_ops temp_ops; + /* station management */ + void (*add_bcast_station)(struct iwl_priv *priv); }; struct iwl_led_ops { diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 842f1565323..fcac73cf82b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1127,6 +1127,7 @@ static void iwl_sta_init_bcast_lq(struct iwl_priv *priv) */ void iwl_add_bcast_station(struct iwl_priv *priv) { + IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); /* Set up default rate scaling table in device's station table */ @@ -1134,6 +1135,16 @@ void iwl_add_bcast_station(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_add_bcast_station); +/** + * iwl3945_add_bcast_station - add broadcast station into station table. + */ +void iwl3945_add_bcast_station(struct iwl_priv *priv) +{ + IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); + iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); +} +EXPORT_SYMBOL(iwl3945_add_bcast_station); + /** * iwl_get_sta_id - Find station's index within station table * diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 8c6850d03e4..2dc35fe28f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -53,6 +53,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv, int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); void iwl_add_bcast_station(struct iwl_priv *priv); +void iwl3945_add_bcast_station(struct iwl_priv *priv); int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); void iwl_clear_stations_table(struct iwl_priv *priv); int iwl_get_free_ucode_key_index(struct iwl_priv *priv); -- cgit v1.2.3 From dab1c161fed18eb6b3472bdbfd827264caae097f Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 22 Jan 2010 14:22:50 -0800 Subject: iwlwifi: bit field description for BT Config command Give better bit filed define and description for flag parameter in REPLY_BT_CONFIG command: flags: bit 0 - 1: BT channel announcement enabled 0: disable bit 1 - 1: priority of BT device enabled 0: disable bit 2 - 1: BT 2 wire support enabled 0: disable Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 15 ++++++++++++--- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 8823d18b9f4..ce538946f3f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2247,10 +2247,19 @@ struct iwl_link_quality_cmd { __le32 reserved2; } __attribute__ ((packed)); +/* + * BT configuration enable flags: + * bit 0 - 1: BT channel announcement enabled + * 0: disable + * bit 1 - 1: priority of BT device enabled + * 0: disable + * bit 2 - 1: BT 2 wire support enabled + * 0: disable + */ #define BT_COEX_DISABLE (0x0) -#define BT_COEX_MODE_2W (0x1) -#define BT_COEX_MODE_3W (0x2) -#define BT_COEX_MODE_4W (0x3) +#define BT_ENABLE_CHANNEL_ANNOUNCE BIT(0) +#define BT_ENABLE_PRIORITY BIT(1) +#define BT_ENABLE_2_WIRE BIT(2) #define BT_LEAD_TIME_MIN (0x0) #define BT_LEAD_TIME_DEF (0x1E) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 645bc133577..d625aa8fe7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1977,7 +1977,7 @@ EXPORT_SYMBOL(iwl_isr_legacy); int iwl_send_bt_config(struct iwl_priv *priv) { struct iwl_bt_cmd bt_cmd = { - .flags = BT_COEX_MODE_4W, + .flags = BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY, .lead_time = BT_LEAD_TIME_DEF, .max_kill = BT_MAX_KILL_DEF, .kill_ack_mask = 0, -- cgit v1.2.3 From 06702a735eacf8679e9ff0d49eb3c989bc6b96ce Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 22 Jan 2010 14:22:51 -0800 Subject: iwlwifi: module parameter to enable/disable bt co-exist Adding "bt_coex_active" module parameter for iwlcore to enable/disable BT coexist; if bt_coex_active is true (default), uCode will do kill/defer every time the priority line is asserted (BT is sending signals on the priority line in the PCIx). By disable the bt_coex_active, uCode will ignore the BT activity and perform the normal operation. Users might experience transmit issue on some platform due to this WiFi/BT co-exist problem. The possible symptoms are: NetworkManager and other similar programs can scan and find all the available APs, but will timeout and unable to associate with any of the APs; no out-going frames can be found with wireless sniffer tools. On those platforms, WiFi communication can be restored by set "bt_coex_active" module parameter to "false" Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-commands.h | 3 +++ drivers/net/wireless/iwlwifi/iwl-core.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index ce538946f3f..c2f31eb26be 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2261,6 +2261,9 @@ struct iwl_link_quality_cmd { #define BT_ENABLE_PRIORITY BIT(1) #define BT_ENABLE_2_WIRE BIT(2) +#define BT_COEX_DISABLE (0x0) +#define BT_COEX_ENABLE (BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY) + #define BT_LEAD_TIME_MIN (0x0) #define BT_LEAD_TIME_DEF (0x1E) #define BT_LEAD_TIME_MAX (0xFF) diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d625aa8fe7a..1cfabd6be0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -47,6 +47,26 @@ MODULE_VERSION(IWLWIFI_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); +/* + * set bt_coex_active to true, uCode will do kill/defer + * every time the priority line is asserted (BT is sending signals on the + * priority line in the PCIx). + * set bt_coex_active to false, uCode will ignore the BT activity and + * perform the normal operation + * + * User might experience transmit issue on some platform due to WiFi/BT + * co-exist problem. The possible behaviors are: + * Able to scan and finding all the available AP + * Not able to associate with any AP + * On those platforms, WiFi communication can be restored by set + * "bt_coex_active" module parameter to "false" + * + * default: bt_coex_active = true (BT_COEX_ENABLE) + */ +static bool bt_coex_active = true; +module_param(bt_coex_active, bool, S_IRUGO); +MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist\n"); + static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 0, COEX_UNASSOC_IDLE_FLAGS}, @@ -1977,13 +1997,20 @@ EXPORT_SYMBOL(iwl_isr_legacy); int iwl_send_bt_config(struct iwl_priv *priv) { struct iwl_bt_cmd bt_cmd = { - .flags = BT_ENABLE_CHANNEL_ANNOUNCE | BT_ENABLE_PRIORITY, .lead_time = BT_LEAD_TIME_DEF, .max_kill = BT_MAX_KILL_DEF, .kill_ack_mask = 0, .kill_cts_mask = 0, }; + if (!bt_coex_active) + bt_cmd.flags = BT_COEX_DISABLE; + else + bt_cmd.flags = BT_COEX_ENABLE; + + IWL_DEBUG_INFO(priv, "BT coex %s\n", + (bt_cmd.flags == BT_COEX_DISABLE) ? "disable" : "active"); + return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(struct iwl_bt_cmd), &bt_cmd); } -- cgit v1.2.3 From 1d8c4ae9169ee8d8ca7fb84a7b6bb4c7a4d49397 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2010 14:22:52 -0800 Subject: iwlwifi: is no longer experimental It really hasn't been for a long time, not sure why this stuck around. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index b16b06c2031..e44e572acb9 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,6 +1,6 @@ config IWLWIFI tristate "Intel Wireless Wifi" - depends on PCI && MAC80211 && EXPERIMENTAL + depends on PCI && MAC80211 select FW_LOADER config IWLWIFI_SPECTRUM_MEASUREMENT -- cgit v1.2.3 From 158bea07c6017fa67bc0c64815ce5c3a998083dc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2010 14:22:53 -0800 Subject: iwlwifi: reorder device setup It is better to first notify cfg80211 about the hw rfkill state (so the rfkill device that will be registered won't have the wrong state while being registered), and the power/tt variable init can (and probably should) also be done first. Also rename iwl_setup_mac to iwl_mac_setup_register to better describe what it really does. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index bed5dda8d6b..1853064855c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2608,7 +2608,7 @@ void iwl_post_associate(struct iwl_priv *priv) * Not a mac80211 entry point function, but it fits in with all the * other mac80211 functions grouped here. */ -static int iwl_setup_mac(struct iwl_priv *priv) +static int iwl_mac_setup_register(struct iwl_priv *priv) { int ret; struct ieee80211_hw *hw = priv->hw; @@ -3625,9 +3625,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_setup_deferred_work(priv); iwl_setup_rx_handlers(priv); - /********************************** - * 8. Setup and register mac80211 - **********************************/ + /********************************************* + * 8. Enable interrupts and read RFKILL state + *********************************************/ /* enable interrupts if needed: hw bug w/a */ pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); @@ -3638,14 +3638,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_enable_interrupts(priv); - err = iwl_setup_mac(priv); - if (err) - goto out_remove_sysfs; - - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - /* If platform's RF_KILL switch is NOT set to KILL */ if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &priv->status); @@ -3657,6 +3649,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) iwl_power_initialize(priv); iwl_tt_initialize(priv); + + /************************************************** + * 9. Setup and register with mac80211 and debugfs + **************************************************/ + err = iwl_mac_setup_register(priv); + if (err) + goto out_remove_sysfs; + + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + return 0; out_remove_sysfs: -- cgit v1.2.3 From 4c84a8f1679f754d6080e49892f5cae2c88c91a8 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2010 14:22:54 -0800 Subject: iwlwifi: clean up debugfs code The debugfs code can be made a whole lot more efficient by using debugfs_remove_recursive(), the large chunk of variables can completely go away and by moving two variables we no longer need to allocate an extra chunk of memory. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-debug.h | 64 +------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 239 ++++++++++------------------- drivers/net/wireless/iwlwifi/iwl-dev.h | 3 +- 3 files changed, 91 insertions(+), 215 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index aff1dc0756f..1c7b53d511c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -67,63 +67,6 @@ do { \ DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ } while (0) -#ifdef CONFIG_IWLWIFI_DEBUGFS -struct iwl_debugfs { - const char *name; - struct dentry *dir_drv; - struct dentry *dir_data; - struct dentry *dir_debug; - struct dentry *dir_rf; - struct dir_data_files { - struct dentry *file_sram; - struct dentry *file_nvm; - struct dentry *file_stations; - struct dentry *file_log_event; - struct dentry *file_channels; - struct dentry *file_status; - struct dentry *file_interrupt; - struct dentry *file_qos; - struct dentry *file_thermal_throttling; - struct dentry *file_led; - struct dentry *file_disable_ht40; - struct dentry *file_sleep_level_override; - struct dentry *file_current_sleep_command; - } dbgfs_data_files; - struct dir_rf_files { - struct dentry *file_disable_sensitivity; - struct dentry *file_disable_chain_noise; - struct dentry *file_disable_tx_power; - } dbgfs_rf_files; - struct dir_debug_files { - struct dentry *file_rx_statistics; - struct dentry *file_tx_statistics; - struct dentry *file_traffic_log; - struct dentry *file_rx_queue; - struct dentry *file_tx_queue; - struct dentry *file_ucode_rx_stats; - struct dentry *file_ucode_tx_stats; - struct dentry *file_ucode_general_stats; - struct dentry *file_sensitivity; - struct dentry *file_chain_noise; - struct dentry *file_tx_power; - struct dentry *file_power_save_status; - struct dentry *file_clear_ucode_statistics; - struct dentry *file_clear_traffic_statistics; - struct dentry *file_csr; - struct dentry *file_ucode_tracing; - struct dentry *file_fh_reg; - struct dentry *file_missed_beacon; - struct dentry *file_internal_scan; - struct dentry *file_plcp_delta; - } dbgfs_debug_files; - u32 sram_offset; - u32 sram_len; -}; - -int iwl_dbgfs_register(struct iwl_priv *priv, const char *name); -void iwl_dbgfs_unregister(struct iwl_priv *priv); -#endif - #else #define IWL_DEBUG(__priv, level, fmt, args...) #define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) @@ -132,9 +75,10 @@ static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, {} #endif /* CONFIG_IWLWIFI_DEBUG */ - - -#ifndef CONFIG_IWLWIFI_DEBUGFS +#ifdef CONFIG_IWLWIFI_DEBUGFS +int iwl_dbgfs_register(struct iwl_priv *priv, const char *name); +void iwl_dbgfs_unregister(struct iwl_priv *priv); +#else static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) { return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 3f9c0399849..5c8377b9ad9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -41,43 +41,28 @@ #include "iwl-calib.h" /* create and remove of files */ -#define DEBUGFS_ADD_DIR(name, parent) do { \ - dbgfs->dir_##name = debugfs_create_dir(#name, parent); \ - if (!(dbgfs->dir_##name)) \ - goto err; \ +#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ + if (!debugfs_create_file(#name, mode, parent, priv, \ + &iwl_dbgfs_##name##_ops)) \ + goto err; \ } while (0) -#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ - dbgfs->dbgfs_##parent##_files.file_##name = \ - debugfs_create_file(#name, mode, \ - dbgfs->dir_##parent, priv, \ - &iwl_dbgfs_##name##_ops); \ - if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ - goto err; \ +#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ + struct dentry *__tmp; \ + __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ + parent, ptr); \ + if (IS_ERR(__tmp) || !__tmp) \ + goto err; \ } while (0) -#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ - dbgfs->dbgfs_##parent##_files.file_##name = \ - debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ - dbgfs->dir_##parent, ptr); \ - if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ - || !dbgfs->dbgfs_##parent##_files.file_##name) \ - goto err; \ +#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ + struct dentry *__tmp; \ + __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ + parent, ptr); \ + if (IS_ERR(__tmp) || !__tmp) \ + goto err; \ } while (0) -#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ - dbgfs->dbgfs_##parent##_files.file_##name = \ - debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \ - if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ - || !dbgfs->dbgfs_##parent##_files.file_##name) \ - goto err; \ -} while (0) - -#define DEBUGFS_REMOVE(name) do { \ - debugfs_remove(name); \ - name = NULL; \ -} while (0); - /* file operation */ #define DEBUGFS_READ_FUNC(name) \ static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ @@ -236,24 +221,24 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, size_t bufsz; /* default is to dump the entire data segment */ - if (!priv->dbgfs->sram_offset && !priv->dbgfs->sram_len) { - priv->dbgfs->sram_offset = 0x800000; + if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { + priv->dbgfs_sram_offset = 0x800000; if (priv->ucode_type == UCODE_INIT) - priv->dbgfs->sram_len = priv->ucode_init_data.len; + priv->dbgfs_sram_len = priv->ucode_init_data.len; else - priv->dbgfs->sram_len = priv->ucode_data.len; + priv->dbgfs_sram_len = priv->ucode_data.len; } - bufsz = 30 + priv->dbgfs->sram_len * sizeof(char) * 10; + bufsz = 30 + priv->dbgfs_sram_len * sizeof(char) * 10; buf = kmalloc(bufsz, GFP_KERNEL); if (!buf) return -ENOMEM; pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", - priv->dbgfs->sram_len); + priv->dbgfs_sram_len); pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", - priv->dbgfs->sram_offset); - for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { - val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ - priv->dbgfs->sram_len - i); + priv->dbgfs_sram_offset); + for (i = priv->dbgfs_sram_len; i > 0; i -= 4) { + val = iwl_read_targ_mem(priv, priv->dbgfs_sram_offset + \ + priv->dbgfs_sram_len - i); if (i < 4) { switch (i) { case 1: @@ -293,11 +278,11 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file, return -EFAULT; if (sscanf(buf, "%x,%x", &offset, &len) == 2) { - priv->dbgfs->sram_offset = offset; - priv->dbgfs->sram_len = len; + priv->dbgfs_sram_offset = offset; + priv->dbgfs_sram_len = len; } else { - priv->dbgfs->sram_offset = 0; - priv->dbgfs->sram_len = 0; + priv->dbgfs_sram_offset = 0; + priv->dbgfs_sram_len = 0; } return count; @@ -2263,75 +2248,73 @@ DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); */ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) { - struct iwl_debugfs *dbgfs; struct dentry *phyd = priv->hw->wiphy->debugfsdir; - int ret = 0; + struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; - dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); - if (!dbgfs) { - ret = -ENOMEM; - goto err; - } + dir_drv = debugfs_create_dir(name, phyd); + if (!dir_drv) + return -ENOMEM; - priv->dbgfs = dbgfs; - dbgfs->name = name; - dbgfs->dir_drv = debugfs_create_dir(name, phyd); - if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { - ret = -ENOENT; + priv->debugfs_dir = dir_drv; + + dir_data = debugfs_create_dir("data", dir_drv); + if (!dir_data) + goto err; + dir_rf = debugfs_create_dir("rf", dir_drv); + if (!dir_rf) + goto err; + dir_debug = debugfs_create_dir("debug", dir_drv); + if (!dir_debug) goto err; - } - DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); - DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); - DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); - DEBUGFS_ADD_FILE(nvm, data, S_IRUSR); - DEBUGFS_ADD_FILE(sram, data, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(log_event, data, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(stations, data, S_IRUSR); - DEBUGFS_ADD_FILE(channels, data, S_IRUSR); - DEBUGFS_ADD_FILE(status, data, S_IRUSR); - DEBUGFS_ADD_FILE(interrupt, data, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(qos, data, S_IRUSR); - DEBUGFS_ADD_FILE(led, data, S_IRUSR); - DEBUGFS_ADD_FILE(sleep_level_override, data, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(current_sleep_command, data, S_IRUSR); - DEBUGFS_ADD_FILE(thermal_throttling, data, S_IRUSR); - DEBUGFS_ADD_FILE(disable_ht40, data, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(rx_statistics, debug, S_IRUSR); - DEBUGFS_ADD_FILE(tx_statistics, debug, S_IRUSR); - DEBUGFS_ADD_FILE(traffic_log, debug, S_IWUSR | S_IRUSR); - DEBUGFS_ADD_FILE(rx_queue, debug, S_IRUSR); - DEBUGFS_ADD_FILE(tx_queue, debug, S_IRUSR); - DEBUGFS_ADD_FILE(tx_power, debug, S_IRUSR); - DEBUGFS_ADD_FILE(power_save_status, debug, S_IRUSR); - DEBUGFS_ADD_FILE(clear_ucode_statistics, debug, S_IWUSR); - DEBUGFS_ADD_FILE(clear_traffic_statistics, debug, S_IWUSR); - DEBUGFS_ADD_FILE(csr, debug, S_IWUSR); - DEBUGFS_ADD_FILE(fh_reg, debug, S_IRUSR); - DEBUGFS_ADD_FILE(missed_beacon, debug, S_IWUSR); - DEBUGFS_ADD_FILE(internal_scan, debug, S_IWUSR); - DEBUGFS_ADD_FILE(plcp_delta, debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); + DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); + DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(internal_scan, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { - DEBUGFS_ADD_FILE(ucode_rx_stats, debug, S_IRUSR); - DEBUGFS_ADD_FILE(ucode_tx_stats, debug, S_IRUSR); - DEBUGFS_ADD_FILE(ucode_general_stats, debug, S_IRUSR); - DEBUGFS_ADD_FILE(sensitivity, debug, S_IRUSR); - DEBUGFS_ADD_FILE(chain_noise, debug, S_IRUSR); - DEBUGFS_ADD_FILE(ucode_tracing, debug, S_IWUSR | S_IRUSR); + 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); + DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); } - DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); - DEBUGFS_ADD_BOOL(disable_chain_noise, rf, + DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); + DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &priv->disable_chain_noise_cal); if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) - DEBUGFS_ADD_BOOL(disable_tx_power, rf, + DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &priv->disable_tx_power_cal); return 0; err: - IWL_ERR(priv, "Can't open the debugfs directory\n"); + IWL_ERR(priv, "Can't create the debugfs directory\n"); iwl_dbgfs_unregister(priv); - return ret; + return -ENOMEM; } EXPORT_SYMBOL(iwl_dbgfs_register); @@ -2341,63 +2324,11 @@ EXPORT_SYMBOL(iwl_dbgfs_register); */ void iwl_dbgfs_unregister(struct iwl_priv *priv) { - if (!priv->dbgfs) + if (!priv->debugfs_dir) return; - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40); - DEBUGFS_REMOVE(priv->dbgfs->dir_data); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_clear_ucode_statistics); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_clear_traffic_statistics); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_csr); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_fh_reg); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_missed_beacon); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_internal_scan); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_plcp_delta); - if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_ucode_rx_stats); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_ucode_tx_stats); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_ucode_general_stats); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_sensitivity); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_chain_noise); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. - file_ucode_tracing); - } - DEBUGFS_REMOVE(priv->dbgfs->dir_debug); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); - if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || - ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) - 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); - priv->dbgfs = NULL; + debugfs_remove_recursive(priv->debugfs_dir); + priv->debugfs_dir = NULL; } EXPORT_SYMBOL(iwl_dbgfs_unregister); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index a1f3ecb69ed..d9f325bd4b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1309,7 +1309,8 @@ struct iwl_priv { u16 rx_traffic_idx; u8 *tx_traffic; u8 *rx_traffic; - struct iwl_debugfs *dbgfs; + struct dentry *debugfs_dir; + u32 dbgfs_sram_offset, dbgfs_sram_len; #endif /* CONFIG_IWLWIFI_DEBUGFS */ #endif /* CONFIG_IWLWIFI_DEBUG */ -- cgit v1.2.3 From 875295f183a8cb18e9fde0edae0ab88719debcbd Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2010 14:22:55 -0800 Subject: iwlwifi: fix sparse warning sparse correctly warns about symbol not being static, make static to shut it up. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1853064855c..d4500b5e017 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -705,7 +705,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, spin_unlock_irqrestore(&priv->reg_lock, reg_flags); } -void iwl_continuous_event_trace(struct iwl_priv *priv) +static void iwl_continuous_event_trace(struct iwl_priv *priv) { u32 capacity; /* event log capacity in # entries */ u32 base; /* SRAM byte address of event log header */ -- cgit v1.2.3 From 65baa90d92097ce9b7c080697e6b370d335c2efc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Jan 2010 14:22:56 -0800 Subject: iwlwifi: check endianness annotations by default sparse won't check endianness annotations by default, but iwlwifi is and should be clean so we can make sparse check them on it. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 7f82044af24..bdaa924d285 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -20,3 +20,5 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o # 3945 obj-$(CONFIG_IWL3945) += iwl3945.o iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o + +ccflags-y += -D__CHECK_ENDIAN__ -- cgit v1.2.3 From 81963d68575d497d626ce13e42c84518a931cc12 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Fri, 22 Jan 2010 14:22:57 -0800 Subject: iwlwifi: cleanup spectrum measurement command support In iwlagn the support for spectrum measurement command has been disabled since v2.6.29 without any requests for it. In addition to this when this command is indeed enabled it has been found to trigger firmware SYSASSERT on at least 4965 and 5100 hardware (see http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=1952 ). Since then this code has been bitrotting and cannot just be enabled without porting. Remove support for spectrum measurement command from iwlagn. It can be added back if there is a future need and the firmware problem it triggers has been fixed. Support for the spectrim measurement notification remains as it has been enabled all the time. In addition to this remove the 3945 spectrum measurement command Kconfig option and make this command always supported. The code added by this enabling is minimal and only run when user triggers a spectrum measurement request via sysfs. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/Kconfig | 12 -- drivers/net/wireless/iwlwifi/Makefile | 1 - drivers/net/wireless/iwlwifi/iwl-agn.c | 11 +- drivers/net/wireless/iwlwifi/iwl-core.h | 10 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 3 +- drivers/net/wireless/iwlwifi/iwl-rx.c | 18 +++ drivers/net/wireless/iwlwifi/iwl-spectrum.c | 198 ---------------------------- drivers/net/wireless/iwlwifi/iwl3945-base.c | 27 ++-- 8 files changed, 33 insertions(+), 247 deletions(-) delete mode 100644 drivers/net/wireless/iwlwifi/iwl-spectrum.c (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index e44e572acb9..dc8ed152766 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -3,12 +3,6 @@ config IWLWIFI depends on PCI && MAC80211 select FW_LOADER -config IWLWIFI_SPECTRUM_MEASUREMENT - bool "Enable Spectrum Measurement in iwlagn driver" - depends on IWLWIFI - ---help--- - This option will enable spectrum measurement for the iwlagn driver. - config IWLWIFI_DEBUG bool "Enable full debugging output in iwlagn and iwl3945 drivers" depends on IWLWIFI @@ -120,9 +114,3 @@ config IWL3945 inserted in and removed from the running kernel whenever you want), say M here and read . The module will be called iwl3945. - -config IWL3945_SPECTRUM_MEASUREMENT - bool "Enable Spectrum Measurement in iwl3945 driver" - depends on IWL3945 - ---help--- - This option will enable spectrum measurement for the iwl3945 driver. diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index bdaa924d285..4e378faee65 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -3,7 +3,6 @@ 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 iwl-calib.o iwlcore-objs += iwl-scan.o iwl-led.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o -iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o iwlcore-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o CFLAGS_iwl-devtrace.o := -I$(src) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d4500b5e017..4a268927377 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -73,13 +73,7 @@ #define VD #endif -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT -#define VS "s" -#else -#define VS -#endif - -#define DRV_VERSION IWLWIFI_VERSION VD VS +#define DRV_VERSION IWLWIFI_VERSION VD MODULE_DESCRIPTION(DRV_DESCRIPTION); @@ -889,6 +883,8 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; + priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = + iwl_rx_spectrum_measure_notif; priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; @@ -902,7 +898,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_reply_statistics; priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; - iwl_setup_spectrum_handlers(priv); iwl_setup_rx_scan_handlers(priv); /* status change handler */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e14e32976b8..ec1fe1d7cc9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -429,6 +429,8 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); /* Handlers */ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); void iwl_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwl_reply_statistics(struct iwl_priv *priv, @@ -531,14 +533,6 @@ int iwl_send_calib_results(struct iwl_priv *priv); int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); void iwl_calib_free_results(struct iwl_priv *priv); -/******************************************************************************* - * Spectrum Measureemtns in iwl-spectrum.c - ******************************************************************************/ -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT -void iwl_setup_spectrum_handlers(struct iwl_priv *priv); -#else -static inline void iwl_setup_spectrum_handlers(struct iwl_priv *priv) {} -#endif /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index d9f325bd4b6..9b0a5cbc20f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1055,11 +1055,10 @@ struct iwl_priv { struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; -#if defined(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) || defined(CONFIG_IWL3945_SPECTRUM_MEASUREMENT) /* spectrum measurement report caching */ struct iwl_spectrum_notification measure_report; u8 measurement_status; -#endif + /* ucode beacon time */ u32 ucode_beacon_time; int missed_beacon_threshold; diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index ea309f42a78..5df66382d92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -512,6 +512,24 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); +void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); + + if (!report->state) { + IWL_DEBUG_11H(priv, + "Spectrum Measure Notification: Start\n"); + return; + } + + memcpy(&priv->measure_report, report, sizeof(*report)); + priv->measurement_status |= MEASUREMENT_READY; +} +EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); + + /* Calculate noise level, based on measurements during network silence just * before arriving beacon. This measurement can be done only if we know diff --git a/drivers/net/wireless/iwlwifi/iwl-spectrum.c b/drivers/net/wireless/iwlwifi/iwl-spectrum.c deleted file mode 100644 index da166d1d1b1..00000000000 --- a/drivers/net/wireless/iwlwifi/iwl-spectrum.c +++ /dev/null @@ -1,198 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. - * - * Portions of this file are derived from the ipw3945 project, as well - * as portions of the ieee80211 subsystem header files. - * - * 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. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "iwl-eeprom.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-io.h" -#include "iwl-spectrum.h" - -#define BEACON_TIME_MASK_LOW 0x00FFFFFF -#define BEACON_TIME_MASK_HIGH 0xFF000000 -#define TIME_UNIT 1024 - -/* - * extended beacon time format - * time in usec will be changed into a 32-bit value in 8:24 format - * the high 1 byte is the beacon counts - * the lower 3 bytes is the time in usec within one beacon interval - */ - -/* TOOD: was used in sysfs debug interface need to add to mac */ -#if 0 -static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval) -{ - u32 quot; - u32 rem; - u32 interval = beacon_interval * 1024; - - if (!interval || !usec) - return 0; - - quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24); - rem = (usec % interval) & BEACON_TIME_MASK_LOW; - - return (quot << 24) + rem; -} - -/* base is usually what we get from ucode with each received frame, - * the same as HW timer counter counting down - */ - -static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) -{ - u32 base_low = base & BEACON_TIME_MASK_LOW; - u32 addon_low = addon & BEACON_TIME_MASK_LOW; - u32 interval = beacon_interval * TIME_UNIT; - u32 res = (base & BEACON_TIME_MASK_HIGH) + - (addon & BEACON_TIME_MASK_HIGH); - - if (base_low > addon_low) - res += base_low - addon_low; - else if (base_low < addon_low) { - res += interval + base_low - addon_low; - res += (1 << 24); - } else - res += (1 << 24); - - return cpu_to_le32(res); -} -static int iwl_get_measurement(struct iwl_priv *priv, - struct ieee80211_measurement_params *params, - u8 type) -{ - struct iwl4965_spectrum_cmd spectrum; - struct iwl_rx_packet *res; - struct iwl_host_cmd cmd = { - .id = REPLY_SPECTRUM_MEASUREMENT_CMD, - .data = (void *)&spectrum, - .meta.flags = CMD_WANT_SKB, - }; - u32 add_time = le64_to_cpu(params->start_time); - int rc; - int spectrum_resp_status; - int duration = le16_to_cpu(params->duration); - - if (iwl_is_associated(priv)) - add_time = - iwl_usecs_to_beacons( - le64_to_cpu(params->start_time) - priv->last_tsf, - le16_to_cpu(priv->rxon_timing.beacon_interval)); - - memset(&spectrum, 0, sizeof(spectrum)); - - spectrum.channel_count = cpu_to_le16(1); - spectrum.flags = - RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK; - spectrum.filter_flags = MEASUREMENT_FILTER_FLAG; - cmd.len = sizeof(spectrum); - spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); - - if (iwl_is_associated(priv)) - spectrum.start_time = - iwl_add_beacon_time(priv->last_beacon_time, - add_time, - le16_to_cpu(priv->rxon_timing.beacon_interval)); - else - spectrum.start_time = 0; - - spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); - spectrum.channels[0].channel = params->channel; - spectrum.channels[0].type = type; - if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK) - spectrum.flags |= RXON_FLG_BAND_24G_MSK | - RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; - - rc = iwl_send_cmd_sync(priv, &cmd); - if (rc) - return rc; - - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; - if (res->hdr.flags & IWL_CMD_FAILED_MSK) { - IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); - rc = -EIO; - } - - spectrum_resp_status = le16_to_cpu(res->u.spectrum.status); - switch (spectrum_resp_status) { - case 0: /* Command will be handled */ - if (res->u.spectrum.id != 0xff) { - IWL_DEBUG_INFO(priv, - "Replaced existing measurement: %d\n", - res->u.spectrum.id); - priv->measurement_status &= ~MEASUREMENT_READY; - } - priv->measurement_status |= MEASUREMENT_ACTIVE; - rc = 0; - break; - - case 1: /* Command will not be handled */ - rc = -EAGAIN; - break; - } - - dev_kfree_skb_any(cmd.meta.u.skb); - - return rc; -} -#endif - -static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); - - if (!report->state) { - IWL_DEBUG_11H(priv, - "Spectrum Measure Notification: Start\n"); - return; - } - - memcpy(&priv->measure_report, report, sizeof(*report)); - priv->measurement_status |= MEASUREMENT_READY; -} - -void iwl_setup_spectrum_handlers(struct iwl_priv *priv) -{ - priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = - iwl_rx_spectrum_measure_notif; -} -EXPORT_SYMBOL(iwl_setup_spectrum_handlers); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 9c0b6ebbdc5..cd42b5838b3 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -56,6 +56,7 @@ #include "iwl-helpers.h" #include "iwl-core.h" #include "iwl-dev.h" +#include "iwl-spectrum.h" /* * module name, copyright, version, etc. @@ -70,13 +71,12 @@ #define VD #endif -#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT -#define VS "s" -#else -#define VS -#endif - -#define DRV_VERSION IWLWIFI_VERSION VD VS +/* + * add "s" to indicate spectrum measurement included. + * we add it here to be consistent with previous releases in which + * this was configurable. + */ +#define DRV_VERSION IWLWIFI_VERSION VD "s" #define DRV_COPYRIGHT "Copyright(c) 2003-2010 Intel Corporation" #define DRV_AUTHOR "" @@ -689,10 +689,6 @@ drop: return -1; } -#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT - -#include "iwl-spectrum.h" - #define BEACON_TIME_MASK_LOW 0x00FFFFFF #define BEACON_TIME_MASK_HIGH 0xFF000000 #define TIME_UNIT 1024 @@ -819,7 +815,6 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, return rc; } -#endif static void iwl3945_rx_reply_alive(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) @@ -962,6 +957,8 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; + priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = + iwl_rx_spectrum_measure_notif; priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = iwl_rx_pm_debug_statistics_notif; @@ -975,7 +972,6 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv) priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; - iwl_setup_spectrum_handlers(priv); iwl_setup_rx_scan_handlers(priv); priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; @@ -3569,8 +3565,6 @@ static ssize_t store_filter_flags(struct device *d, static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, store_filter_flags); -#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT - static ssize_t show_measurement(struct device *d, struct device_attribute *attr, char *buf) { @@ -3640,7 +3634,6 @@ static ssize_t store_measurement(struct device *d, static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, show_measurement, store_measurement); -#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */ static ssize_t store_retry_rate(struct device *d, struct device_attribute *attr, @@ -3823,9 +3816,7 @@ static struct attribute *iwl3945_sysfs_entries[] = { &dev_attr_dump_errors.attr, &dev_attr_flags.attr, &dev_attr_filter_flags.attr, -#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT &dev_attr_measurement.attr, -#endif &dev_attr_retry_rate.attr, &dev_attr_statistics.attr, &dev_attr_status.attr, -- cgit v1.2.3 From ff27fabe62d288038b36f41ac6a2190ed7d15993 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Fri, 22 Jan 2010 14:22:58 -0800 Subject: iwlwifi: fix throughput degradation in aggregation mode The following commit commit e4da8c37af626001ff704fb29ea14eb58f5f7208 Author: Johannes Berg Date: Wed Dec 23 13:15:43 2009 +0100 mac80211: make off-channel work generic triggered a bug in iwlwifi where HT parameters would not be correctly set in some mac80211 pathways. The aggregation (and possibly other) station flags were not being set, which limited the size of aggregation blocks and reduced throughput at high rates. >From Johannes: """ Due to Wey-Yi's patch to use the set-channel command when the channel changes while associated, we don't get a full new RXON. Therefore, we don't re-set the rxon-station either. However, under some circumstances that apparently have gotten more likely mac80211 will first set up the BSS info, then add the station and then switch to an HT channel type. Therefore, the check for "priv->current_ht_config.is_ht" in iwl_rxon_add_station() will hit false and not fill in the HT information. However, that check can just be removed, which is the easiest fix for all this, because the HT capa struct is always there, just could possibly have the ht_supported member set to false. """ A sample good link in my 3x3 network improves by approximately 25% TCP throughput. This fixes Bug 2144 (http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2144). Signed-off-by: Daniel Halperin Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-sta.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index fcac73cf82b..e0b13fb7865 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1045,24 +1045,19 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) struct ieee80211_sta_ht_cap *cur_ht_config = NULL; u8 sta_id; - /* Add station to device's station table */ - /* - * XXX: This check is definitely not correct, if we're an AP - * it'll always be false which is not what we want, but - * it doesn't look like iwlagn is prepared to be an HT - * AP anyway. + * Set HT capabilities. It is ok to set this struct even if not using + * HT config: the priv->current_ht_config.is_ht flag will just be false */ - if (priv->current_ht_config.is_ht) { - rcu_read_lock(); - sta = ieee80211_find_sta(priv->vif, addr); - if (sta) { - memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); - cur_ht_config = &ht_config; - } - rcu_read_unlock(); + rcu_read_lock(); + sta = ieee80211_find_sta(priv->vif, addr); + if (sta) { + memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config)); + cur_ht_config = &ht_config; } + rcu_read_unlock(); + /* Add station to device's station table */ sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config); /* Set up default rate scaling table in device's station table */ -- cgit v1.2.3 From 658965107e2a45a1a4297cb494adc55797dd9ad1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 24 Jan 2010 03:26:11 +0100 Subject: ath9k: improve max rate retry handling ath9k currently forces hw->max_rate_tries to 4 to work around rate control inefficiencies. This has some negative side effects, such as rate_control_send_low also using a maximum of 4 tries, which could negatively affect reliability of unicast management frames. This patch pushes the retry limit to the rate control instead, and allows it to use more tries on the last stage to prevent unnecessary packet loss. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 3 +-- drivers/net/wireless/ath/ath9k/rc.c | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5f78d7a5ff2..c3066b55354 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -640,8 +640,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->max_rates = 4; hw->channel_change_time = 5000; hw->max_listen_interval = 10; - /* Hardware supports 10 but we use 4 */ - hw->max_rate_tries = 4; + hw->max_rate_tries = 10; hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index c915954d4d5..74290137f43 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -678,13 +678,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, * For Multi Rate Retry we use a different number of * retry attempt counts. This ends up looking like this: * - * MRR[0] = 2 - * MRR[1] = 2 - * MRR[2] = 2 - * MRR[3] = 4 + * MRR[0] = 4 + * MRR[1] = 4 + * MRR[2] = 4 + * MRR[3] = 8 * */ - try_per_rate = sc->hw->max_rate_tries; + try_per_rate = 4; rate_table = sc->cur_rate_table; rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); @@ -714,7 +714,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, for ( ; i < 4; i++) { /* Use twice the number of tries for the last MRR segment. */ if (i + 1 == 4) - try_per_rate = 4; + try_per_rate = 8; ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix); /* All other rates in the series have RTS enabled */ -- cgit v1.2.3 From 96869a39399269a776a94812e9fff3d38b47d838 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sun, 24 Jan 2010 13:13:32 +0100 Subject: b43: Workaround circular locking in hw-tkip key update callback The TKIP key update callback is called from the RX path, where the driver mutex is already locked. This results in a circular locking bug. Avoid this by removing the lock. Johannes noted that there is a separate bug: The callback still breaks on SDIO hardware, because SDIO hardware access needs to sleep, but we are not allowed to sleep in the callback due to mac80211's RCU locking. Signed-off-by: Michael Buesch Tested-by: Larry Finger Reported-by: kecsa@kutfo.hit.bme.hu Cc: Johannes Berg Cc: stable Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 6d7cf3c2f7b..66220cde9c4 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -856,22 +856,19 @@ static void b43_op_update_tkip_key(struct ieee80211_hw *hw, if (B43_WARN_ON(!modparam_hwtkip)) return; - mutex_lock(&wl->mutex); - + /* This is only called from the RX path through mac80211, where + * our mutex is already locked. */ + B43_WARN_ON(!mutex_is_locked(&wl->mutex)); dev = wl->current_dev; - if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) - goto out_unlock; + B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED); keymac_write(dev, index, NULL); /* First zero out mac to avoid race */ rx_tkip_phase1_write(dev, index, iv32, phase1key); /* only pairwise TKIP keys are supported right now */ if (WARN_ON(!sta)) - goto out_unlock; + return; keymac_write(dev, index, sta->addr); - -out_unlock: - mutex_unlock(&wl->mutex); } static void do_key_write(struct b43_wldev *dev, -- cgit v1.2.3 From 3ed0fac3b56504aaaa3d800e7891ed4a7068b85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 25 Jan 2010 18:59:58 +0100 Subject: b43: N-PHY: fix one bit off in parsing RF Ctrl Override arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index a45a1f3ced4..061b01b814d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1031,7 +1031,7 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, u8 index = fls(field); u8 addr, en_addr, val_addr; /* we expect only one bit set */ - B43_WARN_ON(field & (~(1 << index))); + B43_WARN_ON(field & (~(1 << (index - 1)))); if (dev->phy.rev >= 3) { const struct nphy_rf_control_override_rev3 *rf_ctrl; -- cgit v1.2.3 From 986504540306137dfc90a936f9f25086d15621c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 25 Jan 2010 18:59:59 +0100 Subject: b43: make cordic common (LP-PHY and N-PHY need it) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.c | 38 +++++++++++++++++++++++++++++ drivers/net/wireless/b43/phy_common.h | 3 +++ drivers/net/wireless/b43/phy_lp.c | 45 ++--------------------------------- 3 files changed, 43 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 75b26e175e8..446c41bb1e9 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -421,3 +421,41 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) { b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); } + +struct b43_c32 b43_cordic(int theta) +{ + u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, + 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, + 229, 115, 57, 29, }; + int i, tmp, signx = 1, angle = 0; + struct b43_c32 ret = { .i = 39797, .q = 0, }; + + theta = clamp_t(int, theta, -180, 180); + + if (theta > 90) { + theta -= 180; + signx = -1; + } else if (theta < -90) { + theta += 180; + signx = -1; + } + + for (i = 0; i <= 17; i++) { + if (theta > angle) { + tmp = ret.i - (ret.q >> i); + ret.q += ret.i >> i; + ret.i = tmp; + angle += arctg[i]; + } else { + tmp = ret.i + (ret.q >> i); + ret.q -= ret.i >> i; + ret.i = tmp; + angle -= arctg[i]; + } + } + + ret.i *= signx; + ret.q *= signx; + + return ret; +} diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index f635f9e4f83..9e4de47d060 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -5,6 +5,8 @@ struct b43_wldev; +/* Complex number using 2 32-bit signed integers */ +struct b43_c32 { s32 i, q; }; /* PHY register routing bits */ #define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ @@ -421,5 +423,6 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset); */ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); +struct b43_c32 b43_cordic(int theta); #endif /* LINUX_B43_PHY_COMMON_H_ */ diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index b58d6cf2658..45358507343 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -1767,47 +1767,6 @@ out: return ret; } -/* Complex number using 2 32-bit signed integers */ -typedef struct {s32 i, q;} lpphy_c32; - -static lpphy_c32 lpphy_cordic(int theta) -{ - u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, - 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, - 229, 115, 57, 29, }; - int i, tmp, signx = 1, angle = 0; - lpphy_c32 ret = { .i = 39797, .q = 0, }; - - theta = clamp_t(int, theta, -180, 180); - - if (theta > 90) { - theta -= 180; - signx = -1; - } else if (theta < -90) { - theta += 180; - signx = -1; - } - - for (i = 0; i <= 17; i++) { - if (theta > angle) { - tmp = ret.i - (ret.q >> i); - ret.q += ret.i >> i; - ret.i = tmp; - angle += arctg[i]; - } else { - tmp = ret.i + (ret.q >> i); - ret.q -= ret.i >> i; - ret.i = tmp; - angle -= arctg[i]; - } - } - - ret.i *= signx; - ret.q *= signx; - - return ret; -} - static void lpphy_run_samples(struct b43_wldev *dev, u16 samples, u16 loops, u16 wait) { @@ -1826,7 +1785,7 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) struct b43_phy_lp *lpphy = dev->phy.lp; u16 buf[64]; int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; - lpphy_c32 sample; + struct b43_c32 sample; lpphy->tx_tone_freq = freq; @@ -1842,7 +1801,7 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) } for (i = 0; i < samples; i++) { - sample = lpphy_cordic(angle); + sample = b43_cordic(angle); angle += rotation; buf[i] = ((sample.i * max) & 0xFF) << 8; buf[i] |= (sample.q * max) & 0xFF; -- cgit v1.2.3 From 6f98e62a9f1bdbd83d8d1be8c2ca6f58099846ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 25 Jan 2010 19:00:00 +0100 Subject: b43: update cordic code to match current specs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Tested-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_common.c | 19 +++++++++++++------ drivers/net/wireless/b43/phy_common.h | 4 ++++ drivers/net/wireless/b43/phy_lp.c | 7 ++++--- 3 files changed, 21 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 446c41bb1e9..8f7d7eff2d8 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -422,21 +422,28 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on) b43_write16(dev, B43_MMIO_PHY0, on ? 0 : 0xF4); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/Cordic */ struct b43_c32 b43_cordic(int theta) { u32 arctg[] = { 2949120, 1740967, 919879, 466945, 234379, 117304, 58666, 29335, 14668, 7334, 3667, 1833, 917, 458, 229, 115, 57, 29, }; - int i, tmp, signx = 1, angle = 0; + u8 i; + s32 tmp; + s8 signx = 1; + u32 angle = 0; struct b43_c32 ret = { .i = 39797, .q = 0, }; - theta = clamp_t(int, theta, -180, 180); + while (theta > (180 << 16)) + theta -= (360 << 16); + while (theta < -(180 << 16)) + theta += (360 << 16); - if (theta > 90) { - theta -= 180; + if (theta > (90 << 16)) { + theta -= (180 << 16); signx = -1; - } else if (theta < -90) { - theta += 180; + } else if (theta < -(90 << 16)) { + theta += (180 << 16); signx = -1; } diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index 9e4de47d060..bd480b481bf 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -8,6 +8,10 @@ struct b43_wldev; /* Complex number using 2 32-bit signed integers */ struct b43_c32 { s32 i, q; }; +#define CORDIC_CONVERT(value) (((value) >= 0) ? \ + ((((value) >> 15) + 1) >> 1) : \ + -((((-(value)) >> 15) + 1) >> 1)) + /* PHY register routing bits */ #define B43_PHYROUTE 0x0C00 /* PHY register routing bits mask */ #define B43_PHYROUTE_BASE 0x0000 /* Base registers */ diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 45358507343..185219e0a55 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c @@ -1784,7 +1784,8 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) { struct b43_phy_lp *lpphy = dev->phy.lp; u16 buf[64]; - int i, samples = 0, angle = 0, rotation = (9 * freq) / 500; + int i, samples = 0, angle = 0; + int rotation = (((36 * freq) / 20) << 16) / 100; struct b43_c32 sample; lpphy->tx_tone_freq = freq; @@ -1803,8 +1804,8 @@ static void lpphy_start_tx_tone(struct b43_wldev *dev, s32 freq, u16 max) for (i = 0; i < samples; i++) { sample = b43_cordic(angle); angle += rotation; - buf[i] = ((sample.i * max) & 0xFF) << 8; - buf[i] |= (sample.q * max) & 0xFF; + buf[i] = CORDIC_CONVERT((sample.i * max) & 0xFF) << 8; + buf[i] |= CORDIC_CONVERT((sample.q * max) & 0xFF); } b43_lptab_write_bulk(dev, B43_LPTAB16(5, 0), samples, buf); -- cgit v1.2.3 From f2982181e0531c0b12752336a1578626f99e7828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 25 Jan 2010 19:00:01 +0100 Subject: b43: N-PHY: use cordic to generate samples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 061b01b814d..df4bf435e21 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -821,8 +821,9 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, bool test) { int i; - u16 bw, len, num, rot, angle; - /* TODO: *buffer; */ + u16 bw, len, rot, angle; + b43_c32 *samples; + bw = (dev->phy.is_40mhz) ? 40 : 20; len = bw << 3; @@ -839,18 +840,20 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, len = bw << 1; } - /* TODO: buffer = kzalloc(len * sizeof(u32), GFP_KERNEL); */ - num = len; + samples = kzalloc(len * sizeof(b43_c32), GFP_KERNEL); rot = (((freq * 36) / bw) << 16) / 100; angle = 0; - for (i = 0; i < num; i++) { - /* TODO */ + for (i = 0; i < len; i++) { + samples[i] = b43_cordic(angle); + angle += rot; + samples[i].q = CORDIC_CONVERT(samples[i].q * max); + samples[i].i = CORDIC_CONVERT(samples[i].i * max); } - /* TODO: Call N PHY Load Sample Table with buffer, num as arguments */ - /* TODO: kfree(buffer); */ - return num; + /* TODO: Call N PHY Load Sample Table with buffer, len as arguments */ + kfree(samples); + return len; } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ -- cgit v1.2.3 From 56007a028c51cbf800a6c969d6f6431d23443b99 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Jan 2010 14:19:52 +0100 Subject: mac80211: wait for beacon before enabling powersave Because DTIM information is required for powersave but is only conveyed in beacons, wait for a beacon before enabling powersave, and change the way the information is conveyed to the driver accordingly. mwl8k doesn't currently seem to implement PS but requires the DTIM period in a different way; after talking to Lennert we agreed to just have mwl8k do the parsing itself in the finalize_join work. Signed-off-by: Johannes Berg Acked-by: Lennert Buytenhek Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/mwl8k.c | 14 +++++++++----- drivers/net/wireless/wl12xx/wl1251.h | 3 --- drivers/net/wireless/wl12xx/wl1251_main.c | 25 +++++++------------------ 4 files changed, 17 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 8599444bef0..9e3ca064145 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -319,7 +319,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; if (priv->vif) - dtimper = priv->vif->bss_conf.dtim_period; + dtimper = priv->hw->conf.ps_dtim_period; else dtimper = 1; diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 68546ca0ba3..f0f08f3919c 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -3881,12 +3881,16 @@ static void mwl8k_finalize_join_worker(struct work_struct *work) struct mwl8k_priv *priv = container_of(work, struct mwl8k_priv, finalize_join_worker); struct sk_buff *skb = priv->beacon_skb; - struct mwl8k_vif *mwl8k_vif; + struct ieee80211_mgmt *mgmt = (void *)skb->data; + int len = skb->len - offsetof(struct ieee80211_mgmt, u.beacon.variable); + const u8 *tim = cfg80211_find_ie(WLAN_EID_TIM, + mgmt->u.beacon.variable, len); + int dtim_period = 1; + + if (tim && tim[1] >= 2) + dtim_period = tim[3]; - mwl8k_vif = mwl8k_first_vif(priv); - if (mwl8k_vif != NULL) - mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, - mwl8k_vif->vif->bss_conf.dtim_period); + mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, dtim_period); dev_kfree_skb(skb); priv->beacon_skb = NULL; diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h index 6301578d156..37c61c19cae 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl12xx/wl1251.h @@ -341,9 +341,6 @@ struct wl1251 { /* Are we currently scanning */ bool scanning; - /* Our association ID */ - u16 aid; - /* Default key (for WEP) */ u32 default_key; diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c index 595f0f94d16..a717dde4822 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl12xx/wl1251_main.c @@ -617,10 +617,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) wl->psm_requested = true; + wl->dtim_period = conf->ps_dtim_period; + + ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, + wl->dtim_period); + /* - * We enter PSM only if we're already associated. - * If we're not, we'll enter it when joining an SSID, - * through the bss_info_changed() hook. + * mac80211 enables PSM only if we're already associated. */ ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE); if (ret < 0) @@ -943,7 +946,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *bss_conf, u32 changed) { - enum wl1251_cmd_ps_mode mode; struct wl1251 *wl = hw->priv; struct sk_buff *beacon, *skb; int ret; @@ -984,11 +986,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { if (bss_conf->assoc) { wl->beacon_int = bss_conf->beacon_int; - wl->dtim_period = bss_conf->dtim_period; - - ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int, - wl->dtim_period); - wl->aid = bss_conf->aid; skb = ieee80211_pspoll_get(wl->hw, wl->vif); if (!skb) @@ -1001,17 +998,9 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw, if (ret < 0) goto out_sleep; - ret = wl1251_acx_aid(wl, wl->aid); + ret = wl1251_acx_aid(wl, bss_conf->aid); if (ret < 0) goto out_sleep; - - /* If we want to go in PSM but we're not there yet */ - if (wl->psm_requested && !wl->psm) { - mode = STATION_POWER_SAVE_MODE; - ret = wl1251_ps_set_mode(wl, mode); - if (ret < 0) - goto out_sleep; - } } else { /* use defaults when not associated */ wl->beacon_int = WL1251_DEFAULT_BEACON_INT; -- cgit v1.2.3 From 47db3a677b533489d1a5a027282aa33f46dffa79 Mon Sep 17 00:00:00 2001 From: Luca Verdesca Date: Tue, 22 Dec 2009 18:10:01 +0100 Subject: ath5k: adding LED support for AR5BXB63 cards With following patch, LED should now work with LiteOn AR5BXB63 mini pci-e cards. (Broken patch fixed-up by me...let's hope I did it right! -- JWL) Signed-off-by: Luca Verdesca Acked-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/led.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 60f547503d7..67aa52e9bf9 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c @@ -77,6 +77,8 @@ static const struct pci_device_id ath5k_led_devices[] = { { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) }, /* HP Compaq C700 (nitrousnrg@gmail.com) */ { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) }, + /* LiteOn AR5BXB63 (magooz@salug.it) */ + { ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) }, /* IBM-specific AR5212 (all others) */ { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) }, /* Dell Vostro A860 (shahar@shahar-or.co.il) */ -- cgit v1.2.3 From d3d5621abf6d2105700795fcbdf784b9cb46b495 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 27 Jan 2010 14:23:17 -0500 Subject: libertas: add comment re: v10 firmware key handling Comment text suggested by Dan Williams in <1263952092.4481.2.camel@localhost.localdomain>. Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/assoc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index 0979b07799a..f03d5e4e59c 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -2062,6 +2062,11 @@ void lbs_association_worker(struct work_struct *work) goto out; } + /* + * v10 FW wants WPA keys to be set/cleared before WEP key operations, + * otherwise it will fail to correctly associate to WEP networks. + * Other firmware versions don't appear to care. + */ if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { ret = assoc_helper_wpa_keys(priv, assoc_req); -- cgit v1.2.3 From d2bb8e02810cc5844fe2bd5a81d4058b8afe6de9 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 26 Jan 2010 16:22:20 -0500 Subject: rtl8180: implement get_tsf op for mac80211 Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8180_dev.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 5a2b7199f5d..109ab1baf62 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -761,6 +761,14 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev, rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); } +static u64 rtl8180_get_tsf(struct ieee80211_hw *dev) +{ + struct rtl8180_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + static const struct ieee80211_ops rtl8180_ops = { .tx = rtl8180_tx, .start = rtl8180_start, @@ -771,6 +779,7 @@ static const struct ieee80211_ops rtl8180_ops = { .bss_info_changed = rtl8180_bss_info_changed, .prepare_multicast = rtl8180_prepare_multicast, .configure_filter = rtl8180_configure_filter, + .get_tsf = rtl8180_get_tsf, }; static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) -- cgit v1.2.3 From da8604757b1cdf79f24e118b156349543eb1b722 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 26 Jan 2010 16:42:02 -0600 Subject: b43: N PHY: Fix compilation after removal of typdef b43_c32 In the conversion between typedef and struct, two places that needed a "struct" were missed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index df4bf435e21..8c39fb126d4 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -822,7 +822,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, { int i; u16 bw, len, rot, angle; - b43_c32 *samples; + struct b43_c32 *samples; bw = (dev->phy.is_40mhz) ? 40 : 20; @@ -840,7 +840,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, len = bw << 1; } - samples = kzalloc(len * sizeof(b43_c32), GFP_KERNEL); + samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); rot = (((freq * 36) / bw) << 16) / 100; angle = 0; -- cgit v1.2.3 From 22e16e55e36ab91148592c9bf0f2444bf766cd3c Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 26 Jan 2010 17:45:28 -0600 Subject: rtl8187: Add callback for get_tsf Signed-off-by: Larry Finger Acked-by: Hin-Tak Leung Signed-off-by: John W. Linville --- drivers/net/wireless/rtl818x/rtl8187_dev.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index f336c63053c..a0538255778 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -1265,6 +1265,14 @@ static int rtl8187_conf_tx(struct ieee80211_hw *dev, u16 queue, return 0; } +static u64 rtl8187_get_tsf(struct ieee80211_hw *dev) +{ + struct rtl8187_priv *priv = dev->priv; + + return rtl818x_ioread32(priv, &priv->map->TSFT[0]) | + (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32; +} + static const struct ieee80211_ops rtl8187_ops = { .tx = rtl8187_tx, .start = rtl8187_start, @@ -1276,7 +1284,8 @@ static const struct ieee80211_ops rtl8187_ops = { .prepare_multicast = rtl8187_prepare_multicast, .configure_filter = rtl8187_configure_filter, .conf_tx = rtl8187_conf_tx, - .rfkill_poll = rtl8187_rfkill_poll + .rfkill_poll = rtl8187_rfkill_poll, + .get_tsf = rtl8187_get_tsf, }; static void rtl8187_eeprom_register_read(struct eeprom_93cx6 *eeprom) -- cgit v1.2.3 From c1596b75c29eb5b32c65ef1e186c8b08c289bf05 Mon Sep 17 00:00:00 2001 From: Hamish Guthrie Date: Thu, 28 Jan 2010 12:54:09 +0100 Subject: ps3_gelic_wireless: Remove PS3 gelic legacy wpa support The current PS3 gelic wireless driver has support for wireless extensions. The original PS3 gelic wireless driver exposed a dedicated API for a dedicated wpa_supplicant driver. This old API could be enabled with CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE, however, as this is not being used by any distros, and it is being removed from the driver and from wpa_supplicant. Signed-off-by: Hamish Guthrie Acked-by: Geoff Levand Signed-off-by: John W. Linville --- drivers/net/Kconfig | 14 ---- drivers/net/ps3_gelic_wireless.c | 137 --------------------------------------- 2 files changed, 151 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 18ff622703b..6460505ab24 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2354,20 +2354,6 @@ config GELIC_WIRELESS the driver automatically distinguishes the models, you can safely enable this option even if you have a wireless-less model. -config GELIC_WIRELESS_OLD_PSK_INTERFACE - bool "PS3 Wireless private PSK interface (OBSOLETE)" - depends on GELIC_WIRELESS - select WEXT_PRIV - help - This option retains the obsolete private interface to pass - the PSK from user space programs to the driver. The PSK - stands for 'Pre Shared Key' and is used for WPA[2]-PSK - (WPA-Personal) environment. - If WPA[2]-PSK is used and you need to use old programs that - support only this old interface, say Y. Otherwise N. - - If unsure, say N. - config FSL_PQ_MDIO tristate "Freescale PQ MDIO" depends on FSL_SOC diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 227b141c4fb..7571dbba6a0 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -1389,113 +1389,6 @@ static int gelic_wl_get_mode(struct net_device *netdev, return 0; } -#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE -/* SIOCIWFIRSTPRIV */ -static int hex2bin(u8 *str, u8 *bin, unsigned int len) -{ - unsigned int i; - static unsigned char *hex = "0123456789ABCDEF"; - unsigned char *p, *q; - u8 tmp; - - if (len != WPA_PSK_LEN * 2) - return -EINVAL; - - for (i = 0; i < WPA_PSK_LEN * 2; i += 2) { - p = strchr(hex, toupper(str[i])); - q = strchr(hex, toupper(str[i + 1])); - if (!p || !q) { - pr_info("%s: unconvertible PSK digit=%d\n", - __func__, i); - return -EINVAL; - } - tmp = ((p - hex) << 4) + (q - hex); - *bin++ = tmp; - } - return 0; -}; - -static int gelic_wl_priv_set_psk(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); - unsigned int len; - unsigned long irqflag; - int ret = 0; - - pr_debug("%s:<- len=%d\n", __func__, data->data.length); - len = data->data.length - 1; - if (len <= 2) - return -EINVAL; - - spin_lock_irqsave(&wl->lock, irqflag); - if (extra[0] == '"' && extra[len - 1] == '"') { - pr_debug("%s: passphrase mode\n", __func__); - /* pass phrase */ - if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) { - pr_info("%s: passphrase too long\n", __func__); - ret = -E2BIG; - goto out; - } - memset(wl->psk, 0, sizeof(wl->psk)); - wl->psk_len = len - 2; - memcpy(wl->psk, &(extra[1]), wl->psk_len); - wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE; - } else { - ret = hex2bin(extra, wl->psk, len); - if (ret) - goto out; - wl->psk_len = WPA_PSK_LEN; - wl->psk_type = GELIC_EURUS_WPA_PSK_BIN; - } - set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat); -out: - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s:->\n", __func__); - return ret; -} - -static int gelic_wl_priv_get_psk(struct net_device *net_dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev)); - char *p; - unsigned long irqflag; - unsigned int i; - - pr_debug("%s:<-\n", __func__); - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - spin_lock_irqsave(&wl->lock, irqflag); - p = extra; - if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) { - if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) { - for (i = 0; i < wl->psk_len; i++) { - sprintf(p, "%02xu", wl->psk[i]); - p += 2; - } - *p = '\0'; - data->data.length = wl->psk_len * 2; - } else { - *p++ = '"'; - memcpy(p, wl->psk, wl->psk_len); - p += wl->psk_len; - *p++ = '"'; - *p = '\0'; - data->data.length = wl->psk_len + 2; - } - } else - /* no psk set */ - data->data.length = 0; - spin_unlock_irqrestore(&wl->lock, irqflag); - pr_debug("%s:-> %d\n", __func__, data->data.length); - return 0; -} -#endif - /* SIOCGIWNICKN */ static int gelic_wl_get_nick(struct net_device *net_dev, struct iw_request_info *info, @@ -2406,40 +2299,10 @@ static const iw_handler gelic_wl_wext_handler[] = IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick, }; -#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE -static struct iw_priv_args gelic_wl_private_args[] = -{ - { - .cmd = GELIC_WL_PRIV_SET_PSK, - .set_args = IW_PRIV_TYPE_CHAR | - (GELIC_WL_EURUS_PSK_MAX_LEN + 2), - .name = "set_psk" - }, - { - .cmd = GELIC_WL_PRIV_GET_PSK, - .get_args = IW_PRIV_TYPE_CHAR | - (GELIC_WL_EURUS_PSK_MAX_LEN + 2), - .name = "get_psk" - } -}; - -static const iw_handler gelic_wl_private_handler[] = -{ - gelic_wl_priv_set_psk, - gelic_wl_priv_get_psk, -}; -#endif - static const struct iw_handler_def gelic_wl_wext_handler_def = { .num_standard = ARRAY_SIZE(gelic_wl_wext_handler), .standard = gelic_wl_wext_handler, .get_wireless_stats = gelic_wl_get_wireless_stats, -#ifdef CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE - .num_private = ARRAY_SIZE(gelic_wl_private_handler), - .num_private_args = ARRAY_SIZE(gelic_wl_private_args), - .private = gelic_wl_private_handler, - .private_args = gelic_wl_private_args, -#endif }; static struct net_device * __devinit gelic_wl_alloc(struct gelic_card *card) -- cgit v1.2.3 From f276586a8af410d2b79733daf52471605b6559e9 Mon Sep 17 00:00:00 2001 From: Hamish Guthrie Date: Thu, 28 Jan 2010 12:54:10 +0100 Subject: ps3_gelic_wireless: fix directed ssid scan If the association worker requests a directed ssid scan and a bss list already exists, the directed scan is not done. This patch corrects this and cleans up a few typos and debug messages. Signed-off-by: Hamish Guthrie Acked-by: Geoff Levand Signed-off-by: John W. Linville --- drivers/net/ps3_gelic_wireless.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 7571dbba6a0..d520e9e8cdb 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -1449,7 +1449,8 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan, void *buf = NULL; size_t len; - pr_debug("%s: <- always=%d\n", __func__, always_scan); + pr_debug("%s: <- always=%d essid_len=%d\n", __func__, + always_scan, essid_len); if (mutex_lock_interruptible(&wl->scan_lock)) return -ERESTARTSYS; @@ -1464,8 +1465,10 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan, init_completion(&wl->scan_done); /* * If we have already a bss list, don't try to get new + * unless we are doing an ESSID scan */ - if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) { + if ((!essid_len && !always_scan) + && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) { pr_debug("%s: already has the list\n", __func__); complete(&wl->scan_done); goto out; @@ -1566,7 +1569,7 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) } } - /* put them in the newtork_list */ + /* put them in the network_list */ for (i = 0, scan_info_size = 0, scan_info = buf; scan_info_size < data_len; i++, scan_info_size += be16_to_cpu(scan_info->size), @@ -1902,7 +1905,7 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl) /* PSK type */ wpa->psk_type = cpu_to_be16(wl->psk_type); #ifdef DEBUG - pr_debug("%s: sec=%s psktype=%s\nn", __func__, + pr_debug("%s: sec=%s psktype=%s\n", __func__, wpasecstr(wpa->security), (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ? "BIN" : "passphrase"); @@ -1912,9 +1915,9 @@ static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl) * the debug log because this dumps your precious * passphrase/key. */ - pr_debug("%s: psk=%s\n", + pr_debug("%s: psk=%s\n", __func__, (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ? - (char *)"N/A" : (char *)wpa->psk); + "N/A" : wpa->psk); #endif #endif /* issue wpa setup */ -- cgit v1.2.3 From 1dbfd9d46a6df5232ba0b12d2da950da89eff3da Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Fri, 29 Jan 2010 16:56:51 +0530 Subject: ath9k: Handle full sleep in ps_restore. IDLE PS (Full Sleep) doesn't work when ifconfig up is done during Idle unassociated state. Fix this by restoring FULL SLEEP in ps_restore if CONF_IDLE is set. Signed-off-by: Vivek Natarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index bdbcc70df07..3f8a7e773d5 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -480,6 +480,7 @@ struct ath_softc { u8 nbcnvifs; u16 nvifs; bool ps_enabled; + bool ps_idle; unsigned long ps_usecount; enum ath9k_int imask; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6f3e71c5071..e04835cb21b 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -143,8 +143,10 @@ void ath9k_ps_restore(struct ath_softc *sc) if (--sc->ps_usecount != 0) goto unlock; - if (sc->ps_enabled && - !(sc->ps_flags & (PS_WAIT_FOR_BEACON | + if (sc->ps_idle) + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); + else if (sc->ps_enabled && + !(sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | PS_WAIT_FOR_TX_ACK))) @@ -1528,6 +1530,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) spin_unlock_bh(&sc->wiphy_lock); if (enable_radio) { + sc->ps_idle = false; ath_radio_enable(sc, hw); ath_print(common, ATH_DBG_CONFIG, "not-idle: enabling radio\n"); @@ -1635,6 +1638,7 @@ skip_chan_change: if (disable_radio) { ath_print(common, ATH_DBG_CONFIG, "idle: disabling radio\n"); + sc->ps_idle = true; ath_radio_disable(sc, hw); } -- cgit v1.2.3 From 49dcc819b077c2d473062e17d5a1373a8b660e02 Mon Sep 17 00:00:00 2001 From: Daniel Halperin Date: Tue, 19 Jan 2010 10:22:19 -0800 Subject: iwlwifi: optimize power saving In hostap AP mode, every time the client sends the AP a packet the STA_NOTIFY_AWAKE code is sent from mac80211. This results in a command being sent to the uCode even if the client was not asleep. The following simple patch has fixed the issue for me without any degradation that I can find. Signed-off-by: Daniel Halperin Acked-by: Johannes Berg Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 4a268927377..380d2087bf3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3007,6 +3007,8 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw, break; case STA_NOTIFY_AWAKE: WARN_ON(!sta_priv->client); + if (!sta_priv->asleep) + break; sta_priv->asleep = false; sta_id = iwl_find_station(priv, sta->addr); if (sta_id != IWL_INVALID_STATION) -- cgit v1.2.3 From a7fce6ee8dd693fb2a9d19ddf9ee1fe380893fa1 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Tue, 19 Jan 2010 16:51:50 -0800 Subject: iwlwifi: sysassert identifier change Change in uCode to include a unique identifier as part of sysassert, in order to tell the difference, add the "ADVANCED SYSASSERT" description when dump nic error to indicate the difference. Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 380d2087bf3..1c54425afe2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1757,7 +1757,7 @@ static const char *desc_lookup_text[] = { "DEBUG_1", "DEBUG_2", "DEBUG_3", - "UNKNOWN" + "ADVANCED SYSASSERT" }; static const char *desc_lookup(int i) -- cgit v1.2.3 From 47e28f41dce90ea4317d35cf23f232c1a6b07adf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Jan 2010 11:21:06 -0800 Subject: iwlwifi: fix locking in iwl_mac_add_interface The corresponding iwl_mac_remove_interface only acquires the mutex, leading me to believe that the spinlock is not necessary. However, this doesn't actually acquire the mutex around the vif pointer check and assignment, fix that. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-core.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 1cfabd6be0b..02bf17ecaf5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2631,23 +2631,21 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; - unsigned long flags; + int err = 0; IWL_DEBUG_MAC80211(priv, "enter: type %d\n", vif->type); + mutex_lock(&priv->mutex); + if (priv->vif) { IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); - return -EOPNOTSUPP; + err = -EOPNOTSUPP; + goto out; } - spin_lock_irqsave(&priv->lock, flags); priv->vif = vif; priv->iw_mode = vif->type; - spin_unlock_irqrestore(&priv->lock, flags); - - mutex_lock(&priv->mutex); - if (vif->addr) { IWL_DEBUG_MAC80211(priv, "Set %pM\n", vif->addr); memcpy(priv->mac_addr, vif->addr, ETH_ALEN); @@ -2657,10 +2655,11 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, /* we are not ready, will run again when ready */ set_bit(STATUS_MODE_PENDING, &priv->status); + out: mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); - return 0; + return err; } EXPORT_SYMBOL(iwl_mac_add_interface); -- cgit v1.2.3 From 2494f63cc7394fc4424c4833b83d1831f52e54c8 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 20 Jan 2010 12:22:52 -0800 Subject: iwlwifi: update sensitivity calibration data for 6x00 series Update sensitivity range values for 6000 & 6x50 series Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 81e03e33ec7..a9f8551e0e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -108,7 +108,7 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { .auto_corr_max_ofdm = 145, .auto_corr_max_ofdm_mrc = 232, - .auto_corr_max_ofdm_x1 = 145, + .auto_corr_max_ofdm_x1 = 110, .auto_corr_max_ofdm_mrc_x1 = 232, .auto_corr_min_cck = 125, -- cgit v1.2.3 From 9bead7632adb6341548056a80ec36e7ae098f4f4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 20 Jan 2010 12:22:53 -0800 Subject: iwlwifi: update sensitivity calibration data for 5x00 series Update sensitivity range values for 5x00 series Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 6027e2a658d..6bb433a0e53 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -263,8 +263,8 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { .auto_corr_max_ofdm = 120, .auto_corr_max_ofdm_mrc = 210, - .auto_corr_max_ofdm_x1 = 155, - .auto_corr_max_ofdm_mrc_x1 = 290, + .auto_corr_max_ofdm_x1 = 120, + .auto_corr_max_ofdm_mrc_x1 = 240, .auto_corr_min_cck = 125, .auto_corr_max_cck = 200, -- cgit v1.2.3 From fac06108701a2a081a47d4dc6f03220aaab54486 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Wed, 20 Jan 2010 12:22:54 -0800 Subject: iwlwifi: update sensitivity calibration data for 1000 series Update sensitivity range values for 1000 series Signed-off-by: Wey-Yi Guy Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-1000.c | 72 ++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 4281999cfaa..9d1820676f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -89,8 +89,78 @@ static void iwl1000_nic_config(struct iwl_priv *priv) ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); } +static struct iwl_sensitivity_ranges iwl1000_sensitivity = { + .min_nrg_cck = 95, + .max_nrg_cck = 0, /* not used, set to 0 */ + .auto_corr_min_ofdm = 90, + .auto_corr_min_ofdm_mrc = 170, + .auto_corr_min_ofdm_x1 = 120, + .auto_corr_min_ofdm_mrc_x1 = 240, + + .auto_corr_max_ofdm = 120, + .auto_corr_max_ofdm_mrc = 210, + .auto_corr_max_ofdm_x1 = 155, + .auto_corr_max_ofdm_mrc_x1 = 290, + + .auto_corr_min_cck = 125, + .auto_corr_max_cck = 200, + .auto_corr_min_cck_mrc = 170, + .auto_corr_max_cck_mrc = 400, + .nrg_th_cck = 95, + .nrg_th_ofdm = 95, + + .barker_corr_th_min = 190, + .barker_corr_th_min_mrc = 390, + .nrg_th_cca = 62, +}; + +static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) +{ + if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && + priv->cfg->mod_params->num_of_queues <= IWL50_NUM_QUEUES) + priv->cfg->num_of_queues = + priv->cfg->mod_params->num_of_queues; + + priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; + priv->hw_params.scd_bc_tbls_size = + priv->cfg->num_of_queues * + sizeof(struct iwl5000_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_data_size = IWL50_RTC_DATA_SIZE; + priv->hw_params.max_inst_size = IWL50_RTC_INST_SIZE; + + priv->hw_params.max_bsm_size = 0; + priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_2GHZ) | + BIT(IEEE80211_BAND_5GHZ); + priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR; + + priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant); + priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); + priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; + priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; + + if (priv->cfg->ops->lib->temp_ops.set_ct_kill) + priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + + /* Set initial sensitivity parameters */ + /* Set initial calibration set */ + priv->hw_params.sens = &iwl1000_sensitivity; + priv->hw_params.calib_init_cfg = + BIT(IWL_CALIB_XTAL) | + BIT(IWL_CALIB_LO) | + BIT(IWL_CALIB_TX_IQ) | + BIT(IWL_CALIB_TX_IQ_PERD) | + BIT(IWL_CALIB_BASE_BAND); + + return 0; +} + static struct iwl_lib_ops iwl1000_lib = { - .set_hw_params = iwl5000_hw_set_hw_params, + .set_hw_params = iwl1000_hw_set_hw_params, .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, -- cgit v1.2.3 From 4d6959219bb71aa34383fc1a1a520820aee6292b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2010 05:24:04 -0800 Subject: iwlwifi: no need to test iw_mode in power saving mac80211 will only enable powersaving for station mode. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-power.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 9e3ca064145..232dd1879ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -308,8 +308,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) { int ret = 0; struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - bool enabled = (priv->iw_mode == NL80211_IFTYPE_STATION) && - (priv->hw->conf.flags & IEEE80211_CONF_PS); + bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; bool update_chains; struct iwl_powertable_cmd cmd; int dtimper; -- cgit v1.2.3 From 9f1f3ceacb7e52d9bc0364b4f26ae418de79656f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2010 05:28:40 -0800 Subject: iwlagn: simplify ucode loading Move the waiting into iwl5000_load_section instead of duplicating it in the caller. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-5000.c | 63 ++++++++++++--------------------- 1 file changed, 22 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 6bb433a0e53..6d598890134 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -412,12 +412,14 @@ static void iwl5000_rx_calib_complete(struct iwl_priv *priv, /* * ucode */ -static int iwl5000_load_section(struct iwl_priv *priv, - struct fw_desc *image, - u32 dst_addr) +static int iwl5000_load_section(struct iwl_priv *priv, const char *name, + struct fw_desc *image, u32 dst_addr) { dma_addr_t phy_addr = image->p_addr; u32 byte_cnt = image->len; + int ret; + + priv->ucode_write_complete = 0; iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), @@ -447,57 +449,36 @@ static int iwl5000_load_section(struct iwl_priv *priv, FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - return 0; -} - -static int iwl5000_load_given_ucode(struct iwl_priv *priv, - struct fw_desc *inst_image, - struct fw_desc *data_image) -{ - int ret = 0; - - ret = iwl5000_load_section(priv, inst_image, - IWL50_RTC_INST_LOWER_BOUND); - if (ret) - return ret; - - IWL_DEBUG_INFO(priv, "INST uCode section being loaded...\n"); + IWL_DEBUG_INFO(priv, "%s uCode section being loaded...\n", name); ret = wait_event_interruptible_timeout(priv->wait_command_queue, priv->ucode_write_complete, 5 * HZ); if (ret == -ERESTARTSYS) { - IWL_ERR(priv, "Could not load the INST uCode section due " - "to interrupt\n"); + IWL_ERR(priv, "Could not load the %s uCode section due " + "to interrupt\n", name); return ret; } if (!ret) { - IWL_ERR(priv, "Could not load the INST uCode section\n"); + IWL_ERR(priv, "Could not load the %s uCode section\n", + name); return -ETIMEDOUT; } - priv->ucode_write_complete = 0; - - ret = iwl5000_load_section( - priv, data_image, IWL50_RTC_DATA_LOWER_BOUND); - if (ret) - return ret; + return 0; +} - IWL_DEBUG_INFO(priv, "DATA uCode section being loaded...\n"); +static int iwl5000_load_given_ucode(struct iwl_priv *priv, + struct fw_desc *inst_image, + struct fw_desc *data_image) +{ + int ret = 0; - ret = wait_event_interruptible_timeout(priv->wait_command_queue, - priv->ucode_write_complete, 5 * HZ); - if (ret == -ERESTARTSYS) { - IWL_ERR(priv, "Could not load the INST uCode section due " - "to interrupt\n"); + ret = iwl5000_load_section(priv, "INST", inst_image, + IWL50_RTC_INST_LOWER_BOUND); + if (ret) return ret; - } else if (!ret) { - IWL_ERR(priv, "Could not load the DATA uCode section\n"); - return -ETIMEDOUT; - } else - ret = 0; - - priv->ucode_write_complete = 0; - return ret; + return iwl5000_load_section(priv, "DATA", data_image, + IWL50_RTC_DATA_LOWER_BOUND); } int iwl5000_load_ucode(struct iwl_priv *priv) -- cgit v1.2.3 From 80676518da523e926e70794ac2767829effcf3ba Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2010 06:07:17 -0800 Subject: iwlwifi: remove bg_up work There's no need to queue a work struct from within a work struct, just move the code to execute directly. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-agn.c | 21 +++++++-------------- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl3945-base.c | 21 +++++++-------------- 3 files changed, 14 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1c54425afe2..b528a20ade4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2439,18 +2439,6 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) return; } -static void iwl_bg_up(struct work_struct *data) -{ - struct iwl_priv *priv = container_of(data, struct iwl_priv, up); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - __iwl_up(priv); - mutex_unlock(&priv->mutex); -} - static void iwl_bg_restart(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); @@ -2467,7 +2455,13 @@ static void iwl_bg_restart(struct work_struct *data) ieee80211_restart_hw(priv->hw); } else { iwl_down(priv); - queue_work(priv->workqueue, &priv->up); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + __iwl_up(priv); + mutex_unlock(&priv->mutex); } } @@ -3285,7 +3279,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) init_waitqueue_head(&priv->wait_command_queue); - INIT_WORK(&priv->up, iwl_bg_up); INIT_WORK(&priv->restart, iwl_bg_restart); INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 9b0a5cbc20f..1cd565aef62 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1264,7 +1264,6 @@ struct iwl_priv { struct workqueue_struct *workqueue; - struct work_struct up; struct work_struct restart; struct work_struct calibrated_work; struct work_struct scan_completed; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index cd42b5838b3..119da54116d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3033,18 +3033,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data) mutex_unlock(&priv->mutex); } -static void iwl3945_bg_up(struct work_struct *data) -{ - struct iwl_priv *priv = container_of(data, struct iwl_priv, up); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - __iwl3945_up(priv); - mutex_unlock(&priv->mutex); -} - static void iwl3945_bg_restart(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); @@ -3061,7 +3049,13 @@ static void iwl3945_bg_restart(struct work_struct *data) ieee80211_restart_hw(priv->hw); } else { iwl3945_down(priv); - queue_work(priv->workqueue, &priv->up); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + __iwl3945_up(priv); + mutex_unlock(&priv->mutex); } } @@ -3782,7 +3776,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) init_waitqueue_head(&priv->wait_command_queue); - INIT_WORK(&priv->up, iwl3945_bg_up); INIT_WORK(&priv->restart, iwl3945_bg_restart); INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); -- cgit v1.2.3 From 71d75cf9ab858b99d072fece9784ab338af8e388 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2010 06:08:19 -0800 Subject: iwlwifi: remove unused work structs auth_work, calibrated_work, update_link_led and report_work are never used, so remove them. Signed-off-by: Johannes Berg Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-dev.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1cd565aef62..55dc5a86654 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1265,13 +1265,9 @@ struct iwl_priv { struct workqueue_struct *workqueue; struct work_struct restart; - struct work_struct calibrated_work; struct work_struct scan_completed; struct work_struct rx_replenish; struct work_struct abort_scan; - struct work_struct update_link_led; - struct work_struct auth_work; - struct work_struct report_work; struct work_struct request_scan; struct work_struct beacon_update; struct work_struct tt_work; -- cgit v1.2.3 From 7ae810776a51dc4dc6580013b0f6ba0f34d2b165 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 21 Jan 2010 11:47:59 -0800 Subject: iwlwifi: fix typo in IWL_CCK_RATES_MASK Due to a typo, the variable contains OFDM rates as well. The only user doesn't care, so this change doesn't really do anything but fix up my confusion. Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 2f0094a4326..e71923961e6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -191,7 +191,7 @@ enum { IWL_RATE_2M_MASK) #define IWL_CCK_RATES_MASK \ - (IWL_BASIC_RATES_MASK | \ + (IWL_CCK_BASIC_RATES_MASK | \ IWL_RATE_5M_MASK | \ IWL_RATE_11M_MASK) -- cgit v1.2.3 From d3a571971e5af241074947fc80f6284677f6e014 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Thu, 21 Jan 2010 11:52:28 -0800 Subject: iwlwifi: iwl_power_update_mode always hold mutex iwl_power_update_mode expects to be called with mutex held, for example to protect priv->vif. Only one caller currently does not do this, fix this. Also, add a comment to iwl_power_update_mode to indicate this requirement. Signed-off-by: Reinette Chatre --- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 5c8377b9ad9..d134301b553 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -815,7 +815,9 @@ static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, priv->power_data.debug_sleep_level_override = value; + mutex_lock(&priv->mutex); iwl_power_update_mode(priv, true); + mutex_unlock(&priv->mutex); return count; } diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 232dd1879ba..1a1a9f081cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -303,7 +303,7 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) sizeof(struct iwl_powertable_cmd), cmd); } - +/* priv->mutex must be held */ int iwl_power_update_mode(struct iwl_priv *priv, bool force) { int ret = 0; -- cgit v1.2.3 From c6c97bdaa3307d0811f14c99c38c63a8dae36e1f Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 1 Feb 2010 09:55:56 -0500 Subject: ps3_gelic_wireless: fix format warning Signed-off-by: John W. Linville --- drivers/net/ps3_gelic_wireless.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index d520e9e8cdb..448c5b6789d 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -1449,7 +1449,7 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan, void *buf = NULL; size_t len; - pr_debug("%s: <- always=%d essid_len=%d\n", __func__, + pr_debug("%s: <- always=%d essid_len=%z\n", __func__, always_scan, essid_len); if (mutex_lock_interruptible(&wl->scan_lock)) return -ERESTARTSYS; -- cgit v1.2.3 From f643e51d717b52ac28830e8bb98559b006a73bf4 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 29 Jan 2010 17:22:12 -0500 Subject: ath: make gcc check format arguments of ath_print(), fix all misuses Numeric channel is hard to get, so it won't be printed. Replace Mhz with MHz on the affected lines and add commas as needed. Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 6 +++--- drivers/net/wireless/ath/ath9k/recv.c | 2 +- drivers/net/wireless/ath/ath9k/xmit.c | 2 +- drivers/net/wireless/ath/debug.h | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e04835cb21b..12069aac1d6 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -206,7 +206,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, r = ath9k_hw_reset(ah, hchan, fastcc); if (r) { ath_print(common, ATH_DBG_FATAL, - "Unable to reset channel (%u Mhz) " + "Unable to reset channel (%u MHz), " "reset status %d\n", channel->center_freq, r); spin_unlock_bh(&sc->sc_resetlock); @@ -869,7 +869,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) r = ath9k_hw_reset(ah, ah->curchan, false); if (r) { ath_print(common, ATH_DBG_FATAL, - "Unable to reset channel %u (%uMhz) ", + "Unable to reset channel (%u MHz), " "reset status %d\n", channel->center_freq, r); } @@ -924,7 +924,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) r = ath9k_hw_reset(ah, ah->curchan, false); if (r) { ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, - "Unable to reset channel %u (%uMhz) " + "Unable to reset channel (%u MHz), " "reset status %d\n", channel->center_freq, r); } diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 40b5d05edcc..1ca42e5148c 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -429,7 +429,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA; ath_print(common, ATH_DBG_PS, "Going back to sleep after having received " - "PS-Poll data (0x%x)\n", + "PS-Poll data (0x%lx)\n", sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a6893cf0c43..3c790a4f38f 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1857,7 +1857,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK; ath_print(common, ATH_DBG_PS, "Going back to sleep after having " - "received TX status (0x%x)\n", + "received TX status (0x%lx)\n", sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA | diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index d6b685a06c5..8263633c003 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -65,11 +65,11 @@ enum ATH_DEBUG { #define ATH_DBG_DEFAULT (ATH_DBG_FATAL) #ifdef CONFIG_ATH_DEBUG -void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...); +void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))); #else -static inline void ath_print(struct ath_common *common, - int dbg_mask, - const char *fmt, ...) +static inline void __attribute__ ((format (printf, 3, 4))) +ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) { } #endif /* CONFIG_ATH_DEBUG */ -- cgit v1.2.3 From 991a0987d9e821df1790bbbc368cf36db0c678d3 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 29 Jan 2010 17:22:26 -0500 Subject: ath9k: allocate string buffer in read_file_dma() by kmalloc() Using stack for that causes warnings with CONFIG_FRAME_WARN=1024 Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/debug.c | 43 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 9489b6b25b5..42d2a506845 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -75,17 +75,24 @@ static const struct file_operations fops_debug = { #endif +#define DMA_BUF_LEN 1024 + static ssize_t read_file_dma(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; struct ath_hw *ah = sc->sc_ah; - char buf[1024]; + char *buf; + int retval; unsigned int len = 0; u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; int i, qcuOffset = 0, dcuOffset = 0; u32 *qcuBase = &val[0], *dcuBase = &val[4]; + buf = kmalloc(DMA_BUF_LEN, GFP_KERNEL); + if (!buf) + return 0; + ath9k_ps_wakeup(sc); REG_WRITE_D(ah, AR_MACMISC, @@ -93,20 +100,20 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, (AR_MACMISC_MISC_OBS_BUS_1 << AR_MACMISC_MISC_OBS_BUS_MSB_S))); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "Raw DMA Debug values:\n"); for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { if (i % 4 == 0) - len += snprintf(buf + len, sizeof(buf) - len, "\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); - len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ", + len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ", i, val[i]); } - len += snprintf(buf + len, sizeof(buf) - len, "\n\n"); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { @@ -120,7 +127,7 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, dcuBase++; } - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "%2d %2x %1x %2x %2x\n", i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), @@ -128,35 +135,37 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); } - len += snprintf(buf + len, sizeof(buf) - len, "\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "qcu_stitch state: %2x qcu_fetch state: %2x\n", (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "qcu_complete state: %2x dcu_complete state: %2x\n", (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "dcu_arb state: %2x dcu_fp state: %2x\n", (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); - len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n", + len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n", REG_READ_D(ah, AR_OBS_BUS_1)); - len += snprintf(buf + len, sizeof(buf) - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); ath9k_ps_restore(sc); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + return retval; } static const struct file_operations fops_dma = { -- cgit v1.2.3 From 28fd7daabfb35b7a0df2f7eaf460221e16dd2608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 00:12:19 +0100 Subject: b43: N-PHY: update general workarounds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 215 ++++++++++++++++++++------------------- drivers/net/wireless/b43/phy_n.h | 4 + 2 files changed, 115 insertions(+), 104 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 8c39fb126d4..60e730a6f1d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -246,110 +246,6 @@ static void b43_nphy_tables_init(struct b43_wldev *dev) b43_nphy_rev3plus_tables_init(dev); } -static void b43_nphy_workarounds(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - unsigned int i; - - b43_phy_set(dev, B43_NPHY_IQFLIP, - B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); - if (1 /* FIXME band is 2.4GHz */) { - b43_phy_set(dev, B43_NPHY_CLASSCTL, - B43_NPHY_CLASSCTL_CCKEN); - } else { - b43_phy_mask(dev, B43_NPHY_CLASSCTL, - ~B43_NPHY_CLASSCTL_CCKEN); - } - b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); - b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8); - - /* Fixup some tables */ - b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA); - b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA); - b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); - b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); - b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0); - b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0); - b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); - b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); - b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800); - b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800); - - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); - b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); - - //TODO set RF sequence - - /* Set narrowband clip threshold */ - b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66); - b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66); - - /* Set wideband clip 2 threshold */ - b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, - ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, - 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT); - b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, - ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, - 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT); - - /* Set Clip 2 detect */ - b43_phy_set(dev, B43_NPHY_C1_CGAINI, - B43_NPHY_C1_CGAINI_CL2DETECT); - b43_phy_set(dev, B43_NPHY_C2_CGAINI, - B43_NPHY_C2_CGAINI_CL2DETECT); - - if (0 /*FIXME*/) { - /* Set dwell lengths */ - b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43); - b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43); - b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9); - b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9); - - /* Set gain backoff */ - b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, - ~B43_NPHY_C1_CGAINI_GAINBKOFF, - 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT); - b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, - ~B43_NPHY_C2_CGAINI_GAINBKOFF, - 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT); - - /* Set HPVGA2 index */ - b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, - ~B43_NPHY_C1_INITGAIN_HPVGA2, - 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); - b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, - ~B43_NPHY_C2_INITGAIN_HPVGA2, - 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); - - //FIXME verify that the specs really mean to use autoinc here. - for (i = 0; i < 3; i++) - b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673); - } - - /* Set minimum gain value */ - b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, - ~B43_NPHY_C1_MINGAIN, - 23 << B43_NPHY_C1_MINGAIN_SHIFT); - b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, - ~B43_NPHY_C2_MINGAIN, - 23 << B43_NPHY_C2_MINGAIN_SHIFT); - - if (phy->rev < 2) { - b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, - ~B43_NPHY_SCRAM_SIGCTL_SCM); - } - - /* Set phase track alpha and beta */ - b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); - b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); - b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); - b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); - b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); - b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); -} - /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable) { @@ -816,6 +712,117 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ +static void b43_nphy_workarounds(struct b43_wldev *dev) +{ + struct ssb_bus *bus = dev->dev->bus; + struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = phy->n; + + u8 events1[7] = { 0x0, 0x1, 0x2, 0x8, 0x4, 0x5, 0x3 }; + u8 delays1[7] = { 0x8, 0x6, 0x6, 0x2, 0x4, 0x3C, 0x1 }; + + u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 }; + u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 }; + + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + b43_nphy_classifier(dev, 1, 0); + else + b43_nphy_classifier(dev, 1, 1); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 1); + + b43_phy_set(dev, B43_NPHY_IQFLIP, + B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); + + if (dev->phy.rev >= 3) { + /* TODO */ + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ && + nphy->band5g_pwrgain) { + b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8); + b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8); + } else { + b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); + b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8); + } + + /* TODO: convert to b43_ntab_write? */ + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2000); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2010); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x000A); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2002); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2012); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0xCDAA); + + if (dev->phy.rev < 2) { + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2008); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2018); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0000); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2007); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2017); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x7AAB); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2006); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x2016); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0800); + } + + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); + b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); + + if (bus->sprom.boardflags2_lo & 0x100 && + bus->boardinfo.type == 0x8B) { + delays1[0] = 0x1; + delays1[5] = 0x14; + } + /*TODO:b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);*/ + /*TODO:b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);*/ + + /*TODO:b43_nphy_gain_crtl_workarounds(dev);*/ + + if (dev->phy.rev < 2) { + if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) + ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/ + } else if (dev->phy.rev == 2) { + b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); + b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); + } + + if (dev->phy.rev < 2) + b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, + ~B43_NPHY_SCRAM_SIGCTL_SCM); + + /* Set phase track alpha and beta */ + b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); + b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); + b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); + b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); + b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); + b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); + + b43_phy_mask(dev, B43_NPHY_PIL_DW1, + (u16)~B43_NPHY_PIL_DW_64QAM); + b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5); + b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4); + b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00); + + if (dev->phy.rev == 2) + b43_phy_set(dev, B43_NPHY_FINERX2_CGC, + B43_NPHY_FINERX2_CGC_DECGC); + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, 0); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GenLoadSamples */ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, bool test) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index f5a27661f65..ae82f0fc209 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -976,6 +976,10 @@ struct b43_phy_n { s32 preamble_override; u32 bb_mult_save; + bool gain_boost; + bool elna_gain_config; + bool band5g_pwrgain; + u8 mphase_cal_phase_id; u16 mphase_txcal_cmdidx; u16 mphase_txcal_numcmds; -- cgit v1.2.3 From ef5127a4d256b9c0f47caae6cdc8ccfceedb09f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 00:12:20 +0100 Subject: b43: N-PHY: add workarounds for gain control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 130 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 60e730a6f1d..d738d769b02 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -712,6 +712,134 @@ static void b43_nphy_stop_playback(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, 0); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ +static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + u8 i, j; + u8 code; + + /* TODO: for PHY >= 3 + s8 *lna1_gain, *lna2_gain; + u8 *gain_db, *gain_bits; + u16 *rfseq_init; + u8 lpf_gain[6] = { 0x00, 0x06, 0x0C, 0x12, 0x12, 0x12 }; + u8 lpf_bits[6] = { 0, 1, 2, 3, 3, 3 }; + */ + + u8 rfseq_events[3] = { 6, 8, 7 }; + u8 rfseq_delays[3] = { 10, 30, 1 }; + + if (dev->phy.rev >= 3) { + /* TODO */ + } else { + /* Set Clip 2 detect */ + b43_phy_set(dev, B43_NPHY_C1_CGAINI, + B43_NPHY_C1_CGAINI_CL2DETECT); + b43_phy_set(dev, B43_NPHY_C2_CGAINI, + B43_NPHY_C2_CGAINI_CL2DETECT); + + /* Set narrowband clip threshold */ + b43_phy_set(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); + b43_phy_set(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); + + if (!dev->phy.is_40mhz) { + /* Set dwell lengths */ + b43_phy_set(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); + b43_phy_set(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); + b43_phy_set(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 0x0009); + b43_phy_set(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 0x0009); + } + + /* Set wideband clip 2 threshold */ + b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, + ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, + 21); + b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, + ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, + 21); + + if (!dev->phy.is_40mhz) { + b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, + ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1); + b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, + ~B43_NPHY_C2_CGAINI_GAINBKOFF, 0x1); + b43_phy_maskset(dev, B43_NPHY_C1_CCK_CGAINI, + ~B43_NPHY_C1_CCK_CGAINI_GAINBKOFF, 0x1); + b43_phy_maskset(dev, B43_NPHY_C2_CCK_CGAINI, + ~B43_NPHY_C2_CCK_CGAINI_GAINBKOFF, 0x1); + } + + b43_phy_set(dev, B43_NPHY_CCK_SHIFTB_REF, 0x809C); + + if (nphy->gain_boost) { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && + dev->phy.is_40mhz) + code = 4; + else + code = 5; + } else { + code = dev->phy.is_40mhz ? 6 : 7; + } + + /* Set HPVGA2 index */ + b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, + ~B43_NPHY_C1_INITGAIN_HPVGA2, + code << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); + b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, + ~B43_NPHY_C2_INITGAIN_HPVGA2, + code << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + (code << 8 | 0x7C)); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + (code << 8 | 0x7C)); + + /* TODO: b43_nphy_adjust_lna_gain_table(dev); */ + + if (nphy->elna_gain_config) { + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0808); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x0C08); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x0); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, 0x1); + + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D06); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + (code << 8 | 0x74)); + b43_phy_write(dev, B43_NPHY_TABLE_DATALO, + (code << 8 | 0x74)); + } + + if (dev->phy.rev == 2) { + for (i = 0; i < 4; i++) { + b43_phy_write(dev, B43_NPHY_TABLE_ADDR, + (0x0400 * i) + 0x0020); + for (j = 0; j < 21; j++) + b43_phy_write(dev, + B43_NPHY_TABLE_DATALO, 3 * j); + } + + /* TODO: b43_nphy_set_rf_sequence(dev, 5, + rfseq_events, rfseq_delays, 3);*/ + b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, + (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV, + 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); + + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + b43_phy_maskset(dev, B43_PHY_N(0xC5D), + 0xFF80, 4); + } + } +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ static void b43_nphy_workarounds(struct b43_wldev *dev) { @@ -786,7 +914,7 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) /*TODO:b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);*/ /*TODO:b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);*/ - /*TODO:b43_nphy_gain_crtl_workarounds(dev);*/ + b43_nphy_gain_crtl_workarounds(dev); if (dev->phy.rev < 2) { if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) -- cgit v1.2.3 From 99b82c419bc685c5ca3d8d815564bac41e2716e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 20:18:03 +0100 Subject: b43: N-PHY: split RSSI selection into two per-PHY-revision functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 101 ++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d738d769b02..558d3c052d9 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1316,66 +1316,69 @@ static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale, b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ -static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) +static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) { u16 val; - if (dev->phy.rev >= 3) { - /* TODO */ - } else { - if (type < 3) - val = 0; - else if (type == 6) - val = 1; - else if (type == 3) - val = 2; - else - val = 3; + if (type < 3) + val = 0; + else if (type == 6) + val = 1; + else if (type == 3) + val = 2; + else + val = 3; - val = (val << 12) | (val << 14); - b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); - b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); + val = (val << 12) | (val << 14); + b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val); + b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val); + if (type < 3) { + b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, + (type + 1) << 4); + b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, + (type + 1) << 4); + } + + /* TODO use some definitions */ + if (code == 0) { + b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); if (type < 3) { - b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF, - (type + 1) << 4); - b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF, - (type + 1) << 4); + b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFEC7, 0); + b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xEFDC, 0); + b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0); + udelay(20); + b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); } - - /* TODO use some definitions */ - if (code == 0) { - b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0); - if (type < 3) { - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, - 0xFEC7, 0); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, - 0xEFDC, 0); - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, - 0xFFFE, 0); - udelay(20); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, - 0xFFFE, 0); - } - } else { - b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, - 0x3000); - if (type < 3) { - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, - 0xFEC7, 0x0180); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, - 0xEFDC, (code << 1 | 0x1021)); - b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, - 0xFFFE, 0x0001); - udelay(20); - b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, - 0xFFFE, 0); - } + } else { + b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, + 0x3000); + if (type < 3) { + b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, + 0xFEC7, 0x0180); + b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, + 0xEFDC, (code << 1 | 0x1021)); + b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD, 0xFFFE, 0x1); + udelay(20); + b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER, 0xFFFE, 0); } } } +static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) +{ + /* TODO */ +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ +static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type) +{ + if (dev->phy.rev >= 3) + b43_nphy_rev3_rssi_select(dev, code, type); + else + b43_nphy_rev2_rssi_select(dev, code, type); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */ static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf) { -- cgit v1.2.3 From 6e3b15a9e7c3e4f22e9ade658b9e185311078648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 20:18:04 +0100 Subject: b43: N-PHY: add RSSI selection for newer PHYs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 84 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 558d3c052d9..0e04a2668ea 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1367,7 +1367,89 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type) static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type) { - /* TODO */ + struct b43_phy_n *nphy = dev->phy.n; + u8 i; + u16 reg, val; + + if (code == 0) { + b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, 0xFDFF); + b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, 0xFDFF); + b43_phy_mask(dev, B43_NPHY_AFECTL_C1, 0xFCFF); + b43_phy_mask(dev, B43_NPHY_AFECTL_C2, 0xFCFF); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S0, 0xFFDF); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B32S1, 0xFFDF); + b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0xFFC3); + b43_phy_mask(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0xFFC3); + } else { + for (i = 0; i < 2; i++) { + if ((code == 1 && i == 1) || (code == 2 && !i)) + continue; + + reg = (i == 0) ? + B43_NPHY_AFECTL_OVER1 : B43_NPHY_AFECTL_OVER; + b43_phy_maskset(dev, reg, 0xFDFF, 0x0200); + + if (type < 3) { + reg = (i == 0) ? + B43_NPHY_AFECTL_C1 : + B43_NPHY_AFECTL_C2; + b43_phy_maskset(dev, reg, 0xFCFF, 0); + + reg = (i == 0) ? + B43_NPHY_RFCTL_LUT_TRSW_UP1 : + B43_NPHY_RFCTL_LUT_TRSW_UP2; + b43_phy_maskset(dev, reg, 0xFFC3, 0); + + if (type == 0) + val = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 4 : 8; + else if (type == 1) + val = 16; + else + val = 32; + b43_phy_set(dev, reg, val); + + reg = (i == 0) ? + B43_NPHY_TXF_40CO_B1S0 : + B43_NPHY_TXF_40CO_B32S1; + b43_phy_set(dev, reg, 0x0020); + } else { + if (type == 6) + val = 0x0100; + else if (type == 3) + val = 0x0200; + else + val = 0x0300; + + reg = (i == 0) ? + B43_NPHY_AFECTL_C1 : + B43_NPHY_AFECTL_C2; + + b43_phy_maskset(dev, reg, 0xFCFF, val); + b43_phy_maskset(dev, reg, 0xF3FF, val << 2); + + if (type != 3 && type != 6) { + enum ieee80211_band band = + b43_current_band(dev->wl); + + if ((nphy->ipa2g_on && + band == IEEE80211_BAND_2GHZ) || + (nphy->ipa5g_on && + band == IEEE80211_BAND_5GHZ)) + val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; + else + val = 0x11; + reg = (i == 0) ? 0x2000 : 0x3000; + reg |= B2055_PADDRV; + b43_radio_write16(dev, reg, val); + + reg = (i == 0) ? + B43_NPHY_AFECTL_OVER1 : + B43_NPHY_AFECTL_OVER; + b43_phy_set(dev, reg, 0x0200); + } + } + } + } } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */ -- cgit v1.2.3 From 38bb902921dc31c15a707b74ebc6896438bb357e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 20:18:05 +0100 Subject: b43: N-PHY: fix Cal TX IQ LO for newer PHYs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 0e04a2668ea..1dace55d243 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2229,7 +2229,17 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, (dev->phy.rev == 5 && nphy->ipa2g_on && b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); if (phy6or5x) { - /* TODO */ + if (dev->phy.is_40mhz) { + b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, + tbl_tx_iqlo_cal_loft_ladder_40); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, + tbl_tx_iqlo_cal_iqimb_ladder_40); + } else { + b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, + tbl_tx_iqlo_cal_loft_ladder_20); + b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, + tbl_tx_iqlo_cal_iqimb_ladder_20); + } } b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); -- cgit v1.2.3 From 52cb5e978f505ba6436dfe1867da0d2818fdb9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 20:18:06 +0100 Subject: b43: N-PHY: add TX radio setup for newer PHYs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 53 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 1dace55d243..78e0cf6c78c 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1803,9 +1803,60 @@ static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; u16 *save = nphy->tx_rx_cal_radio_saveregs; + u16 tmp; + u8 offset, i; if (dev->phy.rev >= 3) { - /* TODO */ + for (i = 0; i < 2; i++) { + tmp = (i == 0) ? 0x2000 : 0x3000; + offset = i * 11; + + save[offset + 0] = b43_radio_read16(dev, B2055_CAL_RVARCTL); + save[offset + 1] = b43_radio_read16(dev, B2055_CAL_LPOCTL); + save[offset + 2] = b43_radio_read16(dev, B2055_CAL_TS); + save[offset + 3] = b43_radio_read16(dev, B2055_CAL_RCCALRTS); + save[offset + 4] = b43_radio_read16(dev, B2055_CAL_RCALRTS); + save[offset + 5] = b43_radio_read16(dev, B2055_PADDRV); + save[offset + 6] = b43_radio_read16(dev, B2055_XOCTL1); + save[offset + 7] = b43_radio_read16(dev, B2055_XOCTL2); + save[offset + 8] = b43_radio_read16(dev, B2055_XOREGUL); + save[offset + 9] = b43_radio_read16(dev, B2055_XOMISC); + save[offset + 10] = b43_radio_read16(dev, B2055_PLL_LFC1); + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x0A); + b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); + b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); + b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); + b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); + if (nphy->ipa5g_on) { + b43_radio_write16(dev, tmp | B2055_PADDRV, 4); + b43_radio_write16(dev, tmp | B2055_XOCTL1, 1); + } else { + b43_radio_write16(dev, tmp | B2055_PADDRV, 0); + b43_radio_write16(dev, tmp | B2055_XOCTL1, 0x2F); + } + b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); + } else { + b43_radio_write16(dev, tmp | B2055_CAL_RVARCTL, 0x06); + b43_radio_write16(dev, tmp | B2055_CAL_LPOCTL, 0x40); + b43_radio_write16(dev, tmp | B2055_CAL_TS, 0x55); + b43_radio_write16(dev, tmp | B2055_CAL_RCCALRTS, 0); + b43_radio_write16(dev, tmp | B2055_CAL_RCALRTS, 0); + b43_radio_write16(dev, tmp | B2055_XOCTL1, 0); + if (nphy->ipa2g_on) { + b43_radio_write16(dev, tmp | B2055_PADDRV, 6); + b43_radio_write16(dev, tmp | B2055_XOCTL2, + (dev->phy.rev < 5) ? 0x11 : 0x01); + } else { + b43_radio_write16(dev, tmp | B2055_PADDRV, 0); + b43_radio_write16(dev, tmp | B2055_XOCTL2, 0); + } + } + b43_radio_write16(dev, tmp | B2055_XOREGUL, 0); + b43_radio_write16(dev, tmp | B2055_XOMISC, 0); + b43_radio_write16(dev, tmp | B2055_PLL_LFC1, 0); + } } else { save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1); b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29); -- cgit v1.2.3 From 9501fefec6aa9a3319bb61edb99851ba30653f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sat, 30 Jan 2010 20:18:07 +0100 Subject: b43: N-PHY: implement setting RF sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 78e0cf6c78c..6392da25efe 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -64,6 +64,8 @@ enum b43_nphy_rf_sequence { B43_RFSEQ_UPDATE_GAINU, }; +static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, + u8 *events, u8 *delays, u8 length); static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, enum b43_nphy_rf_sequence seq); @@ -827,8 +829,8 @@ static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) B43_NPHY_TABLE_DATALO, 3 * j); } - /* TODO: b43_nphy_set_rf_sequence(dev, 5, - rfseq_events, rfseq_delays, 3);*/ + b43_nphy_set_rf_sequence(dev, 5, + rfseq_events, rfseq_delays, 3); b43_phy_maskset(dev, B43_NPHY_OVER_DGAIN1, (u16)~B43_NPHY_OVER_DGAIN_CCKDGECV, 0x5A << B43_NPHY_OVER_DGAIN_CCKDGECV_SHIFT); @@ -911,8 +913,8 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) delays1[0] = 0x1; delays1[5] = 0x14; } - /*TODO:b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);*/ - /*TODO:b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);*/ + b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); + b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); b43_nphy_gain_crtl_workarounds(dev); @@ -1131,6 +1133,31 @@ static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev) b43_nphy_stay_in_carrier_search(dev, false); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRfSeq */ +static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd, + u8 *events, u8 *delays, u8 length) +{ + struct b43_phy_n *nphy = dev->phy.n; + u8 i; + u8 end = (dev->phy.rev >= 3) ? 0x1F : 0x0F; + u16 offset1 = cmd << 4; + u16 offset2 = offset1 + 0x80; + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + b43_ntab_write_bulk(dev, B43_NTAB8(7, offset1), length, events); + b43_ntab_write_bulk(dev, B43_NTAB8(7, offset2), length, delays); + + for (i = length; i < 16; i++) { + b43_ntab_write(dev, B43_NTAB8(7, offset1 + i), end); + b43_ntab_write(dev, B43_NTAB8(7, offset2 + i), 1); + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ForceRFSeq */ static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, enum b43_nphy_rf_sequence seq) -- cgit v1.2.3 From e389900ed31975f3ce091764bf394b045058dad1 Mon Sep 17 00:00:00 2001 From: Hamish Guthrie Date: Mon, 1 Feb 2010 17:42:38 +0100 Subject: ps3_gelic_wireless: Remove superfluous debug info Signed-off-by: John W. Linville --- drivers/net/ps3_gelic_wireless.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 448c5b6789d..2663b2fdc0b 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -1449,8 +1449,7 @@ static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan, void *buf = NULL; size_t len; - pr_debug("%s: <- always=%d essid_len=%z\n", __func__, - always_scan, essid_len); + pr_debug("%s: <- always=%d\n", __func__, always_scan); if (mutex_lock_interruptible(&wl->scan_lock)) return -ERESTARTSYS; -- cgit v1.2.3 From ab5132a26236e308c6d3d832a3e04fca351656d8 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 30 Jan 2010 21:37:24 -0500 Subject: ath9k: fix access to freed data on unload Calling ath_bus_cleanup() after ieee80211_free_hw() resulted in access to common->bus_ops, which is already freed as part of the device data. Remove the cleanup field in struct ath_bus_ops, as it was never used properly. Remove ath_bus_cleanup(). Merge cleanup functions in place of the ath_bus_cleanup() calls. Take care not to use any device data after ieee80211_free_hw(). Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath.h | 1 - drivers/net/wireless/ath/ath9k/ahb.c | 12 ++---------- drivers/net/wireless/ath/ath9k/ath9k.h | 5 ----- drivers/net/wireless/ath/ath9k/pci.c | 18 +++++------------- 4 files changed, 7 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 9e05648356f..71fc960814f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -74,7 +74,6 @@ struct ath_common; struct ath_bus_ops { void (*read_cachesize)(struct ath_common *common, int *csz); - void (*cleanup)(struct ath_common *common); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); void (*bt_coex_prep)(struct ath_common *common); }; diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 9e62a569e81..ca4994f1315 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz) *csz = L1_CACHE_BYTES >> 2; } -static void ath_ahb_cleanup(struct ath_common *common) -{ - struct ath_softc *sc = (struct ath_softc *)common->priv; - iounmap(sc->mem); -} - static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) { struct ath_softc *sc = (struct ath_softc *)common->priv; @@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) static struct ath_bus_ops ath_ahb_bus_ops = { .read_cachesize = ath_ahb_read_cachesize, - .cleanup = ath_ahb_cleanup, - .eeprom_read = ath_ahb_eeprom_read, }; @@ -164,12 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev) if (hw) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + void __iomem *mem = sc->mem; ath9k_deinit_device(sc); free_irq(sc->irq, sc); ieee80211_free_hw(sc->hw); - ath_bus_cleanup(common); + iounmap(mem); platform_set_drvdata(pdev, NULL); } diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 3f8a7e773d5..0ea340fd071 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -538,11 +538,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) common->bus_ops->read_cachesize(common, csz); } -static inline void ath_bus_cleanup(struct ath_common *common) -{ - common->bus_ops->cleanup(common); -} - extern struct ieee80211_ops ath9k_ops; extern int modparam_nohwcrypt; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 4ae7b5f1202..f2afcbefc07 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -49,16 +49,6 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz) *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ } -static void ath_pci_cleanup(struct ath_common *common) -{ - struct ath_softc *sc = (struct ath_softc *) common->priv; - struct pci_dev *pdev = to_pci_dev(sc->dev); - - pci_iounmap(pdev, sc->mem); - pci_disable_device(pdev); - pci_release_region(pdev, 0); -} - static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) { struct ath_hw *ah = (struct ath_hw *) common->ah; @@ -98,7 +88,6 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) static const struct ath_bus_ops ath_pci_bus_ops = { .read_cachesize = ath_pci_read_cachesize, - .cleanup = ath_pci_cleanup, .eeprom_read = ath_pci_eeprom_read, .bt_coex_prep = ath_pci_bt_coex_prep, }; @@ -245,12 +234,15 @@ static void ath_pci_remove(struct pci_dev *pdev) struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); + void __iomem *mem = sc->mem; ath9k_deinit_device(sc); free_irq(sc->irq, sc); ieee80211_free_hw(sc->hw); - ath_bus_cleanup(common); + + pci_iounmap(pdev, mem); + pci_disable_device(pdev); + pci_release_region(pdev, 0); } #ifdef CONFIG_PM -- cgit v1.2.3 From f09c256375c7cf1e112b8ef6306cdd313490d7c0 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 2 Feb 2010 15:34:50 +0100 Subject: airo: fix setting zero length WEP key Patch prevents call set_wep_key() with zero key length. That fix long standing regression since commit c0380693520b1a1e4f756799a0edc379378b462a "airo: clean up WEP key operations". Additionally print call trace when someone will try to use improper parameters, and remove key.len = 0 assignment, because it is in not possible code path. Reported-by: Chris Siebenmann Bisected-by: Chris Siebenmann Tested-by: Chris Siebenmann Cc: Dan Williams Cc: Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 4331d675fcc..2a9f029a3c7 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5254,11 +5254,7 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key, WepKeyRid wkr; int rc; - if (keylen == 0) { - airo_print_err(ai->dev->name, "%s: key length to set was zero", - __func__); - return -1; - } + WARN_ON(keylen == 0); memset(&wkr, 0, sizeof(wkr)); wkr.len = cpu_to_le16(sizeof(wkr)); @@ -6405,11 +6401,7 @@ static int airo_set_encode(struct net_device *dev, if (dwrq->length > MIN_KEY_SIZE) key.len = MAX_KEY_SIZE; else - if (dwrq->length > 0) - key.len = MIN_KEY_SIZE; - else - /* Disable the key */ - key.len = 0; + key.len = MIN_KEY_SIZE; /* Check if the key is not marked as invalid */ if(!(dwrq->flags & IW_ENCODE_NOKEY)) { /* Cleanup */ @@ -6590,12 +6582,22 @@ static int airo_set_encodeext(struct net_device *dev, default: return -EINVAL; } - /* Send the key to the card */ - rc = set_wep_key(local, idx, key.key, key.len, perm, 1); - if (rc < 0) { - airo_print_err(local->dev->name, "failed to set WEP key" - " at index %d: %d.", idx, rc); - return rc; + if (key.len == 0) { + rc = set_wep_tx_idx(local, idx, perm, 1); + if (rc < 0) { + airo_print_err(local->dev->name, + "failed to set WEP transmit index to %d: %d.", + idx, rc); + return rc; + } + } else { + rc = set_wep_key(local, idx, key.key, key.len, perm, 1); + if (rc < 0) { + airo_print_err(local->dev->name, + "failed to set WEP key at index %d: %d.", + idx, rc); + return rc; + } } } -- cgit v1.2.3 From 5ffaf8a361b4c9025963959a744f21d8173c7669 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 2 Feb 2010 11:58:33 -0500 Subject: ath9k: add support for 802.11n bonded out AR2427 Some single chip family devices are sold in the market with 802.11n bonded out, these have no hardware capability for 802.11n but ath9k can still support them. These are called AR2427. Cc: stable@kernel.org Reported-by: Rolf Leggewie Tested-by: Bernhard Reiter Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 7 ++++++- drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/init.c | 4 +++- drivers/net/wireless/ath/ath9k/pci.c | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 0b1dd10f1d8..0b1b88ffa49 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -334,7 +334,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.pcie_clock_req = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; - ah->config.ht_enable = 1; ah->config.ofdm_trig_low = 200; ah->config.ofdm_trig_high = 500; ah->config.cck_trig_high = 200; @@ -346,6 +345,11 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.spurchans[i][1] = AR_NO_SPUR; } + if (ah->hw_version.devid != AR2427_DEVID_PCIE) + ah->config.ht_enable = 1; + else + ah->config.ht_enable = 0; + ah->config.rx_intr_mitigation = true; /* @@ -542,6 +546,7 @@ static bool ath9k_hw_devid_supported(u16 devid) case AR5416_DEVID_AR9287_PCI: case AR5416_DEVID_AR9287_PCIE: case AR9271_USB: + case AR2427_DEVID_PCIE: return true; default: break; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ab1f1981d85..dbbf7ca5f97 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -40,6 +40,7 @@ #define AR9280_DEVID_PCI 0x0029 #define AR9280_DEVID_PCIE 0x002a #define AR9285_DEVID_PCIE 0x002b +#define AR2427_DEVID_PCIE 0x002c #define AR5416_AR9100_DEVID 0x000b diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c3066b55354..4b5e5484868 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -620,11 +620,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_SPECTRUM_MGMT; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) + hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; + if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) hw->flags |= IEEE80211_HW_MFP_CAPABLE; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index f2afcbefc07..f318b3b1abe 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -25,6 +25,7 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = { { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ + { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ { 0 } -- cgit v1.2.3