aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2008-06-30 05:23:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-30 17:37:40 -0400
commit1781a07fbe9cce3dc1697288a5edd260ea7edc02 (patch)
treebe06e824b69af8d43edfeab2c78a353f0bf7f8ce
parent37deb2a0baf1bb540b723cc8a3972b42ff2daac6 (diff)
iwlwifi: move RX handlers to iwl-rx.c
This patch moves RX handlers to iwl-rx.c Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c703
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c853
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c152
5 files changed, 861 insertions, 860 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 1688803af58..d8e6d2e6a86 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1929,707 +1929,6 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv,
1929 queue_work(priv->workqueue, &priv->txpower_work); 1929 queue_work(priv->workqueue, &priv->txpower_work);
1930} 1930}
1931 1931
1932static void iwl4965_add_radiotap(struct iwl_priv *priv,
1933 struct sk_buff *skb,
1934 struct iwl4965_rx_phy_res *rx_start,
1935 struct ieee80211_rx_status *stats,
1936 u32 ampdu_status)
1937{
1938 s8 signal = stats->signal;
1939 s8 noise = 0;
1940 int rate = stats->rate_idx;
1941 u64 tsf = stats->mactime;
1942 __le16 antenna;
1943 __le16 phy_flags_hw = rx_start->phy_flags;
1944 struct iwl4965_rt_rx_hdr {
1945 struct ieee80211_radiotap_header rt_hdr;
1946 __le64 rt_tsf; /* TSF */
1947 u8 rt_flags; /* radiotap packet flags */
1948 u8 rt_rate; /* rate in 500kb/s */
1949 __le16 rt_channelMHz; /* channel in MHz */
1950 __le16 rt_chbitmask; /* channel bitfield */
1951 s8 rt_dbmsignal; /* signal in dBm, kluged to signed */
1952 s8 rt_dbmnoise;
1953 u8 rt_antenna; /* antenna number */
1954 } __attribute__ ((packed)) *iwl4965_rt;
1955
1956 /* TODO: We won't have enough headroom for HT frames. Fix it later. */
1957 if (skb_headroom(skb) < sizeof(*iwl4965_rt)) {
1958 if (net_ratelimit())
1959 printk(KERN_ERR "not enough headroom [%d] for "
1960 "radiotap head [%zd]\n",
1961 skb_headroom(skb), sizeof(*iwl4965_rt));
1962 return;
1963 }
1964
1965 /* put radiotap header in front of 802.11 header and data */
1966 iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt));
1967
1968 /* initialise radiotap header */
1969 iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
1970 iwl4965_rt->rt_hdr.it_pad = 0;
1971
1972 /* total header + data */
1973 put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)),
1974 &iwl4965_rt->rt_hdr.it_len);
1975
1976 /* Indicate all the fields we add to the radiotap header */
1977 put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
1978 (1 << IEEE80211_RADIOTAP_FLAGS) |
1979 (1 << IEEE80211_RADIOTAP_RATE) |
1980 (1 << IEEE80211_RADIOTAP_CHANNEL) |
1981 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
1982 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
1983 (1 << IEEE80211_RADIOTAP_ANTENNA)),
1984 &iwl4965_rt->rt_hdr.it_present);
1985
1986 /* Zero the flags, we'll add to them as we go */
1987 iwl4965_rt->rt_flags = 0;
1988
1989 put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf);
1990
1991 iwl4965_rt->rt_dbmsignal = signal;
1992 iwl4965_rt->rt_dbmnoise = noise;
1993
1994 /* Convert the channel frequency and set the flags */
1995 put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz);
1996 if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
1997 put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
1998 IEEE80211_CHAN_5GHZ),
1999 &iwl4965_rt->rt_chbitmask);
2000 else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
2001 put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK |
2002 IEEE80211_CHAN_2GHZ),
2003 &iwl4965_rt->rt_chbitmask);
2004 else /* 802.11g */
2005 put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
2006 IEEE80211_CHAN_2GHZ),
2007 &iwl4965_rt->rt_chbitmask);
2008
2009 if (rate == -1)
2010 iwl4965_rt->rt_rate = 0;
2011 else
2012 iwl4965_rt->rt_rate = iwl_rates[rate].ieee;
2013
2014 /*
2015 * "antenna number"
2016 *
2017 * It seems that the antenna field in the phy flags value
2018 * is actually a bitfield. This is undefined by radiotap,
2019 * it wants an actual antenna number but I always get "7"
2020 * for most legacy frames I receive indicating that the
2021 * same frame was received on all three RX chains.
2022 *
2023 * I think this field should be removed in favour of a
2024 * new 802.11n radiotap field "RX chains" that is defined
2025 * as a bitmask.
2026 */
2027 antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
2028 iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4;
2029
2030 /* set the preamble flag if appropriate */
2031 if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
2032 iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
2033
2034 stats->flag |= RX_FLAG_RADIOTAP;
2035}
2036
2037static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
2038{
2039 /* 0 - mgmt, 1 - cnt, 2 - data */
2040 int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
2041 priv->rx_stats[idx].cnt++;
2042 priv->rx_stats[idx].bytes += len;
2043}
2044
2045/*
2046 * returns non-zero if packet should be dropped
2047 */
2048static int iwl4965_set_decrypted_flag(struct iwl_priv *priv,
2049 struct ieee80211_hdr *hdr,
2050 u32 decrypt_res,
2051 struct ieee80211_rx_status *stats)
2052{
2053 u16 fc = le16_to_cpu(hdr->frame_control);
2054
2055 if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
2056 return 0;
2057
2058 if (!(fc & IEEE80211_FCTL_PROTECTED))
2059 return 0;
2060
2061 IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
2062 switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
2063 case RX_RES_STATUS_SEC_TYPE_TKIP:
2064 /* The uCode has got a bad phase 1 Key, pushes the packet.
2065 * Decryption will be done in SW. */
2066 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
2067 RX_RES_STATUS_BAD_KEY_TTAK)
2068 break;
2069
2070 case RX_RES_STATUS_SEC_TYPE_WEP:
2071 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
2072 RX_RES_STATUS_BAD_ICV_MIC) {
2073 /* bad ICV, the packet is destroyed since the
2074 * decryption is inplace, drop it */
2075 IWL_DEBUG_RX("Packet destroyed\n");
2076 return -1;
2077 }
2078 case RX_RES_STATUS_SEC_TYPE_CCMP:
2079 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
2080 RX_RES_STATUS_DECRYPT_OK) {
2081 IWL_DEBUG_RX("hw decrypt successfully!!!\n");
2082 stats->flag |= RX_FLAG_DECRYPTED;
2083 }
2084 break;
2085
2086 default:
2087 break;
2088 }
2089 return 0;
2090}
2091
2092static u32 iwl4965_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
2093{
2094 u32 decrypt_out = 0;
2095
2096 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
2097 RX_RES_STATUS_STATION_FOUND)
2098 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
2099 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
2100
2101 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
2102
2103 /* packet was not encrypted */
2104 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
2105 RX_RES_STATUS_SEC_TYPE_NONE)
2106 return decrypt_out;
2107
2108 /* packet was encrypted with unknown alg */
2109 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
2110 RX_RES_STATUS_SEC_TYPE_ERR)
2111 return decrypt_out;
2112
2113 /* decryption was not done in HW */
2114 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
2115 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
2116 return decrypt_out;
2117
2118 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
2119
2120 case RX_RES_STATUS_SEC_TYPE_CCMP:
2121 /* alg is CCM: check MIC only */
2122 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
2123 /* Bad MIC */
2124 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
2125 else
2126 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
2127
2128 break;
2129
2130 case RX_RES_STATUS_SEC_TYPE_TKIP:
2131 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
2132 /* Bad TTAK */
2133 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
2134 break;
2135 }
2136 /* fall through if TTAK OK */
2137 default:
2138 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
2139 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
2140 else
2141 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
2142 break;
2143 };
2144
2145 IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
2146 decrypt_in, decrypt_out);
2147
2148 return decrypt_out;
2149}
2150
2151static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data,
2152 int include_phy,
2153 struct iwl_rx_mem_buffer *rxb,
2154 struct ieee80211_rx_status *stats)
2155{
2156 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
2157 struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
2158 (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
2159 struct ieee80211_hdr *hdr;
2160 u16 len;
2161 __le32 *rx_end;
2162 unsigned int skblen;
2163 u32 ampdu_status;
2164 u32 ampdu_status_legacy;
2165
2166 if (!include_phy && priv->last_phy_res[0])
2167 rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
2168
2169 if (!rx_start) {
2170 IWL_ERROR("MPDU frame without a PHY data\n");
2171 return;
2172 }
2173 if (include_phy) {
2174 hdr = (struct ieee80211_hdr *)((u8 *) & rx_start[1] +
2175 rx_start->cfg_phy_cnt);
2176
2177 len = le16_to_cpu(rx_start->byte_count);
2178
2179 rx_end = (__le32 *) ((u8 *) & pkt->u.raw[0] +
2180 sizeof(struct iwl4965_rx_phy_res) +
2181 rx_start->cfg_phy_cnt + len);
2182
2183 } else {
2184 struct iwl4965_rx_mpdu_res_start *amsdu =
2185 (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
2186
2187 hdr = (struct ieee80211_hdr *)(pkt->u.raw +
2188 sizeof(struct iwl4965_rx_mpdu_res_start));
2189 len = le16_to_cpu(amsdu->byte_count);
2190 rx_start->byte_count = amsdu->byte_count;
2191 rx_end = (__le32 *) (((u8 *) hdr) + len);
2192 }
2193 /* In monitor mode allow 802.11 ACk frames (10 bytes) */
2194 if (len > priv->hw_params.max_pkt_size ||
2195 len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) {
2196 IWL_WARNING("byte count out of range [16,4K] : %d\n", len);
2197 return;
2198 }
2199
2200 ampdu_status = le32_to_cpu(*rx_end);
2201 skblen = ((u8 *) rx_end - (u8 *) & pkt->u.raw[0]) + sizeof(u32);
2202
2203 if (!include_phy) {
2204 /* New status scheme, need to translate */
2205 ampdu_status_legacy = ampdu_status;
2206 ampdu_status = iwl4965_translate_rx_status(priv, ampdu_status);
2207 }
2208
2209 /* start from MAC */
2210 skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
2211 skb_put(rxb->skb, len); /* end where data ends */
2212
2213 /* We only process data packets if the interface is open */
2214 if (unlikely(!priv->is_open)) {
2215 IWL_DEBUG_DROP_LIMIT
2216 ("Dropping packet while interface is not open.\n");
2217 return;
2218 }
2219
2220 stats->flag = 0;
2221 hdr = (struct ieee80211_hdr *)rxb->skb->data;
2222
2223 /* in case of HW accelerated crypto and bad decryption, drop */
2224 if (!priv->hw_params.sw_crypto &&
2225 iwl4965_set_decrypted_flag(priv, hdr, ampdu_status, stats))
2226 return;
2227
2228 if (priv->add_radiotap)
2229 iwl4965_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
2230
2231 iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
2232 ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
2233 priv->alloc_rxb_skb--;
2234 rxb->skb = NULL;
2235}
2236
2237/* Calc max signal level (dBm) among 3 possible receivers */
2238static int iwl4965_calc_rssi(struct iwl_priv *priv,
2239 struct iwl4965_rx_phy_res *rx_resp)
2240{
2241 /* data from PHY/DSP regarding signal strength, etc.,
2242 * contents are always there, not configurable by host. */
2243 struct iwl4965_rx_non_cfg_phy *ncphy =
2244 (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
2245 u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
2246 >> IWL_AGC_DB_POS;
2247
2248 u32 valid_antennae =
2249 (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
2250 >> RX_PHY_FLAGS_ANTENNAE_OFFSET;
2251 u8 max_rssi = 0;
2252 u32 i;
2253
2254 /* Find max rssi among 3 possible receivers.
2255 * These values are measured by the digital signal processor (DSP).
2256 * They should stay fairly constant even as the signal strength varies,
2257 * if the radio's automatic gain control (AGC) is working right.
2258 * AGC value (see below) will provide the "interesting" info. */
2259 for (i = 0; i < 3; i++)
2260 if (valid_antennae & (1 << i))
2261 max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
2262
2263 IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
2264 ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
2265 max_rssi, agc);
2266
2267 /* dBm = max_rssi dB - agc dB - constant.
2268 * Higher AGC (higher radio gain) means lower signal. */
2269 return (max_rssi - agc - IWL_RSSI_OFFSET);
2270}
2271
2272static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
2273{
2274 unsigned long flags;
2275
2276 spin_lock_irqsave(&priv->sta_lock, flags);
2277 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
2278 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
2279 priv->stations[sta_id].sta.sta.modify_mask = 0;
2280 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2281 spin_unlock_irqrestore(&priv->sta_lock, flags);
2282
2283 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
2284}
2285
2286static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
2287{
2288 /* FIXME: need locking over ps_status ??? */
2289 u8 sta_id = iwl_find_station(priv, addr);
2290
2291 if (sta_id != IWL_INVALID_STATION) {
2292 u8 sta_awake = priv->stations[sta_id].
2293 ps_status == STA_PS_STATUS_WAKE;
2294
2295 if (sta_awake && ps_bit)
2296 priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP;
2297 else if (!sta_awake && !ps_bit) {
2298 iwl4965_sta_modify_ps_wake(priv, sta_id);
2299 priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE;
2300 }
2301 }
2302}
2303#ifdef CONFIG_IWLWIFI_DEBUG
2304
2305/**
2306 * iwl4965_dbg_report_frame - dump frame to syslog during debug sessions
2307 *
2308 * You may hack this function to show different aspects of received frames,
2309 * including selective frame dumps.
2310 * group100 parameter selects whether to show 1 out of 100 good frames.
2311 *
2312 * TODO: This was originally written for 3945, need to audit for
2313 * proper operation with 4965.
2314 */
2315static void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2316 struct iwl_rx_packet *pkt,
2317 struct ieee80211_hdr *header, int group100)
2318{
2319 u32 to_us;
2320 u32 print_summary = 0;
2321 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
2322 u32 hundred = 0;
2323 u32 dataframe = 0;
2324 __le16 fc;
2325 u16 seq_ctl;
2326 u16 channel;
2327 u16 phy_flags;
2328 int rate_sym;
2329 u16 length;
2330 u16 status;
2331 u16 bcn_tmr;
2332 u32 tsf_low;
2333 u64 tsf;
2334 u8 rssi;
2335 u8 agc;
2336 u16 sig_avg;
2337 u16 noise_diff;
2338 struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
2339 struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
2340 struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
2341 u8 *data = IWL_RX_DATA(pkt);
2342
2343 if (likely(!(priv->debug_level & IWL_DL_RX)))
2344 return;
2345
2346 /* MAC header */
2347 fc = header->frame_control;
2348 seq_ctl = le16_to_cpu(header->seq_ctrl);
2349
2350 /* metadata */
2351 channel = le16_to_cpu(rx_hdr->channel);
2352 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
2353 rate_sym = rx_hdr->rate;
2354 length = le16_to_cpu(rx_hdr->len);
2355
2356 /* end-of-frame status and timestamp */
2357 status = le32_to_cpu(rx_end->status);
2358 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
2359 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
2360 tsf = le64_to_cpu(rx_end->timestamp);
2361
2362 /* signal statistics */
2363 rssi = rx_stats->rssi;
2364 agc = rx_stats->agc;
2365 sig_avg = le16_to_cpu(rx_stats->sig_avg);
2366 noise_diff = le16_to_cpu(rx_stats->noise_diff);
2367
2368 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
2369
2370 /* if data frame is to us and all is good,
2371 * (optionally) print summary for only 1 out of every 100 */
2372 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
2373 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
2374 dataframe = 1;
2375 if (!group100)
2376 print_summary = 1; /* print each frame */
2377 else if (priv->framecnt_to_us < 100) {
2378 priv->framecnt_to_us++;
2379 print_summary = 0;
2380 } else {
2381 priv->framecnt_to_us = 0;
2382 print_summary = 1;
2383 hundred = 1;
2384 }
2385 } else {
2386 /* print summary for all other frames */
2387 print_summary = 1;
2388 }
2389
2390 if (print_summary) {
2391 char *title;
2392 int rate_idx;
2393 u32 bitrate;
2394
2395 if (hundred)
2396 title = "100Frames";
2397 else if (ieee80211_has_retry(fc))
2398 title = "Retry";
2399 else if (ieee80211_is_assoc_resp(fc))
2400 title = "AscRsp";
2401 else if (ieee80211_is_reassoc_resp(fc))
2402 title = "RasRsp";
2403 else if (ieee80211_is_probe_resp(fc)) {
2404 title = "PrbRsp";
2405 print_dump = 1; /* dump frame contents */
2406 } else if (ieee80211_is_beacon(fc)) {
2407 title = "Beacon";
2408 print_dump = 1; /* dump frame contents */
2409 } else if (ieee80211_is_atim(fc))
2410 title = "ATIM";
2411 else if (ieee80211_is_auth(fc))
2412 title = "Auth";
2413 else if (ieee80211_is_deauth(fc))
2414 title = "DeAuth";
2415 else if (ieee80211_is_disassoc(fc))
2416 title = "DisAssoc";
2417 else
2418 title = "Frame";
2419
2420 rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
2421 if (unlikely(rate_idx == -1))
2422 bitrate = 0;
2423 else
2424 bitrate = iwl_rates[rate_idx].ieee / 2;
2425
2426 /* print frame summary.
2427 * MAC addresses show just the last byte (for brevity),
2428 * but you can hack it to show more, if you'd like to. */
2429 if (dataframe)
2430 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
2431 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
2432 title, le16_to_cpu(fc), header->addr1[5],
2433 length, rssi, channel, bitrate);
2434 else {
2435 /* src/dst addresses assume managed mode */
2436 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
2437 "src=0x%02x, rssi=%u, tim=%lu usec, "
2438 "phy=0x%02x, chnl=%d\n",
2439 title, le16_to_cpu(fc), header->addr1[5],
2440 header->addr3[5], rssi,
2441 tsf_low - priv->scan_start_tsf,
2442 phy_flags, channel);
2443 }
2444 }
2445 if (print_dump)
2446 iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
2447}
2448#else
2449static inline void iwl4965_dbg_report_frame(struct iwl_priv *priv,
2450 struct iwl_rx_packet *pkt,
2451 struct ieee80211_hdr *header,
2452 int group100)
2453{
2454}
2455#endif
2456
2457
2458
2459/* Called for REPLY_RX (legacy ABG frames), or
2460 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
2461void iwl4965_rx_reply_rx(struct iwl_priv *priv,
2462 struct iwl_rx_mem_buffer *rxb)
2463{
2464 struct ieee80211_hdr *header;
2465 struct ieee80211_rx_status rx_status;
2466 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
2467 /* Use phy data (Rx signal strength, etc.) contained within
2468 * this rx packet for legacy frames,
2469 * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
2470 int include_phy = (pkt->hdr.cmd == REPLY_RX);
2471 struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
2472 (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
2473 (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
2474 __le32 *rx_end;
2475 unsigned int len = 0;
2476 u16 fc;
2477 u8 network_packet;
2478
2479 rx_status.mactime = le64_to_cpu(rx_start->timestamp);
2480 rx_status.freq =
2481 ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
2482 rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
2483 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
2484 rx_status.rate_idx =
2485 iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
2486 if (rx_status.band == IEEE80211_BAND_5GHZ)
2487 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
2488
2489 rx_status.antenna = 0;
2490 rx_status.flag = 0;
2491
2492 if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
2493 IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
2494 rx_start->cfg_phy_cnt);
2495 return;
2496 }
2497
2498 if (!include_phy) {
2499 if (priv->last_phy_res[0])
2500 rx_start = (struct iwl4965_rx_phy_res *)
2501 &priv->last_phy_res[1];
2502 else
2503 rx_start = NULL;
2504 }
2505
2506 if (!rx_start) {
2507 IWL_ERROR("MPDU frame without a PHY data\n");
2508 return;
2509 }
2510
2511 if (include_phy) {
2512 header = (struct ieee80211_hdr *)((u8 *) & rx_start[1]
2513 + rx_start->cfg_phy_cnt);
2514
2515 len = le16_to_cpu(rx_start->byte_count);
2516 rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
2517 sizeof(struct iwl4965_rx_phy_res) + len);
2518 } else {
2519 struct iwl4965_rx_mpdu_res_start *amsdu =
2520 (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
2521
2522 header = (void *)(pkt->u.raw +
2523 sizeof(struct iwl4965_rx_mpdu_res_start));
2524 len = le16_to_cpu(amsdu->byte_count);
2525 rx_end = (__le32 *) (pkt->u.raw +
2526 sizeof(struct iwl4965_rx_mpdu_res_start) + len);
2527 }
2528
2529 if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
2530 !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
2531 IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
2532 le32_to_cpu(*rx_end));
2533 return;
2534 }
2535
2536 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
2537
2538 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
2539 rx_status.signal = iwl4965_calc_rssi(priv, rx_start);
2540
2541 /* Meaningful noise values are available only from beacon statistics,
2542 * which are gathered only when associated, and indicate noise
2543 * only for the associated network channel ...
2544 * Ignore these noise values while scanning (other channels) */
2545 if (iwl_is_associated(priv) &&
2546 !test_bit(STATUS_SCANNING, &priv->status)) {
2547 rx_status.noise = priv->last_rx_noise;
2548 rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal,
2549 rx_status.noise);
2550 } else {
2551 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
2552 rx_status.qual = iwl4965_calc_sig_qual(rx_status.signal, 0);
2553 }
2554
2555 /* Reset beacon noise level if not associated. */
2556 if (!iwl_is_associated(priv))
2557 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
2558
2559 /* Set "1" to report good data frames in groups of 100 */
2560 /* FIXME: need to optimze the call: */
2561 iwl4965_dbg_report_frame(priv, pkt, header, 1);
2562
2563 IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
2564 rx_status.signal, rx_status.noise, rx_status.signal,
2565 (unsigned long long)rx_status.mactime);
2566
2567
2568 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
2569 iwl4965_handle_data_packet(priv, 1, include_phy,
2570 rxb, &rx_status);
2571 return;
2572 }
2573
2574 network_packet = iwl4965_is_network_packet(priv, header);
2575 if (network_packet) {
2576 priv->last_rx_rssi = rx_status.signal;
2577 priv->last_beacon_time = priv->ucode_beacon_time;
2578 priv->last_tsf = le64_to_cpu(rx_start->timestamp);
2579 }
2580
2581 fc = le16_to_cpu(header->frame_control);
2582 switch (fc & IEEE80211_FCTL_FTYPE) {
2583 case IEEE80211_FTYPE_MGMT:
2584 if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
2585 iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
2586 header->addr2);
2587 iwl4965_handle_data_packet(priv, 0, include_phy, rxb, &rx_status);
2588 break;
2589
2590 case IEEE80211_FTYPE_CTL:
2591 switch (fc & IEEE80211_FCTL_STYPE) {
2592 case IEEE80211_STYPE_BACK_REQ:
2593 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
2594 iwl4965_handle_data_packet(priv, 0, include_phy,
2595 rxb, &rx_status);
2596 break;
2597 default:
2598 break;
2599 }
2600 break;
2601
2602 case IEEE80211_FTYPE_DATA: {
2603 DECLARE_MAC_BUF(mac1);
2604 DECLARE_MAC_BUF(mac2);
2605 DECLARE_MAC_BUF(mac3);
2606
2607 if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
2608 iwl4965_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
2609 header->addr2);
2610
2611 if (unlikely(!network_packet))
2612 IWL_DEBUG_DROP("Dropping (non network): "
2613 "%s, %s, %s\n",
2614 print_mac(mac1, header->addr1),
2615 print_mac(mac2, header->addr2),
2616 print_mac(mac3, header->addr3));
2617 else if (unlikely(iwl4965_is_duplicate_packet(priv, header)))
2618 IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
2619 print_mac(mac1, header->addr1),
2620 print_mac(mac2, header->addr2),
2621 print_mac(mac3, header->addr3));
2622 else
2623 iwl4965_handle_data_packet(priv, 1, include_phy, rxb,
2624 &rx_status);
2625 break;
2626 }
2627 default:
2628 break;
2629
2630 }
2631}
2632
2633/** 1932/**
2634 * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack 1933 * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack
2635 * 1934 *
@@ -3253,7 +2552,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
3253static void iwl4965_rx_handler_setup(struct iwl_priv *priv) 2552static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
3254{ 2553{
3255 /* Legacy Rx frames */ 2554 /* Legacy Rx frames */
3256 priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx; 2555 priv->rx_handlers[REPLY_RX] = iwl_rx_reply_rx;
3257 /* Tx response */ 2556 /* Tx response */
3258 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; 2557 priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
3259 /* block ack */ 2558 /* block ack */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 0cff64d878e..0d8cc8c659a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -372,7 +372,11 @@ extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
372extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); 372extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
373extern int iwl_verify_ucode(struct iwl_priv *priv); 373extern int iwl_verify_ucode(struct iwl_priv *priv);
374extern int iwl_send_lq_cmd(struct iwl_priv *priv, 374extern int iwl_send_lq_cmd(struct iwl_priv *priv,
375 struct iwl_link_quality_cmd *lq, u8 flags); 375 struct iwl_link_quality_cmd *lq, u8 flags);
376extern void iwl_rx_reply_rx(struct iwl_priv *priv,
377 struct iwl_rx_mem_buffer *rxb);
378extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
379 struct iwl_rx_mem_buffer *rxb);
376 380
377static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) 381static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
378{ 382{
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index fd008ab63bd..8017e57dc14 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -591,11 +591,6 @@ extern int iwl_send_add_sta(struct iwl_priv *priv,
591 struct iwl_addsta_cmd *sta, u8 flags); 591 struct iwl_addsta_cmd *sta, u8 flags);
592u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, 592u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
593 u8 flags, struct ieee80211_ht_info *ht_info); 593 u8 flags, struct ieee80211_ht_info *ht_info);
594extern int iwl4965_is_network_packet(struct iwl_priv *priv,
595 struct ieee80211_hdr *header);
596extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv,
597 struct ieee80211_hdr *header);
598extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm);
599extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, 594extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
600 struct ieee80211_hdr *hdr, 595 struct ieee80211_hdr *hdr,
601 const u8 *dest, int left); 596 const u8 *dest, int left);
@@ -625,8 +620,6 @@ extern void iwl_txq_ctx_stop(struct iwl_priv *priv);
625extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, 620extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
626 struct iwl_frame *frame, u8 rate); 621 struct iwl_frame *frame, u8 rate);
627extern void iwl4965_disable_events(struct iwl_priv *priv); 622extern void iwl4965_disable_events(struct iwl_priv *priv);
628extern void iwl4965_rx_reply_rx(struct iwl_priv *priv,
629 struct iwl_rx_mem_buffer *rxb);
630 623
631extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel); 624extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);
632extern int iwl_queue_space(const struct iwl_queue *q); 625extern int iwl_queue_space(const struct iwl_queue *q);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index b3ca1375c01..e0d3e2dd1d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -27,6 +27,7 @@
27 * 27 *
28 *****************************************************************************/ 28 *****************************************************************************/
29 29
30#include <linux/etherdevice.h>
30#include <net/mac80211.h> 31#include <net/mac80211.h>
31#include "iwl-eeprom.h" 32#include "iwl-eeprom.h"
32#include "iwl-dev.h" 33#include "iwl-dev.h"
@@ -541,3 +542,855 @@ void iwl_rx_statistics(struct iwl_priv *priv,
541 priv->cfg->ops->lib->temperature(priv, &pkt->u.stats); 542 priv->cfg->ops->lib->temperature(priv, &pkt->u.stats);
542} 543}
543EXPORT_SYMBOL(iwl_rx_statistics); 544EXPORT_SYMBOL(iwl_rx_statistics);
545
546#define PERFECT_RSSI (-20) /* dBm */
547#define WORST_RSSI (-95) /* dBm */
548#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
549
550/* Calculate an indication of rx signal quality (a percentage, not dBm!).
551 * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
552 * about formulas used below. */
553static int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm)
554{
555 int sig_qual;
556 int degradation = PERFECT_RSSI - rssi_dbm;
557
558 /* If we get a noise measurement, use signal-to-noise ratio (SNR)
559 * as indicator; formula is (signal dbm - noise dbm).
560 * SNR at or above 40 is a great signal (100%).
561 * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
562 * Weakest usable signal is usually 10 - 15 dB SNR. */
563 if (noise_dbm) {
564 if (rssi_dbm - noise_dbm >= 40)
565 return 100;
566 else if (rssi_dbm < noise_dbm)
567 return 0;
568 sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
569
570 /* Else use just the signal level.
571 * This formula is a least squares fit of data points collected and
572 * compared with a reference system that had a percentage (%) display
573 * for signal quality. */
574 } else
575 sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
576 (15 * RSSI_RANGE + 62 * degradation)) /
577 (RSSI_RANGE * RSSI_RANGE);
578
579 if (sig_qual > 100)
580 sig_qual = 100;
581 else if (sig_qual < 1)
582 sig_qual = 0;
583
584 return sig_qual;
585}
586
587#ifdef CONFIG_IWLWIFI_DEBUG
588
589/**
590 * iwl_dbg_report_frame - dump frame to syslog during debug sessions
591 *
592 * You may hack this function to show different aspects of received frames,
593 * including selective frame dumps.
594 * group100 parameter selects whether to show 1 out of 100 good frames.
595 *
596 * TODO: This was originally written for 3945, need to audit for
597 * proper operation with 4965.
598 */
599static void iwl_dbg_report_frame(struct iwl_priv *priv,
600 struct iwl_rx_packet *pkt,
601 struct ieee80211_hdr *header, int group100)
602{
603 u32 to_us;
604 u32 print_summary = 0;
605 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
606 u32 hundred = 0;
607 u32 dataframe = 0;
608 __le16 fc;
609 u16 seq_ctl;
610 u16 channel;
611 u16 phy_flags;
612 int rate_sym;
613 u16 length;
614 u16 status;
615 u16 bcn_tmr;
616 u32 tsf_low;
617 u64 tsf;
618 u8 rssi;
619 u8 agc;
620 u16 sig_avg;
621 u16 noise_diff;
622 struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
623 struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
624 struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt);
625 u8 *data = IWL_RX_DATA(pkt);
626
627 if (likely(!(priv->debug_level & IWL_DL_RX)))
628 return;
629
630 /* MAC header */
631 fc = header->frame_control;
632 seq_ctl = le16_to_cpu(header->seq_ctrl);
633
634 /* metadata */
635 channel = le16_to_cpu(rx_hdr->channel);
636 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
637 rate_sym = rx_hdr->rate;
638 length = le16_to_cpu(rx_hdr->len);
639
640 /* end-of-frame status and timestamp */
641 status = le32_to_cpu(rx_end->status);
642 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
643 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
644 tsf = le64_to_cpu(rx_end->timestamp);
645
646 /* signal statistics */
647 rssi = rx_stats->rssi;
648 agc = rx_stats->agc;
649 sig_avg = le16_to_cpu(rx_stats->sig_avg);
650 noise_diff = le16_to_cpu(rx_stats->noise_diff);
651
652 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
653
654 /* if data frame is to us and all is good,
655 * (optionally) print summary for only 1 out of every 100 */
656 if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) ==
657 cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
658 dataframe = 1;
659 if (!group100)
660 print_summary = 1; /* print each frame */
661 else if (priv->framecnt_to_us < 100) {
662 priv->framecnt_to_us++;
663 print_summary = 0;
664 } else {
665 priv->framecnt_to_us = 0;
666 print_summary = 1;
667 hundred = 1;
668 }
669 } else {
670 /* print summary for all other frames */
671 print_summary = 1;
672 }
673
674 if (print_summary) {
675 char *title;
676 int rate_idx;
677 u32 bitrate;
678
679 if (hundred)
680 title = "100Frames";
681 else if (ieee80211_has_retry(fc))
682 title = "Retry";
683 else if (ieee80211_is_assoc_resp(fc))
684 title = "AscRsp";
685 else if (ieee80211_is_reassoc_resp(fc))
686 title = "RasRsp";
687 else if (ieee80211_is_probe_resp(fc)) {
688 title = "PrbRsp";
689 print_dump = 1; /* dump frame contents */
690 } else if (ieee80211_is_beacon(fc)) {
691 title = "Beacon";
692 print_dump = 1; /* dump frame contents */
693 } else if (ieee80211_is_atim(fc))
694 title = "ATIM";
695 else if (ieee80211_is_auth(fc))
696 title = "Auth";
697 else if (ieee80211_is_deauth(fc))
698 title = "DeAuth";
699 else if (ieee80211_is_disassoc(fc))
700 title = "DisAssoc";
701 else
702 title = "Frame";
703
704 rate_idx = iwl_hwrate_to_plcp_idx(rate_sym);
705 if (unlikely(rate_idx == -1))
706 bitrate = 0;
707 else
708 bitrate = iwl_rates[rate_idx].ieee / 2;
709
710 /* print frame summary.
711 * MAC addresses show just the last byte (for brevity),
712 * but you can hack it to show more, if you'd like to. */
713 if (dataframe)
714 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
715 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
716 title, le16_to_cpu(fc), header->addr1[5],
717 length, rssi, channel, bitrate);
718 else {
719 /* src/dst addresses assume managed mode */
720 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
721 "src=0x%02x, rssi=%u, tim=%lu usec, "
722 "phy=0x%02x, chnl=%d\n",
723 title, le16_to_cpu(fc), header->addr1[5],
724 header->addr3[5], rssi,
725 tsf_low - priv->scan_start_tsf,
726 phy_flags, channel);
727 }
728 }
729 if (print_dump)
730 iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
731}
732#else
733static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
734 struct iwl_rx_packet *pkt,
735 struct ieee80211_hdr *header,
736 int group100)
737{
738}
739#endif
740
741static void iwl_add_radiotap(struct iwl_priv *priv,
742 struct sk_buff *skb,
743 struct iwl4965_rx_phy_res *rx_start,
744 struct ieee80211_rx_status *stats,
745 u32 ampdu_status)
746{
747 s8 signal = stats->signal;
748 s8 noise = 0;
749 int rate = stats->rate_idx;
750 u64 tsf = stats->mactime;
751 __le16 antenna;
752 __le16 phy_flags_hw = rx_start->phy_flags;
753 struct iwl4965_rt_rx_hdr {
754 struct ieee80211_radiotap_header rt_hdr;
755 __le64 rt_tsf; /* TSF */
756 u8 rt_flags; /* radiotap packet flags */
757 u8 rt_rate; /* rate in 500kb/s */
758 __le16 rt_channelMHz; /* channel in MHz */
759 __le16 rt_chbitmask; /* channel bitfield */
760 s8 rt_dbmsignal; /* signal in dBm, kluged to signed */
761 s8 rt_dbmnoise;
762 u8 rt_antenna; /* antenna number */
763 } __attribute__ ((packed)) *iwl4965_rt;
764
765 /* TODO: We won't have enough headroom for HT frames. Fix it later. */
766 if (skb_headroom(skb) < sizeof(*iwl4965_rt)) {
767 if (net_ratelimit())
768 printk(KERN_ERR "not enough headroom [%d] for "
769 "radiotap head [%zd]\n",
770 skb_headroom(skb), sizeof(*iwl4965_rt));
771 return;
772 }
773
774 /* put radiotap header in front of 802.11 header and data */
775 iwl4965_rt = (void *)skb_push(skb, sizeof(*iwl4965_rt));
776
777 /* initialise radiotap header */
778 iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
779 iwl4965_rt->rt_hdr.it_pad = 0;
780
781 /* total header + data */
782 put_unaligned(cpu_to_le16(sizeof(*iwl4965_rt)),
783 &iwl4965_rt->rt_hdr.it_len);
784
785 /* Indicate all the fields we add to the radiotap header */
786 put_unaligned(cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
787 (1 << IEEE80211_RADIOTAP_FLAGS) |
788 (1 << IEEE80211_RADIOTAP_RATE) |
789 (1 << IEEE80211_RADIOTAP_CHANNEL) |
790 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
791 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
792 (1 << IEEE80211_RADIOTAP_ANTENNA)),
793 &iwl4965_rt->rt_hdr.it_present);
794
795 /* Zero the flags, we'll add to them as we go */
796 iwl4965_rt->rt_flags = 0;
797
798 put_unaligned(cpu_to_le64(tsf), &iwl4965_rt->rt_tsf);
799
800 iwl4965_rt->rt_dbmsignal = signal;
801 iwl4965_rt->rt_dbmnoise = noise;
802
803 /* Convert the channel frequency and set the flags */
804 put_unaligned(cpu_to_le16(stats->freq), &iwl4965_rt->rt_channelMHz);
805 if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK))
806 put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
807 IEEE80211_CHAN_5GHZ),
808 &iwl4965_rt->rt_chbitmask);
809 else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK)
810 put_unaligned(cpu_to_le16(IEEE80211_CHAN_CCK |
811 IEEE80211_CHAN_2GHZ),
812 &iwl4965_rt->rt_chbitmask);
813 else /* 802.11g */
814 put_unaligned(cpu_to_le16(IEEE80211_CHAN_OFDM |
815 IEEE80211_CHAN_2GHZ),
816 &iwl4965_rt->rt_chbitmask);
817
818 if (rate == -1)
819 iwl4965_rt->rt_rate = 0;
820 else
821 iwl4965_rt->rt_rate = iwl_rates[rate].ieee;
822
823 /*
824 * "antenna number"
825 *
826 * It seems that the antenna field in the phy flags value
827 * is actually a bitfield. This is undefined by radiotap,
828 * it wants an actual antenna number but I always get "7"
829 * for most legacy frames I receive indicating that the
830 * same frame was received on all three RX chains.
831 *
832 * I think this field should be removed in favour of a
833 * new 802.11n radiotap field "RX chains" that is defined
834 * as a bitmask.
835 */
836 antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK;
837 iwl4965_rt->rt_antenna = le16_to_cpu(antenna) >> 4;
838
839 /* set the preamble flag if appropriate */
840 if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
841 iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
842
843 stats->flag |= RX_FLAG_RADIOTAP;
844}
845
846static void iwl_update_rx_stats(struct iwl_priv *priv, u16 fc, u16 len)
847{
848 /* 0 - mgmt, 1 - cnt, 2 - data */
849 int idx = (fc & IEEE80211_FCTL_FTYPE) >> 2;
850 priv->rx_stats[idx].cnt++;
851 priv->rx_stats[idx].bytes += len;
852}
853
854/*
855 * returns non-zero if packet should be dropped
856 */
857static int iwl_set_decrypted_flag(struct iwl_priv *priv,
858 struct ieee80211_hdr *hdr,
859 u32 decrypt_res,
860 struct ieee80211_rx_status *stats)
861{
862 u16 fc = le16_to_cpu(hdr->frame_control);
863
864 if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
865 return 0;
866
867 if (!(fc & IEEE80211_FCTL_PROTECTED))
868 return 0;
869
870 IWL_DEBUG_RX("decrypt_res:0x%x\n", decrypt_res);
871 switch (decrypt_res & RX_RES_STATUS_SEC_TYPE_MSK) {
872 case RX_RES_STATUS_SEC_TYPE_TKIP:
873 /* The uCode has got a bad phase 1 Key, pushes the packet.
874 * Decryption will be done in SW. */
875 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
876 RX_RES_STATUS_BAD_KEY_TTAK)
877 break;
878
879 case RX_RES_STATUS_SEC_TYPE_WEP:
880 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
881 RX_RES_STATUS_BAD_ICV_MIC) {
882 /* bad ICV, the packet is destroyed since the
883 * decryption is inplace, drop it */
884 IWL_DEBUG_RX("Packet destroyed\n");
885 return -1;
886 }
887 case RX_RES_STATUS_SEC_TYPE_CCMP:
888 if ((decrypt_res & RX_RES_STATUS_DECRYPT_TYPE_MSK) ==
889 RX_RES_STATUS_DECRYPT_OK) {
890 IWL_DEBUG_RX("hw decrypt successfully!!!\n");
891 stats->flag |= RX_FLAG_DECRYPTED;
892 }
893 break;
894
895 default:
896 break;
897 }
898 return 0;
899}
900
901static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
902{
903 u32 decrypt_out = 0;
904
905 if ((decrypt_in & RX_RES_STATUS_STATION_FOUND) ==
906 RX_RES_STATUS_STATION_FOUND)
907 decrypt_out |= (RX_RES_STATUS_STATION_FOUND |
908 RX_RES_STATUS_NO_STATION_INFO_MISMATCH);
909
910 decrypt_out |= (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK);
911
912 /* packet was not encrypted */
913 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
914 RX_RES_STATUS_SEC_TYPE_NONE)
915 return decrypt_out;
916
917 /* packet was encrypted with unknown alg */
918 if ((decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) ==
919 RX_RES_STATUS_SEC_TYPE_ERR)
920 return decrypt_out;
921
922 /* decryption was not done in HW */
923 if ((decrypt_in & RX_MPDU_RES_STATUS_DEC_DONE_MSK) !=
924 RX_MPDU_RES_STATUS_DEC_DONE_MSK)
925 return decrypt_out;
926
927 switch (decrypt_in & RX_RES_STATUS_SEC_TYPE_MSK) {
928
929 case RX_RES_STATUS_SEC_TYPE_CCMP:
930 /* alg is CCM: check MIC only */
931 if (!(decrypt_in & RX_MPDU_RES_STATUS_MIC_OK))
932 /* Bad MIC */
933 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
934 else
935 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
936
937 break;
938
939 case RX_RES_STATUS_SEC_TYPE_TKIP:
940 if (!(decrypt_in & RX_MPDU_RES_STATUS_TTAK_OK)) {
941 /* Bad TTAK */
942 decrypt_out |= RX_RES_STATUS_BAD_KEY_TTAK;
943 break;
944 }
945 /* fall through if TTAK OK */
946 default:
947 if (!(decrypt_in & RX_MPDU_RES_STATUS_ICV_OK))
948 decrypt_out |= RX_RES_STATUS_BAD_ICV_MIC;
949 else
950 decrypt_out |= RX_RES_STATUS_DECRYPT_OK;
951 break;
952 };
953
954 IWL_DEBUG_RX("decrypt_in:0x%x decrypt_out = 0x%x\n",
955 decrypt_in, decrypt_out);
956
957 return decrypt_out;
958}
959
960static void iwl_handle_data_packet(struct iwl_priv *priv, int is_data,
961 int include_phy,
962 struct iwl_rx_mem_buffer *rxb,
963 struct ieee80211_rx_status *stats)
964{
965 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
966 struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
967 (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
968 struct ieee80211_hdr *hdr;
969 u16 len;
970 __le32 *rx_end;
971 unsigned int skblen;
972 u32 ampdu_status;
973 u32 ampdu_status_legacy;
974
975 if (!include_phy && priv->last_phy_res[0])
976 rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
977
978 if (!rx_start) {
979 IWL_ERROR("MPDU frame without a PHY data\n");
980 return;
981 }
982 if (include_phy) {
983 hdr = (struct ieee80211_hdr *)((u8 *) &rx_start[1] +
984 rx_start->cfg_phy_cnt);
985
986 len = le16_to_cpu(rx_start->byte_count);
987
988 rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] +
989 sizeof(struct iwl4965_rx_phy_res) +
990 rx_start->cfg_phy_cnt + len);
991
992 } else {
993 struct iwl4965_rx_mpdu_res_start *amsdu =
994 (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
995
996 hdr = (struct ieee80211_hdr *)(pkt->u.raw +
997 sizeof(struct iwl4965_rx_mpdu_res_start));
998 len = le16_to_cpu(amsdu->byte_count);
999 rx_start->byte_count = amsdu->byte_count;
1000 rx_end = (__le32 *) (((u8 *) hdr) + len);
1001 }
1002 /* In monitor mode allow 802.11 ACk frames (10 bytes) */
1003 if (len > priv->hw_params.max_pkt_size ||
1004 len < ((priv->iw_mode == IEEE80211_IF_TYPE_MNTR) ? 10 : 16)) {
1005 IWL_WARNING("byte count out of range [16,4K] : %d\n", len);
1006 return;
1007 }
1008
1009 ampdu_status = le32_to_cpu(*rx_end);
1010 skblen = ((u8 *) rx_end - (u8 *) &pkt->u.raw[0]) + sizeof(u32);
1011
1012 if (!include_phy) {
1013 /* New status scheme, need to translate */
1014 ampdu_status_legacy = ampdu_status;
1015 ampdu_status = iwl_translate_rx_status(priv, ampdu_status);
1016 }
1017
1018 /* start from MAC */
1019 skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
1020 skb_put(rxb->skb, len); /* end where data ends */
1021
1022 /* We only process data packets if the interface is open */
1023 if (unlikely(!priv->is_open)) {
1024 IWL_DEBUG_DROP_LIMIT
1025 ("Dropping packet while interface is not open.\n");
1026 return;
1027 }
1028
1029 stats->flag = 0;
1030 hdr = (struct ieee80211_hdr *)rxb->skb->data;
1031
1032 /* in case of HW accelerated crypto and bad decryption, drop */
1033 if (!priv->hw_params.sw_crypto &&
1034 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
1035 return;
1036
1037 if (priv->add_radiotap)
1038 iwl_add_radiotap(priv, rxb->skb, rx_start, stats, ampdu_status);
1039
1040 iwl_update_rx_stats(priv, le16_to_cpu(hdr->frame_control), len);
1041 ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
1042 priv->alloc_rxb_skb--;
1043 rxb->skb = NULL;
1044}
1045
1046/* Calc max signal level (dBm) among 3 possible receivers */
1047static int iwl_calc_rssi(struct iwl_priv *priv,
1048 struct iwl4965_rx_phy_res *rx_resp)
1049{
1050 /* data from PHY/DSP regarding signal strength, etc.,
1051 * contents are always there, not configurable by host. */
1052 struct iwl4965_rx_non_cfg_phy *ncphy =
1053 (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
1054 u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
1055 >> IWL_AGC_DB_POS;
1056
1057 u32 valid_antennae =
1058 (le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
1059 >> RX_PHY_FLAGS_ANTENNAE_OFFSET;
1060 u8 max_rssi = 0;
1061 u32 i;
1062
1063 /* Find max rssi among 3 possible receivers.
1064 * These values are measured by the digital signal processor (DSP).
1065 * They should stay fairly constant even as the signal strength varies,
1066 * if the radio's automatic gain control (AGC) is working right.
1067 * AGC value (see below) will provide the "interesting" info. */
1068 for (i = 0; i < 3; i++)
1069 if (valid_antennae & (1 << i))
1070 max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
1071
1072 IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
1073 ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
1074 max_rssi, agc);
1075
1076 /* dBm = max_rssi dB - agc dB - constant.
1077 * Higher AGC (higher radio gain) means lower signal. */
1078 return max_rssi - agc - IWL_RSSI_OFFSET;
1079}
1080
1081static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1082{
1083 unsigned long flags;
1084
1085 spin_lock_irqsave(&priv->sta_lock, flags);
1086 priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK;
1087 priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
1088 priv->stations[sta_id].sta.sta.modify_mask = 0;
1089 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1090 spin_unlock_irqrestore(&priv->sta_lock, flags);
1091
1092 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1093}
1094
1095static void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
1096{
1097 /* FIXME: need locking over ps_status ??? */
1098 u8 sta_id = iwl_find_station(priv, addr);
1099
1100 if (sta_id != IWL_INVALID_STATION) {
1101 u8 sta_awake = priv->stations[sta_id].
1102 ps_status == STA_PS_STATUS_WAKE;
1103
1104 if (sta_awake && ps_bit)
1105 priv->stations[sta_id].ps_status = STA_PS_STATUS_SLEEP;
1106 else if (!sta_awake && !ps_bit) {
1107 iwl_sta_modify_ps_wake(priv, sta_id);
1108 priv->stations[sta_id].ps_status = STA_PS_STATUS_WAKE;
1109 }
1110 }
1111}
1112
1113#define IWL_PACKET_RETRY_TIME HZ
1114
1115static int iwl_is_duplicate_packet(struct iwl_priv *priv,
1116 struct ieee80211_hdr *header)
1117{
1118 u16 sc = le16_to_cpu(header->seq_ctrl);
1119 u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
1120 u16 frag = sc & IEEE80211_SCTL_FRAG;
1121 u16 *last_seq, *last_frag;
1122 unsigned long *last_time;
1123
1124 switch (priv->iw_mode) {
1125 case IEEE80211_IF_TYPE_IBSS:{
1126 struct list_head *p;
1127 struct iwl4965_ibss_seq *entry = NULL;
1128 u8 *mac = header->addr2;
1129 int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
1130
1131 __list_for_each(p, &priv->ibss_mac_hash[index]) {
1132 entry = list_entry(p, struct iwl4965_ibss_seq, list);
1133 if (!compare_ether_addr(entry->mac, mac))
1134 break;
1135 }
1136 if (p == &priv->ibss_mac_hash[index]) {
1137 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
1138 if (!entry) {
1139 IWL_ERROR("Cannot malloc new mac entry\n");
1140 return 0;
1141 }
1142 memcpy(entry->mac, mac, ETH_ALEN);
1143 entry->seq_num = seq;
1144 entry->frag_num = frag;
1145 entry->packet_time = jiffies;
1146 list_add(&entry->list, &priv->ibss_mac_hash[index]);
1147 return 0;
1148 }
1149 last_seq = &entry->seq_num;
1150 last_frag = &entry->frag_num;
1151 last_time = &entry->packet_time;
1152 break;
1153 }
1154 case IEEE80211_IF_TYPE_STA:
1155 last_seq = &priv->last_seq_num;
1156 last_frag = &priv->last_frag_num;
1157 last_time = &priv->last_packet_time;
1158 break;
1159 default:
1160 return 0;
1161 }
1162 if ((*last_seq == seq) &&
1163 time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
1164 if (*last_frag == frag)
1165 goto drop;
1166 if (*last_frag + 1 != frag)
1167 /* out-of-order fragment */
1168 goto drop;
1169 } else
1170 *last_seq = seq;
1171
1172 *last_frag = frag;
1173 *last_time = jiffies;
1174 return 0;
1175
1176 drop:
1177 return 1;
1178}
1179
1180static int iwl_is_network_packet(struct iwl_priv *priv,
1181 struct ieee80211_hdr *header)
1182{
1183 /* Filter incoming packets to determine if they are targeted toward
1184 * this network, discarding packets coming from ourselves */
1185 switch (priv->iw_mode) {
1186 case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
1187 /* packets from our adapter are dropped (echo) */
1188 if (!compare_ether_addr(header->addr2, priv->mac_addr))
1189 return 0;
1190 /* {broad,multi}cast packets to our IBSS go through */
1191 if (is_multicast_ether_addr(header->addr1))
1192 return !compare_ether_addr(header->addr3, priv->bssid);
1193 /* packets to our adapter go through */
1194 return !compare_ether_addr(header->addr1, priv->mac_addr);
1195 case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
1196 /* packets from our adapter are dropped (echo) */
1197 if (!compare_ether_addr(header->addr3, priv->mac_addr))
1198 return 0;
1199 /* {broad,multi}cast packets to our BSS go through */
1200 if (is_multicast_ether_addr(header->addr1))
1201 return !compare_ether_addr(header->addr2, priv->bssid);
1202 /* packets to our adapter go through */
1203 return !compare_ether_addr(header->addr1, priv->mac_addr);
1204 default:
1205 break;
1206 }
1207
1208 return 1;
1209}
1210
1211/* Called for REPLY_RX (legacy ABG frames), or
1212 * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
1213void iwl_rx_reply_rx(struct iwl_priv *priv,
1214 struct iwl_rx_mem_buffer *rxb)
1215{
1216 struct ieee80211_hdr *header;
1217 struct ieee80211_rx_status rx_status;
1218 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1219 /* Use phy data (Rx signal strength, etc.) contained within
1220 * this rx packet for legacy frames,
1221 * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
1222 int include_phy = (pkt->hdr.cmd == REPLY_RX);
1223 struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
1224 (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
1225 (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
1226 __le32 *rx_end;
1227 unsigned int len = 0;
1228 u16 fc;
1229 u8 network_packet;
1230
1231 rx_status.mactime = le64_to_cpu(rx_start->timestamp);
1232 rx_status.freq =
1233 ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel));
1234 rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
1235 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
1236 rx_status.rate_idx =
1237 iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags));
1238 if (rx_status.band == IEEE80211_BAND_5GHZ)
1239 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
1240
1241 rx_status.antenna = 0;
1242 rx_status.flag = 0;
1243
1244 if ((unlikely(rx_start->cfg_phy_cnt > 20))) {
1245 IWL_DEBUG_DROP("dsp size out of range [0,20]: %d/n",
1246 rx_start->cfg_phy_cnt);
1247 return;
1248 }
1249
1250 if (!include_phy) {
1251 if (priv->last_phy_res[0])
1252 rx_start = (struct iwl4965_rx_phy_res *)
1253 &priv->last_phy_res[1];
1254 else
1255 rx_start = NULL;
1256 }
1257
1258 if (!rx_start) {
1259 IWL_ERROR("MPDU frame without a PHY data\n");
1260 return;
1261 }
1262
1263 if (include_phy) {
1264 header = (struct ieee80211_hdr *)((u8 *) &rx_start[1]
1265 + rx_start->cfg_phy_cnt);
1266
1267 len = le16_to_cpu(rx_start->byte_count);
1268 rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
1269 sizeof(struct iwl4965_rx_phy_res) + len);
1270 } else {
1271 struct iwl4965_rx_mpdu_res_start *amsdu =
1272 (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1273
1274 header = (void *)(pkt->u.raw +
1275 sizeof(struct iwl4965_rx_mpdu_res_start));
1276 len = le16_to_cpu(amsdu->byte_count);
1277 rx_end = (__le32 *) (pkt->u.raw +
1278 sizeof(struct iwl4965_rx_mpdu_res_start) + len);
1279 }
1280
1281 if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
1282 !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1283 IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n",
1284 le32_to_cpu(*rx_end));
1285 return;
1286 }
1287
1288 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
1289
1290 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1291 rx_status.signal = iwl_calc_rssi(priv, rx_start);
1292
1293 /* Meaningful noise values are available only from beacon statistics,
1294 * which are gathered only when associated, and indicate noise
1295 * only for the associated network channel ...
1296 * Ignore these noise values while scanning (other channels) */
1297 if (iwl_is_associated(priv) &&
1298 !test_bit(STATUS_SCANNING, &priv->status)) {
1299 rx_status.noise = priv->last_rx_noise;
1300 rx_status.qual = iwl_calc_sig_qual(rx_status.signal,
1301 rx_status.noise);
1302 } else {
1303 rx_status.noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1304 rx_status.qual = iwl_calc_sig_qual(rx_status.signal, 0);
1305 }
1306
1307 /* Reset beacon noise level if not associated. */
1308 if (!iwl_is_associated(priv))
1309 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1310
1311 /* Set "1" to report good data frames in groups of 100 */
1312 /* FIXME: need to optimze the call: */
1313 iwl_dbg_report_frame(priv, pkt, header, 1);
1314
1315 IWL_DEBUG_STATS_LIMIT("Rssi %d, noise %d, qual %d, TSF %llu\n",
1316 rx_status.signal, rx_status.noise, rx_status.signal,
1317 (unsigned long long)rx_status.mactime);
1318
1319
1320 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
1321 iwl_handle_data_packet(priv, 1, include_phy,
1322 rxb, &rx_status);
1323 return;
1324 }
1325
1326 network_packet = iwl_is_network_packet(priv, header);
1327 if (network_packet) {
1328 priv->last_rx_rssi = rx_status.signal;
1329 priv->last_beacon_time = priv->ucode_beacon_time;
1330 priv->last_tsf = le64_to_cpu(rx_start->timestamp);
1331 }
1332
1333 fc = le16_to_cpu(header->frame_control);
1334 switch (fc & IEEE80211_FCTL_FTYPE) {
1335 case IEEE80211_FTYPE_MGMT:
1336 if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
1337 iwl_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
1338 header->addr2);
1339 iwl_handle_data_packet(priv, 0, include_phy, rxb, &rx_status);
1340 break;
1341
1342 case IEEE80211_FTYPE_CTL:
1343 switch (fc & IEEE80211_FCTL_STYPE) {
1344 case IEEE80211_STYPE_BACK_REQ:
1345 IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n");
1346 iwl_handle_data_packet(priv, 0, include_phy,
1347 rxb, &rx_status);
1348 break;
1349 default:
1350 break;
1351 }
1352 break;
1353
1354 case IEEE80211_FTYPE_DATA: {
1355 DECLARE_MAC_BUF(mac1);
1356 DECLARE_MAC_BUF(mac2);
1357 DECLARE_MAC_BUF(mac3);
1358
1359 if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
1360 iwl_update_ps_mode(priv, fc & IEEE80211_FCTL_PM,
1361 header->addr2);
1362
1363 if (unlikely(!network_packet))
1364 IWL_DEBUG_DROP("Dropping (non network): "
1365 "%s, %s, %s\n",
1366 print_mac(mac1, header->addr1),
1367 print_mac(mac2, header->addr2),
1368 print_mac(mac3, header->addr3));
1369 else if (unlikely(iwl_is_duplicate_packet(priv, header)))
1370 IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n",
1371 print_mac(mac1, header->addr1),
1372 print_mac(mac2, header->addr2),
1373 print_mac(mac3, header->addr3));
1374 else
1375 iwl_handle_data_packet(priv, 1, include_phy, rxb,
1376 &rx_status);
1377 break;
1378 }
1379 default:
1380 break;
1381
1382 }
1383}
1384EXPORT_SYMBOL(iwl_rx_reply_rx);
1385
1386/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1387 * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1388void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
1389 struct iwl_rx_mem_buffer *rxb)
1390{
1391 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1392 priv->last_phy_res[0] = 1;
1393 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
1394 sizeof(struct iwl4965_rx_phy_res));
1395}
1396EXPORT_SYMBOL(iwl_rx_reply_rx_phy);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index a607b39223e..499705ff888 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -613,36 +613,6 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force)
613 } 613 }
614} 614}
615 615
616int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
617{
618 /* Filter incoming packets to determine if they are targeted toward
619 * this network, discarding packets coming from ourselves */
620 switch (priv->iw_mode) {
621 case IEEE80211_IF_TYPE_IBSS: /* Header: Dest. | Source | BSSID */
622 /* packets from our adapter are dropped (echo) */
623 if (!compare_ether_addr(header->addr2, priv->mac_addr))
624 return 0;
625 /* {broad,multi}cast packets to our IBSS go through */
626 if (is_multicast_ether_addr(header->addr1))
627 return !compare_ether_addr(header->addr3, priv->bssid);
628 /* packets to our adapter go through */
629 return !compare_ether_addr(header->addr1, priv->mac_addr);
630 case IEEE80211_IF_TYPE_STA: /* Header: Dest. | AP{BSSID} | Source */
631 /* packets from our adapter are dropped (echo) */
632 if (!compare_ether_addr(header->addr3, priv->mac_addr))
633 return 0;
634 /* {broad,multi}cast packets to our BSS go through */
635 if (is_multicast_ether_addr(header->addr1))
636 return !compare_ether_addr(header->addr2, priv->bssid);
637 /* packets to our adapter go through */
638 return !compare_ether_addr(header->addr1, priv->mac_addr);
639 default:
640 break;
641 }
642
643 return 1;
644}
645
646static void iwl4965_sequence_reset(struct iwl_priv *priv) 616static void iwl4965_sequence_reset(struct iwl_priv *priv)
647{ 617{
648 /* Reset ieee stats */ 618 /* Reset ieee stats */
@@ -906,72 +876,6 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
906 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 876 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
907} 877}
908 878
909#define IWL_PACKET_RETRY_TIME HZ
910
911int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header)
912{
913 u16 sc = le16_to_cpu(header->seq_ctrl);
914 u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4;
915 u16 frag = sc & IEEE80211_SCTL_FRAG;
916 u16 *last_seq, *last_frag;
917 unsigned long *last_time;
918
919 switch (priv->iw_mode) {
920 case IEEE80211_IF_TYPE_IBSS:{
921 struct list_head *p;
922 struct iwl4965_ibss_seq *entry = NULL;
923 u8 *mac = header->addr2;
924 int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1);
925
926 __list_for_each(p, &priv->ibss_mac_hash[index]) {
927 entry = list_entry(p, struct iwl4965_ibss_seq, list);
928 if (!compare_ether_addr(entry->mac, mac))
929 break;
930 }
931 if (p == &priv->ibss_mac_hash[index]) {
932 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
933 if (!entry) {
934 IWL_ERROR("Cannot malloc new mac entry\n");
935 return 0;
936 }
937 memcpy(entry->mac, mac, ETH_ALEN);
938 entry->seq_num = seq;
939 entry->frag_num = frag;
940 entry->packet_time = jiffies;
941 list_add(&entry->list, &priv->ibss_mac_hash[index]);
942 return 0;
943 }
944 last_seq = &entry->seq_num;
945 last_frag = &entry->frag_num;
946 last_time = &entry->packet_time;
947 break;
948 }
949 case IEEE80211_IF_TYPE_STA:
950 last_seq = &priv->last_seq_num;
951 last_frag = &priv->last_frag_num;
952 last_time = &priv->last_packet_time;
953 break;
954 default:
955 return 0;
956 }
957 if ((*last_seq == seq) &&
958 time_after(*last_time + IWL_PACKET_RETRY_TIME, jiffies)) {
959 if (*last_frag == frag)
960 goto drop;
961 if (*last_frag + 1 != frag)
962 /* out-of-order fragment */
963 goto drop;
964 } else
965 *last_seq = seq;
966
967 *last_frag = frag;
968 *last_time = jiffies;
969 return 0;
970
971 drop:
972 return 1;
973}
974
975#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT 879#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
976 880
977#include "iwl-spectrum.h" 881#include "iwl-spectrum.h"
@@ -1350,17 +1254,6 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
1350 wake_up_interruptible(&priv->wait_command_queue); 1254 wake_up_interruptible(&priv->wait_command_queue);
1351} 1255}
1352 1256
1353/* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
1354 * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
1355static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv,
1356 struct iwl_rx_mem_buffer *rxb)
1357{
1358 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
1359 priv->last_phy_res[0] = 1;
1360 memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
1361 sizeof(struct iwl4965_rx_phy_res));
1362}
1363
1364/** 1257/**
1365 * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks 1258 * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
1366 * 1259 *
@@ -1398,8 +1291,8 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv)
1398 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = 1291 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
1399 iwl_rx_missed_beacon_notif; 1292 iwl_rx_missed_beacon_notif;
1400 /* Rx handlers */ 1293 /* Rx handlers */
1401 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl4965_rx_reply_rx_phy; 1294 priv->rx_handlers[REPLY_RX_PHY_CMD] = iwl_rx_reply_rx_phy;
1402 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl4965_rx_reply_rx; 1295 priv->rx_handlers[REPLY_RX_MPDU_CMD] = iwl_rx_reply_rx;
1403 /* Set up hardware specific Rx handlers */ 1296 /* Set up hardware specific Rx handlers */
1404 priv->cfg->ops->lib->rx_handler_setup(priv); 1297 priv->cfg->ops->lib->rx_handler_setup(priv);
1405} 1298}
@@ -1530,47 +1423,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
1530 iwl_rx_queue_restock(priv); 1423 iwl_rx_queue_restock(priv);
1531} 1424}
1532 1425
1533#define PERFECT_RSSI (-20) /* dBm */
1534#define WORST_RSSI (-95) /* dBm */
1535#define RSSI_RANGE (PERFECT_RSSI - WORST_RSSI)
1536
1537/* Calculate an indication of rx signal quality (a percentage, not dBm!).
1538 * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info
1539 * about formulas used below. */
1540int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm)
1541{
1542 int sig_qual;
1543 int degradation = PERFECT_RSSI - rssi_dbm;
1544
1545 /* If we get a noise measurement, use signal-to-noise ratio (SNR)
1546 * as indicator; formula is (signal dbm - noise dbm).
1547 * SNR at or above 40 is a great signal (100%).
1548 * Below that, scale to fit SNR of 0 - 40 dB within 0 - 100% indicator.
1549 * Weakest usable signal is usually 10 - 15 dB SNR. */
1550 if (noise_dbm) {
1551 if (rssi_dbm - noise_dbm >= 40)
1552 return 100;
1553 else if (rssi_dbm < noise_dbm)
1554 return 0;
1555 sig_qual = ((rssi_dbm - noise_dbm) * 5) / 2;
1556
1557 /* Else use just the signal level.
1558 * This formula is a least squares fit of data points collected and
1559 * compared with a reference system that had a percentage (%) display
1560 * for signal quality. */
1561 } else
1562 sig_qual = (100 * (RSSI_RANGE * RSSI_RANGE) - degradation *
1563 (15 * RSSI_RANGE + 62 * degradation)) /
1564 (RSSI_RANGE * RSSI_RANGE);
1565
1566 if (sig_qual > 100)
1567 sig_qual = 100;
1568 else if (sig_qual < 1)
1569 sig_qual = 0;
1570
1571 return sig_qual;
1572}
1573
1574#ifdef CONFIG_IWLWIFI_DEBUG 1426#ifdef CONFIG_IWLWIFI_DEBUG
1575static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv) 1427static void iwl4965_print_rx_config_cmd(struct iwl_priv *priv)
1576{ 1428{