aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-03-01 18:52:00 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 17:09:46 -0500
commit17744ff6ae7eafe33dac9772f2ef9ab5fb738db8 (patch)
treefff5b091d2d6ed8682893f66072c698aa7308218 /drivers/net/wireless/iwlwifi/iwl-3945.c
parent8211ef78d9023a8772e5acf6b7934598156b2fc8 (diff)
iwlwifi: Fix 52 rate report in rx status
This patch fixes reporting rate in RX packets in 52 band. The rate was updated from CCK rate index instead of OFDM rate 6M Most of the patch is collateral clean up Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c231
1 files changed, 196 insertions, 35 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 82d282730b75..63e832cdba75 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -183,6 +183,16 @@ void iwl3945_disable_events(struct iwl3945_priv *priv)
183 183
184} 184}
185 185
186static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
187{
188 int idx;
189
190 for (idx = 0; idx < IWL_RATE_COUNT; idx++)
191 if (iwl3945_rates[idx].plcp == plcp)
192 return idx;
193 return -1;
194}
195
186/** 196/**
187 * iwl3945_get_antenna_flags - Get antenna flags for RXON command 197 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
188 * @priv: eeprom and antenna fields are used to determine antenna flags 198 * @priv: eeprom and antenna fields are used to determine antenna flags
@@ -238,6 +248,156 @@ void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_b
238 priv->last_statistics_time = jiffies; 248 priv->last_statistics_time = jiffies;
239} 249}
240 250
251/******************************************************************************
252 *
253 * Misc. internal state and helper functions
254 *
255 ******************************************************************************/
256#ifdef CONFIG_IWL3945_DEBUG
257
258/**
259 * iwl3945_report_frame - dump frame to syslog during debug sessions
260 *
261 * You may hack this function to show different aspects of received frames,
262 * including selective frame dumps.
263 * group100 parameter selects whether to show 1 out of 100 good frames.
264 */
265static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
266 struct iwl3945_rx_packet *pkt,
267 struct ieee80211_hdr *header, int group100)
268{
269 u32 to_us;
270 u32 print_summary = 0;
271 u32 print_dump = 0; /* set to 1 to dump all frames' contents */
272 u32 hundred = 0;
273 u32 dataframe = 0;
274 u16 fc;
275 u16 seq_ctl;
276 u16 channel;
277 u16 phy_flags;
278 u16 length;
279 u16 status;
280 u16 bcn_tmr;
281 u32 tsf_low;
282 u64 tsf;
283 u8 rssi;
284 u8 agc;
285 u16 sig_avg;
286 u16 noise_diff;
287 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
288 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
289 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
290 u8 *data = IWL_RX_DATA(pkt);
291
292 /* MAC header */
293 fc = le16_to_cpu(header->frame_control);
294 seq_ctl = le16_to_cpu(header->seq_ctrl);
295
296 /* metadata */
297 channel = le16_to_cpu(rx_hdr->channel);
298 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
299 length = le16_to_cpu(rx_hdr->len);
300
301 /* end-of-frame status and timestamp */
302 status = le32_to_cpu(rx_end->status);
303 bcn_tmr = le32_to_cpu(rx_end->beacon_timestamp);
304 tsf_low = le64_to_cpu(rx_end->timestamp) & 0x0ffffffff;
305 tsf = le64_to_cpu(rx_end->timestamp);
306
307 /* signal statistics */
308 rssi = rx_stats->rssi;
309 agc = rx_stats->agc;
310 sig_avg = le16_to_cpu(rx_stats->sig_avg);
311 noise_diff = le16_to_cpu(rx_stats->noise_diff);
312
313 to_us = !compare_ether_addr(header->addr1, priv->mac_addr);
314
315 /* if data frame is to us and all is good,
316 * (optionally) print summary for only 1 out of every 100 */
317 if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) ==
318 (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) {
319 dataframe = 1;
320 if (!group100)
321 print_summary = 1; /* print each frame */
322 else if (priv->framecnt_to_us < 100) {
323 priv->framecnt_to_us++;
324 print_summary = 0;
325 } else {
326 priv->framecnt_to_us = 0;
327 print_summary = 1;
328 hundred = 1;
329 }
330 } else {
331 /* print summary for all other frames */
332 print_summary = 1;
333 }
334
335 if (print_summary) {
336 char *title;
337 u32 rate;
338
339 if (hundred)
340 title = "100Frames";
341 else if (fc & IEEE80211_FCTL_RETRY)
342 title = "Retry";
343 else if (ieee80211_is_assoc_response(fc))
344 title = "AscRsp";
345 else if (ieee80211_is_reassoc_response(fc))
346 title = "RasRsp";
347 else if (ieee80211_is_probe_response(fc)) {
348 title = "PrbRsp";
349 print_dump = 1; /* dump frame contents */
350 } else if (ieee80211_is_beacon(fc)) {
351 title = "Beacon";
352 print_dump = 1; /* dump frame contents */
353 } else if (ieee80211_is_atim(fc))
354 title = "ATIM";
355 else if (ieee80211_is_auth(fc))
356 title = "Auth";
357 else if (ieee80211_is_deauth(fc))
358 title = "DeAuth";
359 else if (ieee80211_is_disassoc(fc))
360 title = "DisAssoc";
361 else
362 title = "Frame";
363
364 rate = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
365 if (rate == -1)
366 rate = 0;
367 else
368 rate = iwl3945_rates[rate].ieee / 2;
369
370 /* print frame summary.
371 * MAC addresses show just the last byte (for brevity),
372 * but you can hack it to show more, if you'd like to. */
373 if (dataframe)
374 IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, "
375 "len=%u, rssi=%d, chnl=%d, rate=%u, \n",
376 title, fc, header->addr1[5],
377 length, rssi, channel, rate);
378 else {
379 /* src/dst addresses assume managed mode */
380 IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, "
381 "src=0x%02x, rssi=%u, tim=%lu usec, "
382 "phy=0x%02x, chnl=%d\n",
383 title, fc, header->addr1[5],
384 header->addr3[5], rssi,
385 tsf_low - priv->scan_start_tsf,
386 phy_flags, channel);
387 }
388 }
389 if (print_dump)
390 iwl3945_print_hex_dump(IWL_DL_RX, data, length);
391}
392#else
393static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv,
394 struct iwl3945_rx_packet *pkt,
395 struct ieee80211_hdr *header, int group100)
396{
397}
398#endif
399
400
241static void iwl3945_add_radiotap(struct iwl3945_priv *priv, 401static void iwl3945_add_radiotap(struct iwl3945_priv *priv,
242 struct sk_buff *skb, 402 struct sk_buff *skb,
243 struct iwl3945_rx_frame_hdr *rx_hdr, 403 struct iwl3945_rx_frame_hdr *rx_hdr,
@@ -376,24 +536,28 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
376static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, 536static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
377 struct iwl3945_rx_mem_buffer *rxb) 537 struct iwl3945_rx_mem_buffer *rxb)
378{ 538{
539 struct ieee80211_hdr *header;
540 struct ieee80211_rx_status rx_status;
379 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; 541 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
380 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); 542 struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
381 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); 543 struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
382 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); 544 struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
383 struct ieee80211_hdr *header; 545 int snr;
384 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); 546 u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
385 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); 547 u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
386 struct ieee80211_rx_status stats = {
387 .mactime = le64_to_cpu(rx_end->timestamp),
388 .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)),
389 .band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
390 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ,
391 .antenna = 0,
392 .rate_idx = iwl3945_rate_index_from_plcp(rx_hdr->rate),
393 .flag = 0,
394 };
395 u8 network_packet; 548 u8 network_packet;
396 int snr; 549
550 rx_status.antenna = 0;
551 rx_status.flag = 0;
552 rx_status.mactime = le64_to_cpu(rx_end->timestamp);
553 rx_status.freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel));
554 rx_status.band = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
555 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
556
557 rx_status.rate_idx = iwl3945_hwrate_to_plcp_idx(rx_hdr->rate);
558
559 if (rx_status.band == IEEE80211_BAND_5GHZ)
560 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
397 561
398 if ((unlikely(rx_stats->phy_count > 20))) { 562 if ((unlikely(rx_stats->phy_count > 20))) {
399 IWL_DEBUG_DROP 563 IWL_DEBUG_DROP
@@ -409,12 +573,12 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
409 } 573 }
410 574
411 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { 575 if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
412 iwl3945_handle_data_packet(priv, 1, rxb, &stats); 576 iwl3945_handle_data_packet(priv, 1, rxb, &rx_status);
413 return; 577 return;
414 } 578 }
415 579
416 /* Convert 3945's rssi indicator to dBm */ 580 /* Convert 3945's rssi indicator to dBm */
417 stats.ssi = rx_stats->rssi - IWL_RSSI_OFFSET; 581 rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET;
418 582
419 /* Set default noise value to -127 */ 583 /* Set default noise value to -127 */
420 if (priv->last_rx_noise == 0) 584 if (priv->last_rx_noise == 0)
@@ -430,50 +594,47 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
430 * signal-to-noise ratio (SNR) is (sig_avg / noise_diff). 594 * signal-to-noise ratio (SNR) is (sig_avg / noise_diff).
431 * Convert linear SNR to dB SNR, then subtract that from rssi dBm 595 * Convert linear SNR to dB SNR, then subtract that from rssi dBm
432 * to obtain noise level in dBm. 596 * to obtain noise level in dBm.
433 * Calculate stats.signal (quality indicator in %) based on SNR. */ 597 * Calculate rx_status.signal (quality indicator in %) based on SNR. */
434 if (rx_stats_noise_diff) { 598 if (rx_stats_noise_diff) {
435 snr = rx_stats_sig_avg / rx_stats_noise_diff; 599 snr = rx_stats_sig_avg / rx_stats_noise_diff;
436 stats.noise = stats.ssi - iwl3945_calc_db_from_ratio(snr); 600 rx_status.noise = rx_status.ssi -
437 stats.signal = iwl3945_calc_sig_qual(stats.ssi, stats.noise); 601 iwl3945_calc_db_from_ratio(snr);
602 rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi,
603 rx_status.noise);
438 604
439 /* If noise info not available, calculate signal quality indicator (%) 605 /* If noise info not available, calculate signal quality indicator (%)
440 * using just the dBm signal level. */ 606 * using just the dBm signal level. */
441 } else { 607 } else {
442 stats.noise = priv->last_rx_noise; 608 rx_status.noise = priv->last_rx_noise;
443 stats.signal = iwl3945_calc_sig_qual(stats.ssi, 0); 609 rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0);
444 } 610 }
445 611
446 612
447 IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", 613 IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
448 stats.ssi, stats.noise, stats.signal, 614 rx_status.ssi, rx_status.noise, rx_status.signal,
449 rx_stats_sig_avg, rx_stats_noise_diff); 615 rx_stats_sig_avg, rx_stats_noise_diff);
450 616
451 /* can be covered by iwl3945_report_frame() in most cases */
452/* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */
453
454 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); 617 header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
455 618
456 network_packet = iwl3945_is_network_packet(priv, header); 619 network_packet = iwl3945_is_network_packet(priv, header);
457 620
458#ifdef CONFIG_IWL3945_DEBUG 621 IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n",
459 if (iwl3945_debug_level & IWL_DL_STATS && net_ratelimit()) 622 network_packet ? '*' : ' ',
460 IWL_DEBUG_STATS 623 le16_to_cpu(rx_hdr->channel),
461 ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", 624 rx_status.ssi, rx_status.ssi,
462 network_packet ? '*' : ' ', 625 rx_status.ssi, rx_status.rate_idx);
463 le16_to_cpu(rx_hdr->channel),
464 stats.ssi, stats.ssi,
465 stats.ssi, stats.rate_idx);
466 626
627#ifdef CONFIG_IWL3945_DEBUG
467 if (iwl3945_debug_level & (IWL_DL_RX)) 628 if (iwl3945_debug_level & (IWL_DL_RX))
468 /* Set "1" to report good data frames in groups of 100 */ 629 /* Set "1" to report good data frames in groups of 100 */
469 iwl3945_report_frame(priv, pkt, header, 1); 630 iwl3945_dbg_report_frame(priv, pkt, header, 1);
470#endif 631#endif
471 632
472 if (network_packet) { 633 if (network_packet) {
473 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); 634 priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
474 priv->last_tsf = le64_to_cpu(rx_end->timestamp); 635 priv->last_tsf = le64_to_cpu(rx_end->timestamp);
475 priv->last_rx_rssi = stats.ssi; 636 priv->last_rx_rssi = rx_status.ssi;
476 priv->last_rx_noise = stats.noise; 637 priv->last_rx_noise = rx_status.noise;
477 } 638 }
478 639
479 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) { 640 switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
@@ -560,7 +721,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
560 } 721 }
561 } 722 }
562 723
563 iwl3945_handle_data_packet(priv, 0, rxb, &stats); 724 iwl3945_handle_data_packet(priv, 0, rxb, &rx_status);
564 break; 725 break;
565 726
566 case IEEE80211_FTYPE_CTL: 727 case IEEE80211_FTYPE_CTL:
@@ -577,7 +738,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
577 print_mac(mac2, header->addr2), 738 print_mac(mac2, header->addr2),
578 print_mac(mac3, header->addr3)); 739 print_mac(mac3, header->addr3));
579 else 740 else
580 iwl3945_handle_data_packet(priv, 1, rxb, &stats); 741 iwl3945_handle_data_packet(priv, 1, rxb, &rx_status);
581 break; 742 break;
582 } 743 }
583 } 744 }