diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 713 |
1 files changed, 30 insertions, 683 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 90315c69cdf6..8837171ad553 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
35 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
36 | #include <linux/netdevice.h> | 36 | #include <linux/netdevice.h> |
37 | #include <linux/firmware.h> | ||
38 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
39 | #include <linux/if_arp.h> | 38 | #include <linux/if_arp.h> |
40 | 39 | ||
@@ -42,6 +41,7 @@ | |||
42 | 41 | ||
43 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
44 | 43 | ||
44 | #include "iwl-ucode.h" | ||
45 | #include "iwl-eeprom.h" | 45 | #include "iwl-eeprom.h" |
46 | #include "iwl-wifi.h" | 46 | #include "iwl-wifi.h" |
47 | #include "iwl-dev.h" | 47 | #include "iwl-dev.h" |
@@ -328,14 +328,14 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
328 | ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); | 328 | ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); |
329 | 329 | ||
330 | /* Make sure device is powered up for SRAM reads */ | 330 | /* Make sure device is powered up for SRAM reads */ |
331 | spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags); | 331 | spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); |
332 | if (iwl_grab_nic_access(bus(priv))) { | 332 | if (iwl_grab_nic_access(trans(priv))) { |
333 | spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); | 333 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); |
334 | return; | 334 | return; |
335 | } | 335 | } |
336 | 336 | ||
337 | /* Set starting address; reads will auto-increment */ | 337 | /* Set starting address; reads will auto-increment */ |
338 | iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); | 338 | iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); |
339 | rmb(); | 339 | rmb(); |
340 | 340 | ||
341 | /* | 341 | /* |
@@ -352,19 +352,19 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, | |||
352 | * place event id # at far right for easier visual parsing. | 352 | * place event id # at far right for easier visual parsing. |
353 | */ | 353 | */ |
354 | for (i = 0; i < num_events; i++) { | 354 | for (i = 0; i < num_events; i++) { |
355 | ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 355 | ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
356 | time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 356 | time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
357 | if (mode == 0) { | 357 | if (mode == 0) { |
358 | trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); | 358 | trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); |
359 | } else { | 359 | } else { |
360 | data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); | 360 | data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); |
361 | trace_iwlwifi_dev_ucode_cont_event(priv, time, | 361 | trace_iwlwifi_dev_ucode_cont_event(priv, time, |
362 | data, ev); | 362 | data, ev); |
363 | } | 363 | } |
364 | } | 364 | } |
365 | /* Allow device to power down */ | 365 | /* Allow device to power down */ |
366 | iwl_release_nic_access(bus(priv)); | 366 | iwl_release_nic_access(trans(priv)); |
367 | spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); | 367 | spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); |
368 | } | 368 | } |
369 | 369 | ||
370 | static void iwl_continuous_event_trace(struct iwl_priv *priv) | 370 | static void iwl_continuous_event_trace(struct iwl_priv *priv) |
@@ -383,7 +383,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) | |||
383 | 383 | ||
384 | base = priv->shrd->device_pointers.log_event_table; | 384 | base = priv->shrd->device_pointers.log_event_table; |
385 | if (iwlagn_hw_valid_rtc_data_addr(base)) { | 385 | if (iwlagn_hw_valid_rtc_data_addr(base)) { |
386 | iwl_read_targ_mem_words(bus(priv), base, &read, sizeof(read)); | 386 | iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read)); |
387 | 387 | ||
388 | capacity = read.capacity; | 388 | capacity = read.capacity; |
389 | mode = read.mode; | 389 | mode = read.mode; |
@@ -490,7 +490,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
490 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 490 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); |
491 | } | 491 | } |
492 | 492 | ||
493 | static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | 493 | void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) |
494 | { | 494 | { |
495 | int i; | 495 | int i; |
496 | 496 | ||
@@ -513,6 +513,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
513 | priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; | 513 | priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; |
514 | priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; | 514 | priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; |
515 | priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; | 515 | priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; |
516 | priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; | ||
516 | priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = | 517 | priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = |
517 | BIT(NL80211_IFTYPE_ADHOC); | 518 | BIT(NL80211_IFTYPE_ADHOC); |
518 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes = | 519 | priv->contexts[IWL_RXON_CTX_BSS].interface_modes = |
@@ -547,609 +548,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) | |||
547 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | 548 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); |
548 | } | 549 | } |
549 | 550 | ||
550 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); | ||
551 | |||
552 | #define UCODE_EXPERIMENTAL_INDEX 100 | ||
553 | #define UCODE_EXPERIMENTAL_TAG "exp" | ||
554 | |||
555 | static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) | ||
556 | { | ||
557 | const char *name_pre = cfg(priv)->fw_name_pre; | ||
558 | char tag[8]; | ||
559 | |||
560 | if (first) { | ||
561 | #ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE | ||
562 | priv->fw_index = UCODE_EXPERIMENTAL_INDEX; | ||
563 | strcpy(tag, UCODE_EXPERIMENTAL_TAG); | ||
564 | } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { | ||
565 | #endif | ||
566 | priv->fw_index = cfg(priv)->ucode_api_max; | ||
567 | sprintf(tag, "%d", priv->fw_index); | ||
568 | } else { | ||
569 | priv->fw_index--; | ||
570 | sprintf(tag, "%d", priv->fw_index); | ||
571 | } | ||
572 | |||
573 | if (priv->fw_index < cfg(priv)->ucode_api_min) { | ||
574 | IWL_ERR(priv, "no suitable firmware found!\n"); | ||
575 | return -ENOENT; | ||
576 | } | ||
577 | |||
578 | sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); | ||
579 | |||
580 | IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", | ||
581 | (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
582 | ? "EXPERIMENTAL " : "", | ||
583 | priv->firmware_name); | ||
584 | |||
585 | return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, | ||
586 | bus(priv)->dev, | ||
587 | GFP_KERNEL, priv, iwl_ucode_callback); | ||
588 | } | ||
589 | |||
590 | struct iwlagn_firmware_pieces { | ||
591 | const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; | ||
592 | size_t inst_size, data_size, init_size, init_data_size, | ||
593 | wowlan_inst_size, wowlan_data_size; | ||
594 | |||
595 | u32 build; | ||
596 | |||
597 | u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; | ||
598 | u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; | ||
599 | }; | ||
600 | |||
601 | static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, | ||
602 | const struct firmware *ucode_raw, | ||
603 | struct iwlagn_firmware_pieces *pieces) | ||
604 | { | ||
605 | struct iwl_ucode_header *ucode = (void *)ucode_raw->data; | ||
606 | u32 api_ver, hdr_size; | ||
607 | const u8 *src; | ||
608 | |||
609 | priv->ucode_ver = le32_to_cpu(ucode->ver); | ||
610 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
611 | |||
612 | switch (api_ver) { | ||
613 | default: | ||
614 | hdr_size = 28; | ||
615 | if (ucode_raw->size < hdr_size) { | ||
616 | IWL_ERR(priv, "File size too small!\n"); | ||
617 | return -EINVAL; | ||
618 | } | ||
619 | pieces->build = le32_to_cpu(ucode->u.v2.build); | ||
620 | pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); | ||
621 | pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); | ||
622 | pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); | ||
623 | pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); | ||
624 | src = ucode->u.v2.data; | ||
625 | break; | ||
626 | case 0: | ||
627 | case 1: | ||
628 | case 2: | ||
629 | hdr_size = 24; | ||
630 | if (ucode_raw->size < hdr_size) { | ||
631 | IWL_ERR(priv, "File size too small!\n"); | ||
632 | return -EINVAL; | ||
633 | } | ||
634 | pieces->build = 0; | ||
635 | pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); | ||
636 | pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); | ||
637 | pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); | ||
638 | pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); | ||
639 | src = ucode->u.v1.data; | ||
640 | break; | ||
641 | } | ||
642 | |||
643 | /* Verify size of file vs. image size info in file's header */ | ||
644 | if (ucode_raw->size != hdr_size + pieces->inst_size + | ||
645 | pieces->data_size + pieces->init_size + | ||
646 | pieces->init_data_size) { | ||
647 | |||
648 | IWL_ERR(priv, | ||
649 | "uCode file size %d does not match expected size\n", | ||
650 | (int)ucode_raw->size); | ||
651 | return -EINVAL; | ||
652 | } | ||
653 | |||
654 | pieces->inst = src; | ||
655 | src += pieces->inst_size; | ||
656 | pieces->data = src; | ||
657 | src += pieces->data_size; | ||
658 | pieces->init = src; | ||
659 | src += pieces->init_size; | ||
660 | pieces->init_data = src; | ||
661 | src += pieces->init_data_size; | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static int iwlagn_load_firmware(struct iwl_priv *priv, | ||
667 | const struct firmware *ucode_raw, | ||
668 | struct iwlagn_firmware_pieces *pieces, | ||
669 | struct iwlagn_ucode_capabilities *capa) | ||
670 | { | ||
671 | struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; | ||
672 | struct iwl_ucode_tlv *tlv; | ||
673 | size_t len = ucode_raw->size; | ||
674 | const u8 *data; | ||
675 | int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; | ||
676 | int tmp; | ||
677 | u64 alternatives; | ||
678 | u32 tlv_len; | ||
679 | enum iwl_ucode_tlv_type tlv_type; | ||
680 | const u8 *tlv_data; | ||
681 | |||
682 | if (len < sizeof(*ucode)) { | ||
683 | IWL_ERR(priv, "uCode has invalid length: %zd\n", len); | ||
684 | return -EINVAL; | ||
685 | } | ||
686 | |||
687 | if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { | ||
688 | IWL_ERR(priv, "invalid uCode magic: 0X%x\n", | ||
689 | le32_to_cpu(ucode->magic)); | ||
690 | return -EINVAL; | ||
691 | } | ||
692 | |||
693 | /* | ||
694 | * Check which alternatives are present, and "downgrade" | ||
695 | * when the chosen alternative is not present, warning | ||
696 | * the user when that happens. Some files may not have | ||
697 | * any alternatives, so don't warn in that case. | ||
698 | */ | ||
699 | alternatives = le64_to_cpu(ucode->alternatives); | ||
700 | tmp = wanted_alternative; | ||
701 | if (wanted_alternative > 63) | ||
702 | wanted_alternative = 63; | ||
703 | while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) | ||
704 | wanted_alternative--; | ||
705 | if (wanted_alternative && wanted_alternative != tmp) | ||
706 | IWL_WARN(priv, | ||
707 | "uCode alternative %d not available, choosing %d\n", | ||
708 | tmp, wanted_alternative); | ||
709 | |||
710 | priv->ucode_ver = le32_to_cpu(ucode->ver); | ||
711 | pieces->build = le32_to_cpu(ucode->build); | ||
712 | data = ucode->data; | ||
713 | |||
714 | len -= sizeof(*ucode); | ||
715 | |||
716 | while (len >= sizeof(*tlv)) { | ||
717 | u16 tlv_alt; | ||
718 | |||
719 | len -= sizeof(*tlv); | ||
720 | tlv = (void *)data; | ||
721 | |||
722 | tlv_len = le32_to_cpu(tlv->length); | ||
723 | tlv_type = le16_to_cpu(tlv->type); | ||
724 | tlv_alt = le16_to_cpu(tlv->alternative); | ||
725 | tlv_data = tlv->data; | ||
726 | |||
727 | if (len < tlv_len) { | ||
728 | IWL_ERR(priv, "invalid TLV len: %zd/%u\n", | ||
729 | len, tlv_len); | ||
730 | return -EINVAL; | ||
731 | } | ||
732 | len -= ALIGN(tlv_len, 4); | ||
733 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | ||
734 | |||
735 | /* | ||
736 | * Alternative 0 is always valid. | ||
737 | * | ||
738 | * Skip alternative TLVs that are not selected. | ||
739 | */ | ||
740 | if (tlv_alt != 0 && tlv_alt != wanted_alternative) | ||
741 | continue; | ||
742 | |||
743 | switch (tlv_type) { | ||
744 | case IWL_UCODE_TLV_INST: | ||
745 | pieces->inst = tlv_data; | ||
746 | pieces->inst_size = tlv_len; | ||
747 | break; | ||
748 | case IWL_UCODE_TLV_DATA: | ||
749 | pieces->data = tlv_data; | ||
750 | pieces->data_size = tlv_len; | ||
751 | break; | ||
752 | case IWL_UCODE_TLV_INIT: | ||
753 | pieces->init = tlv_data; | ||
754 | pieces->init_size = tlv_len; | ||
755 | break; | ||
756 | case IWL_UCODE_TLV_INIT_DATA: | ||
757 | pieces->init_data = tlv_data; | ||
758 | pieces->init_data_size = tlv_len; | ||
759 | break; | ||
760 | case IWL_UCODE_TLV_BOOT: | ||
761 | IWL_ERR(priv, "Found unexpected BOOT ucode\n"); | ||
762 | break; | ||
763 | case IWL_UCODE_TLV_PROBE_MAX_LEN: | ||
764 | if (tlv_len != sizeof(u32)) | ||
765 | goto invalid_tlv_len; | ||
766 | capa->max_probe_length = | ||
767 | le32_to_cpup((__le32 *)tlv_data); | ||
768 | break; | ||
769 | case IWL_UCODE_TLV_PAN: | ||
770 | if (tlv_len) | ||
771 | goto invalid_tlv_len; | ||
772 | capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; | ||
773 | break; | ||
774 | case IWL_UCODE_TLV_FLAGS: | ||
775 | /* must be at least one u32 */ | ||
776 | if (tlv_len < sizeof(u32)) | ||
777 | goto invalid_tlv_len; | ||
778 | /* and a proper number of u32s */ | ||
779 | if (tlv_len % sizeof(u32)) | ||
780 | goto invalid_tlv_len; | ||
781 | /* | ||
782 | * This driver only reads the first u32 as | ||
783 | * right now no more features are defined, | ||
784 | * if that changes then either the driver | ||
785 | * will not work with the new firmware, or | ||
786 | * it'll not take advantage of new features. | ||
787 | */ | ||
788 | capa->flags = le32_to_cpup((__le32 *)tlv_data); | ||
789 | break; | ||
790 | case IWL_UCODE_TLV_INIT_EVTLOG_PTR: | ||
791 | if (tlv_len != sizeof(u32)) | ||
792 | goto invalid_tlv_len; | ||
793 | pieces->init_evtlog_ptr = | ||
794 | le32_to_cpup((__le32 *)tlv_data); | ||
795 | break; | ||
796 | case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: | ||
797 | if (tlv_len != sizeof(u32)) | ||
798 | goto invalid_tlv_len; | ||
799 | pieces->init_evtlog_size = | ||
800 | le32_to_cpup((__le32 *)tlv_data); | ||
801 | break; | ||
802 | case IWL_UCODE_TLV_INIT_ERRLOG_PTR: | ||
803 | if (tlv_len != sizeof(u32)) | ||
804 | goto invalid_tlv_len; | ||
805 | pieces->init_errlog_ptr = | ||
806 | le32_to_cpup((__le32 *)tlv_data); | ||
807 | break; | ||
808 | case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: | ||
809 | if (tlv_len != sizeof(u32)) | ||
810 | goto invalid_tlv_len; | ||
811 | pieces->inst_evtlog_ptr = | ||
812 | le32_to_cpup((__le32 *)tlv_data); | ||
813 | break; | ||
814 | case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: | ||
815 | if (tlv_len != sizeof(u32)) | ||
816 | goto invalid_tlv_len; | ||
817 | pieces->inst_evtlog_size = | ||
818 | le32_to_cpup((__le32 *)tlv_data); | ||
819 | break; | ||
820 | case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: | ||
821 | if (tlv_len != sizeof(u32)) | ||
822 | goto invalid_tlv_len; | ||
823 | pieces->inst_errlog_ptr = | ||
824 | le32_to_cpup((__le32 *)tlv_data); | ||
825 | break; | ||
826 | case IWL_UCODE_TLV_ENHANCE_SENS_TBL: | ||
827 | if (tlv_len) | ||
828 | goto invalid_tlv_len; | ||
829 | priv->enhance_sensitivity_table = true; | ||
830 | break; | ||
831 | case IWL_UCODE_TLV_WOWLAN_INST: | ||
832 | pieces->wowlan_inst = tlv_data; | ||
833 | pieces->wowlan_inst_size = tlv_len; | ||
834 | break; | ||
835 | case IWL_UCODE_TLV_WOWLAN_DATA: | ||
836 | pieces->wowlan_data = tlv_data; | ||
837 | pieces->wowlan_data_size = tlv_len; | ||
838 | break; | ||
839 | case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: | ||
840 | if (tlv_len != sizeof(u32)) | ||
841 | goto invalid_tlv_len; | ||
842 | capa->standard_phy_calibration_size = | ||
843 | le32_to_cpup((__le32 *)tlv_data); | ||
844 | break; | ||
845 | default: | ||
846 | IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); | ||
847 | break; | ||
848 | } | ||
849 | } | ||
850 | |||
851 | if (len) { | ||
852 | IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); | ||
853 | iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); | ||
854 | return -EINVAL; | ||
855 | } | ||
856 | |||
857 | return 0; | ||
858 | |||
859 | invalid_tlv_len: | ||
860 | IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); | ||
861 | iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); | ||
862 | |||
863 | return -EINVAL; | ||
864 | } | ||
865 | |||
866 | /** | ||
867 | * iwl_ucode_callback - callback when firmware was loaded | ||
868 | * | ||
869 | * If loaded successfully, copies the firmware into buffers | ||
870 | * for the card to fetch (via DMA). | ||
871 | */ | ||
872 | static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | ||
873 | { | ||
874 | struct iwl_priv *priv = context; | ||
875 | struct iwl_ucode_header *ucode; | ||
876 | int err; | ||
877 | struct iwlagn_firmware_pieces pieces; | ||
878 | const unsigned int api_max = cfg(priv)->ucode_api_max; | ||
879 | unsigned int api_ok = cfg(priv)->ucode_api_ok; | ||
880 | const unsigned int api_min = cfg(priv)->ucode_api_min; | ||
881 | u32 api_ver; | ||
882 | char buildstr[25]; | ||
883 | u32 build; | ||
884 | struct iwlagn_ucode_capabilities ucode_capa = { | ||
885 | .max_probe_length = 200, | ||
886 | .standard_phy_calibration_size = | ||
887 | IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, | ||
888 | }; | ||
889 | |||
890 | if (!api_ok) | ||
891 | api_ok = api_max; | ||
892 | |||
893 | memset(&pieces, 0, sizeof(pieces)); | ||
894 | |||
895 | if (!ucode_raw) { | ||
896 | if (priv->fw_index <= api_ok) | ||
897 | IWL_ERR(priv, | ||
898 | "request for firmware file '%s' failed.\n", | ||
899 | priv->firmware_name); | ||
900 | goto try_again; | ||
901 | } | ||
902 | |||
903 | IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", | ||
904 | priv->firmware_name, ucode_raw->size); | ||
905 | |||
906 | /* Make sure that we got at least the API version number */ | ||
907 | if (ucode_raw->size < 4) { | ||
908 | IWL_ERR(priv, "File size way too small!\n"); | ||
909 | goto try_again; | ||
910 | } | ||
911 | |||
912 | /* Data from ucode file: header followed by uCode images */ | ||
913 | ucode = (struct iwl_ucode_header *)ucode_raw->data; | ||
914 | |||
915 | if (ucode->ver) | ||
916 | err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); | ||
917 | else | ||
918 | err = iwlagn_load_firmware(priv, ucode_raw, &pieces, | ||
919 | &ucode_capa); | ||
920 | |||
921 | if (err) | ||
922 | goto try_again; | ||
923 | |||
924 | api_ver = IWL_UCODE_API(priv->ucode_ver); | ||
925 | build = pieces.build; | ||
926 | |||
927 | /* | ||
928 | * api_ver should match the api version forming part of the | ||
929 | * firmware filename ... but we don't check for that and only rely | ||
930 | * on the API version read from firmware header from here on forward | ||
931 | */ | ||
932 | /* no api version check required for experimental uCode */ | ||
933 | if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { | ||
934 | if (api_ver < api_min || api_ver > api_max) { | ||
935 | IWL_ERR(priv, | ||
936 | "Driver unable to support your firmware API. " | ||
937 | "Driver supports v%u, firmware is v%u.\n", | ||
938 | api_max, api_ver); | ||
939 | goto try_again; | ||
940 | } | ||
941 | |||
942 | if (api_ver < api_ok) { | ||
943 | if (api_ok != api_max) | ||
944 | IWL_ERR(priv, "Firmware has old API version, " | ||
945 | "expected v%u through v%u, got v%u.\n", | ||
946 | api_ok, api_max, api_ver); | ||
947 | else | ||
948 | IWL_ERR(priv, "Firmware has old API version, " | ||
949 | "expected v%u, got v%u.\n", | ||
950 | api_max, api_ver); | ||
951 | IWL_ERR(priv, "New firmware can be obtained from " | ||
952 | "http://www.intellinuxwireless.org/.\n"); | ||
953 | } | ||
954 | } | ||
955 | |||
956 | if (build) | ||
957 | sprintf(buildstr, " build %u%s", build, | ||
958 | (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) | ||
959 | ? " (EXP)" : ""); | ||
960 | else | ||
961 | buildstr[0] = '\0'; | ||
962 | |||
963 | IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", | ||
964 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
965 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
966 | IWL_UCODE_API(priv->ucode_ver), | ||
967 | IWL_UCODE_SERIAL(priv->ucode_ver), | ||
968 | buildstr); | ||
969 | |||
970 | snprintf(priv->hw->wiphy->fw_version, | ||
971 | sizeof(priv->hw->wiphy->fw_version), | ||
972 | "%u.%u.%u.%u%s", | ||
973 | IWL_UCODE_MAJOR(priv->ucode_ver), | ||
974 | IWL_UCODE_MINOR(priv->ucode_ver), | ||
975 | IWL_UCODE_API(priv->ucode_ver), | ||
976 | IWL_UCODE_SERIAL(priv->ucode_ver), | ||
977 | buildstr); | ||
978 | |||
979 | /* | ||
980 | * For any of the failures below (before allocating pci memory) | ||
981 | * we will try to load a version with a smaller API -- maybe the | ||
982 | * user just got a corrupted version of the latest API. | ||
983 | */ | ||
984 | |||
985 | IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", | ||
986 | priv->ucode_ver); | ||
987 | IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", | ||
988 | pieces.inst_size); | ||
989 | IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", | ||
990 | pieces.data_size); | ||
991 | IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", | ||
992 | pieces.init_size); | ||
993 | IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", | ||
994 | pieces.init_data_size); | ||
995 | |||
996 | /* Verify that uCode images will fit in card's SRAM */ | ||
997 | if (pieces.inst_size > hw_params(priv).max_inst_size) { | ||
998 | IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", | ||
999 | pieces.inst_size); | ||
1000 | goto try_again; | ||
1001 | } | ||
1002 | |||
1003 | if (pieces.data_size > hw_params(priv).max_data_size) { | ||
1004 | IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", | ||
1005 | pieces.data_size); | ||
1006 | goto try_again; | ||
1007 | } | ||
1008 | |||
1009 | if (pieces.init_size > hw_params(priv).max_inst_size) { | ||
1010 | IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", | ||
1011 | pieces.init_size); | ||
1012 | goto try_again; | ||
1013 | } | ||
1014 | |||
1015 | if (pieces.init_data_size > hw_params(priv).max_data_size) { | ||
1016 | IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", | ||
1017 | pieces.init_data_size); | ||
1018 | goto try_again; | ||
1019 | } | ||
1020 | |||
1021 | /* Allocate ucode buffers for card's bus-master loading ... */ | ||
1022 | |||
1023 | /* Runtime instructions and 2 copies of data: | ||
1024 | * 1) unmodified from disk | ||
1025 | * 2) backup cache for save/restore during power-downs */ | ||
1026 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code, | ||
1027 | pieces.inst, pieces.inst_size)) | ||
1028 | goto err_pci_alloc; | ||
1029 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data, | ||
1030 | pieces.data, pieces.data_size)) | ||
1031 | goto err_pci_alloc; | ||
1032 | |||
1033 | /* Initialization instructions and data */ | ||
1034 | if (pieces.init_size && pieces.init_data_size) { | ||
1035 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code, | ||
1036 | pieces.init, pieces.init_size)) | ||
1037 | goto err_pci_alloc; | ||
1038 | if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, | ||
1039 | pieces.init_data, pieces.init_data_size)) | ||
1040 | goto err_pci_alloc; | ||
1041 | } | ||
1042 | |||
1043 | /* WoWLAN instructions and data */ | ||
1044 | if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { | ||
1045 | if (iwl_alloc_fw_desc(bus(priv), | ||
1046 | &trans(priv)->ucode_wowlan.code, | ||
1047 | pieces.wowlan_inst, | ||
1048 | pieces.wowlan_inst_size)) | ||
1049 | goto err_pci_alloc; | ||
1050 | if (iwl_alloc_fw_desc(bus(priv), | ||
1051 | &trans(priv)->ucode_wowlan.data, | ||
1052 | pieces.wowlan_data, | ||
1053 | pieces.wowlan_data_size)) | ||
1054 | goto err_pci_alloc; | ||
1055 | } | ||
1056 | |||
1057 | /* Now that we can no longer fail, copy information */ | ||
1058 | |||
1059 | /* | ||
1060 | * The (size - 16) / 12 formula is based on the information recorded | ||
1061 | * for each event, which is of mode 1 (including timestamp) for all | ||
1062 | * new microcodes that include this information. | ||
1063 | */ | ||
1064 | priv->init_evtlog_ptr = pieces.init_evtlog_ptr; | ||
1065 | if (pieces.init_evtlog_size) | ||
1066 | priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; | ||
1067 | else | ||
1068 | priv->init_evtlog_size = | ||
1069 | cfg(priv)->base_params->max_event_log_size; | ||
1070 | priv->init_errlog_ptr = pieces.init_errlog_ptr; | ||
1071 | priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; | ||
1072 | if (pieces.inst_evtlog_size) | ||
1073 | priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; | ||
1074 | else | ||
1075 | priv->inst_evtlog_size = | ||
1076 | cfg(priv)->base_params->max_event_log_size; | ||
1077 | priv->inst_errlog_ptr = pieces.inst_errlog_ptr; | ||
1078 | #ifndef CONFIG_IWLWIFI_P2P | ||
1079 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1080 | #endif | ||
1081 | |||
1082 | priv->new_scan_threshold_behaviour = | ||
1083 | !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | ||
1084 | |||
1085 | if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) | ||
1086 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; | ||
1087 | |||
1088 | /* | ||
1089 | * if not PAN, then don't support P2P -- might be a uCode | ||
1090 | * packaging bug or due to the eeprom check above | ||
1091 | */ | ||
1092 | if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) | ||
1093 | ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; | ||
1094 | |||
1095 | if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||
1096 | priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||
1097 | priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; | ||
1098 | } else { | ||
1099 | priv->sta_key_max_num = STA_KEY_MAX_NUM; | ||
1100 | priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||
1101 | } | ||
1102 | /* | ||
1103 | * figure out the offset of chain noise reset and gain commands | ||
1104 | * base on the size of standard phy calibration commands table size | ||
1105 | */ | ||
1106 | if (ucode_capa.standard_phy_calibration_size > | ||
1107 | IWL_MAX_PHY_CALIBRATE_TBL_SIZE) | ||
1108 | ucode_capa.standard_phy_calibration_size = | ||
1109 | IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; | ||
1110 | |||
1111 | priv->phy_calib_chain_noise_reset_cmd = | ||
1112 | ucode_capa.standard_phy_calibration_size; | ||
1113 | priv->phy_calib_chain_noise_gain_cmd = | ||
1114 | ucode_capa.standard_phy_calibration_size + 1; | ||
1115 | |||
1116 | /* initialize all valid contexts */ | ||
1117 | iwl_init_context(priv, ucode_capa.flags); | ||
1118 | |||
1119 | /************************************************** | ||
1120 | * This is still part of probe() in a sense... | ||
1121 | * | ||
1122 | * 9. Setup and register with mac80211 and debugfs | ||
1123 | **************************************************/ | ||
1124 | err = iwlagn_mac_setup_register(priv, &ucode_capa); | ||
1125 | if (err) | ||
1126 | goto out_unbind; | ||
1127 | |||
1128 | err = iwl_dbgfs_register(priv, DRV_NAME); | ||
1129 | if (err) | ||
1130 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | ||
1131 | |||
1132 | /* We have our copies now, allow OS release its copies */ | ||
1133 | release_firmware(ucode_raw); | ||
1134 | complete(&priv->firmware_loading_complete); | ||
1135 | return; | ||
1136 | |||
1137 | try_again: | ||
1138 | /* try next, if any */ | ||
1139 | if (iwl_request_firmware(priv, false)) | ||
1140 | goto out_unbind; | ||
1141 | release_firmware(ucode_raw); | ||
1142 | return; | ||
1143 | |||
1144 | err_pci_alloc: | ||
1145 | IWL_ERR(priv, "failed to allocate pci memory\n"); | ||
1146 | iwl_dealloc_ucode(trans(priv)); | ||
1147 | out_unbind: | ||
1148 | complete(&priv->firmware_loading_complete); | ||
1149 | device_release_driver(bus(priv)->dev); | ||
1150 | release_firmware(ucode_raw); | ||
1151 | } | ||
1152 | |||
1153 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | 551 | static void iwl_rf_kill_ct_config(struct iwl_priv *priv) |
1154 | { | 552 | { |
1155 | struct iwl_ct_kill_config cmd; | 553 | struct iwl_ct_kill_config cmd; |
@@ -1158,7 +556,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) | |||
1158 | int ret = 0; | 556 | int ret = 0; |
1159 | 557 | ||
1160 | spin_lock_irqsave(&priv->shrd->lock, flags); | 558 | spin_lock_irqsave(&priv->shrd->lock, flags); |
1161 | iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, | 559 | iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, |
1162 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); | 560 | CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); |
1163 | spin_unlock_irqrestore(&priv->shrd->lock, flags); | 561 | spin_unlock_irqrestore(&priv->shrd->lock, flags); |
1164 | priv->thermal_throttle.ct_kill_toggle = false; | 562 | priv->thermal_throttle.ct_kill_toggle = false; |
@@ -1243,9 +641,6 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
1243 | int ret = 0; | 641 | int ret = 0; |
1244 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 642 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
1245 | 643 | ||
1246 | /*TODO: this should go to the transport layer */ | ||
1247 | iwl_reset_ict(trans(priv)); | ||
1248 | |||
1249 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | 644 | IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); |
1250 | 645 | ||
1251 | /* After the ALIVE response, we can send host commands to the uCode */ | 646 | /* After the ALIVE response, we can send host commands to the uCode */ |
@@ -1692,13 +1087,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) | |||
1692 | #endif | 1087 | #endif |
1693 | } | 1088 | } |
1694 | 1089 | ||
1695 | |||
1696 | |||
1697 | static u32 iwl_hw_detect(struct iwl_priv *priv) | ||
1698 | { | ||
1699 | return iwl_read32(bus(priv), CSR_HW_REV); | ||
1700 | } | ||
1701 | |||
1702 | /* Size of one Rx buffer in host DRAM */ | 1090 | /* Size of one Rx buffer in host DRAM */ |
1703 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) | 1091 | #define IWL_RX_BUF_SIZE_4K (4 * 1024) |
1704 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) | 1092 | #define IWL_RX_BUF_SIZE_8K (8 * 1024) |
@@ -1730,32 +1118,32 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
1730 | 1118 | ||
1731 | static void iwl_debug_config(struct iwl_priv *priv) | 1119 | static void iwl_debug_config(struct iwl_priv *priv) |
1732 | { | 1120 | { |
1733 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG " | 1121 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " |
1734 | #ifdef CONFIG_IWLWIFI_DEBUG | 1122 | #ifdef CONFIG_IWLWIFI_DEBUG |
1735 | "enabled\n"); | 1123 | "enabled\n"); |
1736 | #else | 1124 | #else |
1737 | "disabled\n"); | 1125 | "disabled\n"); |
1738 | #endif | 1126 | #endif |
1739 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " | 1127 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " |
1740 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1128 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1741 | "enabled\n"); | 1129 | "enabled\n"); |
1742 | #else | 1130 | #else |
1743 | "disabled\n"); | 1131 | "disabled\n"); |
1744 | #endif | 1132 | #endif |
1745 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " | 1133 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " |
1746 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING | 1134 | #ifdef CONFIG_IWLWIFI_DEVICE_TRACING |
1747 | "enabled\n"); | 1135 | "enabled\n"); |
1748 | #else | 1136 | #else |
1749 | "disabled\n"); | 1137 | "disabled\n"); |
1750 | #endif | 1138 | #endif |
1751 | 1139 | ||
1752 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " | 1140 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " |
1753 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE | 1141 | #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE |
1754 | "enabled\n"); | 1142 | "enabled\n"); |
1755 | #else | 1143 | #else |
1756 | "disabled\n"); | 1144 | "disabled\n"); |
1757 | #endif | 1145 | #endif |
1758 | dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P " | 1146 | dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P " |
1759 | #ifdef CONFIG_IWLWIFI_P2P | 1147 | #ifdef CONFIG_IWLWIFI_P2P |
1760 | "enabled\n"); | 1148 | "enabled\n"); |
1761 | #else | 1149 | #else |
@@ -1770,7 +1158,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1770 | struct iwl_priv *priv; | 1158 | struct iwl_priv *priv; |
1771 | struct ieee80211_hw *hw; | 1159 | struct ieee80211_hw *hw; |
1772 | u16 num_mac; | 1160 | u16 num_mac; |
1773 | u32 hw_rev; | ||
1774 | 1161 | ||
1775 | /************************ | 1162 | /************************ |
1776 | * 1. Allocating HW data | 1163 | * 1. Allocating HW data |
@@ -1783,22 +1170,14 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1783 | } | 1170 | } |
1784 | 1171 | ||
1785 | priv = hw->priv; | 1172 | priv = hw->priv; |
1786 | priv->shrd = &priv->_shrd; | 1173 | priv->shrd = bus->shrd; |
1787 | bus->shrd = priv->shrd; | ||
1788 | priv->shrd->bus = bus; | ||
1789 | priv->shrd->priv = priv; | 1174 | priv->shrd->priv = priv; |
1790 | 1175 | ||
1791 | priv->shrd->trans = trans_ops->alloc(priv->shrd); | ||
1792 | if (priv->shrd->trans == NULL) { | ||
1793 | err = -ENOMEM; | ||
1794 | goto out_free_traffic_mem; | ||
1795 | } | ||
1796 | |||
1797 | /* At this point both hw and priv are allocated. */ | 1176 | /* At this point both hw and priv are allocated. */ |
1798 | 1177 | ||
1799 | SET_IEEE80211_DEV(hw, bus(priv)->dev); | 1178 | SET_IEEE80211_DEV(hw, trans(priv)->dev); |
1800 | 1179 | ||
1801 | /* what debugging capabilities we have */ | 1180 | /* show what debugging capabilities we have */ |
1802 | iwl_debug_config(priv); | 1181 | iwl_debug_config(priv); |
1803 | 1182 | ||
1804 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); | 1183 | IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); |
@@ -1821,41 +1200,29 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1821 | /* these spin locks will be used in apm_ops.init and EEPROM access | 1200 | /* these spin locks will be used in apm_ops.init and EEPROM access |
1822 | * we should init now | 1201 | * we should init now |
1823 | */ | 1202 | */ |
1824 | spin_lock_init(&bus(priv)->reg_lock); | 1203 | spin_lock_init(&trans(priv)->reg_lock); |
1825 | spin_lock_init(&priv->shrd->lock); | 1204 | spin_lock_init(&priv->shrd->lock); |
1826 | 1205 | ||
1827 | /* | ||
1828 | * stop and reset the on-board processor just in case it is in a | ||
1829 | * strange state ... like being left stranded by a primary kernel | ||
1830 | * and this is now the kdump kernel trying to start up | ||
1831 | */ | ||
1832 | iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||
1833 | |||
1834 | /*********************** | 1206 | /*********************** |
1835 | * 3. Read REV register | 1207 | * 3. Read REV register |
1836 | ***********************/ | 1208 | ***********************/ |
1837 | hw_rev = iwl_hw_detect(priv); | ||
1838 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", | 1209 | IWL_INFO(priv, "Detected %s, REV=0x%X\n", |
1839 | cfg(priv)->name, hw_rev); | 1210 | cfg(priv)->name, trans(priv)->hw_rev); |
1840 | 1211 | ||
1841 | err = iwl_trans_request_irq(trans(priv)); | 1212 | err = iwl_trans_start_hw(trans(priv)); |
1842 | if (err) | 1213 | if (err) |
1843 | goto out_free_trans; | 1214 | goto out_free_traffic_mem; |
1844 | |||
1845 | if (iwl_trans_prepare_card_hw(trans(priv))) { | ||
1846 | err = -EIO; | ||
1847 | IWL_WARN(priv, "Failed, HW not ready\n"); | ||
1848 | goto out_free_trans; | ||
1849 | } | ||
1850 | 1215 | ||
1851 | /***************** | 1216 | /***************** |
1852 | * 4. Read EEPROM | 1217 | * 4. Read EEPROM |
1853 | *****************/ | 1218 | *****************/ |
1854 | /* Read the EEPROM */ | 1219 | /* Read the EEPROM */ |
1855 | err = iwl_eeprom_init(priv, hw_rev); | 1220 | err = iwl_eeprom_init(priv, trans(priv)->hw_rev); |
1221 | /* Reset chip to save power until we load uCode during "up". */ | ||
1222 | iwl_trans_stop_hw(trans(priv)); | ||
1856 | if (err) { | 1223 | if (err) { |
1857 | IWL_ERR(priv, "Unable to init EEPROM\n"); | 1224 | IWL_ERR(priv, "Unable to init EEPROM\n"); |
1858 | goto out_free_trans; | 1225 | goto out_free_traffic_mem; |
1859 | } | 1226 | } |
1860 | err = iwl_eeprom_check_version(priv); | 1227 | err = iwl_eeprom_check_version(priv); |
1861 | if (err) | 1228 | if (err) |
@@ -1903,22 +1270,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, | |||
1903 | iwl_setup_rx_handlers(priv); | 1270 | iwl_setup_rx_handlers(priv); |
1904 | iwl_testmode_init(priv); | 1271 | iwl_testmode_init(priv); |
1905 | 1272 | ||
1906 | /********************************************* | ||
1907 | * 8. Enable interrupts | ||
1908 | *********************************************/ | ||
1909 | |||
1910 | iwl_enable_rfkill_int(priv); | ||
1911 | |||
1912 | /* If platform's RF_KILL switch is NOT set to KILL */ | ||
1913 | if (iwl_read32(bus(priv), | ||
1914 | CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||
1915 | clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | ||
1916 | else | ||
1917 | set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); | ||
1918 | |||
1919 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | ||
1920 | test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); | ||
1921 | |||
1922 | iwl_power_initialize(priv); | 1273 | iwl_power_initialize(priv); |
1923 | iwl_tt_initialize(priv); | 1274 | iwl_tt_initialize(priv); |
1924 | 1275 | ||
@@ -1936,8 +1287,6 @@ out_destroy_workqueue: | |||
1936 | iwl_uninit_drv(priv); | 1287 | iwl_uninit_drv(priv); |
1937 | out_free_eeprom: | 1288 | out_free_eeprom: |
1938 | iwl_eeprom_free(priv->shrd); | 1289 | iwl_eeprom_free(priv->shrd); |
1939 | out_free_trans: | ||
1940 | iwl_trans_free(trans(priv)); | ||
1941 | out_free_traffic_mem: | 1290 | out_free_traffic_mem: |
1942 | iwl_free_traffic_mem(priv); | 1291 | iwl_free_traffic_mem(priv); |
1943 | ieee80211_free_hw(priv->hw); | 1292 | ieee80211_free_hw(priv->hw); |
@@ -1981,8 +1330,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) | |||
1981 | priv->shrd->workqueue = NULL; | 1330 | priv->shrd->workqueue = NULL; |
1982 | iwl_free_traffic_mem(priv); | 1331 | iwl_free_traffic_mem(priv); |
1983 | 1332 | ||
1984 | iwl_trans_free(trans(priv)); | ||
1985 | |||
1986 | iwl_uninit_drv(priv); | 1333 | iwl_uninit_drv(priv); |
1987 | 1334 | ||
1988 | dev_kfree_skb(priv->beacon_skb); | 1335 | dev_kfree_skb(priv->beacon_skb); |