aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c260
1 files changed, 17 insertions, 243 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 35cfa1524c35..8fa4f7a2dc1a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -871,138 +871,6 @@ static void iwl_set_rate(struct iwl_priv *priv)
871 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 871 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
872} 872}
873 873
874#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
875
876#include "iwl-spectrum.h"
877
878#define BEACON_TIME_MASK_LOW 0x00FFFFFF
879#define BEACON_TIME_MASK_HIGH 0xFF000000
880#define TIME_UNIT 1024
881
882/*
883 * extended beacon time format
884 * time in usec will be changed into a 32-bit value in 8:24 format
885 * the high 1 byte is the beacon counts
886 * the lower 3 bytes is the time in usec within one beacon interval
887 */
888
889static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval)
890{
891 u32 quot;
892 u32 rem;
893 u32 interval = beacon_interval * 1024;
894
895 if (!interval || !usec)
896 return 0;
897
898 quot = (usec / interval) & (BEACON_TIME_MASK_HIGH >> 24);
899 rem = (usec % interval) & BEACON_TIME_MASK_LOW;
900
901 return (quot << 24) + rem;
902}
903
904/* base is usually what we get from ucode with each received frame,
905 * the same as HW timer counter counting down
906 */
907
908static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval)
909{
910 u32 base_low = base & BEACON_TIME_MASK_LOW;
911 u32 addon_low = addon & BEACON_TIME_MASK_LOW;
912 u32 interval = beacon_interval * TIME_UNIT;
913 u32 res = (base & BEACON_TIME_MASK_HIGH) +
914 (addon & BEACON_TIME_MASK_HIGH);
915
916 if (base_low > addon_low)
917 res += base_low - addon_low;
918 else if (base_low < addon_low) {
919 res += interval + base_low - addon_low;
920 res += (1 << 24);
921 } else
922 res += (1 << 24);
923
924 return cpu_to_le32(res);
925}
926
927static int iwl_get_measurement(struct iwl_priv *priv,
928 struct ieee80211_measurement_params *params,
929 u8 type)
930{
931 struct iwl4965_spectrum_cmd spectrum;
932 struct iwl_rx_packet *res;
933 struct iwl_host_cmd cmd = {
934 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
935 .data = (void *)&spectrum,
936 .meta.flags = CMD_WANT_SKB,
937 };
938 u32 add_time = le64_to_cpu(params->start_time);
939 int rc;
940 int spectrum_resp_status;
941 int duration = le16_to_cpu(params->duration);
942
943 if (iwl_is_associated(priv))
944 add_time =
945 iwl_usecs_to_beacons(
946 le64_to_cpu(params->start_time) - priv->last_tsf,
947 le16_to_cpu(priv->rxon_timing.beacon_interval));
948
949 memset(&spectrum, 0, sizeof(spectrum));
950
951 spectrum.channel_count = cpu_to_le16(1);
952 spectrum.flags =
953 RXON_FLG_TSF2HOST_MSK | RXON_FLG_ANT_A_MSK | RXON_FLG_DIS_DIV_MSK;
954 spectrum.filter_flags = MEASUREMENT_FILTER_FLAG;
955 cmd.len = sizeof(spectrum);
956 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
957
958 if (iwl_is_associated(priv))
959 spectrum.start_time =
960 iwl_add_beacon_time(priv->last_beacon_time,
961 add_time,
962 le16_to_cpu(priv->rxon_timing.beacon_interval));
963 else
964 spectrum.start_time = 0;
965
966 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
967 spectrum.channels[0].channel = params->channel;
968 spectrum.channels[0].type = type;
969 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)
970 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
971 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
972
973 rc = iwl_send_cmd_sync(priv, &cmd);
974 if (rc)
975 return rc;
976
977 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
978 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
979 IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n");
980 rc = -EIO;
981 }
982
983 spectrum_resp_status = le16_to_cpu(res->u.spectrum.status);
984 switch (spectrum_resp_status) {
985 case 0: /* Command will be handled */
986 if (res->u.spectrum.id != 0xff) {
987 IWL_DEBUG_INFO
988 ("Replaced existing measurement: %d\n",
989 res->u.spectrum.id);
990 priv->measurement_status &= ~MEASUREMENT_READY;
991 }
992 priv->measurement_status |= MEASUREMENT_ACTIVE;
993 rc = 0;
994 break;
995
996 case 1: /* Command will not be handled */
997 rc = -EAGAIN;
998 break;
999 }
1000
1001 dev_kfree_skb_any(cmd.meta.u.skb);
1002
1003 return rc;
1004}
1005#endif
1006 874
1007/****************************************************************************** 875/******************************************************************************
1008 * 876 *
@@ -1072,24 +940,6 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1072 priv->staging_rxon.channel = csa->channel; 940 priv->staging_rxon.channel = csa->channel;
1073} 941}
1074 942
1075static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
1076 struct iwl_rx_mem_buffer *rxb)
1077{
1078#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
1079 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1080 struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
1081
1082 if (!report->state) {
1083 IWL_DEBUG(IWL_DL_11H,
1084 "Spectrum Measure Notification: Start\n");
1085 return;
1086 }
1087
1088 memcpy(&priv->measure_report, report, sizeof(*report));
1089 priv->measurement_status |= MEASUREMENT_READY;
1090#endif
1091}
1092
1093static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, 943static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
1094 struct iwl_rx_mem_buffer *rxb) 944 struct iwl_rx_mem_buffer *rxb)
1095{ 945{
@@ -1298,8 +1148,6 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
1298 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; 1148 priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
1299 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; 1149 priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error;
1300 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; 1150 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
1301 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
1302 iwl_rx_spectrum_measure_notif;
1303 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; 1151 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif;
1304 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = 1152 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
1305 iwl_rx_pm_debug_statistics_notif; 1153 iwl_rx_pm_debug_statistics_notif;
@@ -1313,6 +1161,7 @@ static void iwl_setup_rx_handlers(struct iwl_priv *priv)
1313 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics; 1161 priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_rx_statistics;
1314 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics; 1162 priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_rx_statistics;
1315 1163
1164 iwl_setup_spectrum_handlers(priv);
1316 iwl_setup_rx_scan_handlers(priv); 1165 iwl_setup_rx_scan_handlers(priv);
1317 1166
1318 /* status change handler */ 1167 /* status change handler */
@@ -1359,7 +1208,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
1359 1208
1360 /* uCode's read index (stored in shared DRAM) indicates the last Rx 1209 /* uCode's read index (stored in shared DRAM) indicates the last Rx
1361 * buffer that the driver may process (last buffer filled by ucode). */ 1210 * buffer that the driver may process (last buffer filled by ucode). */
1362 r = priv->cfg->ops->lib->shared_mem_rx_idx(priv); 1211 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
1363 i = rxq->read; 1212 i = rxq->read;
1364 1213
1365 /* Rx interrupt, but nothing sent from uCode */ 1214 /* Rx interrupt, but nothing sent from uCode */
@@ -2002,6 +1851,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
2002 return ret; 1851 return ret;
2003} 1852}
2004 1853
1854/* temporary */
1855static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
1856 struct sk_buff *skb);
1857
2005/** 1858/**
2006 * iwl_alive_start - called after REPLY_ALIVE notification received 1859 * iwl_alive_start - called after REPLY_ALIVE notification received
2007 * from protocol/runtime uCode (initialization uCode's 1860 * from protocol/runtime uCode (initialization uCode's
@@ -2084,6 +1937,15 @@ static void iwl_alive_start(struct iwl_priv *priv)
2084 1937
2085 iwl_power_update_mode(priv, 1); 1938 iwl_power_update_mode(priv, 1);
2086 1939
1940 /* reassociate for ADHOC mode */
1941 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
1942 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
1943 priv->vif);
1944 if (beacon)
1945 iwl_mac_beacon_update(priv->hw, beacon);
1946 }
1947
1948
2087 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) 1949 if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
2088 iwl_set_mode(priv, priv->iw_mode); 1950 iwl_set_mode(priv, priv->iw_mode);
2089 1951
@@ -2183,8 +2045,6 @@ static void __iwl_down(struct iwl_priv *priv)
2183 priv->cfg->ops->lib->apm_ops.stop(priv); 2045 priv->cfg->ops->lib->apm_ops.stop(priv);
2184 else 2046 else
2185 priv->cfg->ops->lib->apm_ops.reset(priv); 2047 priv->cfg->ops->lib->apm_ops.reset(priv);
2186 priv->cfg->ops->lib->free_shared_mem(priv);
2187
2188 exit: 2048 exit:
2189 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); 2049 memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
2190 2050
@@ -2237,12 +2097,6 @@ static int __iwl_up(struct iwl_priv *priv)
2237 2097
2238 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 2098 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
2239 2099
2240 ret = priv->cfg->ops->lib->alloc_shared_mem(priv);
2241 if (ret) {
2242 IWL_ERROR("Unable to allocate shared memory\n");
2243 return ret;
2244 }
2245
2246 ret = iwl_hw_nic_init(priv); 2100 ret = iwl_hw_nic_init(priv);
2247 if (ret) { 2101 if (ret) {
2248 IWL_ERROR("Unable to init nic\n"); 2102 IWL_ERROR("Unable to init nic\n");
@@ -2930,8 +2784,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
2930 * clear sta table, add BCAST sta... */ 2784 * clear sta table, add BCAST sta... */
2931} 2785}
2932 2786
2933/* temporary */
2934static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
2935 2787
2936static int iwl_mac_config_interface(struct ieee80211_hw *hw, 2788static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2937 struct ieee80211_vif *vif, 2789 struct ieee80211_vif *vif,
@@ -2953,7 +2805,9 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw,
2953 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); 2805 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
2954 if (!beacon) 2806 if (!beacon)
2955 return -ENOMEM; 2807 return -ENOMEM;
2808 mutex_lock(&priv->mutex);
2956 rc = iwl_mac_beacon_update(hw, beacon); 2809 rc = iwl_mac_beacon_update(hw, beacon);
2810 mutex_unlock(&priv->mutex);
2957 if (rc) 2811 if (rc)
2958 return rc; 2812 return rc;
2959 } 2813 }
@@ -3529,18 +3383,15 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
3529 unsigned long flags; 3383 unsigned long flags;
3530 __le64 timestamp; 3384 __le64 timestamp;
3531 3385
3532 mutex_lock(&priv->mutex);
3533 IWL_DEBUG_MAC80211("enter\n"); 3386 IWL_DEBUG_MAC80211("enter\n");
3534 3387
3535 if (!iwl_is_ready_rf(priv)) { 3388 if (!iwl_is_ready_rf(priv)) {
3536 IWL_DEBUG_MAC80211("leave - RF not ready\n"); 3389 IWL_DEBUG_MAC80211("leave - RF not ready\n");
3537 mutex_unlock(&priv->mutex);
3538 return -EIO; 3390 return -EIO;
3539 } 3391 }
3540 3392
3541 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { 3393 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
3542 IWL_DEBUG_MAC80211("leave - not IBSS\n"); 3394 IWL_DEBUG_MAC80211("leave - not IBSS\n");
3543 mutex_unlock(&priv->mutex);
3544 return -EIO; 3395 return -EIO;
3545 } 3396 }
3546 3397
@@ -3562,7 +3413,6 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
3562 3413
3563 iwl_post_associate(priv); 3414 iwl_post_associate(priv);
3564 3415
3565 mutex_unlock(&priv->mutex);
3566 3416
3567 return 0; 3417 return 0;
3568} 3418}
@@ -3766,79 +3616,6 @@ static ssize_t store_filter_flags(struct device *d,
3766static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, 3616static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
3767 store_filter_flags); 3617 store_filter_flags);
3768 3618
3769#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
3770
3771static ssize_t show_measurement(struct device *d,
3772 struct device_attribute *attr, char *buf)
3773{
3774 struct iwl_priv *priv = dev_get_drvdata(d);
3775 struct iwl4965_spectrum_notification measure_report;
3776 u32 size = sizeof(measure_report), len = 0, ofs = 0;
3777 u8 *data = (u8 *)&measure_report;
3778 unsigned long flags;
3779
3780 spin_lock_irqsave(&priv->lock, flags);
3781 if (!(priv->measurement_status & MEASUREMENT_READY)) {
3782 spin_unlock_irqrestore(&priv->lock, flags);
3783 return 0;
3784 }
3785 memcpy(&measure_report, &priv->measure_report, size);
3786 priv->measurement_status = 0;
3787 spin_unlock_irqrestore(&priv->lock, flags);
3788
3789 while (size && (PAGE_SIZE - len)) {
3790 hex_dump_to_buffer(data + ofs, size, 16, 1, buf + len,
3791 PAGE_SIZE - len, 1);
3792 len = strlen(buf);
3793 if (PAGE_SIZE - len)
3794 buf[len++] = '\n';
3795
3796 ofs += 16;
3797 size -= min(size, 16U);
3798 }
3799
3800 return len;
3801}
3802
3803static ssize_t store_measurement(struct device *d,
3804 struct device_attribute *attr,
3805 const char *buf, size_t count)
3806{
3807 struct iwl_priv *priv = dev_get_drvdata(d);
3808 struct ieee80211_measurement_params params = {
3809 .channel = le16_to_cpu(priv->active_rxon.channel),
3810 .start_time = cpu_to_le64(priv->last_tsf),
3811 .duration = cpu_to_le16(1),
3812 };
3813 u8 type = IWL_MEASURE_BASIC;
3814 u8 buffer[32];
3815 u8 channel;
3816
3817 if (count) {
3818 char *p = buffer;
3819 strncpy(buffer, buf, min(sizeof(buffer), count));
3820 channel = simple_strtoul(p, NULL, 0);
3821 if (channel)
3822 params.channel = channel;
3823
3824 p = buffer;
3825 while (*p && *p != ' ')
3826 p++;
3827 if (*p)
3828 type = simple_strtoul(p + 1, NULL, 0);
3829 }
3830
3831 IWL_DEBUG_INFO("Invoking measurement of type %d on "
3832 "channel %d (for '%s')\n", type, params.channel, buf);
3833 iwl_get_measurement(priv, &params, type);
3834
3835 return count;
3836}
3837
3838static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
3839 show_measurement, store_measurement);
3840#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
3841
3842static ssize_t store_retry_rate(struct device *d, 3619static ssize_t store_retry_rate(struct device *d,
3843 struct device_attribute *attr, 3620 struct device_attribute *attr,
3844 const char *buf, size_t count) 3621 const char *buf, size_t count)
@@ -4091,9 +3868,6 @@ static struct attribute *iwl_sysfs_entries[] = {
4091 &dev_attr_channels.attr, 3868 &dev_attr_channels.attr,
4092 &dev_attr_flags.attr, 3869 &dev_attr_flags.attr,
4093 &dev_attr_filter_flags.attr, 3870 &dev_attr_filter_flags.attr,
4094#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
4095 &dev_attr_measurement.attr,
4096#endif
4097 &dev_attr_power_level.attr, 3871 &dev_attr_power_level.attr,
4098 &dev_attr_retry_rate.attr, 3872 &dev_attr_retry_rate.attr,
4099 &dev_attr_statistics.attr, 3873 &dev_attr_statistics.attr,