From 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Feb 2013 16:01:34 +0100 Subject: iwlwifi: always copy first 16 bytes of commands The FH hardware will always write back to the scratch field in commands, even host commands not just TX commands, which can overwrite parts of the command. This is problematic if the command is re-used (with IWL_HCMD_DFL_NOCOPY) and can cause calibration issues. Address this problem by always putting at least the first 16 bytes into the buffer we also use for the command header and therefore make the DMA engine write back into this. For commands that are smaller than 16 bytes also always map enough memory for the DMA engine to write back to. Cc: stable@vger.kernel.org Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 10 ++-- drivers/net/wireless/iwlwifi/pcie/internal.h | 9 ++++ drivers/net/wireless/iwlwifi/pcie/tx.c | 75 +++++++++++++++++++++------- 3 files changed, 71 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 9a0f45ec9e01..10f01793d7a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data, TRACE_EVENT(iwlwifi_dev_hcmd, TP_PROTO(const struct device *dev, struct iwl_host_cmd *cmd, u16 total_size, - const void *hdr, size_t hdr_len), - TP_ARGS(dev, cmd, total_size, hdr, hdr_len), + struct iwl_cmd_header *hdr), + TP_ARGS(dev, cmd, total_size, hdr), TP_STRUCT__entry( DEV_ENTRY __dynamic_array(u8, hcmd, total_size) __field(u32, flags) ), TP_fast_assign( - int i, offset = hdr_len; + int i, offset = sizeof(*hdr); DEV_ASSIGN; __entry->flags = cmd->flags; - memcpy(__get_dynamic_array(hcmd), hdr, hdr_len); + memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; - if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) - continue; memcpy((u8 *)__get_dynamic_array(hcmd) + offset, cmd->data[i], cmd->len[i]); offset += cmd->len[i]; diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index aa2a39a637dd..3d62e8055352 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -182,6 +182,15 @@ struct iwl_queue { #define TFD_TX_CMD_SLOTS 256 #define TFD_CMD_SLOTS 32 +/* + * The FH will write back to the first TB only, so we need + * to copy some data into the buffer regardless of whether + * it should be mapped or not. This indicates how much to + * copy, even for HCMDs it must be big enough to fit the + * DRAM scratch from the TX cmd, at least 16 bytes. + */ +#define IWL_HCMD_MIN_COPY_SIZE 16 + struct iwl_pcie_txq_entry { struct iwl_device_cmd *cmd; struct iwl_device_cmd *copy_cmd; diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8e9e3212fe78..8b625a7f5685 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1152,10 +1152,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, void *dup_buf = NULL; dma_addr_t phys_addr; int idx; - u16 copy_size, cmd_size; + u16 copy_size, cmd_size, dma_size; bool had_nocopy = false; int i; u32 cmd_pos; + const u8 *cmddata[IWL_MAX_CMD_TFDS]; + u16 cmdlen[IWL_MAX_CMD_TFDS]; copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); @@ -1164,8 +1166,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + cmddata[i] = cmd->data[i]; + cmdlen[i] = cmd->len[i]; + if (!cmd->len[i]) continue; + + /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ + if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { + int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + + if (copy > cmdlen[i]) + copy = cmdlen[i]; + cmdlen[i] -= copy; + cmddata[i] += copy; + copy_size += copy; + } + if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { had_nocopy = true; if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { @@ -1185,7 +1202,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, goto free_dup_buf; } - dup_buf = kmemdup(cmd->data[i], cmd->len[i], + dup_buf = kmemdup(cmddata[i], cmdlen[i], GFP_ATOMIC); if (!dup_buf) return -ENOMEM; @@ -1195,7 +1212,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, idx = -EINVAL; goto free_dup_buf; } - copy_size += cmd->len[i]; + copy_size += cmdlen[i]; } cmd_size += cmd->len[i]; } @@ -1242,14 +1259,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* and copy the data that needs to be copied */ cmd_pos = offsetof(struct iwl_device_cmd, payload); + copy_size = sizeof(out_cmd->hdr); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { - if (!cmd->len[i]) + int copy = 0; + + if (!cmd->len) continue; - if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | - IWL_HCMD_DFL_DUP)) - break; - memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); - cmd_pos += cmd->len[i]; + + /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ + if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { + copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + + if (copy > cmd->len[i]) + copy = cmd->len[i]; + } + + /* copy everything if not nocopy/dup */ + if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | + IWL_HCMD_DFL_DUP))) + copy = cmd->len[i]; + + if (copy) { + memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy); + cmd_pos += copy; + copy_size += copy; + } } WARN_ON_ONCE(txq->entries[idx].copy_cmd); @@ -1275,7 +1309,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); - phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, + /* + * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must + * still map at least that many bytes for the hardware to write back to. + * We have enough space, so that's not a problem. + */ + dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE); + + phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size, DMA_BIDIRECTIONAL); if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { idx = -ENOMEM; @@ -1283,14 +1324,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, } dma_unmap_addr_set(out_meta, mapping, phys_addr); - dma_unmap_len_set(out_meta, len, copy_size); + dma_unmap_len_set(out_meta, len, dma_size); iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); + /* map the remaining (adjusted) nocopy/dup fragments */ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { - const void *data = cmd->data[i]; + const void *data = cmddata[i]; - if (!cmd->len[i]) + if (!cmdlen[i]) continue; if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | IWL_HCMD_DFL_DUP))) @@ -1298,7 +1340,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) data = dup_buf; phys_addr = dma_map_single(trans->dev, (void *)data, - cmd->len[i], DMA_BIDIRECTIONAL); + cmdlen[i], DMA_BIDIRECTIONAL); if (dma_mapping_error(trans->dev, phys_addr)) { iwl_pcie_tfd_unmap(trans, out_meta, &txq->tfds[q->write_ptr], @@ -1307,7 +1349,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, goto out; } - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0); } out_meta->flags = cmd->flags; @@ -1317,8 +1359,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, txq->need_update = 1; - trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, - &out_cmd->hdr, copy_size); + trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); /* start timer if queue currently empty */ if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) -- cgit v1.2.3 From 38a12b5b029dec6e6dad1b5d3269b4c356c44c0e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Feb 2013 14:07:56 +0100 Subject: iwlwifi: mvm: fix AP/GO mode station removal When stations are removed while packets are in the queue, we drain the queues first, and then remove the stations. If this happens in AP mode while the interface is removed the MAC context might be removed from the firmware before we removed the station(s), resulting in a SYSASSERT 3421. This is because we remove the MAC context from the FW in stop_ap(), but only flush the station drain work later in remove_interface(). Refactor the code a bit to have a common MAC context removal preparation first to solve this. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e8264e11b12d..7e169b085afe 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, return ret; } -static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, + struct ieee80211_vif *vif) { - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); u32 tfd_msk = 0, ac; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) @@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, */ flush_work(&mvm->sta_drained_wk); } +} + +static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + iwl_mvm_prepare_mac_removal(mvm, vif); mutex_lock(&mvm->mutex); /* * For AP/GO interface, the tear down of the resources allocated to the - * interface should be handled as part of the bss_info_changed flow. + * interface is be handled as part of the stop_ap flow. */ if (vif->type == NL80211_IFTYPE_AP) { iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); @@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + iwl_mvm_prepare_mac_removal(mvm, vif); + mutex_lock(&mvm->mutex); mvmvif->ap_active = false; -- cgit v1.2.3 From f444eb10d537c776ce82fbcd07733d75f45346f1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2013 12:04:18 +0100 Subject: iwlwifi: fix wakeup status query and packet reporting The wakeup packet in the status response is padded out to a multiple of 4 bytes by the firmware for transfer to the host, take that into account when checking the length of the command. Also, the reported wakeup packet includes the FCS but the userspace API doesn't, so remove that. If it is a data packet it is reported as an 802.3 packet but I forgot to take into account and remove the encryption head/tail, fix all of that as well. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/d3.c | 104 ++++++++++++++++++++++++--------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 ++ 2 files changed, 81 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index c64d864799cd..994c8c263dc0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -61,6 +61,7 @@ * *****************************************************************************/ +#include #include #include #include "iwl-modparams.h" @@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, sizeof(wkc), &wkc); data->error = ret != 0; + mvm->ptk_ivlen = key->iv_len; + mvm->ptk_icvlen = key->icv_len; + mvm->gtk_ivlen = key->iv_len; + mvm->gtk_icvlen = key->icv_len; + /* don't upload key again */ goto out_unlock; } @@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, */ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { key->hw_key_idx = 0; + mvm->ptk_ivlen = key->iv_len; + mvm->ptk_icvlen = key->icv_len; } else { data->gtk_key_idx++; key->hw_key_idx = data->gtk_key_idx; + mvm->gtk_ivlen = key->iv_len; + mvm->gtk_icvlen = key->icv_len; } ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); @@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* We reprogram keys and shouldn't allocate new key indices */ memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); + mvm->ptk_ivlen = 0; + mvm->ptk_icvlen = 0; + mvm->ptk_ivlen = 0; + mvm->ptk_icvlen = 0; + /* * The D3 firmware still hardcodes the AP station ID for the * BSS we're associated with as 0. As a result, we have to move @@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, struct iwl_wowlan_status *status; u32 reasons; int ret, len; - bool pkt8023 = false; struct sk_buff *pkt = NULL; iwl_trans_read_mem_bytes(mvm->trans, base, @@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, status = (void *)cmd.resp_pkt->data; if (len - sizeof(struct iwl_cmd_header) != - sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { + sizeof(*status) + + ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) { IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); goto out; } @@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, goto report; } - if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) wakeup.magic_pkt = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) wakeup.pattern_idx = le16_to_cpu(status->pattern_number); - pkt8023 = true; - } if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) wakeup.disconnect = true; - if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) wakeup.gtk_rekey_failure = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) wakeup.rfkill_release = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) wakeup.eap_identity_req = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) wakeup.four_way_handshake = true; - pkt8023 = true; - } if (status->wake_packet_bufsize) { - u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); - u32 pktlen = le32_to_cpu(status->wake_packet_length); + int pktsize = le32_to_cpu(status->wake_packet_bufsize); + int pktlen = le32_to_cpu(status->wake_packet_length); + const u8 *pktdata = status->wake_packet; + struct ieee80211_hdr *hdr = (void *)pktdata; + int truncated = pktlen - pktsize; + + /* this would be a firmware bug */ + if (WARN_ON_ONCE(truncated < 0)) + truncated = 0; + + if (ieee80211_is_data(hdr->frame_control)) { + int hdrlen = ieee80211_hdrlen(hdr->frame_control); + int ivlen = 0, icvlen = 4; /* also FCS */ - if (pkt8023) { pkt = alloc_skb(pktsize, GFP_KERNEL); if (!pkt) goto report; - memcpy(skb_put(pkt, pktsize), status->wake_packet, - pktsize); + + memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen); + pktdata += hdrlen; + pktsize -= hdrlen; + + if (ieee80211_has_protected(hdr->frame_control)) { + if (is_multicast_ether_addr(hdr->addr1)) { + ivlen = mvm->gtk_ivlen; + icvlen += mvm->gtk_icvlen; + } else { + ivlen = mvm->ptk_ivlen; + icvlen += mvm->ptk_icvlen; + } + } + + /* if truncated, FCS/ICV is (partially) gone */ + if (truncated >= icvlen) { + icvlen = 0; + truncated -= icvlen; + } else { + icvlen -= truncated; + truncated = 0; + } + + pktsize -= ivlen + icvlen; + pktdata += ivlen; + + memcpy(skb_put(pkt, pktsize), pktdata, pktsize); + if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) goto report; wakeup.packet = pkt->data; wakeup.packet_present_len = pkt->len; - wakeup.packet_len = pkt->len - (pktlen - pktsize); + wakeup.packet_len = pkt->len - truncated; wakeup.packet_80211 = false; } else { + int fcslen = 4; + + if (truncated >= 4) { + truncated -= 4; + fcslen = 0; + } else { + fcslen -= truncated; + truncated = 0; + } + pktsize -= fcslen; wakeup.packet = status->wake_packet; wakeup.packet_present_len = pktsize; - wakeup.packet_len = pktlen; + wakeup.packet_len = pktlen - truncated; wakeup.packet_80211 = true; } } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 4e339ccfa800..537711b10478 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -327,6 +327,10 @@ struct iwl_mvm { struct led_classdev led; struct ieee80211_vif *p2p_device_vif; + +#ifdef CONFIG_PM_SLEEP + int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; +#endif }; /* Extract MVM priv from op_mode and _hw */ -- cgit v1.2.3 From e477598351a40769f5b46ccea78479a1aad6f161 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Tue, 12 Feb 2013 09:49:00 +0200 Subject: iwlwifi: mvm: Remove testing of static PIC in PhyDB The PIC was supposed to be a small signature appended to the PhyDB data, but the signature isn't really static and thus attempting to check it just causes the warnings spuriously so remove them. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 14fc8d39fc28..3392011a8768 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db { u8 data[]; } __packed; -#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587) -static inline void iwl_phy_db_test_pic(__le32 pic) -{ - WARN_ON(IWL_PHY_DB_STATIC_PIC != pic); -} - struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) { struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), @@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; } - /* Test PIC */ - if (type != IWL_PHY_DB_CFG) - iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) + - (size / sizeof(__le32)) - 1)); - IWL_DEBUG_INFO(phy_db->trans, "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", __func__, __LINE__, type, size); @@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, *size = entry->size; } - /* Test PIC */ - if (type != IWL_PHY_DB_CFG) - iwl_phy_db_test_pic(*(((__le32 *)*data) + - (*size / sizeof(__le32)) - 1)); - IWL_DEBUG_INFO(phy_db->trans, "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", __func__, __LINE__, type, *size); -- cgit v1.2.3 From 98891754ea9453de4db9111c91b20122ca330101 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2013 11:28:19 +0100 Subject: iwlwifi: don't map complete commands bidirectionally The reason we mapped them bidirectionally was that not doing so had caused IOMMU exceptions, due to the fact that the HW writes back into the command. Now that the first part of the command including the write-back part is always in the first buffer, we don't need to map the remaining buffer(s) bidi and can get rid of the special-casing for commands. This is a requisite patch for another one to fix DMA mapping. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8b625a7f5685..975492f0b8c8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -367,8 +367,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd) } static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, - struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, - enum dma_data_direction dma_dir) + struct iwl_cmd_meta *meta, + struct iwl_tfd *tfd) { int i; int num_tbs; @@ -392,7 +392,8 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), - iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); + iwl_pcie_tfd_tb_get_len(tfd, i), + DMA_TO_DEVICE); tfd->num_tbs = 0; } @@ -406,8 +407,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, - enum dma_data_direction dma_dir) +static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) { struct iwl_tfd *tfd_tmp = txq->tfds; @@ -418,8 +418,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, lockdep_assert_held(&txq->lock); /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ - iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], - dma_dir); + iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]); /* free SKB */ if (txq->entries) { @@ -565,22 +564,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; - enum dma_data_direction dma_dir; if (!q->n_bd) return; - /* In the command queue, all the TBs are mapped as BIDI - * so unmap them as such. - */ - if (txq_id == trans_pcie->cmd_queue) - dma_dir = DMA_BIDIRECTIONAL; - else - dma_dir = DMA_TO_DEVICE; - spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - iwl_pcie_txq_free_tfd(trans, txq, dma_dir); + iwl_pcie_txq_free_tfd(trans, txq); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); @@ -962,7 +952,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); - iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); + iwl_pcie_txq_free_tfd(trans, txq); } iwl_pcie_txq_progress(trans_pcie, txq); @@ -1340,11 +1330,10 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) data = dup_buf; phys_addr = dma_map_single(trans->dev, (void *)data, - cmdlen[i], DMA_BIDIRECTIONAL); + cmdlen[i], DMA_TO_DEVICE); if (dma_mapping_error(trans->dev, phys_addr)) { iwl_pcie_tfd_unmap(trans, out_meta, - &txq->tfds[q->write_ptr], - DMA_BIDIRECTIONAL); + &txq->tfds[q->write_ptr]); idx = -ENOMEM; goto out; } @@ -1418,7 +1407,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, cmd = txq->entries[cmd_index].cmd; meta = &txq->entries[cmd_index].meta; - iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); + iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]); /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { -- cgit v1.2.3 From 1afbfb6041fb8f639e742620ad933c347e14ba2c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2013 11:32:26 +0100 Subject: iwlwifi: rename IWL_MAX_CMD_TFDS to IWL_MAX_CMD_TBS_PER_TFD The IWL_MAX_CMD_TFDS name for this constant is wrong, the constant really indicates how many TBs we can use in the driver for a single command TFD, rename the constant and also add a comment explaining it. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 12 ++++++++---- drivers/net/wireless/iwlwifi/pcie/tx.c | 12 ++++++------ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 10f01793d7a6..81aa91fab5aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -363,7 +363,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd, __entry->flags = cmd->flags; memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { if (!cmd->len[i]) continue; memcpy((u8 *)__get_dynamic_array(hcmd) + offset, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 8c7bec6b9a0b..058947f213b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -217,7 +217,11 @@ struct iwl_device_cmd { #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) -#define IWL_MAX_CMD_TFDS 2 +/* + * number of transfer buffers (fragments) per transmit frame descriptor; + * this is just the driver's idea, the hardware supports 20 + */ +#define IWL_MAX_CMD_TBS_PER_TFD 2 /** * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command @@ -254,15 +258,15 @@ enum iwl_hcmd_dataflag { * @id: id of the host command */ struct iwl_host_cmd { - const void *data[IWL_MAX_CMD_TFDS]; + const void *data[IWL_MAX_CMD_TBS_PER_TFD]; struct iwl_rx_packet *resp_pkt; unsigned long _rx_page_addr; u32 _rx_page_order; int handler_status; u32 flags; - u16 len[IWL_MAX_CMD_TFDS]; - u8 dataflags[IWL_MAX_CMD_TFDS]; + u16 len[IWL_MAX_CMD_TBS_PER_TFD]; + u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD]; u8 id; }; diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 975492f0b8c8..ff80a7e55f00 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1146,16 +1146,16 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, bool had_nocopy = false; int i; u32 cmd_pos; - const u8 *cmddata[IWL_MAX_CMD_TFDS]; - u16 cmdlen[IWL_MAX_CMD_TFDS]; + const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; + u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); /* need one for the header if the first is NOCOPY */ - BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); + BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1); - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { cmddata[i] = cmd->data[i]; cmdlen[i] = cmd->len[i]; @@ -1250,7 +1250,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* and copy the data that needs to be copied */ cmd_pos = offsetof(struct iwl_device_cmd, payload); copy_size = sizeof(out_cmd->hdr); - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { int copy = 0; if (!cmd->len) @@ -1319,7 +1319,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); /* map the remaining (adjusted) nocopy/dup fragments */ - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { const void *data = cmddata[i]; if (!cmdlen[i]) -- cgit v1.2.3 From aed7d9ac1836defe033b561f4306e39014ac56fd Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 20 Feb 2013 11:33:00 +0200 Subject: iwlwifi: disable 8K A-MSDU by default Supporting 8K A-MSDU means that we need to allocate order 1 pages for every Rx packet. Even when there is no traffic. This adds stress on the memory manager. The handling of compound pages is also less trivial for the memory manager and not using them will make the allocation code run faster although I didn't really measure. Eric also pointed out that having huge buffers with little data in them is not very nice towards the TCP stack since the truesize of the skb is huge. This doesn't allow TCP to have a big Rx window. See https://patchwork.kernel.org/patch/2167711/ for details. Note that very few vendors will actually send A-MSDU. Disable this feature by default. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-drv.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 6f228bb2b844..fbfd2d137117 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1102,7 +1102,6 @@ void iwl_drv_stop(struct iwl_drv *drv) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { - .amsdu_size_8K = 1, .restart_fw = 1, .plcp_check = true, .bt_coex_active = true, @@ -1207,7 +1206,7 @@ MODULE_PARM_DESC(11n_disable, "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, int, S_IRUGO); -MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); +MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index e5e3a79eae2f..2c2a729092f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -91,7 +91,7 @@ enum iwl_power_level { * @sw_crypto: using hardware encryption, default = 0 * @disable_11n: disable 11n capabilities, default = 0, * use IWL_DISABLE_HT_* constants - * @amsdu_size_8K: enable 8K amsdu size, default = 1 + * @amsdu_size_8K: enable 8K amsdu size, default = 0 * @restart_fw: restart firmware, default = 1 * @plcp_check: enable plcp health check, default = true * @wd_disable: enable stuck queue check, default = 0 -- cgit v1.2.3 From 38c0f334b359953f010e9b921e0b55278d3918f7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Feb 2013 13:18:50 +0100 Subject: iwlwifi: use coherent DMA memory for command header Recently in commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 ("iwlwifi: always copy first 16 bytes of commands") we fixed the problem that the hardware writes back to the command and that could overwrite parts of the data that was still needed and would thus be corrupted. Investigating this problem more closely we found that this write-back isn't really ordered very well with respect to other DMA traffic. Therefore, it sometimes happened that the write-back occurred after unmapping the command again which is clearly an issue and could corrupt the next allocation that goes to that spot, or (better) cause IOMMU faults. To fix this, allocate coherent memory for the first 16 bytes of each command, containing the write-back part, and use it for all queues. All the dynamic DMA mappings only need to be TO_DEVICE then. This ensures that even when the write-back happens "too late" it can't hit memory that has been freed or a mapping that doesn't exist any more. Since now the actual command is no longer modified, we can also remove CMD_WANT_HCMD and get rid of the DMA sync that was necessary to update the scratch pointer. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 +- drivers/net/wireless/iwlwifi/pcie/internal.h | 34 +++-- drivers/net/wireless/iwlwifi/pcie/rx.c | 14 +- drivers/net/wireless/iwlwifi/pcie/tx.c | 221 +++++++++++++-------------- 5 files changed, 137 insertions(+), 142 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index 94ef33838bc6..b775769f8322 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); if (!(flags & CMD_ASYNC)) { - cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; + cmd.flags |= CMD_WANT_SKB; might_sleep(); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 058947f213b2..0cac2b7af78b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -186,19 +186,13 @@ struct iwl_rx_packet { * @CMD_ASYNC: Return right away and don't want for the response * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the * response. The caller needs to call iwl_free_resp when done. - * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the - * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be - * copied. The pointer passed to the response handler is in the transport - * ownership and don't need to be freed by the op_mode. This also means - * that the pointer is invalidated after the op_mode's handler returns. * @CMD_ON_DEMAND: This command is sent by the test mode pipe. */ enum CMD_MODE { CMD_SYNC = 0, CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), - CMD_WANT_HCMD = BIT(2), - CMD_ON_DEMAND = BIT(3), + CMD_ON_DEMAND = BIT(2), }; #define DEF_CMD_PAYLOAD_SIZE 320 diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 3d62e8055352..148843e7f34f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) struct iwl_cmd_meta { /* only for SYNC commands, iff the reply skb is wanted */ struct iwl_host_cmd *source; - - DEFINE_DMA_UNMAP_ADDR(mapping); - DEFINE_DMA_UNMAP_LEN(len); - u32 flags; }; @@ -185,25 +181,36 @@ struct iwl_queue { /* * The FH will write back to the first TB only, so we need * to copy some data into the buffer regardless of whether - * it should be mapped or not. This indicates how much to - * copy, even for HCMDs it must be big enough to fit the - * DRAM scratch from the TX cmd, at least 16 bytes. + * it should be mapped or not. This indicates how big the + * first TB must be to include the scratch buffer. Since + * the scratch is 4 bytes at offset 12, it's 16 now. If we + * make it bigger then allocations will be bigger and copy + * slower, so that's probably not useful. */ -#define IWL_HCMD_MIN_COPY_SIZE 16 +#define IWL_HCMD_SCRATCHBUF_SIZE 16 struct iwl_pcie_txq_entry { struct iwl_device_cmd *cmd; - struct iwl_device_cmd *copy_cmd; struct sk_buff *skb; /* buffer to free after command completes */ const void *free_buf; struct iwl_cmd_meta meta; }; +struct iwl_pcie_txq_scratch_buf { + struct iwl_cmd_header hdr; + u8 buf[8]; + __le32 scratch; +}; + /** * struct iwl_txq - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor * @tfds: transmit frame descriptors (DMA memory) + * @scratchbufs: start of command headers, including scratch buffers, for + * the writeback -- this is DMA memory and an array holding one buffer + * for each command on the queue + * @scratchbufs_dma: DMA address for the scratchbufs start * @entries: transmit entries (driver state) * @lock: queue lock * @stuck_timer: timer that fires if queue gets stuck @@ -217,6 +224,8 @@ struct iwl_pcie_txq_entry { struct iwl_txq { struct iwl_queue q; struct iwl_tfd *tfds; + struct iwl_pcie_txq_scratch_buf *scratchbufs; + dma_addr_t scratchbufs_dma; struct iwl_pcie_txq_entry *entries; spinlock_t lock; struct timer_list stuck_timer; @@ -225,6 +234,13 @@ struct iwl_txq { u8 active; }; +static inline dma_addr_t +iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) +{ + return txq->scratchbufs_dma + + sizeof(struct iwl_pcie_txq_scratch_buf) * idx; +} + /** * struct iwl_trans_pcie - PCIe transport specific data * @rxq: all the RX queue data diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index b0ae06d2456f..567e67ad1f61 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, index = SEQ_TO_INDEX(sequence); cmd_index = get_cmd_index(&txq->q, index); - if (reclaim) { - struct iwl_pcie_txq_entry *ent; - ent = &txq->entries[cmd_index]; - cmd = ent->copy_cmd; - WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); - } else { + if (reclaim) + cmd = txq->entries[cmd_index].cmd; + else cmd = NULL; - } err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); if (reclaim) { - /* The original command isn't needed any more */ - kfree(txq->entries[cmd_index].copy_cmd); - txq->entries[cmd_index].copy_cmd = NULL; - /* nor is the duplicated part of the command */ kfree(txq->entries[cmd_index].free_buf); txq->entries[cmd_index].free_buf = NULL; } diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index ff80a7e55f00..8595c16f74de 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) } for (i = q->read_ptr; i != q->write_ptr; - i = iwl_queue_inc_wrap(i, q->n_bd)) { - struct iwl_tx_cmd *tx_cmd = - (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; + i = iwl_queue_inc_wrap(i, q->n_bd)) IWL_ERR(trans, "scratch %d = 0x%08x\n", i, - get_unaligned_le32(&tx_cmd->scratch)); - } + le32_to_cpu(txq->scratchbufs[i].scratch)); iwl_op_mode_nic_error(trans->op_mode); } @@ -382,14 +379,8 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, return; } - /* Unmap tx_cmd */ - if (num_tbs) - dma_unmap_single(trans->dev, - dma_unmap_addr(meta, mapping), - dma_unmap_len(meta, len), - DMA_BIDIRECTIONAL); + /* first TB is never freed - it's the scratchbuf data */ - /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), iwl_pcie_tfd_tb_get_len(tfd, i), @@ -478,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; + size_t scratchbuf_sz; int i; if (WARN_ON(txq->entries || txq->tfds)) @@ -513,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); goto error; } + + BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs)); + BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) != + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch)); + + scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num; + + txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz, + &txq->scratchbufs_dma, + GFP_KERNEL); + if (!txq->scratchbufs) + goto err_free_tfds; + txq->q.id = txq_id; return 0; +err_free_tfds: + dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr); error: if (txq->entries && txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) @@ -600,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < txq->q.n_window; i++) { kfree(txq->entries[i].cmd); - kfree(txq->entries[i].copy_cmd); kfree(txq->entries[i].free_buf); } @@ -609,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) dma_free_coherent(dev, sizeof(struct iwl_tfd) * txq->q.n_bd, txq->tfds, txq->q.dma_addr); txq->q.dma_addr = 0; + + dma_free_coherent(dev, + sizeof(*txq->scratchbufs) * txq->q.n_window, + txq->scratchbufs, txq->scratchbufs_dma); } kfree(txq->entries); @@ -1142,7 +1153,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, void *dup_buf = NULL; dma_addr_t phys_addr; int idx; - u16 copy_size, cmd_size, dma_size; + u16 copy_size, cmd_size, scratch_size; bool had_nocopy = false; int i; u32 cmd_pos; @@ -1162,9 +1173,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (!cmd->len[i]) continue; - /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ - if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { - int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ + if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { + int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; if (copy > cmdlen[i]) copy = cmdlen[i]; @@ -1256,9 +1267,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (!cmd->len) continue; - /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ - if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { - copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ + if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { + copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; if (copy > cmd->len[i]) copy = cmd->len[i]; @@ -1276,48 +1287,36 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, } } - WARN_ON_ONCE(txq->entries[idx].copy_cmd); - - /* - * since out_cmd will be the source address of the FH, it will write - * the retry count there. So when the user needs to receivce the HCMD - * that corresponds to the response in the response handler, it needs - * to set CMD_WANT_HCMD. - */ - if (cmd->flags & CMD_WANT_HCMD) { - txq->entries[idx].copy_cmd = - kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); - if (unlikely(!txq->entries[idx].copy_cmd)) { - idx = -ENOMEM; - goto out; - } - } - IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", get_cmd_string(trans_pcie, out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); - /* - * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must - * still map at least that many bytes for the hardware to write back to. - * We have enough space, so that's not a problem. - */ - dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE); + /* start the TFD with the scratchbuf */ + scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE); + memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size); + iwl_pcie_txq_build_tfd(trans, txq, + iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr), + scratch_size, 1); + + /* map first command fragment, if any remains */ + if (copy_size > scratch_size) { + phys_addr = dma_map_single(trans->dev, + ((u8 *)&out_cmd->hdr) + scratch_size, + copy_size - scratch_size, + DMA_TO_DEVICE); + if (dma_mapping_error(trans->dev, phys_addr)) { + iwl_pcie_tfd_unmap(trans, out_meta, + &txq->tfds[q->write_ptr]); + idx = -ENOMEM; + goto out; + } - phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { - idx = -ENOMEM; - goto out; + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, + copy_size - scratch_size, 0); } - dma_unmap_addr_set(out_meta, mapping, phys_addr); - dma_unmap_len_set(out_meta, len, dma_size); - - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); - /* map the remaining (adjusted) nocopy/dup fragments */ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { const void *data = cmddata[i]; @@ -1586,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_cmd_meta *out_meta; struct iwl_txq *txq; struct iwl_queue *q; - dma_addr_t phys_addr = 0; - dma_addr_t txcmd_phys; - dma_addr_t scratch_phys; - u16 len, firstlen, secondlen; + dma_addr_t tb0_phys, tb1_phys, scratch_phys; + void *tb1_addr; + u16 len, tb1_len, tb2_len; u8 wait_write_ptr = 0; __le16 fc = hdr->frame_control; u8 hdr_len = ieee80211_hdrlen(fc); @@ -1627,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | INDEX_TO_SEQ(q->write_ptr))); + tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr); + scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch); + + tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); + tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); + /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_meta = &txq->entries[q->write_ptr].meta; /* - * Use the first empty entry in this queue's command buffer array - * to contain the Tx command and MAC header concatenated together - * (payload data will be in another buffer). - * Size of this varies, due to varying MAC header length. - * If end is not dword aligned, we'll have 2 extra bytes at the end - * of the MAC header (device reads on dword boundaries). - * We'll tell device about this padding later. + * The second TB (tb1) points to the remainder of the TX command + * and the 802.11 header - dword aligned size + * (This calculation modifies the TX command, so do it before the + * setup of the first TB) */ - len = sizeof(struct iwl_tx_cmd) + - sizeof(struct iwl_cmd_header) + hdr_len; - firstlen = (len + 3) & ~3; + len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + + hdr_len - IWL_HCMD_SCRATCHBUF_SIZE; + tb1_len = (len + 3) & ~3; /* Tell NIC about any 2-byte padding after MAC header */ - if (firstlen != len) + if (tb1_len != len) tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; - /* Physical address of this Tx command's header (not MAC header!), - * within command buffer array. */ - txcmd_phys = dma_map_single(trans->dev, - &dev_cmd->hdr, firstlen, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) - goto out_err; - dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, firstlen); + /* The first TB points to the scratchbuf data - min_copy bytes */ + memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr, + IWL_HCMD_SCRATCHBUF_SIZE); + iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, + IWL_HCMD_SCRATCHBUF_SIZE, 1); - if (!ieee80211_has_morefrags(fc)) { - txq->need_update = 1; - } else { - wait_write_ptr = 1; - txq->need_update = 0; - } + /* there must be data left over for TB1 or this code must be changed */ + BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE); + + /* map the data for TB1 */ + tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE; + tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, tb1_phys))) + goto out_err; + iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0); - /* Set up TFD's 2nd entry to point directly to remainder of skb, - * if any (802.11 null frames have no payload). */ - secondlen = skb->len - hdr_len; - if (secondlen > 0) { - phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, - secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { - dma_unmap_single(trans->dev, - dma_unmap_addr(out_meta, mapping), - dma_unmap_len(out_meta, len), - DMA_BIDIRECTIONAL); + /* + * Set up TFD's third entry to point directly to remainder + * of skb, if any (802.11 null frames have no payload). + */ + tb2_len = skb->len - hdr_len; + if (tb2_len > 0) { + dma_addr_t tb2_phys = dma_map_single(trans->dev, + skb->data + hdr_len, + tb2_len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) { + iwl_pcie_tfd_unmap(trans, out_meta, + &txq->tfds[q->write_ptr]); goto out_err; } + iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0); } - /* Attach buffers to TFD */ - iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); - if (secondlen > 0) - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); - - scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch); - - /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); - tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); - tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); - /* Set up entry for this TFD in Tx byte-count array */ iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); - dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); - trace_iwlwifi_dev_tx(trans->dev, skb, &txq->tfds[txq->q.write_ptr], sizeof(struct iwl_tfd), - &dev_cmd->hdr, firstlen, - skb->data + hdr_len, secondlen); + &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len, + skb->data + hdr_len, tb2_len); trace_iwlwifi_dev_tx_data(trans->dev, skb, - skb->data + hdr_len, secondlen); + skb->data + hdr_len, tb2_len); + + if (!ieee80211_has_morefrags(fc)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } /* start timer if queue currently empty */ if (txq->need_update && q->read_ptr == q->write_ptr && -- cgit v1.2.3 From 715c998ff4d1106c3096bc5a48e4196663e6701a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 28 Feb 2013 08:57:31 +0200 Subject: iwlwifi: mvm: restart the NIC of the cmd queue gets full This situation is clearly an error situation and the only way to recover is to restart the driver / fw. Signed-off-by: Emmanuel Grumbach Reviewed-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/ops.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index aa59adf87db3..d0f9c1e0475e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -624,12 +624,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) ieee80211_free_txskb(mvm->hw, skb); } -static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) +static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) { - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - - iwl_mvm_dump_nic_error_log(mvm); - iwl_abort_notification_waits(&mvm->notif_wait); /* @@ -663,9 +659,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) } } +static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) +{ + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); + + iwl_mvm_dump_nic_error_log(mvm); + + iwl_mvm_nic_restart(mvm); +} + static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) { + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); + WARN_ON(1); + iwl_mvm_nic_restart(mvm); } static const struct iwl_op_mode_ops iwl_mvm_ops = { -- cgit v1.2.3 From e07cbb536acb249db5fd63f6884354630ae875ad Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 23:00:27 +0200 Subject: iwlwifi: mvm: Set valid TX antennas value before calib request We must set the valid TX antennas number in the ucode before sending the phy_cfg_cmd and request for calibrations. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index d3d959db03a9..e6d51a9069c9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -446,6 +446,11 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); WARN_ON(ret); + /* Send TX valid antennas before triggering calibrations */ + ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); + if (ret) + goto error; + /* Override the calibrations from TLV and the const of fw */ iwl_set_default_calib_trigger(mvm); -- cgit v1.2.3 From 6221d47cf7a57eb1e2b5b51c65e2edcde369a0d4 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 15:55:48 +0200 Subject: iwlwifi: mvm: Take the phy_cfg from the TLV value The phy_cfg is given from the TLV value and does not have to be built by us. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index e6d51a9069c9..d3c067e670a8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -241,20 +241,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, return 0; } -#define IWL_HW_REV_ID_RAINBOW 0x2 -#define IWL_PROJ_TYPE_LHP 0x5 - -static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm) -{ - struct iwl_nvm_data *data = mvm->nvm_data; - /* Temp calls to static definitions, will be changed to CSR calls */ - u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW; - u8 project_type = IWL_PROJ_TYPE_LHP; - - return data->radio_cfg_dash | (data->radio_cfg_step << 2) | - (hw_rev_id << 4) | ((project_type & 0x7f) << 6) | - (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20); -} static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) { @@ -262,7 +248,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) enum iwl_ucode_type ucode_type = mvm->cur_ucode; /* Set parameters */ - phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); + phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config); phy_cfg_cmd.calib_control.event_trigger = mvm->fw->default_calib[ucode_type].event_trigger; phy_cfg_cmd.calib_control.flow_trigger = -- cgit v1.2.3 From de8bc6dd2d52cacaa76ea381ffdc00919b100a2c Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 13:01:09 +0200 Subject: iwlwifi: mvm: Remove overriding calibrations for the 7000 family This fix removes the override of calibration request values sent to the FW. Due to that, the sending of default values to now implemented calibrations is removed. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 114 ---------------------------------- 1 file changed, 114 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index d3c067e670a8..500f818dba04 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -79,17 +79,8 @@ #define UCODE_VALID_OK cpu_to_le32(0x1) /* Default calibration values for WkP - set to INIT image w/o running */ -static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f, - 0x00, 0x18, 0x00 }; -static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f }; -static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 }; -static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00, - 0x00 }; -static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 }; static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; -static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 }; struct iwl_calib_default_data { u16 size; @@ -99,12 +90,7 @@ struct iwl_calib_default_data { #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} static const struct iwl_calib_default_data wkp_calib_default_data[12] = { - [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc), - [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter), - [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo), - [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq), [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), - [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq), [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), }; @@ -261,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) sizeof(phy_cfg_cmd), &phy_cfg_cmd); } -/* Starting with the new PHY DB implementation - New calibs are enabled */ -/* Value - 0x405e7 */ -#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\ - IWL_CALIB_CFG_TEMPERATURE_IDX |\ - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ - IWL_CALIB_CFG_DC_IDX |\ - IWL_CALIB_CFG_BB_FILTER_IDX |\ - IWL_CALIB_CFG_LO_LEAKAGE_IDX |\ - IWL_CALIB_CFG_TX_IQ_IDX |\ - IWL_CALIB_CFG_RX_IQ_IDX |\ - IWL_CALIB_CFG_AGC_IDX) - -#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0 - -/* Value 0x41567 */ -#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\ - IWL_CALIB_CFG_TEMPERATURE_IDX |\ - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ - IWL_CALIB_CFG_BB_FILTER_IDX |\ - IWL_CALIB_CFG_DC_IDX |\ - IWL_CALIB_CFG_TX_IQ_IDX |\ - IWL_CALIB_CFG_RX_IQ_IDX |\ - IWL_CALIB_CFG_SENSITIVITY_IDX |\ - IWL_CALIB_CFG_AGC_IDX) - -#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\ - IWL_CALIB_CFG_TEMPERATURE_IDX |\ - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ - IWL_CALIB_CFG_TX_PWR_IDX |\ - IWL_CALIB_CFG_DC_IDX |\ - IWL_CALIB_CFG_TX_IQ_IDX |\ - IWL_CALIB_CFG_SENSITIVITY_IDX) - -/* - * Sets the calibrations trigger values that will be sent to the FW for runtime - * and init calibrations. - * The ones given in the FW TLV are not correct. - */ -static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm) -{ - struct iwl_tlv_calib_ctrl default_calib; - - /* - * WkP FW TLV calib bits are wrong, overwrite them. - * This defines the dynamic calibrations which are implemented in the - * uCode both for init(flow) calculation and event driven calibs. - */ - - /* Init Image */ - default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT); - default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT); - - if (default_calib.event_trigger != - mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger) - IWL_ERR(mvm, - "Updating the event calib for INIT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger, - default_calib.event_trigger); - if (default_calib.flow_trigger != - mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger) - IWL_ERR(mvm, - "Updating the flow calib for INIT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger, - default_calib.flow_trigger); - - memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT], - &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); - IWL_ERR(mvm, - "Setting uCode init calibrations event 0x%x, trigger 0x%x\n", - default_calib.event_trigger, - default_calib.flow_trigger); - - /* Run time image */ - default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN); - default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN); - - if (default_calib.event_trigger != - mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger) - IWL_ERR(mvm, - "Updating the event calib for RT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger, - default_calib.event_trigger); - if (default_calib.flow_trigger != - mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger) - IWL_ERR(mvm, - "Updating the flow calib for RT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger, - default_calib.flow_trigger); - - memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR], - &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); - IWL_ERR(mvm, - "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n", - default_calib.event_trigger, - default_calib.flow_trigger); -} - static int iwl_set_default_calibrations(struct iwl_mvm *mvm) { u8 cmd_raw[16]; /* holds the variable size commands */ @@ -437,9 +326,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) if (ret) goto error; - /* Override the calibrations from TLV and the const of fw */ - iwl_set_default_calib_trigger(mvm); - /* WkP doesn't have all calibrations, need to set default values */ if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { ret = iwl_set_default_calibrations(mvm); -- cgit v1.2.3 From f9aa8dd33714f17c7229ad89309406a1ccb3cd3f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 4 Mar 2013 09:11:08 +0200 Subject: iwlwifi: mvm: ignore STOP_AGG when restarting Since the device is being restarted, all the Rx / Tx Block Ack sessions are been wiped out by the driver. So ignore the requests from mac80211 that stops Tx agg while reconfiguring the device. Note that stopping a non-existing Rx BA session is harmless, so just honor mac80211's request. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/sta.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 861a7f9f8e7f..274f44e2ef60 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -770,6 +770,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u16 txq_id; int err; + + /* + * If mac80211 is cleaning its state, then say that we finished since + * our state has been cleared anyway. + */ + if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + return 0; + } + spin_lock_bh(&mvmsta->lock); txq_id = tid_data->txq_id; -- cgit v1.2.3 From 8101a7f0656bf11c385d6e14f52313b19f017e70 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 28 Feb 2013 11:54:28 +0200 Subject: iwlwifi: mvm: update the rssi calculation Make the rssi more accurate by taking in count per-chain AGC values. Without this, the RSSI reports inaccurate values. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 18 ++++++++------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 ++- drivers/net/wireless/iwlwifi/mvm/rx.c | 37 +++++++++++++++++++------------ 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 23eebda848b0..2adb61f103f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -762,18 +762,20 @@ struct iwl_phy_context_cmd { #define IWL_RX_INFO_PHY_CNT 8 #define IWL_RX_INFO_AGC_IDX 1 #define IWL_RX_INFO_RSSI_AB_IDX 2 -#define IWL_RX_INFO_RSSI_C_IDX 3 -#define IWL_OFDM_AGC_DB_MSK 0xfe00 -#define IWL_OFDM_AGC_DB_POS 9 +#define IWL_OFDM_AGC_A_MSK 0x0000007f +#define IWL_OFDM_AGC_A_POS 0 +#define IWL_OFDM_AGC_B_MSK 0x00003f80 +#define IWL_OFDM_AGC_B_POS 7 +#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000 +#define IWL_OFDM_AGC_CODE_POS 20 #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff -#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 #define IWL_OFDM_RSSI_A_POS 0 +#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 +#define IWL_OFDM_RSSI_ALLBAND_A_POS 8 #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 -#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 #define IWL_OFDM_RSSI_B_POS 16 -#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff -#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 -#define IWL_OFDM_RSSI_C_POS 0 +#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 +#define IWL_OFDM_RSSI_ALLBAND_B_POS 24 /** * struct iwl_rx_phy_info - phy info diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 537711b10478..bdae700c769e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -80,7 +80,8 @@ #define IWL_INVALID_MAC80211_QUEUE 0xff #define IWL_MVM_MAX_ADDRESSES 2 -#define IWL_RSSI_OFFSET 44 +/* RSSI offset for WkP */ +#define IWL_RSSI_OFFSET 50 enum iwl_mvm_tx_fifo { IWL_MVM_TX_FIFO_BK = 0, diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 3f40ab05bbd8..b0b190d0ec23 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, struct iwl_rx_phy_info *phy_info) { - u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db; + int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; + int rssi_all_band_a, rssi_all_band_b; + u32 agc_a, agc_b, max_agc; u32 val; - /* Find max rssi among 3 possible receivers. + /* Find max rssi among 2 possible receivers. * These values are measured by the Digital Signal Processor (DSP). * They should stay fairly constant even as the signal strength varies, * if the radio's Automatic Gain Control (AGC) is working right. * AGC value (see below) will provide the "interesting" info. */ + val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); + agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; + agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; + max_agc = max_t(u32, agc_a, agc_b); + val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]); - rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; - - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); - agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS; + rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >> + IWL_OFDM_RSSI_ALLBAND_A_POS; + rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >> + IWL_OFDM_RSSI_ALLBAND_B_POS; - max_rssi = max_t(u32, rssi_a, rssi_b); - max_rssi = max_t(u32, max_rssi, rssi_c); + /* + * dBm = rssi dB - agc dB - constant. + * Higher AGC (higher radio gain) means lower signal. + */ + rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a; + rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b; + max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm); - IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", - rssi_a, rssi_b, rssi_c, max_rssi, agc_db); + IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", + rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); - /* dBm = max_rssi dB - agc dB - constant. - * Higher AGC (higher radio gain) means lower signal. */ - return max_rssi - agc_db - IWL_RSSI_OFFSET; + return max_rssi_dbm; } /* -- cgit v1.2.3 From 2470b36e84a2e680d7a7e3809cbceae5bfae3606 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 3 Mar 2013 14:35:03 +0200 Subject: iwlwifi: mvm: don't warn on normal BAR sending This flow happens when we get a failed single Tx response on an AMPDU queue. In this case, the frame won't be sent any more. So we need to move the window on the recipient side. This is done by a BAR. Now if we are in the following case: 10, 12 and 13 are ACKed and 11 isn't. 10 11 12 13. V X V V Then, 11 will be sent 16 times as an MPDU (as oppsed to A-MPDU). If this failed, we are entering the flow described above. So we need to send a BAR with ssn = 12. But in this case, the scheduler will tell us to free frames up to 13 (included). So, it is perfectly possible to get a failed single Tx response on an AMPDU queue that makes the scheduler's ssn jump by more than 1 single packet. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/tx.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 6b67ce3f679c..6645efe5c03e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, /* Single frame failure in an AMPDU queue => send BAR */ if (txq_id >= IWL_FIRST_AMPDU_QUEUE && - !(info->flags & IEEE80211_TX_STAT_ACK)) { - /* there must be only one skb in the skb_list */ - WARN_ON_ONCE(skb_freed > 1 || - !skb_queue_empty(&skbs)); + !(info->flags & IEEE80211_TX_STAT_ACK)) info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - } /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { -- cgit v1.2.3 From 410dc5aa5906ed49e2733b451a5287884e8a16dc Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 18 Feb 2013 09:22:28 +0200 Subject: iwlwifi: a few fixes in license 7000.c was released as GPL only by mistake: it should be dual licensed - GPL / BSD. The file that contains the license in the kernel is COPYING and not LICENSE.GPL. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/agn.h | 2 +- drivers/net/wireless/iwlwifi/dvm/calib.c | 2 +- drivers/net/wireless/iwlwifi/dvm/calib.h | 2 +- drivers/net/wireless/iwlwifi/dvm/commands.h | 2 +- drivers/net/wireless/iwlwifi/dvm/debugfs.c | 2 +- drivers/net/wireless/iwlwifi/dvm/lib.c | 2 +- drivers/net/wireless/iwlwifi/dvm/scan.c | 2 +- drivers/net/wireless/iwlwifi/dvm/testmode.c | 2 +- drivers/net/wireless/iwlwifi/dvm/tx.c | 2 +- drivers/net/wireless/iwlwifi/dvm/ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-config.h | 2 +- drivers/net/wireless/iwlwifi/iwl-csr.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debug.c | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +- drivers/net/wireless/iwlwifi/iwl-drv.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom-read.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fh.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fw-file.h | 2 +- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 +- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 2 +- drivers/net/wireless/iwlwifi/iwl-notif-wait.h | 2 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 2 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.h | 2 +- drivers/net/wireless/iwlwifi/iwl-op-mode.h | 2 +- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 2 +- drivers/net/wireless/iwlwifi/iwl-phy-db.h | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 2 +- drivers/net/wireless/iwlwifi/iwl-test.c | 2 +- drivers/net/wireless/iwlwifi/iwl-test.h | 2 +- drivers/net/wireless/iwlwifi/iwl-testmode.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 +- drivers/net/wireless/iwlwifi/mvm/binding.c | 2 +- drivers/net/wireless/iwlwifi/mvm/d3.c | 2 +- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-power.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 2 +- drivers/net/wireless/iwlwifi/mvm/fw.c | 2 +- drivers/net/wireless/iwlwifi/mvm/led.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/iwlwifi/mvm/nvm.c | 2 +- drivers/net/wireless/iwlwifi/mvm/ops.c | 2 +- drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/power.c | 2 +- drivers/net/wireless/iwlwifi/mvm/quota.c | 2 +- drivers/net/wireless/iwlwifi/mvm/rx.c | 2 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 2 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 2 +- drivers/net/wireless/iwlwifi/mvm/sta.h | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.c | 2 +- drivers/net/wireless/iwlwifi/mvm/time-event.h | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 2 +- drivers/net/wireless/iwlwifi/mvm/utils.c | 2 +- drivers/net/wireless/iwlwifi/pcie/7000.c | 61 ++++++++++++++++++++----- drivers/net/wireless/iwlwifi/pcie/cfg.h | 2 +- drivers/net/wireless/iwlwifi/pcie/drv.c | 2 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +- 69 files changed, 117 insertions(+), 80 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 41ec27cb6efe..019d433900ef 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.c b/drivers/net/wireless/iwlwifi/dvm/calib.c index 6468de8634b0..d6c4cf2ad7c5 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/iwlwifi/dvm/calib.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/calib.h b/drivers/net/wireless/iwlwifi/dvm/calib.h index 65e920cab2b7..cfddde194940 100644 --- a/drivers/net/wireless/iwlwifi/dvm/calib.h +++ b/drivers/net/wireless/iwlwifi/dvm/calib.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 84e2c0fcfef6..22100c2a56ea 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 20806cae11b7..9d3b7e3165f4 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 86ea5f4c3939..cddf77c36b36 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c index 3a4aa5239c45..d69b55866714 100644 --- a/drivers/net/wireless/iwlwifi/dvm/scan.c +++ b/drivers/net/wireless/iwlwifi/dvm/scan.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c index dc6f965a123a..b89b9d9b9969 100644 --- a/drivers/net/wireless/iwlwifi/dvm/testmode.c +++ b/drivers/net/wireless/iwlwifi/dvm/testmode.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 6aec2df3bb27..303403b86b75 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 736fe9bb140e..166019afc2d0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -19,7 +19,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index e9975c54c276..6d73f943cefa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 743b48343358..8ba293b2396b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index df3463a38704..20e845d4da04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 87535a67de76..88df574e33de 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index fbfd2d137117..8620de406f64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 594a5c71b272..4c96472ac3ea 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 034f2ff4f43d..28c33512aed5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h index 683fe6a8c58f..37f115390b19 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index ef4806f27cf8..92e7245ced8d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h index b2588c5cbf93..8e941f8bd7d6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index f5592fb3b1ed..484d318245fb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 90873eca35f7..8b6c6fd95ed0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index b545178e46e3..54848d59df0e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index 2c2a729092f5..a2cefe2c3e1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index c3affbc62cdf..721fc64dd44b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h index c2ce764463a3..2e2f1c8c99f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.h +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index a70213bdb83c..2ab4bd67ba92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h index b2692bd287fa..e57fb989661e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/iwlwifi/iwl-op-mode.h index 4a680019e117..98c7aa7346da 100644 --- a/drivers/net/wireless/iwlwifi/iwl-op-mode.h +++ b/drivers/net/wireless/iwlwifi/iwl-op-mode.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 3392011a8768..31c05487a688 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h index d0e43d96ab38..ce983af79644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.h +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index f76e9cad7757..386f2a7c87cb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index ce0c67b425ee..a7cbf7906200 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h index 7fbf4d717caa..8fbd21704840 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.h +++ b/drivers/net/wireless/iwlwifi/iwl-test.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index a963f45c6849..98f48a9afc98 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0cac2b7af78b..205aab851e5f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/binding.c b/drivers/net/wireless/iwlwifi/mvm/binding.c index 73d24aacb90a..93fd1457954b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/binding.c +++ b/drivers/net/wireless/iwlwifi/mvm/binding.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 994c8c263dc0..376a5776db90 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index c1bdb5582126..9e5313776a26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index cf6f9a02fb74..a442ee11a062 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index ae39b7dfda7b..d68640ea41d4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index be36b7604b7f..127051891e9b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index aa3474d08231..fdd33bc0a594 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index 670ac8f95e26..b60d14151721 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 0acb53dda22d..a30691a8a85b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h index 2677914bf0a6..6d53850c5448 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 2adb61f103f4..92cd982f6b27 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 500f818dba04..0f45fa583aa1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/led.c b/drivers/net/wireless/iwlwifi/mvm/led.c index 011906e73a05..2269a9e5cc67 100644 --- a/drivers/net/wireless/iwlwifi/mvm/led.c +++ b/drivers/net/wireless/iwlwifi/mvm/led.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 341dbc0237ea..147e925d6474 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 7e169b085afe..5939af8523c2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index bdae700c769e..23c39eab4d97 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 20016bcbdeab..555095cf4afc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index d0f9c1e0475e..473864733aab 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c index b428448f8ddf..0d537e035ef0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 5a92a4978795..efb9a6f3faac 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 925628468146..df85c49dc599 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index b0b190d0ec23..4dfc21a3e83e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index 9b21b92aa8d1..0d3c76b29242 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 274f44e2ef60..1970001bf96d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 896f88ac8145..119de72c6d18 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index e437e02c7149..c2c7f5176027 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index 64fb57a5ab43..b36424eda361 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 6645efe5c03e..a65acf09f913 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index 000e842c2edd..e308ad93aa9e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c index 6e35b2b72332..d1d3b3074b9e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ b/drivers/net/wireless/iwlwifi/pcie/7000.c @@ -1,27 +1,64 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. + * The full GNU General Public License is included in this distribution + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * + * BSD LICENSE + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * *****************************************************************************/ #include diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h index c6f8e83c3551..f4318fb192df 100644 --- a/drivers/net/wireless/iwlwifi/pcie/cfg.h +++ b/drivers/net/wireless/iwlwifi/pcie/cfg.h @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 7bc0fb9128dd..49b254326d9c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 17bedc50e753..d90cbf5041f5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -22,7 +22,7 @@ * USA * * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. + * in the file called COPYING. * * Contact Information: * Intel Linux Wireless -- cgit v1.2.3 From 5d158efa5577f3851d36f2bdf42ea7af66668b9c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 14:39:58 +0200 Subject: iwlwifi: mvm: respect disable Tx AGG parameter We didn't check that we allowed to start Tx AGG. This can possibly be avoided by a module parameter. Fix that. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 5939af8523c2..65fc5531f7ba 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -273,6 +273,10 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwl_mvm_sta_rx_agg(mvm, sta, tid, 0, false); break; case IEEE80211_AMPDU_TX_START: + if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) { + ret = -EINVAL; + break; + } ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP_CONT: -- cgit v1.2.3 From 80d8565557747854d6ff7fc0a756cc71a9fa2372 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 15:32:42 +0200 Subject: iwlwifi: mvm: free AGG queue when we STA is removed When we stop an AGG session, we need to look at the sequence numbers in in the private area of the ieee80211_sta struct. This allows us to know is the queue is empty. To get access to this private area, we use fw_id_to_mac_id that maps sta_id (index of the STA in fw table) to ieee80211_sta. When the STA exists in fw, but not in mac80211, we set an ERR ptr in fw_id_to_mac_id. But if we first set an ERR ptr to fw_id_to_mac_id, and only then flush the queues, then we won't be able to access the sequence numbers in ieee80211_sta from the reclaim flow. This means that we will never be able to release an AGG queue when a station is deleted. So first, flush the queue. That will let the reclaim flow call iwl_mvm_check_ratid_empty which will disable the AGG queue as needed, and only then, remove the mapping in fw_id_to_mac_id. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/sta.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 1970001bf96d..ca7aba404502 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -340,6 +340,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, if (vif->type == NL80211_IFTYPE_STATION && mvmvif->ap_sta_id == mvm_sta->sta_id) { + /* flush its queues here since we are freeing mvm_sta */ + ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); + /* * Put a non-NULL since the fw station isn't removed. * It will be removed after the MAC will be set as @@ -348,9 +351,6 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm, rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id], ERR_PTR(-EINVAL)); - /* flush its queues here since we are freeing mvm_sta */ - ret = iwl_mvm_flush_tx_path(mvm, mvm_sta->tfd_queue_msk, true); - /* if we are associated - we can't remove the AP STA now */ if (vif->bss_conf.assoc) return ret; -- cgit v1.2.3 From cc7ee2bab3d90b0a09651dcfa2d0c9ec1a115bc8 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Mon, 18 Feb 2013 13:51:36 +0200 Subject: iwlwifi: mvm: don't use cts to self The current fw doesn't currently support cts to self. There is a bug in the fw that prevents us from using cts to self. Use full protection (including RTS) for now. Signed-off-by: Dor Shaish Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 147e925d6474..3a136c1d3a5d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -553,9 +553,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, if (vif->bss_conf.qos) cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); + /* Don't use cts to self as the fw doesn't support it currently. */ if (vif->bss_conf.use_cts_prot) - cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT | - MAC_PROT_FLG_SELF_CTS_EN); + cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); /* * I think that we should enable these 2 flags regardless the HT PROT -- cgit v1.2.3 From 1dcd15eed073d5c7b37b43eff645e6c1dae342d9 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Thu, 14 Feb 2013 14:25:24 +0200 Subject: iwlwifi: mvm: Update MAC context filter flags 1. For P2P Device filter in only probe requests. 2. For station mode filter in all group cast frames, and in addition beacons as long as we are not associated. 3. For AP/GO filter in all group cast and in addition probe requests. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 3a136c1d3a5d..a993f6c7dac0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -651,6 +651,13 @@ static int iwl_mvm_mac_ctxt_cmd_station(struct iwl_mvm *mvm, /* Fill the common data for all mac context types */ iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); + /* Allow beacons to pass through as long as we are not associated,or we + * do not have dtim period information */ + if (!vif->bss_conf.assoc || !vif->bss_conf.dtim_period) + cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_BEACON); + else + cmd.filter_flags &= ~cpu_to_le32(MAC_FILTER_IN_BEACON); + /* Fill the data specific for station mode */ iwl_mvm_mac_ctxt_cmd_fill_sta(mvm, vif, &cmd.sta); @@ -714,7 +721,9 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); - cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROMISC); + + /* Override the filter flags to accept only probe requests */ + cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); /* * This flag should be set to true when the P2P Device is @@ -881,6 +890,9 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, /* Fill the common data for all mac context types */ iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); + /* Also enable probe requests to pass */ + cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); + /* Fill the data specific for ap mode */ iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); -- cgit v1.2.3 From f4a7dfa3f21afc1b2362f19cebc79d3d7d5a9aee Mon Sep 17 00:00:00 2001 From: Beni Lev Date: Tue, 19 Feb 2013 14:30:16 +0200 Subject: iwlwifi: 7000: disable HT greenfield support The 7000 series devices don't support HT greenfield mode so don't advertise or use it. Signed-off-by: Beni Lev Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/7000.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c index d1d3b3074b9e..a5e9cfe3e746 100644 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ b/drivers/net/wireless/iwlwifi/pcie/7000.c @@ -107,7 +107,6 @@ static const struct iwl_base_params iwl7000_base_params = { }; static const struct iwl_ht_params iwl7000_ht_params = { - .ht_greenfield_support = true, .use_rts_for_aggregation = true, /* use rts/cts protection */ .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), }; -- cgit v1.2.3 From 6e6cc9f319bf81b292ceb281228ab1d261172cac Mon Sep 17 00:00:00 2001 From: Beni Lev Date: Tue, 19 Feb 2013 14:40:11 +0200 Subject: iwlwifi: disable greenfield transmissions as a workaround There's a bug that causes the rate scaling to get stuck when it has to use single-stream rates with a peer that can do GF and SGI; the two are incompatible so we can't use them together, but that causes the algorithm to not work at all, it always rejects updates. Disable greenfield for now to prevent that problem. The MVM driver currently only works on devices that don't support greenfield anyway, but better be safe and not allow us to forget about this. Signed-off-by: Beni Lev Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/rs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 56b636d9ab30..a01a6612677e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -680,12 +680,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, */ static bool rs_use_green(struct ieee80211_sta *sta) { - struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; - - bool use_green = !(sta_priv->vif->bss_conf.ht_operation_mode & - IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - - return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && use_green; + /* + * There's a bug somewhere in this code that causes the + * scaling to get stuck because GF+SGI can't be combined + * in SISO rates. Until we find that bug, disable GF, it + * has only limited benefit and we still interoperate with + * GF APs since we can always receive GF transmissions. + */ + return false; } /** -- cgit v1.2.3 From 831e85f3fe078297ba452e12c0dba96008c59438 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Thu, 7 Feb 2013 17:09:09 +0200 Subject: iwlwifi: mvm: Add support for additional addresses Use the number of addresses (max 5) from the NVM instead of limiting to 2 artificially. Signed-off-by: Ilan Peer Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 14 +++++++++----- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 65fc5531f7ba..d08ae2604d7b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -105,7 +105,7 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) { struct ieee80211_hw *hw = mvm->hw; - int num_mac, ret; + int num_mac, ret, i; /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | @@ -156,11 +156,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); hw->wiphy->addresses = mvm->addresses; hw->wiphy->n_addresses = 1; - num_mac = mvm->nvm_data->n_hw_addrs; - if (num_mac > 1) { - memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr, + + /* Extract additional MAC addresses if available */ + num_mac = (mvm->nvm_data->n_hw_addrs > 1) ? + min(IWL_MVM_MAX_ADDRESSES, mvm->nvm_data->n_hw_addrs) : 1; + + for (i = 1; i < num_mac; i++) { + memcpy(mvm->addresses[i].addr, mvm->addresses[i-1].addr, ETH_ALEN); - mvm->addresses[1].addr[5]++; + mvm->addresses[i].addr[5]++; hw->wiphy->n_addresses++; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 23c39eab4d97..efe5da992897 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -79,7 +79,7 @@ #include "fw-api.h" #define IWL_INVALID_MAC80211_QUEUE 0xff -#define IWL_MVM_MAX_ADDRESSES 2 +#define IWL_MVM_MAX_ADDRESSES 5 /* RSSI offset for WkP */ #define IWL_RSSI_OFFSET 50 -- cgit v1.2.3 From e3d9e7ce4cd8ea7299cad568b21d50873a29f011 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 16:13:53 +0200 Subject: iwlwifi: mvm: support IEEE80211_AMPDU_TX_STOP_FLUSH mac80211 tells us when we need to dump the frames from the AGG queue instead of releasing them as single MPDUs. Being able to differentiate between the different cases (IEEE80211_AMPDU_TX_STOP_*) allows us to handle races better. When the station is removed, mac80211 asks to flush and removes the station right away. This allows to avoid a case where we still have frames in AGG queues, but the station has been remove already. Note that we can have frames on the shared queues, but this is not a problem: the station in the fw will be kept until all the frames on the shared queues have been drained. AGG queues are a special case since they are dynamically allocated. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 4 +++- drivers/net/wireless/iwlwifi/mvm/sta.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/sta.h | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index d08ae2604d7b..924cabf88b26 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -284,9 +284,11 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw, ret = iwl_mvm_sta_tx_agg_start(mvm, vif, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP_CONT: + ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); + break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - ret = iwl_mvm_sta_tx_agg_stop(mvm, vif, sta, tid); + ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ca7aba404502..8b8629317e9c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -834,6 +834,34 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return err; } +int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid) +{ + struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; + struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; + u16 txq_id; + + /* + * First set the agg state to OFF to avoid calling + * ieee80211_stop_tx_ba_cb in iwl_mvm_check_ratid_empty. + */ + spin_lock_bh(&mvmsta->lock); + txq_id = tid_data->txq_id; + IWL_DEBUG_TX_QUEUES(mvm, "Flush AGG: sta %d tid %d q %d state %d\n", + mvmsta->sta_id, tid, txq_id, tid_data->state); + tid_data->state = IWL_AGG_OFF; + spin_unlock_bh(&mvmsta->lock); + + if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) + IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); + + iwl_trans_txq_disable(mvm->trans, tid_data->txq_id); + mvm->queue_to_mac80211[tid_data->txq_id] = + IWL_INVALID_MAC80211_QUEUE; + + return 0; +} + static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm) { int i; diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 119de72c6d18..b0352df981e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -348,6 +348,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid, u8 buf_size); int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid); +int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u16 tid); int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm); int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, -- cgit v1.2.3 From f7546c76f756f7fbd8d7ec6f26f32cefe7778f9e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 11 Feb 2013 18:55:58 +0100 Subject: iwlwifi: support DSSS/CCK mode in 40 MHz All hardware after 4965 supports this. It's likely that it wasn't set because for 4965 it was irrelevant (HT is only supported on 5 GHz there) and then never updated. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 28c33512aed5..e170f5e6ee7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -749,7 +749,7 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, } ht_info->ht_supported = true; - ht_info->cap = 0; + ht_info->cap = IEEE80211_HT_CAP_DSSSCCK40; if (iwlwifi_mod_params.amsdu_size_8K) ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; -- cgit v1.2.3 From 9047e4ad435711e67f57b73b76b1235405118c0e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2013 16:29:37 +0100 Subject: iwlwifi: use __get_str in tracing Instead of using (char *)__get_dynamic_array use __get_str. The latter is actually a macro that expands to the former in the code, but trace-cmd in userspace can parse __get_str only. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 81aa91fab5aa..4491c1c72cc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -298,7 +298,7 @@ TRACE_EVENT(iwlwifi_dbg, MAX_MSG_LEN, vaf->fmt, *vaf->va) >= MAX_MSG_LEN); ), - TP_printk("%s", (char *)__get_dynamic_array(msg)) + TP_printk("%s", __get_str(msg)) ); #undef TRACE_SYSTEM -- cgit v1.2.3 From ba5295f8b2c789275cc6ffb0a45e50a8aa3a5c84 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 25 Feb 2013 21:24:11 +0800 Subject: iwlwifi: convert to use simple_open() This removes an open coded simple_open() function and replaces file operations references to the function with simple_open() instead. Signed-off-by: Wei Yongjun Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 9e5313776a26..2ad301164bd9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -69,12 +69,6 @@ struct iwl_dbgfs_mvm_ctx { struct ieee80211_vif *vif; }; -static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - static ssize_t iwl_dbgfs_tx_flush_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -309,7 +303,7 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, #define MVM_DEBUGFS_READ_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ - .open = iwl_dbgfs_open_file_generic, \ + .open = simple_open, \ .llseek = generic_file_llseek, \ } @@ -317,14 +311,14 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ .read = iwl_dbgfs_##name##_read, \ - .open = iwl_dbgfs_open_file_generic, \ + .open = simple_open, \ .llseek = generic_file_llseek, \ }; #define MVM_DEBUGFS_WRITE_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ - .open = iwl_dbgfs_open_file_generic, \ + .open = simple_open, \ .llseek = generic_file_llseek, \ }; -- cgit v1.2.3 From f0c2646af4f7432f7414e1162377cada06c3c747 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 22 Jan 2013 20:41:58 +0100 Subject: iwlwifi: mvm: implement remote wake With remote wake, the firmware creates a TCP connection and sends some configurable data on it, until a special TCP data packet from the server is received that triggers a wakeup. The configuration is a bit tricky because it is based on packet pattern matching but this is hidden in the driver and the exposed API in cfg80211 is just based on the required TCP connection parameters. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/d3.c | 258 +++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h | 51 +++++- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 26 +++ 3 files changed, 334 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 376a5776db90..d4578cefe445 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -62,8 +62,10 @@ *****************************************************************************/ #include +#include #include #include +#include #include "iwl-modparams.h" #include "fw-api.h" #include "mvm.h" @@ -402,6 +404,233 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, sizeof(cmd), &cmd); } +enum iwl_mvm_tcp_packet_type { + MVM_TCP_TX_SYN, + MVM_TCP_RX_SYNACK, + MVM_TCP_TX_DATA, + MVM_TCP_RX_ACK, + MVM_TCP_RX_WAKE, + MVM_TCP_TX_FIN, +}; + +static __le16 pseudo_hdr_check(int len, __be32 saddr, __be32 daddr) +{ + __sum16 check = tcp_v4_check(len, saddr, daddr, 0); + return cpu_to_le16(be16_to_cpu((__force __be16)check)); +} + +static void iwl_mvm_build_tcp_packet(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct cfg80211_wowlan_tcp *tcp, + void *_pkt, u8 *mask, + __le16 *pseudo_hdr_csum, + enum iwl_mvm_tcp_packet_type ptype) +{ + struct { + struct ethhdr eth; + struct iphdr ip; + struct tcphdr tcp; + u8 data[]; + } __packed *pkt = _pkt; + u16 ip_tot_len = sizeof(struct iphdr) + sizeof(struct tcphdr); + int i; + + pkt->eth.h_proto = cpu_to_be16(ETH_P_IP), + pkt->ip.version = 4; + pkt->ip.ihl = 5; + pkt->ip.protocol = IPPROTO_TCP; + + switch (ptype) { + case MVM_TCP_TX_SYN: + case MVM_TCP_TX_DATA: + case MVM_TCP_TX_FIN: + memcpy(pkt->eth.h_dest, tcp->dst_mac, ETH_ALEN); + memcpy(pkt->eth.h_source, vif->addr, ETH_ALEN); + pkt->ip.ttl = 128; + pkt->ip.saddr = tcp->src; + pkt->ip.daddr = tcp->dst; + pkt->tcp.source = cpu_to_be16(tcp->src_port); + pkt->tcp.dest = cpu_to_be16(tcp->dst_port); + /* overwritten for TX SYN later */ + pkt->tcp.doff = sizeof(struct tcphdr) / 4; + pkt->tcp.window = cpu_to_be16(65000); + break; + case MVM_TCP_RX_SYNACK: + case MVM_TCP_RX_ACK: + case MVM_TCP_RX_WAKE: + memcpy(pkt->eth.h_dest, vif->addr, ETH_ALEN); + memcpy(pkt->eth.h_source, tcp->dst_mac, ETH_ALEN); + pkt->ip.saddr = tcp->dst; + pkt->ip.daddr = tcp->src; + pkt->tcp.source = cpu_to_be16(tcp->dst_port); + pkt->tcp.dest = cpu_to_be16(tcp->src_port); + break; + default: + WARN_ON(1); + return; + } + + switch (ptype) { + case MVM_TCP_TX_SYN: + /* firmware assumes 8 option bytes - 8 NOPs for now */ + memset(pkt->data, 0x01, 8); + ip_tot_len += 8; + pkt->tcp.doff = (sizeof(struct tcphdr) + 8) / 4; + pkt->tcp.syn = 1; + break; + case MVM_TCP_TX_DATA: + ip_tot_len += tcp->payload_len; + memcpy(pkt->data, tcp->payload, tcp->payload_len); + pkt->tcp.psh = 1; + pkt->tcp.ack = 1; + break; + case MVM_TCP_TX_FIN: + pkt->tcp.fin = 1; + pkt->tcp.ack = 1; + break; + case MVM_TCP_RX_SYNACK: + pkt->tcp.syn = 1; + pkt->tcp.ack = 1; + break; + case MVM_TCP_RX_ACK: + pkt->tcp.ack = 1; + break; + case MVM_TCP_RX_WAKE: + ip_tot_len += tcp->wake_len; + pkt->tcp.psh = 1; + pkt->tcp.ack = 1; + memcpy(pkt->data, tcp->wake_data, tcp->wake_len); + break; + } + + switch (ptype) { + case MVM_TCP_TX_SYN: + case MVM_TCP_TX_DATA: + case MVM_TCP_TX_FIN: + pkt->ip.tot_len = cpu_to_be16(ip_tot_len); + pkt->ip.check = ip_fast_csum(&pkt->ip, pkt->ip.ihl); + break; + case MVM_TCP_RX_WAKE: + for (i = 0; i < DIV_ROUND_UP(tcp->wake_len, 8); i++) { + u8 tmp = tcp->wake_mask[i]; + mask[i + 6] |= tmp << 6; + if (i + 1 < DIV_ROUND_UP(tcp->wake_len, 8)) + mask[i + 7] = tmp >> 2; + } + /* fall through for ethernet/IP/TCP headers mask */ + case MVM_TCP_RX_SYNACK: + case MVM_TCP_RX_ACK: + mask[0] = 0xff; /* match ethernet */ + /* + * match ethernet, ip.version, ip.ihl + * the ip.ihl half byte is really masked out by firmware + */ + mask[1] = 0x7f; + mask[2] = 0x80; /* match ip.protocol */ + mask[3] = 0xfc; /* match ip.saddr, ip.daddr */ + mask[4] = 0x3f; /* match ip.daddr, tcp.source, tcp.dest */ + mask[5] = 0x80; /* match tcp flags */ + /* leave rest (0 or set for MVM_TCP_RX_WAKE) */ + break; + }; + + *pseudo_hdr_csum = pseudo_hdr_check(ip_tot_len - sizeof(struct iphdr), + pkt->ip.saddr, pkt->ip.daddr); +} + +static int iwl_mvm_send_remote_wake_cfg(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct cfg80211_wowlan_tcp *tcp) +{ + struct iwl_wowlan_remote_wake_config *cfg; + struct iwl_host_cmd cmd = { + .id = REMOTE_WAKE_CONFIG_CMD, + .len = { sizeof(*cfg), }, + .dataflags = { IWL_HCMD_DFL_NOCOPY, }, + .flags = CMD_SYNC, + }; + int ret; + + if (!tcp) + return 0; + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + cmd.data[0] = cfg; + + cfg->max_syn_retries = 10; + cfg->max_data_retries = 10; + cfg->tcp_syn_ack_timeout = 1; /* seconds */ + cfg->tcp_ack_timeout = 1; /* seconds */ + + /* SYN (TX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->syn_tx.data, NULL, + &cfg->syn_tx.info.tcp_pseudo_header_checksum, + MVM_TCP_TX_SYN); + cfg->syn_tx.info.tcp_payload_length = 0; + + /* SYN/ACK (RX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->synack_rx.data, cfg->synack_rx.rx_mask, + &cfg->synack_rx.info.tcp_pseudo_header_checksum, + MVM_TCP_RX_SYNACK); + cfg->synack_rx.info.tcp_payload_length = 0; + + /* KEEPALIVE/ACK (TX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->keepalive_tx.data, NULL, + &cfg->keepalive_tx.info.tcp_pseudo_header_checksum, + MVM_TCP_TX_DATA); + cfg->keepalive_tx.info.tcp_payload_length = + cpu_to_le16(tcp->payload_len); + cfg->sequence_number_offset = tcp->payload_seq.offset; + /* length must be 0..4, the field is little endian */ + cfg->sequence_number_length = tcp->payload_seq.len; + cfg->initial_sequence_number = cpu_to_le32(tcp->payload_seq.start); + cfg->keepalive_interval = cpu_to_le16(tcp->data_interval); + if (tcp->payload_tok.len) { + cfg->token_offset = tcp->payload_tok.offset; + cfg->token_length = tcp->payload_tok.len; + cfg->num_tokens = + cpu_to_le16(tcp->tokens_size % tcp->payload_tok.len); + memcpy(cfg->tokens, tcp->payload_tok.token_stream, + tcp->tokens_size); + } else { + /* set tokens to max value to almost never run out */ + cfg->num_tokens = cpu_to_le16(65535); + } + + /* ACK (RX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->keepalive_ack_rx.data, + cfg->keepalive_ack_rx.rx_mask, + &cfg->keepalive_ack_rx.info.tcp_pseudo_header_checksum, + MVM_TCP_RX_ACK); + cfg->keepalive_ack_rx.info.tcp_payload_length = 0; + + /* WAKEUP (RX) */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->wake_rx.data, cfg->wake_rx.rx_mask, + &cfg->wake_rx.info.tcp_pseudo_header_checksum, + MVM_TCP_RX_WAKE); + cfg->wake_rx.info.tcp_payload_length = + cpu_to_le16(tcp->wake_len); + + /* FIN */ + iwl_mvm_build_tcp_packet( + mvm, vif, tcp, cfg->fin_tx.data, NULL, + &cfg->fin_tx.info.tcp_pseudo_header_checksum, + MVM_TCP_TX_FIN); + cfg->fin_tx.info.tcp_payload_length = 0; + + ret = iwl_mvm_send_cmd(mvm, &cmd); + kfree(cfg); + + return ret; +} + struct iwl_d3_iter_data { struct iwl_mvm *mvm; struct ieee80211_vif *vif; @@ -640,6 +869,22 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) d3_cfg_cmd.wakeup_flags |= cpu_to_le32(IWL_WOWLAN_WAKEUP_RF_KILL_DEASSERT); + if (wowlan->tcp) { + /* + * The firmware currently doesn't really look at these, only + * the IWL_WOWLAN_WAKEUP_LINK_CHANGE bit. We have to set that + * reason bit since losing the connection to the AP implies + * losing the TCP connection. + * Set the flags anyway as long as they exist, in case this + * will be changed in the firmware. + */ + wowlan_config_cmd.wakeup_filter |= + cpu_to_le32(IWL_WOWLAN_WAKEUP_REMOTE_LINK_LOSS | + IWL_WOWLAN_WAKEUP_REMOTE_SIGNATURE_TABLE | + IWL_WOWLAN_WAKEUP_REMOTE_WAKEUP_PACKET | + IWL_WOWLAN_WAKEUP_LINK_CHANGE); + } + iwl_mvm_cancel_scan(mvm); iwl_trans_stop_device(mvm->trans); @@ -755,6 +1000,10 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (ret) goto out; + ret = iwl_mvm_send_remote_wake_cfg(mvm, vif, wowlan->tcp); + if (ret) + goto out; + /* must be last -- this switches firmware state */ ret = iwl_mvm_send_cmd_pdu(mvm, D3_CONFIG_CMD, CMD_SYNC, sizeof(d3_cfg_cmd), &d3_cfg_cmd); @@ -874,6 +1123,15 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) wakeup.four_way_handshake = true; + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS) + wakeup.tcp_connlost = true; + + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE) + wakeup.tcp_nomoretokens = true; + + if (reasons & IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET) + wakeup.tcp_match = true; + if (status->wake_packet_bufsize) { int pktsize = le32_to_cpu(status->wake_packet_bufsize); int pktlen = le32_to_cpu(status->wake_packet_length); diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index a442ee11a062..51e015d1dfb2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h @@ -258,7 +258,7 @@ enum iwl_wowlan_wakeup_reason { IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE = BIT(8), IWL_WOWLAN_WAKEUP_BY_REM_WAKE_LINK_LOSS = BIT(9), IWL_WOWLAN_WAKEUP_BY_REM_WAKE_SIGNATURE_TABLE = BIT(10), - IWL_WOWLAN_WAKEUP_BY_REM_WAKE_TCP_EXTERNAL = BIT(11), + /* BIT(11) reserved */ IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ @@ -277,6 +277,55 @@ struct iwl_wowlan_status { u8 wake_packet[]; /* can be truncated from _length to _bufsize */ } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ +#define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 +#define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 +#define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 + +struct iwl_tcp_packet_info { + __le16 tcp_pseudo_header_checksum; + __le16 tcp_payload_length; +} __packed; /* TCP_PACKET_INFO_API_S_VER_2 */ + +struct iwl_tcp_packet { + struct iwl_tcp_packet_info info; + u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8]; + u8 data[IWL_WOWLAN_TCP_MAX_PACKET_LEN]; +} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */ + +struct iwl_remote_wake_packet { + struct iwl_tcp_packet_info info; + u8 rx_mask[IWL_WOWLAN_MAX_PATTERN_LEN / 8]; + u8 data[IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN]; +} __packed; /* TCP_PROTOCOL_PACKET_API_S_VER_1 */ + +struct iwl_wowlan_remote_wake_config { + __le32 connection_max_time; /* unused */ + /* TCP_PROTOCOL_CONFIG_API_S_VER_1 */ + u8 max_syn_retries; + u8 max_data_retries; + u8 tcp_syn_ack_timeout; + u8 tcp_ack_timeout; + + struct iwl_tcp_packet syn_tx; + struct iwl_tcp_packet synack_rx; + struct iwl_tcp_packet keepalive_ack_rx; + struct iwl_tcp_packet fin_tx; + + struct iwl_remote_wake_packet keepalive_tx; + struct iwl_remote_wake_packet wake_rx; + + /* REMOTE_WAKE_OFFSET_INFO_API_S_VER_1 */ + u8 sequence_number_offset; + u8 sequence_number_length; + u8 token_offset; + u8 token_length; + /* REMOTE_WAKE_PROTOCOL_PARAMS_API_S_VER_1 */ + __le32 initial_sequence_number; + __le16 keepalive_interval; + __le16 num_tokens; + u8 tokens[IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS]; +} __packed; /* REMOTE_WAKE_CONFIG_API_S_VER_2 */ + /* TODO: NetDetect API */ #endif /* __fw_api_d3_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 924cabf88b26..ed2d8754c82b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -65,7 +65,9 @@ #include #include #include +#include #include +#include #include "iwl-op-mode.h" #include "iwl-io.h" @@ -102,6 +104,29 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { }, }; +#ifdef CONFIG_PM_SLEEP +static const struct nl80211_wowlan_tcp_data_token_feature +iwl_mvm_wowlan_tcp_token_feature = { + .min_len = 0, + .max_len = 255, + .bufsize = IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS, +}; + +static const struct wiphy_wowlan_tcp_support iwl_mvm_wowlan_tcp_support = { + .tok = &iwl_mvm_wowlan_tcp_token_feature, + .data_payload_max = IWL_WOWLAN_TCP_MAX_PACKET_LEN - + sizeof(struct ethhdr) - + sizeof(struct iphdr) - + sizeof(struct tcphdr), + .data_interval_max = 65535, /* __le16 in API */ + .wake_payload_max = IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN - + sizeof(struct ethhdr) - + sizeof(struct iphdr) - + sizeof(struct tcphdr), + .seq = true, +}; +#endif + int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) { struct ieee80211_hw *hw = mvm->hw; @@ -210,6 +235,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; + hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; } #endif -- cgit v1.2.3 From 5bc5aaad407ccc49262d9fd3456d6ab332286395 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 12 Feb 2013 14:35:36 +0100 Subject: iwlwifi: mvm: set up initial SMPS/NSS station info When a station is added, we need to tell the firmware what the SMPS settings and number of streams are. After having the initial data, the firmware will track future changes by itself. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/sta.c | 51 ++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 8b8629317e9c..4872ec23b371 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -101,8 +101,55 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, } add_sta_cmd.add_modify = update ? 1 : 0; - /* STA_FLG_FAT_EN_MSK ? */ - /* STA_FLG_MIMO_EN_MSK ? */ + add_sta_cmd.station_flags_msk |= cpu_to_le32(STA_FLG_FAT_EN_MSK | + STA_FLG_MIMO_EN_MSK); + + switch (sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_160MHZ); + /* fall through */ + case IEEE80211_STA_RX_BW_80: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_80MHZ); + /* fall through */ + case IEEE80211_STA_RX_BW_40: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_FAT_EN_40MHZ); + /* fall through */ + case IEEE80211_STA_RX_BW_20: + if (sta->ht_cap.ht_supported) + add_sta_cmd.station_flags |= + cpu_to_le32(STA_FLG_FAT_EN_20MHZ); + break; + } + + switch (sta->rx_nss) { + case 1: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); + break; + case 2: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO2); + break; + case 3 ... 8: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_MIMO3); + break; + } + + switch (sta->smps_mode) { + case IEEE80211_SMPS_AUTOMATIC: + case IEEE80211_SMPS_NUM_MODES: + WARN_ON(1); + break; + case IEEE80211_SMPS_STATIC: + /* override NSS */ + add_sta_cmd.station_flags &= ~cpu_to_le32(STA_FLG_MIMO_EN_MSK); + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_MIMO_EN_SISO); + break; + case IEEE80211_SMPS_DYNAMIC: + add_sta_cmd.station_flags |= cpu_to_le32(STA_FLG_RTS_MIMO_PROT); + break; + case IEEE80211_SMPS_OFF: + /* nothing */ + break; + } if (sta->ht_cap.ht_supported) { add_sta_cmd.station_flags_msk |= -- cgit v1.2.3 From 33158fefc88e58fa17a46fdd90ba5231c3c8c89a Mon Sep 17 00:00:00 2001 From: Eytan Lifshitz Date: Wed, 20 Feb 2013 11:01:13 +0200 Subject: iwlwifi: mvm: advertise VHT capabilities Update the NVM parsing functions to add VHT capabilities; they are only added for 5 GHz, of course. This assumes that all devices with NVM reading (rather than EEPROM) that support 5 GHz have VHT, which is true right now. Signed-off-by: Eytan Lifshitz Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 2ab4bd67ba92..1ae6f2c1558d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -149,6 +149,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { * @NVM_CHANNEL_DFS: dynamic freq selection candidate * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) + * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) + * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) */ enum iwl_nvm_channel_flags { NVM_CHANNEL_VALID = BIT(0), @@ -158,6 +160,8 @@ enum iwl_nvm_channel_flags { NVM_CHANNEL_DFS = BIT(7), NVM_CHANNEL_WIDE = BIT(8), NVM_CHANNEL_40MHZ = BIT(9), + NVM_CHANNEL_80MHZ = BIT(10), + NVM_CHANNEL_160MHZ = BIT(11), }; #define CHECK_AND_PRINT_I(x) \ @@ -210,6 +214,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, else channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; } + if (!(ch_flags & NVM_CHANNEL_80MHZ)) + channel->flags |= IEEE80211_CHAN_NO_80MHZ; + if (!(ch_flags & NVM_CHANNEL_160MHZ)) + channel->flags |= IEEE80211_CHAN_NO_160MHZ; if (!(ch_flags & NVM_CHANNEL_IBSS)) channel->flags |= IEEE80211_CHAN_NO_IBSS; @@ -245,6 +253,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, return n_channels; } +static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, + struct iwl_nvm_data *data, + struct ieee80211_sta_vht_cap *vht_cap) +{ + /* For now, assume new devices with NVM are VHT capable */ + + vht_cap->vht_supported = true; + + vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | + 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + + if (iwlwifi_mod_params.amsdu_size_8K) + vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; + + vht_cap->vht_mcs.rx_mcs_map = + cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | + IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); + + if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { + vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | + IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; + /* this works because NOT_SUPPORTED == 3 */ + vht_cap->vht_mcs.rx_mcs_map |= + cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2); + } + + vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; +} + static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, struct iwl_nvm_data *data, const __le16 *nvm_sw) { @@ -268,6 +313,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, n_used += iwl_init_sband_channels(data, sband, n_channels, IEEE80211_BAND_5GHZ); iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); + iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); if (n_channels != n_used) IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", -- cgit v1.2.3 From 5e4fbe4cc05767fe7e1bbc269376e0e48f365327 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 27 Feb 2013 11:21:07 +0200 Subject: iwlwifi: dvm: pad iwl_compressed_ba_resp All the data coming from the fw must have a length that is multiple of 4. This doesn't change anything to the way we handle the notification. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/commands.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 22100c2a56ea..95ca026ecc9d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -1526,6 +1526,7 @@ struct iwl_compressed_ba_resp { __le16 scd_ssn; u8 txed; /* number of frames sent */ u8 txed_2_done; /* number of frames acked */ + __le16 reserved1; } __packed; /* -- cgit v1.2.3 From b1f553c7484b983aac20c107b9766804b69cf73f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 20 Feb 2013 12:41:58 +0200 Subject: iwlwifi: make device configuration bus agnostic Newer devices can work on different buses. This means that their configuration can be shared between different buses. Hence the configuration structures should exported to all the buses and not only to PCIE. Change this. Note that this requires all the fields to be the same amongst the buses. If differences will appear, we can always define a part that is bus dependent. Today, this is not needed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Makefile | 3 +- drivers/net/wireless/iwlwifi/iwl-1000.c | 140 +++++++++++ drivers/net/wireless/iwlwifi/iwl-2000.c | 242 ++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-5000.c | 179 +++++++++++++ drivers/net/wireless/iwlwifi/iwl-6000.c | 402 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-7000.c | 146 +++++++++++ drivers/net/wireless/iwlwifi/iwl-config.h | 47 ++++ drivers/net/wireless/iwlwifi/pcie/1000.c | 141 ----------- drivers/net/wireless/iwlwifi/pcie/2000.c | 243 ------------------ drivers/net/wireless/iwlwifi/pcie/5000.c | 180 ------------- drivers/net/wireless/iwlwifi/pcie/6000.c | 403 ------------------------------ drivers/net/wireless/iwlwifi/pcie/7000.c | 147 ----------- drivers/net/wireless/iwlwifi/pcie/cfg.h | 115 --------- drivers/net/wireless/iwlwifi/pcie/drv.c | 2 - 14 files changed, 1157 insertions(+), 1233 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-1000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-2000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-5000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-6000.c create mode 100644 drivers/net/wireless/iwlwifi/iwl-7000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/1000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/2000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/5000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/6000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/7000.c delete mode 100644 drivers/net/wireless/iwlwifi/pcie/cfg.h diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 6c7800044a04..3b5613ea458b 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -7,8 +7,7 @@ iwlwifi-objs += iwl-notif-wait.o iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o -iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o -iwlwifi-objs += pcie/7000.o +iwlwifi-objs += iwl-1000.o iwl-2000.o iwl-5000.o iwl-6000.o iwl-7000.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c new file mode 100644 index 000000000000..c080ae3070b2 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-csr.h" +#include "iwl-agn-hw.h" + +/* Highest firmware API version supported */ +#define IWL1000_UCODE_API_MAX 5 +#define IWL100_UCODE_API_MAX 5 + +/* Oldest version we won't warn about */ +#define IWL1000_UCODE_API_OK 5 +#define IWL100_UCODE_API_OK 5 + +/* Lowest firmware API version supported */ +#define IWL1000_UCODE_API_MIN 1 +#define IWL100_UCODE_API_MIN 5 + +/* EEPROM version */ +#define EEPROM_1000_TX_POWER_VERSION (4) +#define EEPROM_1000_EEPROM_VERSION (0x15C) + +#define IWL1000_FW_PRE "iwlwifi-1000-" +#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode" + +#define IWL100_FW_PRE "iwlwifi-100-" +#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" + + +static const struct iwl_base_params iwl1000_base_params = { + .num_of_queues = IWLAGN_NUM_QUEUES, + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, + .max_ll_items = OTP_MAX_LL_ITEMS_1000, + .shadow_ram_support = false, + .led_compensation = 51, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_WATCHDOG_DISABLED, + .max_event_log_size = 128, +}; + +static const struct iwl_ht_params iwl1000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ), +}; + +static const struct iwl_eeprom_params iwl1000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + } +}; + +#define IWL_DEVICE_1000 \ + .fw_name_pre = IWL1000_FW_PRE, \ + .ucode_api_max = IWL1000_UCODE_API_MAX, \ + .ucode_api_ok = IWL1000_UCODE_API_OK, \ + .ucode_api_min = IWL1000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_1000, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ + .base_params = &iwl1000_base_params, \ + .eeprom_params = &iwl1000_eeprom_params, \ + .led_mode = IWL_LED_BLINK + +const struct iwl_cfg iwl1000_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", + IWL_DEVICE_1000, + .ht_params = &iwl1000_ht_params, +}; + +const struct iwl_cfg iwl1000_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", + IWL_DEVICE_1000, +}; + +#define IWL_DEVICE_100 \ + .fw_name_pre = IWL100_FW_PRE, \ + .ucode_api_max = IWL100_UCODE_API_MAX, \ + .ucode_api_ok = IWL100_UCODE_API_OK, \ + .ucode_api_min = IWL100_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_100, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ + .base_params = &iwl1000_base_params, \ + .eeprom_params = &iwl1000_eeprom_params, \ + .led_mode = IWL_LED_RF_STATE, \ + .rx_with_siso_diversity = true + +const struct iwl_cfg iwl100_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", + IWL_DEVICE_100, + .ht_params = &iwl1000_ht_params, +}; + +const struct iwl_cfg iwl100_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 100 BG", + IWL_DEVICE_100, +}; + +MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c new file mode 100644 index 000000000000..a6ddd2f9fba0 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -0,0 +1,242 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" +#include "dvm/commands.h" /* needed for BT for now */ + +/* Highest firmware API version supported */ +#define IWL2030_UCODE_API_MAX 6 +#define IWL2000_UCODE_API_MAX 6 +#define IWL105_UCODE_API_MAX 6 +#define IWL135_UCODE_API_MAX 6 + +/* Oldest version we won't warn about */ +#define IWL2030_UCODE_API_OK 6 +#define IWL2000_UCODE_API_OK 6 +#define IWL105_UCODE_API_OK 6 +#define IWL135_UCODE_API_OK 6 + +/* Lowest firmware API version supported */ +#define IWL2030_UCODE_API_MIN 5 +#define IWL2000_UCODE_API_MIN 5 +#define IWL105_UCODE_API_MIN 5 +#define IWL135_UCODE_API_MIN 5 + +/* EEPROM version */ +#define EEPROM_2000_TX_POWER_VERSION (6) +#define EEPROM_2000_EEPROM_VERSION (0x805) + + +#define IWL2030_FW_PRE "iwlwifi-2030-" +#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" + +#define IWL2000_FW_PRE "iwlwifi-2000-" +#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode" + +#define IWL105_FW_PRE "iwlwifi-105-" +#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" + +#define IWL135_FW_PRE "iwlwifi-135-" +#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl2000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_2x00, + .shadow_ram_support = true, + .led_compensation = 51, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .hd_v2 = true, +}; + + +static const struct iwl_base_params iwl2030_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_2x00, + .shadow_ram_support = true, + .led_compensation = 57, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ + .hd_v2 = true, +}; + +static const struct iwl_ht_params iwl2000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ), +}; + +static const struct iwl_bt_params iwl2030_bt_params = { + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, + .bt_sco_disable = true, + .bt_session_2 = true, +}; + +static const struct iwl_eeprom_params iwl20x0_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REGULATORY_BAND_NO_HT40, + }, + .enhanced_txpower = true, +}; + +#define IWL_DEVICE_2000 \ + .fw_name_pre = IWL2000_FW_PRE, \ + .ucode_api_max = IWL2000_UCODE_API_MAX, \ + .ucode_api_ok = IWL2000_UCODE_API_OK, \ + .ucode_api_min = IWL2000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_2000, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2000_base_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE + +const struct iwl_cfg iwl2000_2bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", + IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, +}; + +const struct iwl_cfg iwl2000_2bgn_d_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", + IWL_DEVICE_2000, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_2030 \ + .fw_name_pre = IWL2030_FW_PRE, \ + .ucode_api_max = IWL2030_UCODE_API_MAX, \ + .ucode_api_ok = IWL2030_UCODE_API_OK, \ + .ucode_api_min = IWL2030_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_2030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true + +const struct iwl_cfg iwl2030_2bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", + IWL_DEVICE_2030, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_105 \ + .fw_name_pre = IWL105_FW_PRE, \ + .ucode_api_max = IWL105_UCODE_API_MAX, \ + .ucode_api_ok = IWL105_UCODE_API_OK, \ + .ucode_api_min = IWL105_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_105, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2000_base_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + .rx_with_siso_diversity = true + +const struct iwl_cfg iwl105_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", + IWL_DEVICE_105, + .ht_params = &iwl2000_ht_params, +}; + +const struct iwl_cfg iwl105_bgn_d_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", + IWL_DEVICE_105, + .ht_params = &iwl2000_ht_params, +}; + +#define IWL_DEVICE_135 \ + .fw_name_pre = IWL135_FW_PRE, \ + .ucode_api_max = IWL135_UCODE_API_MAX, \ + .ucode_api_ok = IWL135_UCODE_API_OK, \ + .ucode_api_min = IWL135_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_135, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ + .base_params = &iwl2030_base_params, \ + .bt_params = &iwl2030_bt_params, \ + .eeprom_params = &iwl20x0_eeprom_params, \ + .need_temp_offset_calib = true, \ + .temp_offset_v2 = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true, \ + .rx_with_siso_diversity = true + +const struct iwl_cfg iwl135_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", + IWL_DEVICE_135, + .ht_params = &iwl2000_ht_params, +}; + +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); +MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c new file mode 100644 index 000000000000..403f3f224bf6 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -0,0 +1,179 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" +#include "iwl-csr.h" + +/* Highest firmware API version supported */ +#define IWL5000_UCODE_API_MAX 5 +#define IWL5150_UCODE_API_MAX 2 + +/* Oldest version we won't warn about */ +#define IWL5000_UCODE_API_OK 5 +#define IWL5150_UCODE_API_OK 2 + +/* Lowest firmware API version supported */ +#define IWL5000_UCODE_API_MIN 1 +#define IWL5150_UCODE_API_MIN 1 + +/* EEPROM versions */ +#define EEPROM_5000_TX_POWER_VERSION (4) +#define EEPROM_5000_EEPROM_VERSION (0x11A) +#define EEPROM_5050_TX_POWER_VERSION (4) +#define EEPROM_5050_EEPROM_VERSION (0x21E) + +#define IWL5000_FW_PRE "iwlwifi-5000-" +#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" + +#define IWL5150_FW_PRE "iwlwifi-5150-" +#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl5000_base_params = { + .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, + .led_compensation = 51, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_WATCHDOG_DISABLED, + .max_event_log_size = 512, + .no_idle_support = true, +}; + +static const struct iwl_ht_params iwl5000_ht_params = { + .ht_greenfield_support = true, + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), +}; + +static const struct iwl_eeprom_params iwl5000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, +}; + +#define IWL_DEVICE_5000 \ + .fw_name_pre = IWL5000_FW_PRE, \ + .ucode_api_max = IWL5000_UCODE_API_MAX, \ + .ucode_api_ok = IWL5000_UCODE_API_OK, \ + .ucode_api_min = IWL5000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_5000, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_5000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ + .base_params = &iwl5000_base_params, \ + .eeprom_params = &iwl5000_eeprom_params, \ + .led_mode = IWL_LED_BLINK + +const struct iwl_cfg iwl5300_agn_cfg = { + .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", + IWL_DEVICE_5000, + /* at least EEPROM 0x11A has wrong info */ + .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ + .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ + .ht_params = &iwl5000_ht_params, +}; + +const struct iwl_cfg iwl5100_bgn_cfg = { + .name = "Intel(R) WiFi Link 5100 BGN", + IWL_DEVICE_5000, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ + .ht_params = &iwl5000_ht_params, +}; + +const struct iwl_cfg iwl5100_abg_cfg = { + .name = "Intel(R) WiFi Link 5100 ABG", + IWL_DEVICE_5000, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ +}; + +const struct iwl_cfg iwl5100_agn_cfg = { + .name = "Intel(R) WiFi Link 5100 AGN", + IWL_DEVICE_5000, + .valid_tx_ant = ANT_B, /* .cfg overwrite */ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ + .ht_params = &iwl5000_ht_params, +}; + +const struct iwl_cfg iwl5350_agn_cfg = { + .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", + .fw_name_pre = IWL5000_FW_PRE, + .ucode_api_max = IWL5000_UCODE_API_MAX, + .ucode_api_ok = IWL5000_UCODE_API_OK, + .ucode_api_min = IWL5000_UCODE_API_MIN, + .device_family = IWL_DEVICE_FAMILY_5000, + .max_inst_size = IWLAGN_RTC_INST_SIZE, + .max_data_size = IWLAGN_RTC_DATA_SIZE, + .nvm_ver = EEPROM_5050_EEPROM_VERSION, + .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, + .base_params = &iwl5000_base_params, + .eeprom_params = &iwl5000_eeprom_params, + .ht_params = &iwl5000_ht_params, + .led_mode = IWL_LED_BLINK, + .internal_wimax_coex = true, +}; + +#define IWL_DEVICE_5150 \ + .fw_name_pre = IWL5150_FW_PRE, \ + .ucode_api_max = IWL5150_UCODE_API_MAX, \ + .ucode_api_ok = IWL5150_UCODE_API_OK, \ + .ucode_api_min = IWL5150_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_5150, \ + .max_inst_size = IWLAGN_RTC_INST_SIZE, \ + .max_data_size = IWLAGN_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_5050_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ + .base_params = &iwl5000_base_params, \ + .eeprom_params = &iwl5000_eeprom_params, \ + .no_xtal_calib = true, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + +const struct iwl_cfg iwl5150_agn_cfg = { + .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", + IWL_DEVICE_5150, + .ht_params = &iwl5000_ht_params, + +}; + +const struct iwl_cfg iwl5150_abg_cfg = { + .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", + IWL_DEVICE_5150, +}; + +MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c new file mode 100644 index 000000000000..b5ab8d1bcac0 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -0,0 +1,402 @@ +/****************************************************************************** + * + * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" +#include "dvm/commands.h" /* needed for BT for now */ + +/* Highest firmware API version supported */ +#define IWL6000_UCODE_API_MAX 6 +#define IWL6050_UCODE_API_MAX 5 +#define IWL6000G2_UCODE_API_MAX 6 +#define IWL6035_UCODE_API_MAX 6 + +/* Oldest version we won't warn about */ +#define IWL6000_UCODE_API_OK 4 +#define IWL6000G2_UCODE_API_OK 5 +#define IWL6050_UCODE_API_OK 5 +#define IWL6000G2B_UCODE_API_OK 6 +#define IWL6035_UCODE_API_OK 6 + +/* Lowest firmware API version supported */ +#define IWL6000_UCODE_API_MIN 4 +#define IWL6050_UCODE_API_MIN 4 +#define IWL6000G2_UCODE_API_MIN 5 +#define IWL6035_UCODE_API_MIN 6 + +/* EEPROM versions */ +#define EEPROM_6000_TX_POWER_VERSION (4) +#define EEPROM_6000_EEPROM_VERSION (0x423) +#define EEPROM_6050_TX_POWER_VERSION (4) +#define EEPROM_6050_EEPROM_VERSION (0x532) +#define EEPROM_6150_TX_POWER_VERSION (6) +#define EEPROM_6150_EEPROM_VERSION (0x553) +#define EEPROM_6005_TX_POWER_VERSION (6) +#define EEPROM_6005_EEPROM_VERSION (0x709) +#define EEPROM_6030_TX_POWER_VERSION (6) +#define EEPROM_6030_EEPROM_VERSION (0x709) +#define EEPROM_6035_TX_POWER_VERSION (6) +#define EEPROM_6035_EEPROM_VERSION (0x753) + +#define IWL6000_FW_PRE "iwlwifi-6000-" +#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode" + +#define IWL6050_FW_PRE "iwlwifi-6050-" +#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode" + +#define IWL6005_FW_PRE "iwlwifi-6000g2a-" +#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode" + +#define IWL6030_FW_PRE "iwlwifi-6000g2b-" +#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl6000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 51, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_base_params iwl6050_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_6x50, + .shadow_ram_support = true, + .led_compensation = 51, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1500, + .wd_timeout = IWL_DEF_WD_TIMEOUT, + .max_event_log_size = 1024, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_base_params iwl6000_g2_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .shadow_ram_support = true, + .led_compensation = 57, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_ht_params iwl6000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), +}; + +static const struct iwl_bt_params iwl6000_bt_params = { + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .agg_time_limit = BT_AGG_THRESHOLD_DEF, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, + .bt_sco_disable = true, +}; + +static const struct iwl_eeprom_params iwl6000_eeprom_params = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, + .enhanced_txpower = true, +}; + +#define IWL_DEVICE_6005 \ + .fw_name_pre = IWL6005_FW_PRE, \ + .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ + .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ + .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6005, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6005_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE + +const struct iwl_cfg iwl6005_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", + IWL_DEVICE_6005, +}; + +const struct iwl_cfg iwl6005_2bg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", + IWL_DEVICE_6005, +}; + +const struct iwl_cfg iwl6005_2agn_sff_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_d_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_mow1_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6005_2agn_mow2_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", + IWL_DEVICE_6005, + .ht_params = &iwl6000_ht_params, +}; + +#define IWL_DEVICE_6030 \ + .fw_name_pre = IWL6030_FW_PRE, \ + .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ + .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ + .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true \ + +const struct iwl_cfg iwl6030_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6030_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", + IWL_DEVICE_6030, +}; + +const struct iwl_cfg iwl6030_2bgn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6030_2bg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", + IWL_DEVICE_6030, +}; + +#define IWL_DEVICE_6035 \ + .fw_name_pre = IWL6030_FW_PRE, \ + .ucode_api_max = IWL6035_UCODE_API_MAX, \ + .ucode_api_ok = IWL6035_UCODE_API_OK, \ + .ucode_api_min = IWL6035_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6030, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ + .base_params = &iwl6000_g2_base_params, \ + .bt_params = &iwl6000_bt_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true + +const struct iwl_cfg iwl6035_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", + IWL_DEVICE_6035, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl1030_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl1030_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", + IWL_DEVICE_6030, +}; + +const struct iwl_cfg iwl130_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", + IWL_DEVICE_6030, + .ht_params = &iwl6000_ht_params, + .rx_with_siso_diversity = true, +}; + +const struct iwl_cfg iwl130_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 130 BG", + IWL_DEVICE_6030, + .rx_with_siso_diversity = true, +}; + +/* + * "i": Internal configuration, use internal Power Amplifier + */ +#define IWL_DEVICE_6000i \ + .fw_name_pre = IWL6000_FW_PRE, \ + .ucode_api_max = IWL6000_UCODE_API_MAX, \ + .ucode_api_ok = IWL6000_UCODE_API_OK, \ + .ucode_api_min = IWL6000_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6000i, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ + .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ + .nvm_ver = EEPROM_6000_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ + .base_params = &iwl6000_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .led_mode = IWL_LED_BLINK + +const struct iwl_cfg iwl6000i_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", + IWL_DEVICE_6000i, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6000i_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", + IWL_DEVICE_6000i, +}; + +const struct iwl_cfg iwl6000i_2bg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", + IWL_DEVICE_6000i, +}; + +#define IWL_DEVICE_6050 \ + .fw_name_pre = IWL6050_FW_PRE, \ + .ucode_api_max = IWL6050_UCODE_API_MAX, \ + .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6050, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ + .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ + .nvm_ver = EEPROM_6050_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ + .base_params = &iwl6050_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + +const struct iwl_cfg iwl6050_2agn_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", + IWL_DEVICE_6050, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6050_2abg_cfg = { + .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", + IWL_DEVICE_6050, +}; + +#define IWL_DEVICE_6150 \ + .fw_name_pre = IWL6050_FW_PRE, \ + .ucode_api_max = IWL6050_UCODE_API_MAX, \ + .ucode_api_min = IWL6050_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_6150, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .nvm_ver = EEPROM_6150_EEPROM_VERSION, \ + .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ + .base_params = &iwl6050_base_params, \ + .eeprom_params = &iwl6000_eeprom_params, \ + .led_mode = IWL_LED_BLINK, \ + .internal_wimax_coex = true + +const struct iwl_cfg iwl6150_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", + IWL_DEVICE_6150, + .ht_params = &iwl6000_ht_params, +}; + +const struct iwl_cfg iwl6150_bg_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", + IWL_DEVICE_6150, +}; + +const struct iwl_cfg iwl6000_3agn_cfg = { + .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", + .fw_name_pre = IWL6000_FW_PRE, + .ucode_api_max = IWL6000_UCODE_API_MAX, + .ucode_api_ok = IWL6000_UCODE_API_OK, + .ucode_api_min = IWL6000_UCODE_API_MIN, + .device_family = IWL_DEVICE_FAMILY_6000, + .max_inst_size = IWL60_RTC_INST_SIZE, + .max_data_size = IWL60_RTC_DATA_SIZE, + .nvm_ver = EEPROM_6000_EEPROM_VERSION, + .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, + .base_params = &iwl6000_base_params, + .eeprom_params = &iwl6000_eeprom_params, + .ht_params = &iwl6000_ht_params, + .led_mode = IWL_LED_BLINK, +}; + +MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c new file mode 100644 index 000000000000..50263e87fe15 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -0,0 +1,146 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include +#include +#include "iwl-config.h" +#include "iwl-agn-hw.h" + +/* Highest firmware API version supported */ +#define IWL7260_UCODE_API_MAX 6 +#define IWL3160_UCODE_API_MAX 6 + +/* Oldest version we won't warn about */ +#define IWL7260_UCODE_API_OK 6 +#define IWL3160_UCODE_API_OK 6 + +/* Lowest firmware API version supported */ +#define IWL7260_UCODE_API_MIN 6 +#define IWL3160_UCODE_API_MIN 6 + +/* NVM versions */ +#define IWL7260_NVM_VERSION 0x0a1d +#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */ +#define IWL3160_NVM_VERSION 0x709 +#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */ + +#define IWL7260_FW_PRE "iwlwifi-7260-" +#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" + +#define IWL3160_FW_PRE "iwlwifi-3160-" +#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" + +static const struct iwl_base_params iwl7000_base_params = { + .eeprom_size = OTP_LOW_IMAGE_SIZE, + .num_of_queues = IWLAGN_NUM_QUEUES, + .pll_cfg_val = 0, + .shadow_ram_support = true, + .led_compensation = 57, + .adv_thermal_throttle = true, + .support_ct_kill_exit = true, + .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, + .chain_noise_scale = 1000, + .wd_timeout = IWL_LONG_WD_TIMEOUT, + .max_event_log_size = 512, + .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ +}; + +static const struct iwl_ht_params iwl7000_ht_params = { + .use_rts_for_aggregation = true, /* use rts/cts protection */ + .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), +}; + +#define IWL_DEVICE_7000 \ + .ucode_api_max = IWL7260_UCODE_API_MAX, \ + .ucode_api_ok = IWL7260_UCODE_API_OK, \ + .ucode_api_min = IWL7260_UCODE_API_MIN, \ + .device_family = IWL_DEVICE_FAMILY_7000, \ + .max_inst_size = IWL60_RTC_INST_SIZE, \ + .max_data_size = IWL60_RTC_DATA_SIZE, \ + .base_params = &iwl7000_base_params, \ + /* TODO: .bt_params? */ \ + .need_temp_offset_calib = true, \ + .led_mode = IWL_LED_RF_STATE, \ + .adv_pm = true \ + + +const struct iwl_cfg iwl7260_2ac_cfg = { + .name = "Intel(R) Dual Band Wireless AC7260", + .fw_name_pre = IWL7260_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL7260_NVM_VERSION, + .nvm_calib_ver = IWL7260_TX_POWER_VERSION, +}; + +const struct iwl_cfg iwl3160_ac_cfg = { + .name = "Intel(R) Dual Band Wireless AC3160", + .fw_name_pre = IWL3160_FW_PRE, + IWL_DEVICE_7000, + .ht_params = &iwl7000_ht_params, + .nvm_ver = IWL3160_NVM_VERSION, + .nvm_calib_ver = IWL3160_TX_POWER_VERSION, +}; + +MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); +MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 8ba293b2396b..c38aa8f77554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -275,4 +275,51 @@ struct iwl_cfg { const bool temp_offset_v2; }; +/* + * This list declares the config structures for all devices. + */ +extern const struct iwl_cfg iwl5300_agn_cfg; +extern const struct iwl_cfg iwl5100_agn_cfg; +extern const struct iwl_cfg iwl5350_agn_cfg; +extern const struct iwl_cfg iwl5100_bgn_cfg; +extern const struct iwl_cfg iwl5100_abg_cfg; +extern const struct iwl_cfg iwl5150_agn_cfg; +extern const struct iwl_cfg iwl5150_abg_cfg; +extern const struct iwl_cfg iwl6005_2agn_cfg; +extern const struct iwl_cfg iwl6005_2abg_cfg; +extern const struct iwl_cfg iwl6005_2bg_cfg; +extern const struct iwl_cfg iwl6005_2agn_sff_cfg; +extern const struct iwl_cfg iwl6005_2agn_d_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; +extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; +extern const struct iwl_cfg iwl1030_bgn_cfg; +extern const struct iwl_cfg iwl1030_bg_cfg; +extern const struct iwl_cfg iwl6030_2agn_cfg; +extern const struct iwl_cfg iwl6030_2abg_cfg; +extern const struct iwl_cfg iwl6030_2bgn_cfg; +extern const struct iwl_cfg iwl6030_2bg_cfg; +extern const struct iwl_cfg iwl6000i_2agn_cfg; +extern const struct iwl_cfg iwl6000i_2abg_cfg; +extern const struct iwl_cfg iwl6000i_2bg_cfg; +extern const struct iwl_cfg iwl6000_3agn_cfg; +extern const struct iwl_cfg iwl6050_2agn_cfg; +extern const struct iwl_cfg iwl6050_2abg_cfg; +extern const struct iwl_cfg iwl6150_bgn_cfg; +extern const struct iwl_cfg iwl6150_bg_cfg; +extern const struct iwl_cfg iwl1000_bgn_cfg; +extern const struct iwl_cfg iwl1000_bg_cfg; +extern const struct iwl_cfg iwl100_bgn_cfg; +extern const struct iwl_cfg iwl100_bg_cfg; +extern const struct iwl_cfg iwl130_bgn_cfg; +extern const struct iwl_cfg iwl130_bg_cfg; +extern const struct iwl_cfg iwl2000_2bgn_cfg; +extern const struct iwl_cfg iwl2000_2bgn_d_cfg; +extern const struct iwl_cfg iwl2030_2bgn_cfg; +extern const struct iwl_cfg iwl6035_2agn_cfg; +extern const struct iwl_cfg iwl105_bgn_cfg; +extern const struct iwl_cfg iwl105_bgn_d_cfg; +extern const struct iwl_cfg iwl135_bgn_cfg; +extern const struct iwl_cfg iwl7260_2ac_cfg; +extern const struct iwl_cfg iwl3160_ac_cfg; + #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/iwlwifi/pcie/1000.c b/drivers/net/wireless/iwlwifi/pcie/1000.c deleted file mode 100644 index ff3389757281..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/1000.c +++ /dev/null @@ -1,141 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-csr.h" -#include "iwl-agn-hw.h" -#include "cfg.h" - -/* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 5 -#define IWL100_UCODE_API_MAX 5 - -/* Oldest version we won't warn about */ -#define IWL1000_UCODE_API_OK 5 -#define IWL100_UCODE_API_OK 5 - -/* Lowest firmware API version supported */ -#define IWL1000_UCODE_API_MIN 1 -#define IWL100_UCODE_API_MIN 5 - -/* EEPROM version */ -#define EEPROM_1000_TX_POWER_VERSION (4) -#define EEPROM_1000_EEPROM_VERSION (0x15C) - -#define IWL1000_FW_PRE "iwlwifi-1000-" -#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode" - -#define IWL100_FW_PRE "iwlwifi-100-" -#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" - - -static const struct iwl_base_params iwl1000_base_params = { - .num_of_queues = IWLAGN_NUM_QUEUES, - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .max_ll_items = OTP_MAX_LL_ITEMS_1000, - .shadow_ram_support = false, - .led_compensation = 51, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_WATCHDOG_DISABLED, - .max_event_log_size = 128, -}; - -static const struct iwl_ht_params iwl1000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ), -}; - -static const struct iwl_eeprom_params iwl1000_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - } -}; - -#define IWL_DEVICE_1000 \ - .fw_name_pre = IWL1000_FW_PRE, \ - .ucode_api_max = IWL1000_UCODE_API_MAX, \ - .ucode_api_ok = IWL1000_UCODE_API_OK, \ - .ucode_api_min = IWL1000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_1000, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .base_params = &iwl1000_base_params, \ - .eeprom_params = &iwl1000_eeprom_params, \ - .led_mode = IWL_LED_BLINK - -const struct iwl_cfg iwl1000_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", - IWL_DEVICE_1000, - .ht_params = &iwl1000_ht_params, -}; - -const struct iwl_cfg iwl1000_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", - IWL_DEVICE_1000, -}; - -#define IWL_DEVICE_100 \ - .fw_name_pre = IWL100_FW_PRE, \ - .ucode_api_max = IWL100_UCODE_API_MAX, \ - .ucode_api_ok = IWL100_UCODE_API_OK, \ - .ucode_api_min = IWL100_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_100, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_1000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_1000_TX_POWER_VERSION, \ - .base_params = &iwl1000_base_params, \ - .eeprom_params = &iwl1000_eeprom_params, \ - .led_mode = IWL_LED_RF_STATE, \ - .rx_with_siso_diversity = true - -const struct iwl_cfg iwl100_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 100 BGN", - IWL_DEVICE_100, - .ht_params = &iwl1000_ht_params, -}; - -const struct iwl_cfg iwl100_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 100 BG", - IWL_DEVICE_100, -}; - -MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c deleted file mode 100644 index e7de33128b16..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ /dev/null @@ -1,243 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "cfg.h" -#include "dvm/commands.h" /* needed for BT for now */ - -/* Highest firmware API version supported */ -#define IWL2030_UCODE_API_MAX 6 -#define IWL2000_UCODE_API_MAX 6 -#define IWL105_UCODE_API_MAX 6 -#define IWL135_UCODE_API_MAX 6 - -/* Oldest version we won't warn about */ -#define IWL2030_UCODE_API_OK 6 -#define IWL2000_UCODE_API_OK 6 -#define IWL105_UCODE_API_OK 6 -#define IWL135_UCODE_API_OK 6 - -/* Lowest firmware API version supported */ -#define IWL2030_UCODE_API_MIN 5 -#define IWL2000_UCODE_API_MIN 5 -#define IWL105_UCODE_API_MIN 5 -#define IWL135_UCODE_API_MIN 5 - -/* EEPROM version */ -#define EEPROM_2000_TX_POWER_VERSION (6) -#define EEPROM_2000_EEPROM_VERSION (0x805) - - -#define IWL2030_FW_PRE "iwlwifi-2030-" -#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" - -#define IWL2000_FW_PRE "iwlwifi-2000-" -#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode" - -#define IWL105_FW_PRE "iwlwifi-105-" -#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" - -#define IWL135_FW_PRE "iwlwifi-135-" -#define IWL135_MODULE_FIRMWARE(api) IWL135_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl2000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_2x00, - .shadow_ram_support = true, - .led_compensation = 51, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ - .hd_v2 = true, -}; - - -static const struct iwl_base_params iwl2030_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_2x00, - .shadow_ram_support = true, - .led_compensation = 57, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ - .hd_v2 = true, -}; - -static const struct iwl_ht_params iwl2000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ), -}; - -static const struct iwl_bt_params iwl2030_bt_params = { - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .advanced_bt_coexist = true, - .agg_time_limit = BT_AGG_THRESHOLD_DEF, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, - .bt_sco_disable = true, - .bt_session_2 = true, -}; - -static const struct iwl_eeprom_params iwl20x0_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REGULATORY_BAND_NO_HT40, - }, - .enhanced_txpower = true, -}; - -#define IWL_DEVICE_2000 \ - .fw_name_pre = IWL2000_FW_PRE, \ - .ucode_api_max = IWL2000_UCODE_API_MAX, \ - .ucode_api_ok = IWL2000_UCODE_API_OK, \ - .ucode_api_min = IWL2000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_2000, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2000_base_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE - -const struct iwl_cfg iwl2000_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2200 BGN", - IWL_DEVICE_2000, - .ht_params = &iwl2000_ht_params, -}; - -const struct iwl_cfg iwl2000_2bgn_d_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2200D BGN", - IWL_DEVICE_2000, - .ht_params = &iwl2000_ht_params, -}; - -#define IWL_DEVICE_2030 \ - .fw_name_pre = IWL2030_FW_PRE, \ - .ucode_api_max = IWL2030_UCODE_API_MAX, \ - .ucode_api_ok = IWL2030_UCODE_API_OK, \ - .ucode_api_min = IWL2030_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_2030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2030_base_params, \ - .bt_params = &iwl2030_bt_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true - -const struct iwl_cfg iwl2030_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 2230 BGN", - IWL_DEVICE_2030, - .ht_params = &iwl2000_ht_params, -}; - -#define IWL_DEVICE_105 \ - .fw_name_pre = IWL105_FW_PRE, \ - .ucode_api_max = IWL105_UCODE_API_MAX, \ - .ucode_api_ok = IWL105_UCODE_API_OK, \ - .ucode_api_min = IWL105_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_105, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2000_base_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true, \ - .rx_with_siso_diversity = true - -const struct iwl_cfg iwl105_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 105 BGN", - IWL_DEVICE_105, - .ht_params = &iwl2000_ht_params, -}; - -const struct iwl_cfg iwl105_bgn_d_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 105D BGN", - IWL_DEVICE_105, - .ht_params = &iwl2000_ht_params, -}; - -#define IWL_DEVICE_135 \ - .fw_name_pre = IWL135_FW_PRE, \ - .ucode_api_max = IWL135_UCODE_API_MAX, \ - .ucode_api_ok = IWL135_UCODE_API_OK, \ - .ucode_api_min = IWL135_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_135, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_2000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_2000_TX_POWER_VERSION, \ - .base_params = &iwl2030_base_params, \ - .bt_params = &iwl2030_bt_params, \ - .eeprom_params = &iwl20x0_eeprom_params, \ - .need_temp_offset_calib = true, \ - .temp_offset_v2 = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true, \ - .rx_with_siso_diversity = true - -const struct iwl_cfg iwl135_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 135 BGN", - IWL_DEVICE_135, - .ht_params = &iwl2000_ht_params, -}; - -MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); -MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); -MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/5000.c b/drivers/net/wireless/iwlwifi/pcie/5000.c deleted file mode 100644 index 5096f7c96ab6..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/5000.c +++ /dev/null @@ -1,180 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "iwl-csr.h" -#include "cfg.h" - -/* Highest firmware API version supported */ -#define IWL5000_UCODE_API_MAX 5 -#define IWL5150_UCODE_API_MAX 2 - -/* Oldest version we won't warn about */ -#define IWL5000_UCODE_API_OK 5 -#define IWL5150_UCODE_API_OK 2 - -/* Lowest firmware API version supported */ -#define IWL5000_UCODE_API_MIN 1 -#define IWL5150_UCODE_API_MIN 1 - -/* EEPROM versions */ -#define EEPROM_5000_TX_POWER_VERSION (4) -#define EEPROM_5000_EEPROM_VERSION (0x11A) -#define EEPROM_5050_TX_POWER_VERSION (4) -#define EEPROM_5050_EEPROM_VERSION (0x21E) - -#define IWL5000_FW_PRE "iwlwifi-5000-" -#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" - -#define IWL5150_FW_PRE "iwlwifi-5150-" -#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl5000_base_params = { - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .led_compensation = 51, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_WATCHDOG_DISABLED, - .max_event_log_size = 512, - .no_idle_support = true, -}; - -static const struct iwl_ht_params iwl5000_ht_params = { - .ht_greenfield_support = true, - .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), -}; - -static const struct iwl_eeprom_params iwl5000_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, -}; - -#define IWL_DEVICE_5000 \ - .fw_name_pre = IWL5000_FW_PRE, \ - .ucode_api_max = IWL5000_UCODE_API_MAX, \ - .ucode_api_ok = IWL5000_UCODE_API_OK, \ - .ucode_api_min = IWL5000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_5000, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_5000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_5000_TX_POWER_VERSION, \ - .base_params = &iwl5000_base_params, \ - .eeprom_params = &iwl5000_eeprom_params, \ - .led_mode = IWL_LED_BLINK - -const struct iwl_cfg iwl5300_agn_cfg = { - .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", - IWL_DEVICE_5000, - /* at least EEPROM 0x11A has wrong info */ - .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ - .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; - -const struct iwl_cfg iwl5100_bgn_cfg = { - .name = "Intel(R) WiFi Link 5100 BGN", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; - -const struct iwl_cfg iwl5100_abg_cfg = { - .name = "Intel(R) WiFi Link 5100 ABG", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ -}; - -const struct iwl_cfg iwl5100_agn_cfg = { - .name = "Intel(R) WiFi Link 5100 AGN", - IWL_DEVICE_5000, - .valid_tx_ant = ANT_B, /* .cfg overwrite */ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ - .ht_params = &iwl5000_ht_params, -}; - -const struct iwl_cfg iwl5350_agn_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_ok = IWL5000_UCODE_API_OK, - .ucode_api_min = IWL5000_UCODE_API_MIN, - .device_family = IWL_DEVICE_FAMILY_5000, - .max_inst_size = IWLAGN_RTC_INST_SIZE, - .max_data_size = IWLAGN_RTC_DATA_SIZE, - .nvm_ver = EEPROM_5050_EEPROM_VERSION, - .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .base_params = &iwl5000_base_params, - .eeprom_params = &iwl5000_eeprom_params, - .ht_params = &iwl5000_ht_params, - .led_mode = IWL_LED_BLINK, - .internal_wimax_coex = true, -}; - -#define IWL_DEVICE_5150 \ - .fw_name_pre = IWL5150_FW_PRE, \ - .ucode_api_max = IWL5150_UCODE_API_MAX, \ - .ucode_api_ok = IWL5150_UCODE_API_OK, \ - .ucode_api_min = IWL5150_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_5150, \ - .max_inst_size = IWLAGN_RTC_INST_SIZE, \ - .max_data_size = IWLAGN_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_5050_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_5050_TX_POWER_VERSION, \ - .base_params = &iwl5000_base_params, \ - .eeprom_params = &iwl5000_eeprom_params, \ - .no_xtal_calib = true, \ - .led_mode = IWL_LED_BLINK, \ - .internal_wimax_coex = true - -const struct iwl_cfg iwl5150_agn_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5150 AGN", - IWL_DEVICE_5150, - .ht_params = &iwl5000_ht_params, - -}; - -const struct iwl_cfg iwl5150_abg_cfg = { - .name = "Intel(R) WiMAX/WiFi Link 5150 ABG", - IWL_DEVICE_5150, -}; - -MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/6000.c b/drivers/net/wireless/iwlwifi/pcie/6000.c deleted file mode 100644 index 801ff49796dd..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/6000.c +++ /dev/null @@ -1,403 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "cfg.h" -#include "dvm/commands.h" /* needed for BT for now */ - -/* Highest firmware API version supported */ -#define IWL6000_UCODE_API_MAX 6 -#define IWL6050_UCODE_API_MAX 5 -#define IWL6000G2_UCODE_API_MAX 6 -#define IWL6035_UCODE_API_MAX 6 - -/* Oldest version we won't warn about */ -#define IWL6000_UCODE_API_OK 4 -#define IWL6000G2_UCODE_API_OK 5 -#define IWL6050_UCODE_API_OK 5 -#define IWL6000G2B_UCODE_API_OK 6 -#define IWL6035_UCODE_API_OK 6 - -/* Lowest firmware API version supported */ -#define IWL6000_UCODE_API_MIN 4 -#define IWL6050_UCODE_API_MIN 4 -#define IWL6000G2_UCODE_API_MIN 5 -#define IWL6035_UCODE_API_MIN 6 - -/* EEPROM versions */ -#define EEPROM_6000_TX_POWER_VERSION (4) -#define EEPROM_6000_EEPROM_VERSION (0x423) -#define EEPROM_6050_TX_POWER_VERSION (4) -#define EEPROM_6050_EEPROM_VERSION (0x532) -#define EEPROM_6150_TX_POWER_VERSION (6) -#define EEPROM_6150_EEPROM_VERSION (0x553) -#define EEPROM_6005_TX_POWER_VERSION (6) -#define EEPROM_6005_EEPROM_VERSION (0x709) -#define EEPROM_6030_TX_POWER_VERSION (6) -#define EEPROM_6030_EEPROM_VERSION (0x709) -#define EEPROM_6035_TX_POWER_VERSION (6) -#define EEPROM_6035_EEPROM_VERSION (0x753) - -#define IWL6000_FW_PRE "iwlwifi-6000-" -#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode" - -#define IWL6050_FW_PRE "iwlwifi-6050-" -#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode" - -#define IWL6005_FW_PRE "iwlwifi-6000g2a-" -#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode" - -#define IWL6030_FW_PRE "iwlwifi-6000g2b-" -#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl6000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_base_params iwl6050_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .led_compensation = 51, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .wd_timeout = IWL_DEF_WD_TIMEOUT, - .max_event_log_size = 1024, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_base_params iwl6000_g2_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 57, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_ht_params iwl6000_ht_params = { - .ht_greenfield_support = true, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), -}; - -static const struct iwl_bt_params iwl6000_bt_params = { - /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ - .advanced_bt_coexist = true, - .agg_time_limit = BT_AGG_THRESHOLD_DEF, - .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, - .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, - .bt_sco_disable = true, -}; - -static const struct iwl_eeprom_params iwl6000_eeprom_params = { - .regulatory_bands = { - EEPROM_REG_BAND_1_CHANNELS, - EEPROM_REG_BAND_2_CHANNELS, - EEPROM_REG_BAND_3_CHANNELS, - EEPROM_REG_BAND_4_CHANNELS, - EEPROM_REG_BAND_5_CHANNELS, - EEPROM_6000_REG_BAND_24_HT40_CHANNELS, - EEPROM_REG_BAND_52_HT40_CHANNELS - }, - .enhanced_txpower = true, -}; - -#define IWL_DEVICE_6005 \ - .fw_name_pre = IWL6005_FW_PRE, \ - .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ - .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6005, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6005_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6005_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE - -const struct iwl_cfg iwl6005_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 ABG", - IWL_DEVICE_6005, -}; - -const struct iwl_cfg iwl6005_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205 BG", - IWL_DEVICE_6005, -}; - -const struct iwl_cfg iwl6005_2agn_sff_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205S AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2agn_d_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6205D AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2agn_mow1_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6206 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6005_2agn_mow2_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6207 AGN", - IWL_DEVICE_6005, - .ht_params = &iwl6000_ht_params, -}; - -#define IWL_DEVICE_6030 \ - .fw_name_pre = IWL6030_FW_PRE, \ - .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ - .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .bt_params = &iwl6000_bt_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ - -const struct iwl_cfg iwl6030_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 AGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6030_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 ABG", - IWL_DEVICE_6030, -}; - -const struct iwl_cfg iwl6030_2bgn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6030_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6230 BG", - IWL_DEVICE_6030, -}; - -#define IWL_DEVICE_6035 \ - .fw_name_pre = IWL6030_FW_PRE, \ - .ucode_api_max = IWL6035_UCODE_API_MAX, \ - .ucode_api_ok = IWL6035_UCODE_API_OK, \ - .ucode_api_min = IWL6035_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6030, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6030_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6030_TX_POWER_VERSION, \ - .base_params = &iwl6000_g2_base_params, \ - .bt_params = &iwl6000_bt_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true - -const struct iwl_cfg iwl6035_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6235 AGN", - IWL_DEVICE_6035, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl1030_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl1030_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1030 BG", - IWL_DEVICE_6030, -}; - -const struct iwl_cfg iwl130_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BGN", - IWL_DEVICE_6030, - .ht_params = &iwl6000_ht_params, - .rx_with_siso_diversity = true, -}; - -const struct iwl_cfg iwl130_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 130 BG", - IWL_DEVICE_6030, - .rx_with_siso_diversity = true, -}; - -/* - * "i": Internal configuration, use internal Power Amplifier - */ -#define IWL_DEVICE_6000i \ - .fw_name_pre = IWL6000_FW_PRE, \ - .ucode_api_max = IWL6000_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000_UCODE_API_OK, \ - .ucode_api_min = IWL6000_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6000i, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .valid_tx_ant = ANT_BC, /* .cfg overwrite */ \ - .valid_rx_ant = ANT_BC, /* .cfg overwrite */ \ - .nvm_ver = EEPROM_6000_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, \ - .base_params = &iwl6000_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .led_mode = IWL_LED_BLINK - -const struct iwl_cfg iwl6000i_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN", - IWL_DEVICE_6000i, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6000i_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG", - IWL_DEVICE_6000i, -}; - -const struct iwl_cfg iwl6000i_2bg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N 6200 BG", - IWL_DEVICE_6000i, -}; - -#define IWL_DEVICE_6050 \ - .fw_name_pre = IWL6050_FW_PRE, \ - .ucode_api_max = IWL6050_UCODE_API_MAX, \ - .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6050, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .valid_tx_ant = ANT_AB, /* .cfg overwrite */ \ - .valid_rx_ant = ANT_AB, /* .cfg overwrite */ \ - .nvm_ver = EEPROM_6050_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6050_TX_POWER_VERSION, \ - .base_params = &iwl6050_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .led_mode = IWL_LED_BLINK, \ - .internal_wimax_coex = true - -const struct iwl_cfg iwl6050_2agn_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN", - IWL_DEVICE_6050, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6050_2abg_cfg = { - .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG", - IWL_DEVICE_6050, -}; - -#define IWL_DEVICE_6150 \ - .fw_name_pre = IWL6050_FW_PRE, \ - .ucode_api_max = IWL6050_UCODE_API_MAX, \ - .ucode_api_min = IWL6050_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_6150, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .nvm_ver = EEPROM_6150_EEPROM_VERSION, \ - .nvm_calib_ver = EEPROM_6150_TX_POWER_VERSION, \ - .base_params = &iwl6050_base_params, \ - .eeprom_params = &iwl6000_eeprom_params, \ - .led_mode = IWL_LED_BLINK, \ - .internal_wimax_coex = true - -const struct iwl_cfg iwl6150_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN", - IWL_DEVICE_6150, - .ht_params = &iwl6000_ht_params, -}; - -const struct iwl_cfg iwl6150_bg_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG", - IWL_DEVICE_6150, -}; - -const struct iwl_cfg iwl6000_3agn_cfg = { - .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN", - .fw_name_pre = IWL6000_FW_PRE, - .ucode_api_max = IWL6000_UCODE_API_MAX, - .ucode_api_ok = IWL6000_UCODE_API_OK, - .ucode_api_min = IWL6000_UCODE_API_MIN, - .device_family = IWL_DEVICE_FAMILY_6000, - .max_inst_size = IWL60_RTC_INST_SIZE, - .max_data_size = IWL60_RTC_DATA_SIZE, - .nvm_ver = EEPROM_6000_EEPROM_VERSION, - .nvm_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .base_params = &iwl6000_base_params, - .eeprom_params = &iwl6000_eeprom_params, - .ht_params = &iwl6000_ht_params, - .led_mode = IWL_LED_BLINK, -}; - -MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/7000.c b/drivers/net/wireless/iwlwifi/pcie/7000.c deleted file mode 100644 index a5e9cfe3e746..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/7000.c +++ /dev/null @@ -1,147 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2012 - 2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ - -#include -#include -#include "iwl-config.h" -#include "iwl-agn-hw.h" -#include "cfg.h" - -/* Highest firmware API version supported */ -#define IWL7260_UCODE_API_MAX 6 -#define IWL3160_UCODE_API_MAX 6 - -/* Oldest version we won't warn about */ -#define IWL7260_UCODE_API_OK 6 -#define IWL3160_UCODE_API_OK 6 - -/* Lowest firmware API version supported */ -#define IWL7260_UCODE_API_MIN 6 -#define IWL3160_UCODE_API_MIN 6 - -/* NVM versions */ -#define IWL7260_NVM_VERSION 0x0a1d -#define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */ -#define IWL3160_NVM_VERSION 0x709 -#define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */ - -#define IWL7260_FW_PRE "iwlwifi-7260-" -#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" - -#define IWL3160_FW_PRE "iwlwifi-3160-" -#define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" - -static const struct iwl_base_params iwl7000_base_params = { - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .num_of_queues = IWLAGN_NUM_QUEUES, - .pll_cfg_val = 0, - .shadow_ram_support = true, - .led_compensation = 57, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .wd_timeout = IWL_LONG_WD_TIMEOUT, - .max_event_log_size = 512, - .shadow_reg_enable = false, /* TODO: fix bugs using this feature */ -}; - -static const struct iwl_ht_params iwl7000_ht_params = { - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), -}; - -#define IWL_DEVICE_7000 \ - .ucode_api_max = IWL7260_UCODE_API_MAX, \ - .ucode_api_ok = IWL7260_UCODE_API_OK, \ - .ucode_api_min = IWL7260_UCODE_API_MIN, \ - .device_family = IWL_DEVICE_FAMILY_7000, \ - .max_inst_size = IWL60_RTC_INST_SIZE, \ - .max_data_size = IWL60_RTC_DATA_SIZE, \ - .base_params = &iwl7000_base_params, \ - /* TODO: .bt_params? */ \ - .need_temp_offset_calib = true, \ - .led_mode = IWL_LED_RF_STATE, \ - .adv_pm = true \ - - -const struct iwl_cfg iwl7260_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC7260", - .fw_name_pre = IWL7260_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL7260_NVM_VERSION, - .nvm_calib_ver = IWL7260_TX_POWER_VERSION, -}; - -const struct iwl_cfg iwl3160_ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC3160", - .fw_name_pre = IWL3160_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL3160_NVM_VERSION, - .nvm_calib_ver = IWL3160_TX_POWER_VERSION, -}; - -MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); -MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/pcie/cfg.h b/drivers/net/wireless/iwlwifi/pcie/cfg.h deleted file mode 100644 index f4318fb192df..000000000000 --- a/drivers/net/wireless/iwlwifi/pcie/cfg.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2007 - 2013 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - *****************************************************************************/ -#ifndef __iwl_pci_h__ -#define __iwl_pci_h__ - - -/* - * This file declares the config structures for all devices. - */ - -extern const struct iwl_cfg iwl5300_agn_cfg; -extern const struct iwl_cfg iwl5100_agn_cfg; -extern const struct iwl_cfg iwl5350_agn_cfg; -extern const struct iwl_cfg iwl5100_bgn_cfg; -extern const struct iwl_cfg iwl5100_abg_cfg; -extern const struct iwl_cfg iwl5150_agn_cfg; -extern const struct iwl_cfg iwl5150_abg_cfg; -extern const struct iwl_cfg iwl6005_2agn_cfg; -extern const struct iwl_cfg iwl6005_2abg_cfg; -extern const struct iwl_cfg iwl6005_2bg_cfg; -extern const struct iwl_cfg iwl6005_2agn_sff_cfg; -extern const struct iwl_cfg iwl6005_2agn_d_cfg; -extern const struct iwl_cfg iwl6005_2agn_mow1_cfg; -extern const struct iwl_cfg iwl6005_2agn_mow2_cfg; -extern const struct iwl_cfg iwl1030_bgn_cfg; -extern const struct iwl_cfg iwl1030_bg_cfg; -extern const struct iwl_cfg iwl6030_2agn_cfg; -extern const struct iwl_cfg iwl6030_2abg_cfg; -extern const struct iwl_cfg iwl6030_2bgn_cfg; -extern const struct iwl_cfg iwl6030_2bg_cfg; -extern const struct iwl_cfg iwl6000i_2agn_cfg; -extern const struct iwl_cfg iwl6000i_2abg_cfg; -extern const struct iwl_cfg iwl6000i_2bg_cfg; -extern const struct iwl_cfg iwl6000_3agn_cfg; -extern const struct iwl_cfg iwl6050_2agn_cfg; -extern const struct iwl_cfg iwl6050_2abg_cfg; -extern const struct iwl_cfg iwl6150_bgn_cfg; -extern const struct iwl_cfg iwl6150_bg_cfg; -extern const struct iwl_cfg iwl1000_bgn_cfg; -extern const struct iwl_cfg iwl1000_bg_cfg; -extern const struct iwl_cfg iwl100_bgn_cfg; -extern const struct iwl_cfg iwl100_bg_cfg; -extern const struct iwl_cfg iwl130_bgn_cfg; -extern const struct iwl_cfg iwl130_bg_cfg; -extern const struct iwl_cfg iwl2000_2bgn_cfg; -extern const struct iwl_cfg iwl2000_2bgn_d_cfg; -extern const struct iwl_cfg iwl2030_2bgn_cfg; -extern const struct iwl_cfg iwl6035_2agn_cfg; -extern const struct iwl_cfg iwl105_bgn_cfg; -extern const struct iwl_cfg iwl105_bgn_d_cfg; -extern const struct iwl_cfg iwl135_bgn_cfg; -extern const struct iwl_cfg iwl7260_2ac_cfg; -extern const struct iwl_cfg iwl3160_ac_cfg; - -#endif /* __iwl_pci_h__ */ diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 49b254326d9c..46ca91f77c9c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -69,8 +69,6 @@ #include "iwl-trans.h" #include "iwl-drv.h" - -#include "cfg.h" #include "internal.h" #define IWL_PCI_DEVICE(dev, subdev, cfg) \ -- cgit v1.2.3 From 506a81e6ba1148a4435dec95651cd93874c2b7cf Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 28 Feb 2013 14:05:14 +0100 Subject: iwlwifi: mvm: don't read system time when modifying AP/GO MAC When modifying a MAC, we update its beacon system time which is taken as a base to calculate TBTT. The firmware doesn't use the new timestamp because the time is never used after the MAC and broadcast station were added, but it is safer to not rely on this and avoids the overhead of reading the register every time the MAC is updated. Reviewed-by: Emmanuel Grumbach Reviewed-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 25 ++++++++++++++++++------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 ++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index a993f6c7dac0..2779235daa35 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -855,10 +855,10 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, */ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_mac_data_ap *ctxt_ap) + struct iwl_mac_data_ap *ctxt_ap, + bool add) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - u32 curr_dev_time; ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); ctxt_ap->bi_reciprocal = @@ -870,10 +870,19 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm, vif->bss_conf.dtim_period)); ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); - curr_dev_time = iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); - ctxt_ap->beacon_time = cpu_to_le32(curr_dev_time); - ctxt_ap->beacon_tsf = cpu_to_le64(curr_dev_time); + /* + * Only read the system time when the MAC is being added, when we + * just modify the MAC then we should keep the time -- the firmware + * can otherwise have a "jumping" TBTT. + */ + if (add) + mvmvif->ap_beacon_time = + iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); + + ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); + + ctxt_ap->beacon_tsf = 0; /* unused */ /* TODO: Assume that the beacon id == mac context id */ ctxt_ap->beacon_template = cpu_to_le32(mvmvif->id); @@ -894,7 +903,8 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm, cmd.filter_flags |= cpu_to_le32(MAC_FILTER_IN_PROBE_REQUEST); /* Fill the data specific for ap mode */ - iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap); + iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.ap, + action == FW_CTXT_ACTION_ADD); return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } @@ -911,7 +921,8 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm, iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); /* Fill the data specific for GO mode */ - iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap); + iwl_mvm_mac_ctxt_cmd_fill_ap(mvm, vif, &cmd.go.ap, + action == FW_CTXT_ACTION_ADD); cmd.go.ctwin = cpu_to_le32(vif->bss_conf.p2p_ctwindow); cmd.go.opp_ps_enabled = cpu_to_le32(!!vif->bss_conf.p2p_oppps); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index efe5da992897..234c5726d196 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -174,6 +174,8 @@ struct iwl_mvm_vif { bool uploaded; bool ap_active; + u32 ap_beacon_time; + enum iwl_tsf_id tsf_id; /* -- cgit v1.2.3 From 1fd4afe2d13588f935d9f8642a696f84aa1f03d1 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 10:18:07 +0200 Subject: iwlwifi: mvm: Change NVM default section read size Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/nvm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 555095cf4afc..93e3d0f174cc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -74,6 +74,9 @@ static const int nvm_to_read[] = { NVM_SECTION_TYPE_PRODUCTION, }; +/* Default NVM size to read */ +#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024); + /* used to simplify the shared operations on NCM_ACCESS_CMD versions */ union iwl_nvm_access_cmd { struct iwl_nvm_access_cmd_ver1 ver1; @@ -193,9 +196,9 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, int ret; bool old_eeprom = mvm->cfg->device_family != IWL_DEVICE_FAMILY_7000; - length = (iwlwifi_mod_params.amsdu_size_8K ? (8 * 1024) : (4 * 1024)) - - sizeof(union iwl_nvm_access_cmd) - - sizeof(struct iwl_rx_packet); + /* Set nvm section read length */ + length = IWL_NVM_DEFAULT_CHUNK_SIZE; + /* * if length is greater than EEPROM size, truncate it because uCode * doesn't check it by itself, and exit the loop when reached. -- cgit v1.2.3 From 1218206e9d642f63801417156be46d8d0175164a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Mar 2013 00:05:26 +0100 Subject: iwlwifi: allow selecting only MVM driver Now that we have two drivers (DVM and MVM) stop selecting the DVM one (but make it default) and allow enabling only the MVM driver if so desired. Add a warning for the case of having neither DVM nor MVM enabled -- that's useless. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Kconfig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index ba319cba3f1e..615ed10825b8 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -6,7 +6,6 @@ config IWLWIFI select LEDS_CLASS select LEDS_TRIGGERS select MAC80211_LEDS - select IWLDVM ---help--- Select to build the driver supporting the: @@ -45,6 +44,7 @@ config IWLWIFI config IWLDVM tristate "Intel Wireless WiFi DVM Firmware support" depends on IWLWIFI + default IWLWIFI help This is the driver supporting the DVM firmware which is currently the only firmware available for existing devices. @@ -58,6 +58,9 @@ config IWLMVM Say yes if you have such a device. +comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM" + depends on IWLWIFI && IWLDVM=n && IWLMVM=n + menu "Debugging Options" depends on IWLWIFI -- cgit v1.2.3 From 48e29340d54104ab0d8f995f32485e28ff00e59e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Mar 2013 00:13:33 +0100 Subject: iwlwifi: export symbols only conditionally If all the pieces of iwlwifi are built into the kernel then there's no need for it to export its symbols to other modules, so prevent that. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/Kconfig | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-debug.c | 11 ++++++----- drivers/net/wireless/iwlwifi/iwl-drv.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-drv.h | 15 +++++++++++++++ drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | 5 +++-- drivers/net/wireless/iwlwifi/iwl-eeprom-read.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-io.c | 19 ++++++++++--------- drivers/net/wireless/iwlwifi/iwl-notif-wait.c | 13 +++++++------ drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 ++- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 9 +++++---- drivers/net/wireless/iwlwifi/iwl-test.c | 9 +++++---- 11 files changed, 64 insertions(+), 35 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 615ed10825b8..56c2040a955b 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -58,6 +58,12 @@ config IWLMVM Say yes if you have such a device. +# don't call it _MODULE -- will confuse Kconfig/fixdep/... +config IWLWIFI_OPMODE_MODULAR + bool + default y if IWLDVM=m + default y if IWLMVM=m + comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM" depends on IWLWIFI && IWLDVM=n && IWLMVM=n diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.c b/drivers/net/wireless/iwlwifi/iwl-debug.c index 88df574e33de..8a44f594528d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.c +++ b/drivers/net/wireless/iwlwifi/iwl-debug.c @@ -66,6 +66,7 @@ #include #include #include +#include "iwl-drv.h" #include "iwl-debug.h" #include "iwl-devtrace.h" @@ -85,11 +86,11 @@ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ } __iwl_fn(warn) -EXPORT_SYMBOL_GPL(__iwl_warn); +IWL_EXPORT_SYMBOL(__iwl_warn); __iwl_fn(info) -EXPORT_SYMBOL_GPL(__iwl_info); +IWL_EXPORT_SYMBOL(__iwl_info); __iwl_fn(crit) -EXPORT_SYMBOL_GPL(__iwl_crit); +IWL_EXPORT_SYMBOL(__iwl_crit); void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, const char *fmt, ...) @@ -110,7 +111,7 @@ void __iwl_err(struct device *dev, bool rfkill_prefix, bool trace_only, trace_iwlwifi_err(&vaf); va_end(args); } -EXPORT_SYMBOL_GPL(__iwl_err); +IWL_EXPORT_SYMBOL(__iwl_err); #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) void __iwl_dbg(struct device *dev, @@ -133,5 +134,5 @@ void __iwl_dbg(struct device *dev, trace_iwlwifi_dbg(level, in_interrupt(), function, &vaf); va_end(args); } -EXPORT_SYMBOL_GPL(__iwl_dbg); +IWL_EXPORT_SYMBOL(__iwl_dbg); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 8620de406f64..15ac54baa833 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1111,7 +1111,7 @@ struct iwl_mod_params iwlwifi_mod_params = { .wd_disable = true, /* the rest are 0 by default */ }; -EXPORT_SYMBOL_GPL(iwlwifi_mod_params); +IWL_EXPORT_SYMBOL(iwlwifi_mod_params); int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) { @@ -1135,7 +1135,7 @@ int iwl_opmode_register(const char *name, const struct iwl_op_mode_ops *ops) mutex_unlock(&iwlwifi_opmode_table_mtx); return -EIO; } -EXPORT_SYMBOL_GPL(iwl_opmode_register); +IWL_EXPORT_SYMBOL(iwl_opmode_register); void iwl_opmode_deregister(const char *name) { @@ -1157,7 +1157,7 @@ void iwl_opmode_deregister(const char *name) } mutex_unlock(&iwlwifi_opmode_table_mtx); } -EXPORT_SYMBOL_GPL(iwl_opmode_deregister); +IWL_EXPORT_SYMBOL(iwl_opmode_deregister); static int __init iwl_drv_init(void) { diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h index 4c96472ac3ea..7d1450916308 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.h +++ b/drivers/net/wireless/iwlwifi/iwl-drv.h @@ -63,6 +63,8 @@ #ifndef __iwl_drv_h__ #define __iwl_drv_h__ +#include + /* for all modules */ #define DRV_NAME "iwlwifi" #define IWLWIFI_VERSION "in-tree:" @@ -123,4 +125,17 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, */ void iwl_drv_stop(struct iwl_drv *drv); +/* + * exported symbol management + * + * The driver can be split into multiple modules, in which case some symbols + * must be exported for the sub-modules. However, if it's not split and + * everything is built-in, then we can avoid that. + */ +#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR +#define IWL_EXPORT_SYMBOL(sym) EXPORT_SYMBOL_GPL(sym) +#else +#define IWL_EXPORT_SYMBOL(sym) +#endif + #endif /* __iwl_drv_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index e170f5e6ee7a..600c9fdd7f71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -62,6 +62,7 @@ #include #include #include +#include "iwl-drv.h" #include "iwl-modparams.h" #include "iwl-eeprom-parse.h" @@ -909,7 +910,7 @@ iwl_parse_eeprom_data(struct device *dev, const struct iwl_cfg *cfg, kfree(data); return NULL; } -EXPORT_SYMBOL_GPL(iwl_parse_eeprom_data); +IWL_EXPORT_SYMBOL(iwl_parse_eeprom_data); /* helper functions */ int iwl_nvm_check_version(struct iwl_nvm_data *data, @@ -928,4 +929,4 @@ int iwl_nvm_check_version(struct iwl_nvm_data *data, data->calib_version, trans->cfg->nvm_calib_ver); return -EINVAL; } -EXPORT_SYMBOL_GPL(iwl_nvm_check_version); +IWL_EXPORT_SYMBOL(iwl_nvm_check_version); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c index 92e7245ced8d..e5f2e362ab0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-read.c @@ -63,6 +63,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-debug.h" #include "iwl-eeprom-read.h" #include "iwl-io.h" @@ -460,4 +461,4 @@ int iwl_read_eeprom(struct iwl_trans *trans, u8 **eeprom, size_t *eeprom_size) return ret; } -EXPORT_SYMBOL_GPL(iwl_read_eeprom); +IWL_EXPORT_SYMBOL(iwl_read_eeprom); diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 276410d82de4..305c81f2c2b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -29,6 +29,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-io.h" #include "iwl-csr.h" #include "iwl-debug.h" @@ -49,7 +50,7 @@ int iwl_poll_bit(struct iwl_trans *trans, u32 addr, return -ETIMEDOUT; } -EXPORT_SYMBOL_GPL(iwl_poll_bit); +IWL_EXPORT_SYMBOL(iwl_poll_bit); u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { @@ -62,7 +63,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) return value; } -EXPORT_SYMBOL_GPL(iwl_read_direct32); +IWL_EXPORT_SYMBOL(iwl_read_direct32); void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) { @@ -73,7 +74,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_write_direct32); +IWL_EXPORT_SYMBOL(iwl_write_direct32); int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout) @@ -89,7 +90,7 @@ int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, return -ETIMEDOUT; } -EXPORT_SYMBOL_GPL(iwl_poll_direct_bit); +IWL_EXPORT_SYMBOL(iwl_poll_direct_bit); static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs) { @@ -115,7 +116,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs) } return val; } -EXPORT_SYMBOL_GPL(iwl_read_prph); +IWL_EXPORT_SYMBOL(iwl_read_prph); void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) { @@ -126,7 +127,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_write_prph); +IWL_EXPORT_SYMBOL(iwl_write_prph); void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) { @@ -138,7 +139,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_set_bits_prph); +IWL_EXPORT_SYMBOL(iwl_set_bits_prph); void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, u32 bits, u32 mask) @@ -151,7 +152,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs, iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph); +IWL_EXPORT_SYMBOL(iwl_set_bits_mask_prph); void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) { @@ -164,4 +165,4 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask) iwl_trans_release_nic_access(trans, &flags); } } -EXPORT_SYMBOL_GPL(iwl_clear_bits_prph); +IWL_EXPORT_SYMBOL(iwl_clear_bits_prph); diff --git a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c index 721fc64dd44b..940b8a9d5285 100644 --- a/drivers/net/wireless/iwlwifi/iwl-notif-wait.c +++ b/drivers/net/wireless/iwlwifi/iwl-notif-wait.c @@ -63,6 +63,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-notif-wait.h" @@ -72,7 +73,7 @@ void iwl_notification_wait_init(struct iwl_notif_wait_data *notif_wait) INIT_LIST_HEAD(¬if_wait->notif_waits); init_waitqueue_head(¬if_wait->notif_waitq); } -EXPORT_SYMBOL_GPL(iwl_notification_wait_init); +IWL_EXPORT_SYMBOL(iwl_notification_wait_init); void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt) @@ -117,7 +118,7 @@ void iwl_notification_wait_notify(struct iwl_notif_wait_data *notif_wait, if (triggered) wake_up_all(¬if_wait->notif_waitq); } -EXPORT_SYMBOL_GPL(iwl_notification_wait_notify); +IWL_EXPORT_SYMBOL(iwl_notification_wait_notify); void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) { @@ -130,7 +131,7 @@ void iwl_abort_notification_waits(struct iwl_notif_wait_data *notif_wait) wake_up_all(¬if_wait->notif_waitq); } -EXPORT_SYMBOL_GPL(iwl_abort_notification_waits); +IWL_EXPORT_SYMBOL(iwl_abort_notification_waits); void iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, @@ -154,7 +155,7 @@ iwl_init_notification_wait(struct iwl_notif_wait_data *notif_wait, list_add(&wait_entry->list, ¬if_wait->notif_waits); spin_unlock_bh(¬if_wait->notif_wait_lock); } -EXPORT_SYMBOL_GPL(iwl_init_notification_wait); +IWL_EXPORT_SYMBOL(iwl_init_notification_wait); int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, struct iwl_notification_wait *wait_entry, @@ -178,7 +179,7 @@ int iwl_wait_notification(struct iwl_notif_wait_data *notif_wait, return -ETIMEDOUT; return 0; } -EXPORT_SYMBOL_GPL(iwl_wait_notification); +IWL_EXPORT_SYMBOL(iwl_wait_notification); void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, struct iwl_notification_wait *wait_entry) @@ -187,4 +188,4 @@ void iwl_remove_notification(struct iwl_notif_wait_data *notif_wait, list_del(&wait_entry->list); spin_unlock_bh(¬if_wait->notif_wait_lock); } -EXPORT_SYMBOL_GPL(iwl_remove_notification); +IWL_EXPORT_SYMBOL(iwl_remove_notification); diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 1ae6f2c1558d..6199a0a597a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c @@ -62,6 +62,7 @@ #include #include #include +#include "iwl-drv.h" #include "iwl-modparams.h" #include "iwl-nvm-parse.h" @@ -389,4 +390,4 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, return data; } -EXPORT_SYMBOL_GPL(iwl_parse_nvm_data); +IWL_EXPORT_SYMBOL(iwl_parse_nvm_data); diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 31c05487a688..25745daa0d5d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -65,6 +65,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-phy-db.h" #include "iwl-debug.h" #include "iwl-op-mode.h" @@ -149,7 +150,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) /* TODO: add default values of the phy db. */ return phy_db; } -EXPORT_SYMBOL(iwl_phy_db_init); +IWL_EXPORT_SYMBOL(iwl_phy_db_init); /* * get phy db section: returns a pointer to a phy db section specified by @@ -215,7 +216,7 @@ void iwl_phy_db_free(struct iwl_phy_db *phy_db) kfree(phy_db); } -EXPORT_SYMBOL(iwl_phy_db_free); +IWL_EXPORT_SYMBOL(iwl_phy_db_free); int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, gfp_t alloc_ctx) @@ -260,7 +261,7 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, return 0; } -EXPORT_SYMBOL(iwl_phy_db_set_section); +IWL_EXPORT_SYMBOL(iwl_phy_db_set_section); static int is_valid_channel(u16 ch_id) { @@ -495,4 +496,4 @@ int iwl_send_phy_db_data(struct iwl_phy_db *phy_db) "Finished sending phy db non channel data\n"); return 0; } -EXPORT_SYMBOL(iwl_send_phy_db_data); +IWL_EXPORT_SYMBOL(iwl_send_phy_db_data); diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c index a7cbf7906200..efff2986b5b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-test.c +++ b/drivers/net/wireless/iwlwifi/iwl-test.c @@ -64,6 +64,7 @@ #include #include +#include "iwl-drv.h" #include "iwl-io.h" #include "iwl-fh.h" #include "iwl-prph.h" @@ -653,7 +654,7 @@ int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb, } return 0; } -EXPORT_SYMBOL_GPL(iwl_test_parse); +IWL_EXPORT_SYMBOL(iwl_test_parse); /* * Handle test commands. @@ -715,7 +716,7 @@ int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb) } return result; } -EXPORT_SYMBOL_GPL(iwl_test_handle_cmd); +IWL_EXPORT_SYMBOL(iwl_test_handle_cmd); static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb, struct netlink_callback *cb) @@ -803,7 +804,7 @@ int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb, } return result; } -EXPORT_SYMBOL_GPL(iwl_test_dump); +IWL_EXPORT_SYMBOL(iwl_test_dump); /* * Multicast a spontaneous messages from the device to the user space. @@ -849,4 +850,4 @@ void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb) if (tst->notify) iwl_test_send_rx(tst, rxb); } -EXPORT_SYMBOL_GPL(iwl_test_rx); +IWL_EXPORT_SYMBOL(iwl_test_rx); -- cgit v1.2.3 From 3b4612fbd3a571b4f37e87fcd66c9b4d213341f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 3 Mar 2013 09:14:51 +0200 Subject: iwlwifi: mvm: add CARD_STATE_NOTIFICATION to the cmd strings Then the transport can print it nicely in its debug prints. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 473864733aab..dda699e1c996 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -293,6 +293,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(NET_DETECT_PROFILES_CMD), CMD(NET_DETECT_HOTSPOTS_CMD), CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), + CMD(CARD_STATE_NOTIFICATION), }; #undef CMD -- cgit v1.2.3 From fb3ceb817503f3d89e3beb4f48a2f4d608a6697f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 14 Jan 2013 15:04:01 +0200 Subject: iwlwifi: mvm: add BT Coex FW API This is the API to tell the fw to handle the BT Coexistence. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h | 319 ++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw-api.h | 7 + drivers/net/wireless/iwlwifi/mvm/ops.c | 4 + 3 files changed, 330 insertions(+) create mode 100644 drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h new file mode 100644 index 000000000000..05c61d6f384e --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h @@ -0,0 +1,319 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __fw_api_bt_coex_h__ +#define __fw_api_bt_coex_h__ + +#include +#include + +#define BITS(nb) (BIT(nb) - 1) + +/** + * enum iwl_bt_coex_flags - flags for BT_COEX command + * @BT_CH_PRIMARY_EN: + * @BT_CH_SECONDARY_EN: + * @BT_NOTIF_COEX_OFF: + * @BT_COEX_MODE_POS: + * @BT_COEX_MODE_MSK: + * @BT_COEX_DISABLE: + * @BT_COEX_2W: + * @BT_COEX_3W: + * @BT_COEX_NW: + * @BT_USE_DEFAULTS: + * @BT_SYNC_2_BT_DISABLE: + * @BT_COEX_CORUNNING_TBL_EN: + */ +enum iwl_bt_coex_flags { + BT_CH_PRIMARY_EN = BIT(0), + BT_CH_SECONDARY_EN = BIT(1), + BT_NOTIF_COEX_OFF = BIT(2), + BT_COEX_MODE_POS = 3, + BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS, + BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS, + BT_COEX_2W = 0x1 << BT_COEX_MODE_POS, + BT_COEX_3W = 0x2 << BT_COEX_MODE_POS, + BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, + BT_USE_DEFAULTS = BIT(6), + BT_SYNC_2_BT_DISABLE = BIT(7), + /* + * For future use - when the flags will be enlarged + * BT_COEX_CORUNNING_TBL_EN = BIT(8), + */ +}; + +/* + * indicates what has changed in the BT_COEX command. + */ +enum iwl_bt_coex_valid_bit_msk { + BT_VALID_ENABLE = BIT(0), + BT_VALID_BT_PRIO_BOOST = BIT(1), + BT_VALID_MAX_KILL = BIT(2), + BT_VALID_3W_TMRS = BIT(3), + BT_VALID_KILL_ACK = BIT(4), + BT_VALID_KILL_CTS = BIT(5), + BT_VALID_REDUCED_TX_POWER = BIT(6), + BT_VALID_LUT = BIT(7), + BT_VALID_WIFI_RX_SW_PRIO_BOOST = BIT(8), + BT_VALID_WIFI_TX_SW_PRIO_BOOST = BIT(9), + BT_VALID_MULTI_PRIO_LUT = BIT(10), + BT_VALID_TRM_KICK_FILTER = BIT(11), + BT_VALID_CORUN_LUT_20 = BIT(12), + BT_VALID_CORUN_LUT_40 = BIT(13), + BT_VALID_ANT_ISOLATION = BIT(14), + BT_VALID_ANT_ISOLATION_THRS = BIT(15), + /* + * For future use - when the valid flags will be enlarged + * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), + * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), + */ +}; + +/** + * enum iwl_bt_reduced_tx_power - allows to reduce txpower for WiFi frames. + * @BT_REDUCED_TX_POWER_CTL: reduce Tx power for control frames + * @BT_REDUCED_TX_POWER_DATA: reduce Tx power for data frames + * + * This mechanism allows to have BT and WiFi run concurrently. Since WiFi + * reduces its Tx power, it can work along with BT, hence reducing the amount + * of WiFi frames being killed by BT. + */ +enum iwl_bt_reduced_tx_power { + BT_REDUCED_TX_POWER_CTL = BIT(0), + BT_REDUCED_TX_POWER_DATA = BIT(1), +}; + +#define BT_COEX_LUT_SIZE (12) + +/** + * struct iwl_bt_coex_cmd - bt coex configuration command + * @flags:&enum iwl_bt_coex_flags + * @lead_time: + * @max_kill: + * @bt3_time_t7_value: + * @kill_ack_msk: + * @kill_cts_msk: + * @bt3_prio_sample_time: + * @bt3_timer_t2_value: + * @bt4_reaction_time: + * @decision_lut[12]: + * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power + * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk + * @bt_prio_boost: values for PTA boost register + * @wifi_tx_prio_boost: SW boost of wifi tx priority + * @wifi_rx_prio_boost: SW boost of wifi rx priority + * + * The structure is used for the BT_COEX command. + */ +struct iwl_bt_coex_cmd { + u8 flags; + u8 lead_time; + u8 max_kill; + u8 bt3_time_t7_value; + __le32 kill_ack_msk; + __le32 kill_cts_msk; + u8 bt3_prio_sample_time; + u8 bt3_timer_t2_value; + __le16 bt4_reaction_time; + __le32 decision_lut[BT_COEX_LUT_SIZE]; + u8 bt_reduced_tx_power; + u8 reserved; + __le16 valid_bit_msk; + __le32 bt_prio_boost; + u8 reserved2; + u8 wifi_tx_prio_boost; + __le16 wifi_rx_prio_boost; +} __packed; /* BT_COEX_CMD_API_S_VER_3 */ + +#define BT_MBOX(n_dw, _msg, _pos, _nbits) \ + BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ + BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS + +enum iwl_bt_mxbox_dw0 { + BT_MBOX(0, LE_SLAVE_LAT, 0, 3), + BT_MBOX(0, LE_PROF1, 3, 1), + BT_MBOX(0, LE_PROF2, 4, 1), + BT_MBOX(0, LE_PROF_OTHER, 5, 1), + BT_MBOX(0, CHL_SEQ_N, 8, 4), + BT_MBOX(0, INBAND_S, 13, 1), + BT_MBOX(0, LE_MIN_RSSI, 16, 4), + BT_MBOX(0, LE_SCAN, 20, 1), + BT_MBOX(0, LE_ADV, 21, 1), + BT_MBOX(0, LE_MAX_TX_POWER, 24, 4), + BT_MBOX(0, OPEN_CON_1, 28, 2), +}; + +enum iwl_bt_mxbox_dw1 { + BT_MBOX(1, BR_MAX_TX_POWER, 0, 4), + BT_MBOX(1, IP_SR, 4, 1), + BT_MBOX(1, LE_MSTR, 5, 1), + BT_MBOX(1, AGGR_TRFC_LD, 8, 6), + BT_MBOX(1, MSG_TYPE, 16, 3), + BT_MBOX(1, SSN, 19, 2), +}; + +enum iwl_bt_mxbox_dw2 { + BT_MBOX(2, SNIFF_ACT, 0, 3), + BT_MBOX(2, PAG, 3, 1), + BT_MBOX(2, INQUIRY, 4, 1), + BT_MBOX(2, CONN, 5, 1), + BT_MBOX(2, SNIFF_INTERVAL, 8, 5), + BT_MBOX(2, DISC, 13, 1), + BT_MBOX(2, SCO_TX_ACT, 16, 2), + BT_MBOX(2, SCO_RX_ACT, 18, 2), + BT_MBOX(2, ESCO_RE_TX, 20, 2), + BT_MBOX(2, SCO_DURATION, 24, 6), +}; + +enum iwl_bt_mxbox_dw3 { + BT_MBOX(3, SCO_STATE, 0, 1), + BT_MBOX(3, SNIFF_STATE, 1, 1), + BT_MBOX(3, A2DP_STATE, 2, 1), + BT_MBOX(3, ACL_STATE, 3, 1), + BT_MBOX(3, MSTR_STATE, 4, 1), + BT_MBOX(3, OBX_STATE, 5, 1), + BT_MBOX(3, OPEN_CON_2, 8, 2), + BT_MBOX(3, TRAFFIC_LOAD, 10, 2), + BT_MBOX(3, CHL_SEQN_LSB, 12, 1), + BT_MBOX(3, INBAND_P, 13, 1), + BT_MBOX(3, MSG_TYPE_2, 16, 3), + BT_MBOX(3, SSN_2, 19, 2), + BT_MBOX(3, UPDATE_REQUEST, 21, 1), +}; + +#define BT_MBOX_MSG(_notif, _num, _field) \ + ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ + >> BT_MBOX##_num##_##_field##_POS) + +/** + * struct iwl_bt_coex_profile_notif - notification about BT coex + * @mbox_msg: message from BT to WiFi + * @:bt_status: 0 - off, 1 - on + * @:bt_open_conn: number of BT connections open + * @:bt_traffic_load: load of BT traffic + * @:bt_agg_traffic_load: aggregated load of BT traffic + * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant + */ +struct iwl_bt_coex_profile_notif { + __le32 mbox_msg[4]; + u8 bt_status; + u8 bt_open_conn; + u8 bt_traffic_load; + u8 bt_agg_traffic_load; + u8 bt_ci_compliance; + u8 reserved[3]; +} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ + +enum iwl_bt_coex_prio_table_event { + BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, + BT_COEX_PRIO_TBL_EVT_DTIM = 6, + BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, + BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, + BT_COEX_PRIO_TBL_EVT_IDLE = 9, + BT_COEX_PRIO_TBL_EVT_MAX = 16, +}; /* BT_COEX_PRIO_TABLE_EVENTS_API_E_VER_1 */ + +enum iwl_bt_coex_prio_table_prio { + BT_COEX_PRIO_TBL_DISABLED = 0, + BT_COEX_PRIO_TBL_PRIO_LOW = 1, + BT_COEX_PRIO_TBL_PRIO_HIGH = 2, + BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, + BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, + BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, + BT_COEX_PRIO_TBL_PRIO_COEX_IDLE = 6, + BT_COEX_PRIO_TBL_MAX = 8, +}; /* BT_COEX_PRIO_TABLE_PRIORITIES_API_E_VER_1 */ + +#define BT_COEX_PRIO_TBL_SHRD_ANT_POS (0) +#define BT_COEX_PRIO_TBL_PRIO_POS (1) +#define BT_COEX_PRIO_TBL_RESERVED_POS (4) + +/** + * struct iwl_bt_coex_prio_tbl_cmd - priority table for BT coex + * @prio_tbl: + */ +struct iwl_bt_coex_prio_tbl_cmd { + u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; +} __packed; + +enum iwl_bt_coex_env_action { + BT_COEX_ENV_CLOSE = 0, + BT_COEX_ENV_OPEN = 1, +}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */ + +/** + * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope + * @action: enum %iwl_bt_coex_env_action + * @type: enum %iwl_bt_coex_prio_table_event + */ +struct iwl_bt_coex_prot_env_cmd { + u8 action; /* 0 = closed, 1 = open */ + u8 type; /* 0 .. 15 */ + u8 reserved[2]; +} __packed; + +#endif /* __fw_api_bt_coex_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 92cd982f6b27..da9ee3fe3379 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -70,6 +70,7 @@ #include "fw-api-mac.h" #include "fw-api-power.h" #include "fw-api-d3.h" +#include "fw-api-bt-coex.h" /* queue and FIFO numbers by usage */ enum { @@ -152,6 +153,7 @@ enum { BEACON_TEMPLATE_CMD = 0x91, TX_ANT_CONFIGURATION_CMD = 0x98, + BT_CONFIG = 0x9b, STATISTICS_NOTIFICATION = 0x9d, /* RF-KILL commands and notifications */ @@ -162,6 +164,11 @@ enum { REPLY_RX_MPDU_CMD = 0xc1, BA_NOTIF = 0xc5, + /* BT Coex */ + BT_COEX_PRIO_TABLE = 0xcc, + BT_COEX_PROT_ENV = 0xcd, + BT_PROFILE_NOTIFICATION = 0xce, + REPLY_DEBUG_CMD = 0xf0, DEBUG_LOG_MSG = 0xf7, diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index dda699e1c996..2003daa0cf76 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -294,6 +294,10 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(NET_DETECT_HOTSPOTS_CMD), CMD(NET_DETECT_HOTSPOTS_QUERY_CMD), CMD(CARD_STATE_NOTIFICATION), + CMD(BT_COEX_PRIO_TABLE), + CMD(BT_COEX_PROT_ENV), + CMD(BT_PROFILE_NOTIFICATION), + CMD(BT_CONFIG), }; #undef CMD -- cgit v1.2.3 From 931d416049cdb6e8382792231317f76be0d922ce Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 17 Jan 2013 09:42:25 +0200 Subject: iwlwifi: mvm: begin basic BT-Coex implementation Send the PRIO table before the calibrations. This table tells the fw what priority to give to what (WiFi / BT) according to events. Send a hardcoded BT_COEX command to the fw to enable basic BT coexistence. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/Makefile | 2 +- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 242 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/fw.c | 12 ++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 + 4 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/iwlwifi/mvm/bt-coex.c diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile index 807b250ec396..2acc44b40986 100644 --- a/drivers/net/wireless/iwlwifi/mvm/Makefile +++ b/drivers/net/wireless/iwlwifi/mvm/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o iwlmvm-y += scan.o time-event.o rs.o -iwlmvm-y += power.o +iwlmvm-y += power.o bt-coex.o iwlmvm-y += led.o iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o iwlmvm-$(CONFIG_PM_SLEEP) += d3.o diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c new file mode 100644 index 000000000000..d37865af3254 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -0,0 +1,242 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called COPYING. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2013 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *****************************************************************************/ + +#include "fw-api-bt-coex.h" +#include "iwl-modparams.h" +#include "mvm.h" + +#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \ + [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \ + ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS)) + +static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1, + BT_COEX_PRIO_TBL_PRIO_BYPASS, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2, + BT_COEX_PRIO_TBL_PRIO_BYPASS, 1), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1, + BT_COEX_PRIO_TBL_PRIO_LOW, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2, + BT_COEX_PRIO_TBL_PRIO_LOW, 1), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1, + BT_COEX_PRIO_TBL_PRIO_HIGH, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2, + BT_COEX_PRIO_TBL_PRIO_HIGH, 1), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM, + BT_COEX_PRIO_TBL_DISABLED, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52, + BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24, + BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0), + EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE, + BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0), + 0, 0, 0, 0, 0, 0, +}; + +#undef EVENT_PRIO_ANT + +int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) +{ + return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, + sizeof(struct iwl_bt_coex_prio_tbl_cmd), + &iwl_bt_prio_tbl); +} + +static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type) +{ + struct iwl_bt_coex_prot_env_cmd env_cmd; + int ret; + + env_cmd.action = action; + env_cmd.type = type; + ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC, + sizeof(env_cmd), &env_cmd); + if (ret) + IWL_ERR(mvm, "failed to send BT env command\n"); + return ret; +} + +enum iwl_bt_kill_msk { + BT_KILL_MSK_DEFAULT, + BT_KILL_MSK_SCO_HID_A2DP, + BT_KILL_MSK_REDUCED_TXPOW, + BT_KILL_MSK_MAX, +}; + +static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { + 0xffffffff, + 0xfffffc00, + 0, +}; + +static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { + 0xffffffff, + 0xfffffc00, + 0, +}; + +#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) + +/* Tight Coex */ +static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xc0004000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), +}; + +/* Loose Coex */ +static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), +}; + +/* Full concurrency */ +static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), +}; + +/* BT Antenna Coupling Threshold (dB) */ +#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) + +int iwl_send_bt_init_conf(struct iwl_mvm *mvm) +{ + struct iwl_bt_coex_cmd cmd = { + .max_kill = 5, + .bt3_time_t7_value = 1, + .bt3_prio_sample_time = 2, + .bt3_timer_t2_value = 0xc, + }; + int ret; + + cmd.flags = iwlwifi_mod_params.bt_coex_active ? + BT_COEX_NW : BT_COEX_DISABLE; + cmd.flags |= iwlwifi_mod_params.bt_ch_announce ? + BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN : 0; + cmd.flags |= BT_SYNC_2_BT_DISABLE; + + cmd.valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | + BT_VALID_BT_PRIO_BOOST | + BT_VALID_MAX_KILL | + BT_VALID_3W_TMRS | + BT_VALID_KILL_ACK | + BT_VALID_KILL_CTS | + BT_VALID_REDUCED_TX_POWER | + BT_VALID_LUT); + + if (iwlwifi_mod_params.ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) + memcpy(&cmd.decision_lut, iwl_loose_lookup, + sizeof(iwl_tight_lookup)); + else + memcpy(&cmd.decision_lut, iwl_tight_lookup, + sizeof(iwl_tight_lookup)); + + cmd.bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST); + cmd.kill_ack_msk = + cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]); + cmd.kill_cts_msk = + cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); + + /* go to CALIB state in internal BT-Coex state machine */ + ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; + + ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; + + return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, + sizeof(cmd), &cmd); +} diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 0f45fa583aa1..1006b3204e7b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -309,6 +309,10 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) goto error; } + ret = iwl_send_bt_prio_tbl(mvm); + if (ret) + goto error; + if (read_nvm) { /* Read nvm */ ret = iwl_nvm_init(mvm); @@ -414,6 +418,14 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) goto error; + ret = iwl_send_bt_prio_tbl(mvm); + if (ret) + goto error; + + ret = iwl_send_bt_init_conf(mvm); + if (ret) + goto error; + /* Send phy db control command and then phy db calibration*/ ret = iwl_send_phy_db_data(mvm->phy_db); if (ret) diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 234c5726d196..b7f27d59fc24 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -504,4 +504,8 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw, void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); +/* BT Coex */ +int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); +int iwl_send_bt_init_conf(struct iwl_mvm *mvm); + #endif /* __IWL_MVM_H__ */ -- cgit v1.2.3 From f421f9c3b2dc77e2be1b9400a4420b6d2cdfb847 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 17 Jan 2013 14:20:29 +0200 Subject: iwlwifi: mvm: handle BT-coex notification The BT-Coex notification is sent by the fw when there are updates wrt. BT activity. Driver action might be taken based on the info in this notification. For now, update the Ack/Cts_kill_msk if HID / SCO / A2DP profiles are active. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 50 ++++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 6 ++++ drivers/net/wireless/iwlwifi/mvm/ops.c | 2 ++ 3 files changed, 58 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index d37865af3254..61159f8abe78 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -64,6 +64,7 @@ #include "fw-api-bt-coex.h" #include "iwl-modparams.h" #include "mvm.h" +#include "iwl-debug.h" #define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \ [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \ @@ -240,3 +241,52 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd); } + +int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *dev_cmd) +{ + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; + struct iwl_bt_coex_cmd cmd = {}; + enum iwl_bt_kill_msk bt_kill_msk; + + IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); + IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); + IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn); + IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load); + IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n", + notif->bt_agg_traffic_load); + IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); + + /* Low latency BT profile is active: give higher prio to BT */ + if (BT_MBOX_MSG(notif, 3, SCO_STATE) || + BT_MBOX_MSG(notif, 3, A2DP_STATE) || + BT_MBOX_MSG(notif, 3, SNIFF_STATE)) + bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP; + else + bt_kill_msk = BT_KILL_MSK_DEFAULT; + + /* Don't send HCMD if there is no update */ + if (bt_kill_msk == mvm->bt_kill_msk) + return 0; + + IWL_DEBUG_COEX(mvm, + "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n", + bt_kill_msk, + BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in", + BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in", + BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in"); + + mvm->bt_kill_msk = bt_kill_msk; + cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); + cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); + + cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); + + if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd)) + IWL_ERR(mvm, "Failed to sent BT Coex CMD\n"); + + /* This handler is ASYNC */ + return 0; +} diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index b7f27d59fc24..a1f1a86643e5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -334,6 +334,9 @@ struct iwl_mvm { #ifdef CONFIG_PM_SLEEP int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; #endif + + /* BT-Coex */ + u8 bt_kill_msk; }; /* Extract MVM priv from op_mode and _hw */ @@ -507,5 +510,8 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, /* BT Coex */ int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); int iwl_send_bt_init_conf(struct iwl_mvm *mvm); +int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, + struct iwl_rx_cmd_buffer *rxb, + struct iwl_device_cmd *cmd); #endif /* __IWL_MVM_H__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 2003daa0cf76..54595eb7b92a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -230,6 +230,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), + RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), + RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), -- cgit v1.2.3 From 7da052b818371b6b29909d871bf803192aa40b84 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 10 Feb 2013 17:06:17 +0200 Subject: iwlwifi: mvm: update SMPS when BT gets active When BT traffic load gets higher, we want to avoid using the shared antenna. In order to do so, we need to tell the AP that we don't support MIMO any more, or at least not all the time: in short, use the SMPS to achieve this. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 61159f8abe78..fa054b364e52 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -242,12 +242,60 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) sizeof(cmd), &cmd); } +struct iwl_bt_notif_iterator_data { + struct iwl_mvm *mvm; + struct iwl_bt_coex_profile_notif *notif; +}; + +static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, + struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_bt_notif_iterator_data *data = _data; + struct ieee80211_chanctx_conf *chanctx_conf; + enum ieee80211_smps_mode smps_mode; + enum ieee80211_band band; + + if (vif->type != NL80211_IFTYPE_STATION) + return; + + rcu_read_lock(); + chanctx_conf = rcu_dereference(vif->chanctx_conf); + if (chanctx_conf && chanctx_conf->def.chan) + band = chanctx_conf->def.chan->band; + else + band = -1; + rcu_read_unlock(); + + if (band != IEEE80211_BAND_2GHZ) + return; + + smps_mode = IEEE80211_SMPS_AUTOMATIC; + + if (data->notif->bt_status) + smps_mode = IEEE80211_SMPS_DYNAMIC; + + if (data->notif->bt_traffic_load) + smps_mode = IEEE80211_SMPS_STATIC; + + IWL_DEBUG_COEX(data->mvm, + "mac %d: bt_status %d traffic_load %d smps_req %d\n", + mvmvif->id, data->notif->bt_status, + data->notif->bt_traffic_load, smps_mode); + + ieee80211_request_smps(vif, smps_mode); +} + int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *dev_cmd) { struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; + struct iwl_bt_notif_iterator_data data = { + .mvm = mvm, + .notif = notif, + }; struct iwl_bt_coex_cmd cmd = {}; enum iwl_bt_kill_msk bt_kill_msk; @@ -259,6 +307,10 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, notif->bt_agg_traffic_load); IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); + ieee80211_iterate_active_interfaces_atomic( + mvm->hw, IEEE80211_IFACE_ITER_NORMAL, + iwl_mvm_bt_notif_iterator, &data); + /* Low latency BT profile is active: give higher prio to BT */ if (BT_MBOX_MSG(notif, 3, SCO_STATE) || BT_MBOX_MSG(notif, 3, A2DP_STATE) || -- cgit v1.2.3 From 1094234284a2afe46202773ebd9ae55416092d9c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 19 Feb 2013 11:02:36 +0200 Subject: iwlwifi: mvm: export last bt_notif through debugfs This will allow to track how BT core updates the driver. This is required to debug the BT Coexistence mechanism. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 3 + drivers/net/wireless/iwlwifi/mvm/debugfs.c | 100 +++++++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 3 files changed, 104 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index fa054b364e52..47954deb6493 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -307,6 +307,9 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, notif->bt_agg_traffic_load); IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); + /* remember this notification for future use: rssi fluctuations */ + memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); + ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_bt_notif_iterator, &data); diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 2ad301164bd9..56bf601f8991 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -300,6 +300,104 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, return count; } +#define BT_MBOX_MSG(_notif, _num, _field) \ + ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ + >> BT_MBOX##_num##_##_field##_POS) + + +#define BT_MBOX_PRINT(_num, _field, _end) \ + pos += scnprintf(buf + pos, bufsz - pos, \ + "\t%s: %d%s", \ + #_field, \ + BT_MBOX_MSG(notif, _num, _field), \ + true ? "\n" : ", "); + +static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; + char *buf; + int ret, pos = 0, bufsz = sizeof(char) * 1024; + + buf = kmalloc(bufsz, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + mutex_lock(&mvm->mutex); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); + + BT_MBOX_PRINT(0, LE_SLAVE_LAT, false); + BT_MBOX_PRINT(0, LE_PROF1, false); + BT_MBOX_PRINT(0, LE_PROF2, false); + BT_MBOX_PRINT(0, LE_PROF_OTHER, false); + BT_MBOX_PRINT(0, CHL_SEQ_N, false); + BT_MBOX_PRINT(0, INBAND_S, false); + BT_MBOX_PRINT(0, LE_MIN_RSSI, false); + BT_MBOX_PRINT(0, LE_SCAN, false); + BT_MBOX_PRINT(0, LE_ADV, false); + BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false); + BT_MBOX_PRINT(0, OPEN_CON_1, true); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n"); + + BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false); + BT_MBOX_PRINT(1, IP_SR, false); + BT_MBOX_PRINT(1, LE_MSTR, false); + BT_MBOX_PRINT(1, AGGR_TRFC_LD, false); + BT_MBOX_PRINT(1, MSG_TYPE, false); + BT_MBOX_PRINT(1, SSN, true); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n"); + + BT_MBOX_PRINT(2, SNIFF_ACT, false); + BT_MBOX_PRINT(2, PAG, false); + BT_MBOX_PRINT(2, INQUIRY, false); + BT_MBOX_PRINT(2, CONN, false); + BT_MBOX_PRINT(2, SNIFF_INTERVAL, false); + BT_MBOX_PRINT(2, DISC, false); + BT_MBOX_PRINT(2, SCO_TX_ACT, false); + BT_MBOX_PRINT(2, SCO_RX_ACT, false); + BT_MBOX_PRINT(2, ESCO_RE_TX, false); + BT_MBOX_PRINT(2, SCO_DURATION, true); + + pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n"); + + BT_MBOX_PRINT(3, SCO_STATE, false); + BT_MBOX_PRINT(3, SNIFF_STATE, false); + BT_MBOX_PRINT(3, A2DP_STATE, false); + BT_MBOX_PRINT(3, ACL_STATE, false); + BT_MBOX_PRINT(3, MSTR_STATE, false); + BT_MBOX_PRINT(3, OBX_STATE, false); + BT_MBOX_PRINT(3, OPEN_CON_2, false); + BT_MBOX_PRINT(3, TRAFFIC_LOAD, false); + BT_MBOX_PRINT(3, CHL_SEQN_LSB, false); + BT_MBOX_PRINT(3, INBAND_P, false); + BT_MBOX_PRINT(3, MSG_TYPE_2, false); + BT_MBOX_PRINT(3, SSN_2, false); + BT_MBOX_PRINT(3, UPDATE_REQUEST, true); + + pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", + notif->bt_status); + pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", + notif->bt_open_conn); + pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", + notif->bt_traffic_load); + pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", + notif->bt_agg_traffic_load); + pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", + notif->bt_ci_compliance); + + mutex_unlock(&mvm->mutex); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + + return ret; +} +#undef BT_MBOX_PRINT + #define MVM_DEBUGFS_READ_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ @@ -339,6 +437,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush); MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); MVM_DEBUGFS_READ_FILE_OPS(stations); +MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); @@ -352,6 +451,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); + MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index a1f1a86643e5..203eb85e03d3 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -337,6 +337,7 @@ struct iwl_mvm { /* BT-Coex */ u8 bt_kill_msk; + struct iwl_bt_coex_profile_notif last_bt_notif; }; /* Extract MVM priv from op_mode and _hw */ -- cgit v1.2.3 From 6bfcb7e88cbb45782664caeb9bfe1a1c1b83a10e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 3 Mar 2013 10:19:45 +0200 Subject: iwlwifi: mvm: update firmware API - MAC ID in RX The firmware tells the driver to what MACs the received frame belongs (based on the time slot in which it was received). Note that there can be several MACs if they share the same binding. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index da9ee3fe3379..f8d7e88234e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -801,6 +801,7 @@ struct iwl_phy_context_cmd { * @byte_count: frame's byte-count * @frame_time: frame's time on the air, based on byte count and frame rate * calculation + * @mac_active_msk: what MACs were active when the frame was received * * Before each Rx, the device sends this data. It contains PHY information * about the reception of the packet. @@ -818,7 +819,7 @@ struct iwl_rx_phy_info { __le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT]; __le32 rate_n_flags; __le32 byte_count; - __le16 reserved2; + __le16 mac_active_msk; __le16 frame_time; } __packed; -- cgit v1.2.3 From 490953ac344725f56746d16ef8480842f4087fc4 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 4 Mar 2013 08:53:07 +0200 Subject: iwlwifi: move firmware restart debugfs hook to op_mode This allows to test fw restart flow. The hook in transport layer doesn't really make the fw assert. Moving this hook to the op_mode allows to use the fw API to actually send a host command that will make the fw assert. Change the restart_fw module parameter to be a boolean on the way. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/debugfs.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/iwl-drv.c | 6 +++--- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 24 ++++++++++++++++++++++++ drivers/net/wireless/iwlwifi/pcie/trans.c | 18 ------------------ 5 files changed, 52 insertions(+), 22 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 9d3b7e3165f4..7b8178be119f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -2324,6 +2324,28 @@ static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file, return count; } +static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + bool restart_fw = iwlwifi_mod_params.restart_fw; + int ret; + + iwlwifi_mod_params.restart_fw = true; + + mutex_lock(&priv->mutex); + + /* take the return value to make compiler happy - it will fail anyway */ + ret = iwl_dvm_send_cmd_pdu(priv, REPLY_ERROR, CMD_SYNC, 0, NULL); + + mutex_unlock(&priv->mutex); + + iwlwifi_mod_params.restart_fw = restart_fw; + + return count; +} + DEBUGFS_READ_FILE_OPS(ucode_rx_stats); DEBUGFS_READ_FILE_OPS(ucode_tx_stats); DEBUGFS_READ_FILE_OPS(ucode_general_stats); @@ -2343,6 +2365,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); +DEBUGFS_WRITE_FILE_OPS(fw_restart); #ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); #endif @@ -2400,6 +2423,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, struct dentry *dbgfs_dir) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(fw_restart, dir_debug, S_IWUSR); #ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 15ac54baa833..3ce4e9d5082d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1102,7 +1102,7 @@ void iwl_drv_stop(struct iwl_drv *drv) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { - .restart_fw = 1, + .restart_fw = true, .plcp_check = true, .bt_coex_active = true, .power_level = IWL_POWER_INDEX_1, @@ -1207,8 +1207,8 @@ MODULE_PARM_DESC(11n_disable, module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K, int, S_IRUGO); MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0)"); -module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO); -MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); +module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, bool, S_IRUGO); +MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)"); module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, int, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index a2cefe2c3e1d..3cc39ffe8ba5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -109,7 +109,7 @@ struct iwl_mod_params { int sw_crypto; unsigned int disable_11n; int amsdu_size_8K; - int restart_fw; + bool restart_fw; bool plcp_check; int wd_disable; bool bt_coex_active; diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 56bf601f8991..b080b4ba5458 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -398,6 +398,28 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, } #undef BT_MBOX_PRINT +static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_mvm *mvm = file->private_data; + bool restart_fw = iwlwifi_mod_params.restart_fw; + int ret; + + iwlwifi_mod_params.restart_fw = true; + + mutex_lock(&mvm->mutex); + + /* take the return value to make compiler happy - it will fail anyway */ + ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, CMD_SYNC, 0, NULL); + + mutex_unlock(&mvm->mutex); + + iwlwifi_mod_params.restart_fw = restart_fw; + + return count; +} + #define MVM_DEBUGFS_READ_FILE_OPS(name) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ @@ -440,6 +462,7 @@ MVM_DEBUGFS_READ_FILE_OPS(stations); MVM_DEBUGFS_READ_FILE_OPS(bt_notif); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); +MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) { @@ -454,6 +477,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); + MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); /* * Create a symlink with mac80211. It will be removed when mac80211 diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d90cbf5041f5..d17fb4bd3efb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1370,28 +1370,11 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, return ret; } -static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_trans *trans = file->private_data; - - if (!trans->op_mode) - return -EAGAIN; - - local_bh_disable(); - iwl_op_mode_nic_error(trans->op_mode); - local_bh_enable(); - - return count; -} - DEBUGFS_READ_WRITE_FILE_OPS(interrupt); DEBUGFS_READ_FILE_OPS(fh_reg); DEBUGFS_READ_FILE_OPS(rx_queue); DEBUGFS_READ_FILE_OPS(tx_queue); DEBUGFS_WRITE_FILE_OPS(csr); -DEBUGFS_WRITE_FILE_OPS(fw_restart); /* * Create the debugfs files and directories @@ -1405,7 +1388,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(csr, dir, S_IWUSR); DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR); - DEBUGFS_ADD_FILE(fw_restart, dir, S_IWUSR); return 0; err: -- cgit v1.2.3 From f9477c17c2ce59f64462635c3e5d43c98c0ad67f Mon Sep 17 00:00:00 2001 From: Amnon Paz Date: Wed, 27 Feb 2013 11:28:16 +0200 Subject: iwlwifi: fix indirect write bug Fix a bug in writing to indirect (periphery) registers; although writes seem successful the data is not written to the desired address). Also fix address mask for HBUS_TARG_PRPH_RADDR and HBUS_TARG_PRPH_WADDR registers. Signed-off-by: Amnon Paz Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index d17fb4bd3efb..6649e377e9cd 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -715,7 +715,8 @@ static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) static u32 iwl_trans_pcie_read_prph(struct iwl_trans *trans, u32 reg) { - iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_RADDR, + ((reg & 0x000FFFFF) | (3 << 24))); return iwl_trans_pcie_read32(trans, HBUS_TARG_PRPH_RDAT); } @@ -723,7 +724,7 @@ static void iwl_trans_pcie_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WADDR, - ((addr & 0x0000FFFF) | (3 << 24))); + ((addr & 0x000FFFFF) | (3 << 24))); iwl_trans_pcie_write32(trans, HBUS_TARG_PRPH_WDAT, val); } -- cgit v1.2.3 From 25b9ea5c797b5d78f8ceced9ad9c7a7daf0db19c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 6 Mar 2013 11:53:38 +0200 Subject: iwlwifi: mvm: the SCD byte count is a TLV flag The SCD byte count layout is decided by the configuration done in fw, it is then logical to export it as a TLV flag and not per HW SKU. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-fw.h | 2 ++ drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 54848d59df0e..435618574240 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -73,12 +73,14 @@ * treats good CRC threshold as a boolean * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. + * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS */ enum iwl_ucode_tlv_flag { IWL_UCODE_TLV_FLAGS_PAN = BIT(0), IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), IWL_UCODE_TLV_FLAGS_MFP = BIT(2), IWL_UCODE_TLV_FLAGS_P2P = BIT(3), + IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), }; /* The default calibrate table size if not specified by firmware file */ diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 54595eb7b92a..828bdddd07e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -370,8 +370,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; - /* TODO: this should really be a TLV */ - if (cfg->device_family == IWL_DEVICE_FAMILY_7000) + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) trans_cfg.bc_table_dword = true; if (!iwlwifi_mod_params.wd_disable) -- cgit v1.2.3