From 680073b78a5ac2b559bb7315528aa9f95e57ae24 Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Mon, 14 Jul 2014 09:40:27 +0300 Subject: iwlwifi: consolidate hw scheduler configuration code Configuring the hw scheduler during queue enablement is done by writing the appropriate values to the scheduler peripherals, and it is essentially the same for all buses. Whenever writing is done via the standard iwl_write_prph, we can avoid duplicating the code for each bus. Those operations are queue deactivation, RA/TID mapping, chain-building settings, enabling/disabling aggregations and activating/deactivating the TX FIFOs. Consolidate this code using static inlines in a new header file. Signed-off-by: Avri Altman Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/tx.c | 39 ++++++++-------------------------- 1 file changed, 9 insertions(+), 30 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 6acccb1..84c3a01 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -34,6 +34,7 @@ #include "iwl-csr.h" #include "iwl-prph.h" #include "iwl-io.h" +#include "iwl-scd.h" #include "iwl-op-mode.h" #include "internal.h" /* FIXME: need to abstract out TX command (once we know what it looks like) */ @@ -644,17 +645,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) memset(txq, 0, sizeof(*txq)); } -/* - * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask - */ -static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) -{ - struct iwl_trans_pcie __maybe_unused *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - - iwl_write_prph(trans, SCD_TXFACT, mask); -} - void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -692,7 +682,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) trans_pcie->cmd_fifo); /* Activate all Tx DMA/FIFO channels */ - iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7)); + iwl_scd_activate_fifos(trans); /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) @@ -745,7 +735,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans) /* Turn off all Tx DMA fifos */ spin_lock(&trans_pcie->irq_lock); - iwl_pcie_txq_set_sched(trans, 0); + iwl_scd_deactivate_fifos(trans); /* Stop each Tx DMA channel, and wait for it to be idle */ for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { @@ -886,7 +876,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans) spin_lock(&trans_pcie->irq_lock); /* Turn off all Tx DMA fifos */ - iwl_write_prph(trans, SCD_TXFACT, 0); + iwl_scd_deactivate_fifos(trans); /* Tell NIC where to find the "keep warm" buffer */ iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, @@ -1072,17 +1062,6 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, return 0; } -static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans, - u16 txq_id) -{ - /* Simply stop the queue, but don't change any configuration; - * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(trans, - SCD_QUEUE_STATUS_BITS(txq_id), - (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| - (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); -} - /* Receiver address (actually, Rx station's index into station table), * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) @@ -1096,11 +1075,11 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, WARN_ONCE(1, "queue %d already used - expect issues", txq_id); /* Stop this Tx queue before configuring it */ - iwl_pcie_txq_set_inactive(trans, txq_id); + iwl_scd_txq_set_inactive(trans, txq_id); /* Set this queue as a chain-building queue unless it is CMD queue */ if (txq_id != trans_pcie->cmd_queue) - iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id)); + iwl_scd_txq_set_chain(trans, txq_id); /* If this queue is mapped to a certain station: it is an AGG queue */ if (sta_id >= 0) { @@ -1110,7 +1089,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); /* enable aggregations for the queue */ - iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); + iwl_scd_txq_enable_agg(trans, txq_id); trans_pcie->txq[txq_id].ampdu = true; } else { /* @@ -1118,7 +1097,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, * ra_tid mapping configuration irrelevant since it is now a * non-AGG queue. */ - iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); + iwl_scd_txq_disable_agg(trans, txq_id); ssn = trans_pcie->txq[txq_id].q.read_ptr; } @@ -1172,7 +1151,7 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) return; } - iwl_pcie_txq_set_inactive(trans, txq_id); + iwl_scd_txq_set_inactive(trans, txq_id); iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, ARRAY_SIZE(zero_val)); -- cgit v1.1 From fea7795f1c976513a3262284c4001606075abf5c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Aug 2014 11:58:47 +0200 Subject: iwlwifi: trans: refactor txq_enable arguments Instead of having all arguments passed to the function, add a struct to hold them and only pass some directly. This will make future work in this area cleaner. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/internal.h | 4 ++-- drivers/net/wireless/iwlwifi/pcie/tx.c | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 78f72c3..5760405 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -364,8 +364,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans); void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); int iwl_pcie_tx_stop(struct iwl_trans *trans); void iwl_pcie_tx_free(struct iwl_trans *trans); -void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, - int sta_id, int tid, int frame_limit, u16 ssn); +void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, + const struct iwl_trans_txq_scd_cfg *cfg); void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, int txq_id); diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 84c3a01..5c95386 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1066,10 +1066,11 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ #define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) -void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, - int sta_id, int tid, int frame_limit, u16 ssn) +void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, + const struct iwl_trans_txq_scd_cfg *cfg) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u8 frame_limit = cfg->frame_limit; if (test_and_set_bit(txq_id, trans_pcie->queue_used)) WARN_ONCE(1, "queue %d already used - expect issues", txq_id); @@ -1082,8 +1083,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, iwl_scd_txq_set_chain(trans, txq_id); /* If this queue is mapped to a certain station: it is an AGG queue */ - if (sta_id >= 0) { - u16 ra_tid = BUILD_RAxTID(sta_id, tid); + if (cfg->sta_id >= 0) { + u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); /* Map receiver-address / traffic-ID to this queue */ iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); @@ -1124,12 +1125,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | - (fifo << SCD_QUEUE_STTS_REG_POS_TXF) | + (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | SCD_QUEUE_STTS_REG_MSK); trans_pcie->txq[txq_id].active = true; IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", - txq_id, fifo, ssn & 0xff); + txq_id, cfg->fifo, ssn & 0xff); } void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) -- cgit v1.1 From d4578ea810ce468fdb8e1b7014818c31db9be5e2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Aug 2014 12:17:40 +0200 Subject: iwlwifi: trans: allow skipping scheduler hardware config In a later patch, the hardware configuration will be moved to firmware. Prepare for this by allowing hardware configuration in the transport to be skipped by not passing a configuration on enable and passing configure_scd=false on disable. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/internal.h | 3 +- drivers/net/wireless/iwlwifi/pcie/tx.c | 99 ++++++++++++++++------------ 2 files changed, 58 insertions(+), 44 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 5760405..163aac5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -366,7 +366,8 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans); void iwl_pcie_tx_free(struct iwl_trans *trans); void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg); -void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); +void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue, + bool configure_scd); int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, int txq_id); void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 5c95386..eb39e58 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1070,37 +1070,41 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, const struct iwl_trans_txq_scd_cfg *cfg) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u8 frame_limit = cfg->frame_limit; + int fifo = -1; if (test_and_set_bit(txq_id, trans_pcie->queue_used)) WARN_ONCE(1, "queue %d already used - expect issues", txq_id); - /* Stop this Tx queue before configuring it */ - iwl_scd_txq_set_inactive(trans, txq_id); + if (cfg) { + fifo = cfg->fifo; - /* Set this queue as a chain-building queue unless it is CMD queue */ - if (txq_id != trans_pcie->cmd_queue) - iwl_scd_txq_set_chain(trans, txq_id); + /* Stop this Tx queue before configuring it */ + iwl_scd_txq_set_inactive(trans, txq_id); - /* If this queue is mapped to a certain station: it is an AGG queue */ - if (cfg->sta_id >= 0) { - u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); + /* Set this queue as a chain-building queue unless it is CMD */ + if (txq_id != trans_pcie->cmd_queue) + iwl_scd_txq_set_chain(trans, txq_id); - /* Map receiver-address / traffic-ID to this queue */ - iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); + /* If this queue is mapped to a certain station: it is an AGG */ + if (cfg->sta_id >= 0) { + u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); - /* enable aggregations for the queue */ - iwl_scd_txq_enable_agg(trans, txq_id); - trans_pcie->txq[txq_id].ampdu = true; - } else { - /* - * disable aggregations for the queue, this will also make the - * ra_tid mapping configuration irrelevant since it is now a - * non-AGG queue. - */ - iwl_scd_txq_disable_agg(trans, txq_id); + /* Map receiver-address / traffic-ID to this queue */ + iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); + + /* enable aggregations for the queue */ + iwl_scd_txq_enable_agg(trans, txq_id); + trans_pcie->txq[txq_id].ampdu = true; + } else { + /* + * disable aggregations for the queue, this will also + * make the ra_tid mapping configuration irrelevant + * since it is now a non-AGG queue. + */ + iwl_scd_txq_disable_agg(trans, txq_id); - ssn = trans_pcie->txq[txq_id].q.read_ptr; + ssn = trans_pcie->txq[txq_id].q.read_ptr; + } } /* Place first TFD at index corresponding to start sequence number. @@ -1108,32 +1112,39 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); - iwl_write_direct32(trans, HBUS_TARG_WRPTR, - (ssn & 0xff) | (txq_id << 8)); - iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); + if (cfg) { + u8 frame_limit = cfg->frame_limit; + + iwl_write_direct32(trans, HBUS_TARG_WRPTR, + (ssn & 0xff) | (txq_id << 8)); + iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); - /* Set up Tx window size and frame limit for this queue */ - iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + - SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); - iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + + /* Set up Tx window size and frame limit for this queue */ + iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr + + SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0); + iwl_trans_write_mem32(trans, + trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & - SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | + SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | ((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & - SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - - /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ - iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), - (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | - (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | - (1 << SCD_QUEUE_STTS_REG_POS_WSL) | - SCD_QUEUE_STTS_REG_MSK); + SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); + + /* Set up status area in SRAM, map to Tx DMA/FIFO, activate */ + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), + (1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) | + (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | + (1 << SCD_QUEUE_STTS_REG_POS_WSL) | + SCD_QUEUE_STTS_REG_MSK); + } + trans_pcie->txq[txq_id].active = true; IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n", - txq_id, cfg->fifo, ssn & 0xff); + txq_id, fifo, ssn & 0xff); } -void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) +void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, + bool configure_scd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 stts_addr = trans_pcie->scd_base_addr + @@ -1152,10 +1163,12 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) return; } - iwl_scd_txq_set_inactive(trans, txq_id); + if (configure_scd) { + iwl_scd_txq_set_inactive(trans, txq_id); - iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, - ARRAY_SIZE(zero_val)); + iwl_trans_write_mem(trans, stts_addr, (void *)zero_val, + ARRAY_SIZE(zero_val)); + } iwl_pcie_txq_unmap(trans, txq_id); trans_pcie->txq[txq_id].ampdu = false; -- cgit v1.1 From 64ba893066528a03d7d21d7e187005748027a309 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Aug 2014 13:33:46 +0200 Subject: iwlwifi: trans: make aggregation explicit for TX queue handling Currently a valid sta_id is assumed to mean that the queue is meant to also be aggregated, but that assumption will not be true in the future, so don't make it in the lower level but only in the inline wrapper. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/tx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index eb39e58..a24c1df 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1085,8 +1085,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, if (txq_id != trans_pcie->cmd_queue) iwl_scd_txq_set_chain(trans, txq_id); - /* If this queue is mapped to a certain station: it is an AGG */ - if (cfg->sta_id >= 0) { + if (cfg->aggregate) { u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid); /* Map receiver-address / traffic-ID to this queue */ -- cgit v1.1 From 002a9e2677cc2a8b0d320731f9749737db5ed23b Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Thu, 24 Jul 2014 19:25:10 +0300 Subject: iwlwifi: trans: configure the scheduler enable register Currently the firmware is handling this, but that is wrong as it then needs to assume a certain command queue, therefore this should be in the driver; add it here so it can be removed from the firmware in the future. Signed-off-by: Avri Altman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/tx.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index a24c1df..9fdfed8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1078,6 +1078,10 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, if (cfg) { fifo = cfg->fifo; + /* Disable the scheduler prior configuring the cmd queue */ + if (txq_id == trans_pcie->cmd_queue) + iwl_scd_enable_set_active(trans, 0); + /* Stop this Tx queue before configuring it */ iwl_scd_txq_set_inactive(trans, txq_id); @@ -1135,6 +1139,10 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, (cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | SCD_QUEUE_STTS_REG_MSK); + + /* enable the scheduler for this queue (only) */ + if (txq_id == trans_pcie->cmd_queue) + iwl_scd_enable_set_active(trans, BIT(txq_id)); } trans_pcie->txq[txq_id].active = true; -- cgit v1.1 From 8b4139dc9f2171f313fc703c08269f6f8a6f6fc4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 24 Jul 2014 14:05:26 +0200 Subject: iwlwifi: add Intel Mobile Communications copyright Our legal structure changed at some point (see wikipedia), but we forgot to immediately switch over to the new copyright notice. For files that we have modified in the time since the change, add the proper copyright notice now. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/drv.c | 2 ++ drivers/net/wireless/iwlwifi/pcie/internal.h | 1 + drivers/net/wireless/iwlwifi/pcie/rx.c | 1 + drivers/net/wireless/iwlwifi/pcie/trans.c | 2 ++ drivers/net/wireless/iwlwifi/pcie/tx.c | 1 + 5 files changed, 7 insertions(+) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index f0e722c..dbbbf23 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -6,6 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * * 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 @@ -31,6 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 163aac5..a4fedc4 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -1,6 +1,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index a2698e5..702f47f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -1,6 +1,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 06e04aa..3076e0e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -6,6 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * * 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 @@ -31,6 +32,7 @@ * BSD LICENSE * * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 9fdfed8..a6336b4 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1,6 +1,7 @@ /****************************************************************************** * * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved. + * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. -- cgit v1.1 From d4200cb2487042291a056d4364450947344362e1 Mon Sep 17 00:00:00 2001 From: Oren Givon Date: Thu, 4 Sep 2014 09:16:49 +0200 Subject: iwlwifi: add and edit 8000 series PCI IDs Edit some 8000 series PCI IDs and add configuration to Dual Band Wireless N 8260 devices. Signed-off-by: Oren Givon Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index b9d5049..ca68c3c 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -405,6 +405,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { /* 8000 Series */ {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, #endif /* CONFIG_IWLMVM */ -- cgit v1.1 From 3a736bcb18f797996064cf18f4eecc4b3e46d39a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 10 Sep 2014 11:16:41 +0300 Subject: iwlwifi: trans: don't configure the set_active in SCD for dvm This configuration is not needed for dvm, and it actually broke it. Reported-by: Oliver Hartkopp Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/internal.h | 2 ++ drivers/net/wireless/iwlwifi/pcie/trans.c | 1 + drivers/net/wireless/iwlwifi/pcie/tx.c | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index a4fedc4..1aea6b6 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -257,6 +257,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) * @cmd_queue - command queue number * @rx_buf_size_8k: 8 kB RX buffer size * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) + * @scd_set_active: should the transport configure the SCD for HCMD queue * @rx_page_order: page order for receive buffer size * @wd_timeout: queue watchdog timeout (jiffies) * @reg_lock: protect hw register access @@ -306,6 +307,7 @@ struct iwl_trans_pcie { bool rx_buf_size_8k; bool bc_table_dword; + bool scd_set_active; u32 rx_page_order; const char *const *command_names; diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 3076e0e..4add964 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1171,6 +1171,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, trans_pcie->command_names = trans_cfg->command_names; trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; + trans_pcie->scd_set_active = trans_cfg->scd_set_active; /* Initialize NAPI here - it should be before registering to mac80211 * in the opmode but after the HW struct is allocated. diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index a6336b4..35fe38e 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1080,7 +1080,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, fifo = cfg->fifo; /* Disable the scheduler prior configuring the cmd queue */ - if (txq_id == trans_pcie->cmd_queue) + if (txq_id == trans_pcie->cmd_queue && + trans_pcie->scd_set_active) iwl_scd_enable_set_active(trans, 0); /* Stop this Tx queue before configuring it */ @@ -1142,7 +1143,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, SCD_QUEUE_STTS_REG_MSK); /* enable the scheduler for this queue (only) */ - if (txq_id == trans_pcie->cmd_queue) + if (txq_id == trans_pcie->cmd_queue && + trans_pcie->scd_set_active) iwl_scd_enable_set_active(trans, BIT(txq_id)); } -- cgit v1.1 From c2a2b28bb7fbcb8e0e11b84714992750bba7b699 Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Sun, 7 Sep 2014 11:41:05 +0300 Subject: iwlwifi: make hw rev checking more readable Rather than ANDing with a mask - use existing macros, which are more readable. Signed-off-by: Liad Kaufman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 4add964..ae99240 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -2190,7 +2190,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, */ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) trans->hw_rev = (trans->hw_rev & 0xfff0) | - ((trans->hw_rev << 2) & 0xc); + (CSR_HW_REV_STEP(trans->hw_rev << 2)); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), -- cgit v1.1 From 5d4185ae0c68eeff26d0390a4e99b6e7359a8b83 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 9 Sep 2014 21:16:06 +0200 Subject: iwlwifi: pcie: clear command data on freeing When freeing the structures used for command data, clear their memory as they may have contained key material at some point. Also clear the duplicated buffer when freeing it to be safe; currently key material is never put there but that may change. Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/rx.c | 2 +- drivers/net/wireless/iwlwifi/pcie/tx.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 702f47f..7b7e2f2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -640,7 +640,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); if (reclaim) { - kfree(txq->entries[cmd_index].free_buf); + kzfree(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 35fe38e..eb8e298 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -620,8 +620,8 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) /* De-alloc array of command/tx buffers */ 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].free_buf); + kzfree(txq->entries[i].cmd); + kzfree(txq->entries[i].free_buf); } /* De-alloc circular buffer of TFDs */ @@ -1409,7 +1409,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, out_meta->flags = cmd->flags; if (WARN_ON_ONCE(txq->entries[idx].free_buf)) - kfree(txq->entries[idx].free_buf); + kzfree(txq->entries[idx].free_buf); txq->entries[idx].free_buf = dup_buf; trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); -- cgit v1.1 From 4f08970f5284dce486f0e2290834aefb2a262189 Mon Sep 17 00:00:00 2001 From: Oren Givon Date: Wed, 17 Sep 2014 10:31:56 +0300 Subject: iwlwifi: Add missing PCI IDs for the 7260 series Add 4 missing PCI IDs for the 7260 series. Cc: [3.10+] Signed-off-by: Oren Givon Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/drv.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index ca68c3c..6ced854 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -275,6 +275,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4C60, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x4C70, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4060, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x406A, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4160, iwl7260_2n_cfg)}, @@ -318,6 +320,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = { {IWL_PCI_DEVICE(0x08B1, 0xC770, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0xC760, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B2, 0xC270, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xCC70, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0xCC60, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B2, 0xC272, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B2, 0xC260, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B2, 0xC26A, iwl7260_n_cfg)}, -- cgit v1.1 From 1fc0e22138406ac0e8451f7203dfbfd74fa5cfba Mon Sep 17 00:00:00 2001 From: Liad Kaufman Date: Wed, 17 Sep 2014 13:28:50 +0300 Subject: iwlwifi: pcie: fix HW_REV saving for 8000 series Align the trans->hw_rev variable format with previous series format. Signed-off-by: Liad Kaufman Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/iwlwifi/pcie') diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index ae99240..1393bac 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -2190,7 +2190,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, */ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) trans->hw_rev = (trans->hw_rev & 0xfff0) | - (CSR_HW_REV_STEP(trans->hw_rev << 2)); + (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), -- cgit v1.1