diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 322 |
1 files changed, 72 insertions, 250 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 55ac850744b3..7ca5627cc078 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -26,7 +26,6 @@ | |||
26 | 26 | ||
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/version.h> | ||
30 | #include <linux/init.h> | 29 | #include <linux/init.h> |
31 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
32 | #include <linux/dma-mapping.h> | 31 | #include <linux/dma-mapping.h> |
@@ -283,8 +282,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, | |||
283 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 282 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
284 | 283 | ||
285 | tx_info = &txq->txb[txq->q.read_ptr]; | 284 | tx_info = &txq->txb[txq->q.read_ptr]; |
286 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0], | 285 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); |
287 | &tx_info->status); | ||
288 | tx_info->skb[0] = NULL; | 286 | tx_info->skb[0] = NULL; |
289 | iwl3945_hw_txq_free_tfd(priv, txq); | 287 | iwl3945_hw_txq_free_tfd(priv, txq); |
290 | } | 288 | } |
@@ -306,7 +304,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
306 | int txq_id = SEQ_TO_QUEUE(sequence); | 304 | int txq_id = SEQ_TO_QUEUE(sequence); |
307 | int index = SEQ_TO_INDEX(sequence); | 305 | int index = SEQ_TO_INDEX(sequence); |
308 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; | 306 | struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; |
309 | struct ieee80211_tx_status *tx_status; | 307 | struct ieee80211_tx_info *info; |
310 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 308 | struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
311 | u32 status = le32_to_cpu(tx_resp->status); | 309 | u32 status = le32_to_cpu(tx_resp->status); |
312 | int rate_idx; | 310 | int rate_idx; |
@@ -319,19 +317,22 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, | |||
319 | return; | 317 | return; |
320 | } | 318 | } |
321 | 319 | ||
322 | tx_status = &(txq->txb[txq->q.read_ptr].status); | 320 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); |
321 | memset(&info->status, 0, sizeof(info->status)); | ||
323 | 322 | ||
324 | tx_status->retry_count = tx_resp->failure_frame; | 323 | info->status.retry_count = tx_resp->failure_frame; |
325 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ | 324 | /* tx_status->rts_retry_count = tx_resp->failure_rts; */ |
326 | tx_status->flags = ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? | 325 | info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? |
327 | IEEE80211_TX_STATUS_ACK : 0; | 326 | IEEE80211_TX_STAT_ACK : 0; |
328 | 327 | ||
329 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", | 328 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", |
330 | txq_id, iwl3945_get_tx_fail_reason(status), status, | 329 | txq_id, iwl3945_get_tx_fail_reason(status), status, |
331 | tx_resp->rate, tx_resp->failure_frame); | 330 | tx_resp->rate, tx_resp->failure_frame); |
332 | 331 | ||
333 | rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); | 332 | rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate); |
334 | tx_status->control.tx_rate = &priv->ieee_rates[rate_idx]; | 333 | if (info->band == IEEE80211_BAND_5GHZ) |
334 | rate_idx -= IWL_FIRST_OFDM_RATE; | ||
335 | info->tx_rate_idx = rate_idx; | ||
335 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 336 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
336 | iwl3945_tx_queue_reclaim(priv, txq_id, index); | 337 | iwl3945_tx_queue_reclaim(priv, txq_id, index); |
337 | 338 | ||
@@ -386,7 +387,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
386 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ | 387 | u32 print_dump = 0; /* set to 1 to dump all frames' contents */ |
387 | u32 hundred = 0; | 388 | u32 hundred = 0; |
388 | u32 dataframe = 0; | 389 | u32 dataframe = 0; |
389 | u16 fc; | 390 | __le16 fc; |
390 | u16 seq_ctl; | 391 | u16 seq_ctl; |
391 | u16 channel; | 392 | u16 channel; |
392 | u16 phy_flags; | 393 | u16 phy_flags; |
@@ -405,7 +406,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
405 | u8 *data = IWL_RX_DATA(pkt); | 406 | u8 *data = IWL_RX_DATA(pkt); |
406 | 407 | ||
407 | /* MAC header */ | 408 | /* MAC header */ |
408 | fc = le16_to_cpu(header->frame_control); | 409 | fc = header->frame_control; |
409 | seq_ctl = le16_to_cpu(header->seq_ctrl); | 410 | seq_ctl = le16_to_cpu(header->seq_ctrl); |
410 | 411 | ||
411 | /* metadata */ | 412 | /* metadata */ |
@@ -429,8 +430,8 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
429 | 430 | ||
430 | /* if data frame is to us and all is good, | 431 | /* if data frame is to us and all is good, |
431 | * (optionally) print summary for only 1 out of every 100 */ | 432 | * (optionally) print summary for only 1 out of every 100 */ |
432 | if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == | 433 | if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == |
433 | (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { | 434 | cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { |
434 | dataframe = 1; | 435 | dataframe = 1; |
435 | if (!group100) | 436 | if (!group100) |
436 | print_summary = 1; /* print each frame */ | 437 | print_summary = 1; /* print each frame */ |
@@ -453,13 +454,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
453 | 454 | ||
454 | if (hundred) | 455 | if (hundred) |
455 | title = "100Frames"; | 456 | title = "100Frames"; |
456 | else if (fc & IEEE80211_FCTL_RETRY) | 457 | else if (ieee80211_has_retry(fc)) |
457 | title = "Retry"; | 458 | title = "Retry"; |
458 | else if (ieee80211_is_assoc_response(fc)) | 459 | else if (ieee80211_is_assoc_resp(fc)) |
459 | title = "AscRsp"; | 460 | title = "AscRsp"; |
460 | else if (ieee80211_is_reassoc_response(fc)) | 461 | else if (ieee80211_is_reassoc_resp(fc)) |
461 | title = "RasRsp"; | 462 | title = "RasRsp"; |
462 | else if (ieee80211_is_probe_response(fc)) { | 463 | else if (ieee80211_is_probe_resp(fc)) { |
463 | title = "PrbRsp"; | 464 | title = "PrbRsp"; |
464 | print_dump = 1; /* dump frame contents */ | 465 | print_dump = 1; /* dump frame contents */ |
465 | } else if (ieee80211_is_beacon(fc)) { | 466 | } else if (ieee80211_is_beacon(fc)) { |
@@ -488,14 +489,14 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
488 | if (dataframe) | 489 | if (dataframe) |
489 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " | 490 | IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " |
490 | "len=%u, rssi=%d, chnl=%d, rate=%d, \n", | 491 | "len=%u, rssi=%d, chnl=%d, rate=%d, \n", |
491 | title, fc, header->addr1[5], | 492 | title, le16_to_cpu(fc), header->addr1[5], |
492 | length, rssi, channel, rate); | 493 | length, rssi, channel, rate); |
493 | else { | 494 | else { |
494 | /* src/dst addresses assume managed mode */ | 495 | /* src/dst addresses assume managed mode */ |
495 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " | 496 | IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " |
496 | "src=0x%02x, rssi=%u, tim=%lu usec, " | 497 | "src=0x%02x, rssi=%u, tim=%lu usec, " |
497 | "phy=0x%02x, chnl=%d\n", | 498 | "phy=0x%02x, chnl=%d\n", |
498 | title, fc, header->addr1[5], | 499 | title, le16_to_cpu(fc), header->addr1[5], |
499 | header->addr3[5], rssi, | 500 | header->addr3[5], rssi, |
500 | tsf_low - priv->scan_start_tsf, | 501 | tsf_low - priv->scan_start_tsf, |
501 | phy_flags, channel); | 502 | phy_flags, channel); |
@@ -512,106 +513,32 @@ static inline void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, | |||
512 | } | 513 | } |
513 | #endif | 514 | #endif |
514 | 515 | ||
515 | 516 | /* This is necessary only for a number of statistics, see the caller. */ | |
516 | static void iwl3945_add_radiotap(struct iwl3945_priv *priv, | 517 | static int iwl3945_is_network_packet(struct iwl3945_priv *priv, |
517 | struct sk_buff *skb, | 518 | struct ieee80211_hdr *header) |
518 | struct iwl3945_rx_frame_hdr *rx_hdr, | ||
519 | struct ieee80211_rx_status *stats) | ||
520 | { | 519 | { |
521 | /* First cache any information we need before we overwrite | 520 | /* Filter incoming packets to determine if they are targeted toward |
522 | * the information provided in the skb from the hardware */ | 521 | * this network, discarding packets coming from ourselves */ |
523 | s8 signal = stats->ssi; | 522 | switch (priv->iw_mode) { |
524 | s8 noise = 0; | 523 | case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */ |
525 | int rate = stats->rate_idx; | 524 | /* packets to our IBSS update information */ |
526 | u64 tsf = stats->mactime; | 525 | return !compare_ether_addr(header->addr3, priv->bssid); |
527 | __le16 phy_flags_hw = rx_hdr->phy_flags, antenna; | 526 | case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */ |
528 | 527 | /* packets to our IBSS update information */ | |
529 | struct iwl3945_rt_rx_hdr { | 528 | return !compare_ether_addr(header->addr2, priv->bssid); |
530 | struct ieee80211_radiotap_header rt_hdr; | 529 | default: |
531 | __le64 rt_tsf; /* TSF */ | 530 | return 1; |
532 | u8 rt_flags; /* radiotap packet flags */ | ||
533 | u8 rt_rate; /* rate in 500kb/s */ | ||
534 | __le16 rt_channelMHz; /* channel in MHz */ | ||
535 | __le16 rt_chbitmask; /* channel bitfield */ | ||
536 | s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ | ||
537 | s8 rt_dbmnoise; | ||
538 | u8 rt_antenna; /* antenna number */ | ||
539 | } __attribute__ ((packed)) *iwl3945_rt; | ||
540 | |||
541 | if (skb_headroom(skb) < sizeof(*iwl3945_rt)) { | ||
542 | if (net_ratelimit()) | ||
543 | printk(KERN_ERR "not enough headroom [%d] for " | ||
544 | "radiotap head [%zd]\n", | ||
545 | skb_headroom(skb), sizeof(*iwl3945_rt)); | ||
546 | return; | ||
547 | } | ||
548 | |||
549 | /* put radiotap header in front of 802.11 header and data */ | ||
550 | iwl3945_rt = (void *)skb_push(skb, sizeof(*iwl3945_rt)); | ||
551 | |||
552 | /* initialise radiotap header */ | ||
553 | iwl3945_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; | ||
554 | iwl3945_rt->rt_hdr.it_pad = 0; | ||
555 | |||
556 | /* total header + data */ | ||
557 | put_unaligned_le16(sizeof(*iwl3945_rt), &iwl3945_rt->rt_hdr.it_len); | ||
558 | |||
559 | /* Indicate all the fields we add to the radiotap header */ | ||
560 | put_unaligned_le32((1 << IEEE80211_RADIOTAP_TSFT) | | ||
561 | (1 << IEEE80211_RADIOTAP_FLAGS) | | ||
562 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
563 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
564 | (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | | ||
565 | (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | | ||
566 | (1 << IEEE80211_RADIOTAP_ANTENNA), | ||
567 | &iwl3945_rt->rt_hdr.it_present); | ||
568 | |||
569 | /* Zero the flags, we'll add to them as we go */ | ||
570 | iwl3945_rt->rt_flags = 0; | ||
571 | |||
572 | put_unaligned_le64(tsf, &iwl3945_rt->rt_tsf); | ||
573 | |||
574 | iwl3945_rt->rt_dbmsignal = signal; | ||
575 | iwl3945_rt->rt_dbmnoise = noise; | ||
576 | |||
577 | /* Convert the channel frequency and set the flags */ | ||
578 | put_unaligned_le16(stats->freq, &iwl3945_rt->rt_channelMHz); | ||
579 | if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) | ||
580 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, | ||
581 | &iwl3945_rt->rt_chbitmask); | ||
582 | else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) | ||
583 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, | ||
584 | &iwl3945_rt->rt_chbitmask); | ||
585 | else /* 802.11g */ | ||
586 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, | ||
587 | &iwl3945_rt->rt_chbitmask); | ||
588 | |||
589 | if (rate == -1) | ||
590 | iwl3945_rt->rt_rate = 0; | ||
591 | else { | ||
592 | if (stats->band == IEEE80211_BAND_5GHZ) | ||
593 | rate += IWL_FIRST_OFDM_RATE; | ||
594 | |||
595 | iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee; | ||
596 | } | 531 | } |
597 | |||
598 | /* antenna number */ | ||
599 | antenna = phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK; | ||
600 | iwl3945_rt->rt_antenna = le16_to_cpu(antenna) >> 4; | ||
601 | |||
602 | /* set the preamble flag if we have it */ | ||
603 | if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | ||
604 | iwl3945_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; | ||
605 | |||
606 | stats->flag |= RX_FLAG_RADIOTAP; | ||
607 | } | 532 | } |
608 | 533 | ||
609 | static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, | 534 | static void iwl3945_pass_packet_to_mac80211(struct iwl3945_priv *priv, |
610 | struct iwl3945_rx_mem_buffer *rxb, | 535 | struct iwl3945_rx_mem_buffer *rxb, |
611 | struct ieee80211_rx_status *stats) | 536 | struct ieee80211_rx_status *stats) |
612 | { | 537 | { |
613 | struct ieee80211_hdr *hdr; | ||
614 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; | 538 | struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; |
539 | #ifdef CONFIG_IWL3945_LEDS | ||
540 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | ||
541 | #endif | ||
615 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); | 542 | struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); |
616 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); | 543 | struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); |
617 | short len = le16_to_cpu(rx_hdr->len); | 544 | short len = le16_to_cpu(rx_hdr->len); |
@@ -633,17 +560,12 @@ static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, | |||
633 | /* Set the size of the skb to the size of the frame */ | 560 | /* Set the size of the skb to the size of the frame */ |
634 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); | 561 | skb_put(rxb->skb, le16_to_cpu(rx_hdr->len)); |
635 | 562 | ||
636 | hdr = (void *)rxb->skb->data; | ||
637 | |||
638 | if (iwl3945_param_hwcrypto) | 563 | if (iwl3945_param_hwcrypto) |
639 | iwl3945_set_decrypted_flag(priv, rxb->skb, | 564 | iwl3945_set_decrypted_flag(priv, rxb->skb, |
640 | le32_to_cpu(rx_end->status), stats); | 565 | le32_to_cpu(rx_end->status), stats); |
641 | 566 | ||
642 | if (priv->add_radiotap) | ||
643 | iwl3945_add_radiotap(priv, rxb->skb, rx_hdr, stats); | ||
644 | |||
645 | #ifdef CONFIG_IWL3945_LEDS | 567 | #ifdef CONFIG_IWL3945_LEDS |
646 | if (is_data) | 568 | if (ieee80211_is_data(hdr->frame_control)) |
647 | priv->rxtxpackets += len; | 569 | priv->rxtxpackets += len; |
648 | #endif | 570 | #endif |
649 | ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); | 571 | ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); |
@@ -666,7 +588,6 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
666 | u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); | 588 | u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff); |
667 | u8 network_packet; | 589 | u8 network_packet; |
668 | 590 | ||
669 | rx_status.antenna = 0; | ||
670 | rx_status.flag = 0; | 591 | rx_status.flag = 0; |
671 | rx_status.mactime = le64_to_cpu(rx_end->timestamp); | 592 | rx_status.mactime = le64_to_cpu(rx_end->timestamp); |
672 | rx_status.freq = | 593 | rx_status.freq = |
@@ -678,6 +599,13 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
678 | if (rx_status.band == IEEE80211_BAND_5GHZ) | 599 | if (rx_status.band == IEEE80211_BAND_5GHZ) |
679 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; | 600 | rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; |
680 | 601 | ||
602 | rx_status.antenna = le16_to_cpu(rx_hdr->phy_flags & | ||
603 | RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; | ||
604 | |||
605 | /* set the preamble flag if appropriate */ | ||
606 | if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) | ||
607 | rx_status.flag |= RX_FLAG_SHORTPRE; | ||
608 | |||
681 | if ((unlikely(rx_stats->phy_count > 20))) { | 609 | if ((unlikely(rx_stats->phy_count > 20))) { |
682 | IWL_DEBUG_DROP | 610 | IWL_DEBUG_DROP |
683 | ("dsp size out of range [0,20]: " | 611 | ("dsp size out of range [0,20]: " |
@@ -691,13 +619,10 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
691 | return; | 619 | return; |
692 | } | 620 | } |
693 | 621 | ||
694 | if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { | 622 | |
695 | iwl3945_handle_data_packet(priv, 1, rxb, &rx_status); | ||
696 | return; | ||
697 | } | ||
698 | 623 | ||
699 | /* Convert 3945's rssi indicator to dBm */ | 624 | /* Convert 3945's rssi indicator to dBm */ |
700 | rx_status.ssi = rx_stats->rssi - IWL_RSSI_OFFSET; | 625 | rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET; |
701 | 626 | ||
702 | /* Set default noise value to -127 */ | 627 | /* Set default noise value to -127 */ |
703 | if (priv->last_rx_noise == 0) | 628 | if (priv->last_rx_noise == 0) |
@@ -716,21 +641,21 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
716 | * Calculate rx_status.signal (quality indicator in %) based on SNR. */ | 641 | * Calculate rx_status.signal (quality indicator in %) based on SNR. */ |
717 | if (rx_stats_noise_diff) { | 642 | if (rx_stats_noise_diff) { |
718 | snr = rx_stats_sig_avg / rx_stats_noise_diff; | 643 | snr = rx_stats_sig_avg / rx_stats_noise_diff; |
719 | rx_status.noise = rx_status.ssi - | 644 | rx_status.noise = rx_status.signal - |
720 | iwl3945_calc_db_from_ratio(snr); | 645 | iwl3945_calc_db_from_ratio(snr); |
721 | rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, | 646 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, |
722 | rx_status.noise); | 647 | rx_status.noise); |
723 | 648 | ||
724 | /* If noise info not available, calculate signal quality indicator (%) | 649 | /* If noise info not available, calculate signal quality indicator (%) |
725 | * using just the dBm signal level. */ | 650 | * using just the dBm signal level. */ |
726 | } else { | 651 | } else { |
727 | rx_status.noise = priv->last_rx_noise; | 652 | rx_status.noise = priv->last_rx_noise; |
728 | rx_status.signal = iwl3945_calc_sig_qual(rx_status.ssi, 0); | 653 | rx_status.qual = iwl3945_calc_sig_qual(rx_status.signal, 0); |
729 | } | 654 | } |
730 | 655 | ||
731 | 656 | ||
732 | IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", | 657 | IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n", |
733 | rx_status.ssi, rx_status.noise, rx_status.signal, | 658 | rx_status.signal, rx_status.noise, rx_status.qual, |
734 | rx_stats_sig_avg, rx_stats_noise_diff); | 659 | rx_stats_sig_avg, rx_stats_noise_diff); |
735 | 660 | ||
736 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); | 661 | header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); |
@@ -740,8 +665,8 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
740 | IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", | 665 | IWL_DEBUG_STATS_LIMIT("[%c] %d RSSI:%d Signal:%u, Noise:%u, Rate:%u\n", |
741 | network_packet ? '*' : ' ', | 666 | network_packet ? '*' : ' ', |
742 | le16_to_cpu(rx_hdr->channel), | 667 | le16_to_cpu(rx_hdr->channel), |
743 | rx_status.ssi, rx_status.ssi, | 668 | rx_status.signal, rx_status.signal, |
744 | rx_status.ssi, rx_status.rate_idx); | 669 | rx_status.noise, rx_status.rate_idx); |
745 | 670 | ||
746 | #ifdef CONFIG_IWL3945_DEBUG | 671 | #ifdef CONFIG_IWL3945_DEBUG |
747 | if (iwl3945_debug_level & (IWL_DL_RX)) | 672 | if (iwl3945_debug_level & (IWL_DL_RX)) |
@@ -752,115 +677,11 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, | |||
752 | if (network_packet) { | 677 | if (network_packet) { |
753 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); | 678 | priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp); |
754 | priv->last_tsf = le64_to_cpu(rx_end->timestamp); | 679 | priv->last_tsf = le64_to_cpu(rx_end->timestamp); |
755 | priv->last_rx_rssi = rx_status.ssi; | 680 | priv->last_rx_rssi = rx_status.signal; |
756 | priv->last_rx_noise = rx_status.noise; | 681 | priv->last_rx_noise = rx_status.noise; |
757 | } | 682 | } |
758 | 683 | ||
759 | switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) { | 684 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
760 | case IEEE80211_FTYPE_MGMT: | ||
761 | switch (le16_to_cpu(header->frame_control) & | ||
762 | IEEE80211_FCTL_STYPE) { | ||
763 | case IEEE80211_STYPE_PROBE_RESP: | ||
764 | case IEEE80211_STYPE_BEACON:{ | ||
765 | /* If this is a beacon or probe response for | ||
766 | * our network then cache the beacon | ||
767 | * timestamp */ | ||
768 | if ((((priv->iw_mode == IEEE80211_IF_TYPE_STA) | ||
769 | && !compare_ether_addr(header->addr2, | ||
770 | priv->bssid)) || | ||
771 | ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | ||
772 | && !compare_ether_addr(header->addr3, | ||
773 | priv->bssid)))) { | ||
774 | struct ieee80211_mgmt *mgmt = | ||
775 | (struct ieee80211_mgmt *)header; | ||
776 | __le32 *pos; | ||
777 | pos = | ||
778 | (__le32 *) & mgmt->u.beacon. | ||
779 | timestamp; | ||
780 | priv->timestamp0 = le32_to_cpu(pos[0]); | ||
781 | priv->timestamp1 = le32_to_cpu(pos[1]); | ||
782 | priv->beacon_int = le16_to_cpu( | ||
783 | mgmt->u.beacon.beacon_int); | ||
784 | if (priv->call_post_assoc_from_beacon && | ||
785 | (priv->iw_mode == | ||
786 | IEEE80211_IF_TYPE_STA)) | ||
787 | queue_work(priv->workqueue, | ||
788 | &priv->post_associate.work); | ||
789 | |||
790 | priv->call_post_assoc_from_beacon = 0; | ||
791 | } | ||
792 | |||
793 | break; | ||
794 | } | ||
795 | |||
796 | case IEEE80211_STYPE_ACTION: | ||
797 | /* TODO: Parse 802.11h frames for CSA... */ | ||
798 | break; | ||
799 | |||
800 | /* | ||
801 | * TODO: Use the new callback function from | ||
802 | * mac80211 instead of sniffing these packets. | ||
803 | */ | ||
804 | case IEEE80211_STYPE_ASSOC_RESP: | ||
805 | case IEEE80211_STYPE_REASSOC_RESP:{ | ||
806 | struct ieee80211_mgmt *mgnt = | ||
807 | (struct ieee80211_mgmt *)header; | ||
808 | |||
809 | /* We have just associated, give some | ||
810 | * time for the 4-way handshake if | ||
811 | * any. Don't start scan too early. */ | ||
812 | priv->next_scan_jiffies = jiffies + | ||
813 | IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; | ||
814 | |||
815 | priv->assoc_id = (~((1 << 15) | (1 << 14)) & | ||
816 | le16_to_cpu(mgnt->u. | ||
817 | assoc_resp.aid)); | ||
818 | priv->assoc_capability = | ||
819 | le16_to_cpu(mgnt->u.assoc_resp.capab_info); | ||
820 | if (priv->beacon_int) | ||
821 | queue_work(priv->workqueue, | ||
822 | &priv->post_associate.work); | ||
823 | else | ||
824 | priv->call_post_assoc_from_beacon = 1; | ||
825 | break; | ||
826 | } | ||
827 | |||
828 | case IEEE80211_STYPE_PROBE_REQ:{ | ||
829 | DECLARE_MAC_BUF(mac1); | ||
830 | DECLARE_MAC_BUF(mac2); | ||
831 | DECLARE_MAC_BUF(mac3); | ||
832 | if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) | ||
833 | IWL_DEBUG_DROP | ||
834 | ("Dropping (non network): %s" | ||
835 | ", %s, %s\n", | ||
836 | print_mac(mac1, header->addr1), | ||
837 | print_mac(mac2, header->addr2), | ||
838 | print_mac(mac3, header->addr3)); | ||
839 | return; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | iwl3945_handle_data_packet(priv, 0, rxb, &rx_status); | ||
844 | break; | ||
845 | |||
846 | case IEEE80211_FTYPE_CTL: | ||
847 | break; | ||
848 | |||
849 | case IEEE80211_FTYPE_DATA: { | ||
850 | DECLARE_MAC_BUF(mac1); | ||
851 | DECLARE_MAC_BUF(mac2); | ||
852 | DECLARE_MAC_BUF(mac3); | ||
853 | |||
854 | if (unlikely(iwl3945_is_duplicate_packet(priv, header))) | ||
855 | IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", | ||
856 | print_mac(mac1, header->addr1), | ||
857 | print_mac(mac2, header->addr2), | ||
858 | print_mac(mac3, header->addr3)); | ||
859 | else | ||
860 | iwl3945_handle_data_packet(priv, 1, rxb, &rx_status); | ||
861 | break; | ||
862 | } | ||
863 | } | ||
864 | } | 685 | } |
865 | 686 | ||
866 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, | 687 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, |
@@ -962,30 +783,31 @@ u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) | |||
962 | */ | 783 | */ |
963 | void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | 784 | void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, |
964 | struct iwl3945_cmd *cmd, | 785 | struct iwl3945_cmd *cmd, |
965 | struct ieee80211_tx_control *ctrl, | 786 | struct ieee80211_tx_info *info, |
966 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) | 787 | struct ieee80211_hdr *hdr, int sta_id, int tx_id) |
967 | { | 788 | { |
968 | unsigned long flags; | 789 | unsigned long flags; |
969 | u16 rate_index = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1); | 790 | u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; |
791 | u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); | ||
970 | u16 rate_mask; | 792 | u16 rate_mask; |
971 | int rate; | 793 | int rate; |
972 | u8 rts_retry_limit; | 794 | u8 rts_retry_limit; |
973 | u8 data_retry_limit; | 795 | u8 data_retry_limit; |
974 | __le32 tx_flags; | 796 | __le32 tx_flags; |
975 | u16 fc = le16_to_cpu(hdr->frame_control); | 797 | __le16 fc = hdr->frame_control; |
976 | 798 | ||
977 | rate = iwl3945_rates[rate_index].plcp; | 799 | rate = iwl3945_rates[rate_index].plcp; |
978 | tx_flags = cmd->cmd.tx.tx_flags; | 800 | tx_flags = cmd->cmd.tx.tx_flags; |
979 | 801 | ||
980 | /* We need to figure out how to get the sta->supp_rates while | 802 | /* We need to figure out how to get the sta->supp_rates while |
981 | * in this running context; perhaps encoding into ctrl->tx_rate? */ | 803 | * in this running context */ |
982 | rate_mask = IWL_RATES_MASK; | 804 | rate_mask = IWL_RATES_MASK; |
983 | 805 | ||
984 | spin_lock_irqsave(&priv->sta_lock, flags); | 806 | spin_lock_irqsave(&priv->sta_lock, flags); |
985 | 807 | ||
986 | priv->stations[sta_id].current_rate.rate_n_flags = rate; | 808 | priv->stations[sta_id].current_rate.rate_n_flags = rate; |
987 | 809 | ||
988 | if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && | 810 | if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && |
989 | (sta_id != priv->hw_setting.bcast_sta_id) && | 811 | (sta_id != priv->hw_setting.bcast_sta_id) && |
990 | (sta_id != IWL_MULTICAST_ID)) | 812 | (sta_id != IWL_MULTICAST_ID)) |
991 | priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate; | 813 | priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate; |
@@ -997,7 +819,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
997 | else | 819 | else |
998 | rts_retry_limit = 7; | 820 | rts_retry_limit = 7; |
999 | 821 | ||
1000 | if (ieee80211_is_probe_response(fc)) { | 822 | if (ieee80211_is_probe_resp(fc)) { |
1001 | data_retry_limit = 3; | 823 | data_retry_limit = 3; |
1002 | if (data_retry_limit < rts_retry_limit) | 824 | if (data_retry_limit < rts_retry_limit) |
1003 | rts_retry_limit = data_retry_limit; | 825 | rts_retry_limit = data_retry_limit; |
@@ -1007,12 +829,12 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, | |||
1007 | if (priv->data_retry_limit != -1) | 829 | if (priv->data_retry_limit != -1) |
1008 | data_retry_limit = priv->data_retry_limit; | 830 | data_retry_limit = priv->data_retry_limit; |
1009 | 831 | ||
1010 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 832 | if (ieee80211_is_mgmt(fc)) { |
1011 | switch (fc & IEEE80211_FCTL_STYPE) { | 833 | switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { |
1012 | case IEEE80211_STYPE_AUTH: | 834 | case cpu_to_le16(IEEE80211_STYPE_AUTH): |
1013 | case IEEE80211_STYPE_DEAUTH: | 835 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): |
1014 | case IEEE80211_STYPE_ASSOC_REQ: | 836 | case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): |
1015 | case IEEE80211_STYPE_REASSOC_REQ: | 837 | case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): |
1016 | if (tx_flags & TX_CMD_FLG_RTS_MSK) { | 838 | if (tx_flags & TX_CMD_FLG_RTS_MSK) { |
1017 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 839 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
1018 | tx_flags |= TX_CMD_FLG_CTS_MSK; | 840 | tx_flags |= TX_CMD_FLG_CTS_MSK; |
@@ -1233,7 +1055,7 @@ int iwl3945_hw_nic_init(struct iwl3945_priv *priv) | |||
1233 | iwl3945_power_init_handle(priv); | 1055 | iwl3945_power_init_handle(priv); |
1234 | 1056 | ||
1235 | spin_lock_irqsave(&priv->lock, flags); | 1057 | spin_lock_irqsave(&priv->lock, flags); |
1236 | iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24)); | 1058 | iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, CSR39_ANA_PLL_CFG_VAL); |
1237 | iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, | 1059 | iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, |
1238 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); | 1060 | CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); |
1239 | 1061 | ||
@@ -1502,7 +1324,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) | |||
1502 | */ | 1324 | */ |
1503 | static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) | 1325 | static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) |
1504 | { | 1326 | { |
1505 | return (((temperature < -260) || (temperature > 25)) ? 1 : 0); | 1327 | return ((temperature < -260) || (temperature > 25)) ? 1 : 0; |
1506 | } | 1328 | } |
1507 | 1329 | ||
1508 | int iwl3945_hw_get_temperature(struct iwl3945_priv *priv) | 1330 | int iwl3945_hw_get_temperature(struct iwl3945_priv *priv) |
@@ -2623,7 +2445,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, | |||
2623 | tx_beacon_cmd->tx.supp_rates[1] = | 2445 | tx_beacon_cmd->tx.supp_rates[1] = |
2624 | (IWL_CCK_BASIC_RATES_MASK & 0xF); | 2446 | (IWL_CCK_BASIC_RATES_MASK & 0xF); |
2625 | 2447 | ||
2626 | return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size); | 2448 | return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size; |
2627 | } | 2449 | } |
2628 | 2450 | ||
2629 | void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) | 2451 | void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) |