2014-09-21 19:15:40

by Emmanuel Grumbach

[permalink] [raw]
Subject: pull request: iwlwifi-next 2014-09-21

Hi John,

Here is another (last?) pull request for 3.18.

I have here a few things that depend on the latest mac80211's changes: RRM, TPC, Quiet Period etc...
Eyal keeps improving our rate control and we have a new device ID. This last patch should probably
have gone to wireless.git, but at that stage, I preferred to send it to -next and CC stable.

Let me know if you have issues!

The following changes since commit 6bd2bd27baf12fa0f2e6d611509fc0e1bffb0f97:

Merge tag 'mac80211-next-for-john-2014-09-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next (2014-09-15 14:51:23 -0400)

are available in the git repository at:


git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git master

for you to fetch changes up to 908f324b609320a8839211922f8c4946c891d56c:

iwlwifi: mvm: Refactor and fix max probe len computation (2014-09-21 13:25:50 +0300)

----------------------------------------------------------------
Alexander Bondar (1):
iwlwifi: mvm: Allow schedule scan while connected

Andrei Otcheretianski (3):
iwlwifi: mvm: Update TX power in TPC reports
iwlwifi: mvm: Set RRM_ENABLED bit in scan commands
iwlwifi: mvm: Refactor and fix max probe len computation

Assaf Krauss (1):
iwlwifi: mvm: Announce Quiet Period support

Avri Altman (1):
iwlwifi: mvm: prepare for scheduler config command

Emmanuel Grumbach (1):
iwlwifi: mvm: disable BT Co-running by default

Eyal Shapira (5):
iwlwifi: mvm: choose an initial tx rate based on rssi conditions
iwlwifi: mvm: rs: refactor to allow direct rs updating
iwlwifi: mvm: limit aggregation size in low latency to 6
iwlwifi: mvm: report all BA notifs to RS
iwlwifi: mvm: rs: fix logic in case of multiple TIDs

Ido Yariv (1):
iwlwifi: mvm: support cloned tx skbs

Liad Kaufman (2):
iwlwifi: pcie: fix HW_REV saving for 8000 series
iwlwifi: 8000: fix fw name to account for revision

Luciano Coelho (1):
iwlwifi: mvm: add debugfs entry to read the current temperature

Oren Givon (1):
iwlwifi: Add missing PCI IDs for the 7260 series

drivers/net/wireless/iwlwifi/iwl-8000.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-drv.c | 18 +++++++++++
drivers/net/wireless/iwlwifi/iwl-fw.h | 17 +++++++++-
drivers/net/wireless/iwlwifi/mvm/constants.h | 3 +-
drivers/net/wireless/iwlwifi/mvm/debugfs.c | 25 +++++++++++++++
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 3 ++
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | 2 ++
drivers/net/wireless/iwlwifi/mvm/fw-api.h | 60 ++++++++++++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 20 ++++++------
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 37 +++++++++++++++-------
drivers/net/wireless/iwlwifi/mvm/mvm.h | 43 ++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/mvm/ops.c | 3 +-
drivers/net/wireless/iwlwifi/mvm/rs.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------
drivers/net/wireless/iwlwifi/mvm/rs.h | 4 +++
drivers/net/wireless/iwlwifi/mvm/rx.c | 41 +++++++++++++++----------
drivers/net/wireless/iwlwifi/mvm/scan.c | 79 +++++++++++++++++++++++++++++++++++++++--------
drivers/net/wireless/iwlwifi/mvm/sta.c | 20 ++++++++----
drivers/net/wireless/iwlwifi/mvm/sta.h | 2 ++
drivers/net/wireless/iwlwifi/mvm/tt.c | 2 +-
drivers/net/wireless/iwlwifi/mvm/tx.c | 60 ++++++++++++++++++++++++++++--------
drivers/net/wireless/iwlwifi/mvm/utils.c | 46 ++++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/pcie/drv.c | 4 +++
drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +-
23 files changed, 573 insertions(+), 160 deletions(-)


Attachments:
signature.asc (819.00 B)
OpenPGP digital signature

2014-09-21 19:22:50

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 16/17] iwlwifi: mvm: disable BT Co-running by default

From: Emmanuel Grumbach <[email protected]>

The tables still contain dummy values.

Cc: <[email protected]> [3.15+]
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/constants.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index f47f458..d4dfbe4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -90,7 +90,7 @@
#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
#define IWL_MVM_BT_COEX_SYNC2SCO 1
-#define IWL_MVM_BT_COEX_CORUNNING 1
+#define IWL_MVM_BT_COEX_CORUNNING 0
#define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
#define IWL_MVM_QUOTA_THRESHOLD 8
--
1.9.1


2014-09-26 19:44:49

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision

On Tue, 2014-09-23 at 11:38 +0000, Grumbach, Emmanuel wrote:
> > "Grumbach, Emmanuel" <[email protected]> writes:
> > >> Emmanuel Grumbach <[email protected]> writes:
> > >>
> > >> > diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c
> > >> > b/drivers/net/wireless/iwlwifi/iwl-8000.c
> > >> > index 4ae8ba6..e435148 100644
> > >> > --- a/drivers/net/wireless/iwlwifi/iwl-8000.c
> > >> > +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
> > >> > @@ -81,7 +81,7 @@
> > >> > #define IWL8000_NVM_VERSION 0x0a1d
> > >> > #define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
> > >> >
> > >> > -#define IWL8000_FW_PRE "iwlwifi-8000-"
> > >> > +#define IWL8000_FW_PRE "iwlwifi-8000"
> > >> > #define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE
> > >> __stringify(api) ".ucode"
> > >>
> > >> Isn't this going to create a misleading MODULE_FIRMWARE entry,
> > >> matching neither of the firmware variants?
> > >>
> > >>
> > > Yes probably - OTOH, this device is far from being on the shelves. By the
> > time it will hit the shelves, we will have removed all the hacks for the early
> > steps of the hardware.
> > > Ideas to make it better?
> >
> > Not exactly elegant, but I would just have duplicated the macros for each
> > new hardware revision. E.g:
> >
> > #define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE "-"
> > __stringify(api) ".ucode"
> > #define IWL8000B_MODULE_FIRMWARE(api) IWL8000_FW_PRE "B-"
> > __stringify(api) ".ucode"
> > MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API
> > _OK));
> > MODULE_FIRMWARE(IWL8000B_MODULE_FIRMWARE(IWL8000_UCODE_AP
> > I_OK));
> >
> > Or maybe make the revision part of the macro or something.
> >
> >
> > > Good to know that someone is actually looking at the patches I take
> > > care to send :)
> >
> > Always looking for new goodies to try out :-) The temperature sensor
> > readout was one this time. Although I would have preferred it as a proper
> > hwmon device instead of a debugfs file. Has this been discussed?
> >
>
> Not really - since I don't think that this is worth it.
> The WiFi device heats up when we Tx, and I think it'd be worth making this data public in the system. The temperature sensor is mostly to avoid burning things out :)

Yeah, the temperature sensor is used to avoid heating the NIC too much
and potentially damaging things. We do things like throttle down the
data flow and, in the most dramatic cases, turn the chip entirely off.

The mean reason for the new debugfs entry is for, well, debugging. :)

Bjørn, do you have any ideas on how this information could be used in a
useful way so that it would be worth the effort of exporting it in a
more "official" way?

--
Cheers,
Luca.


2014-09-21 19:22:47

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 14/17] iwlwifi: mvm: report all BA notifs to RS

From: Eyal Shapira <[email protected]>

Currently BA notifications which don't reclaim any frames
would not cause the RS to be called as no skbs are passed
to mac80211. This is not optimal as RS can benefit from the
statistics of sent vs. acked of such a BA. This can improve the
reaction time of the RS algorithm. Also, an upcoming change in
the firmware would cause BA timeout to be reported as a BA notif
with 0 acked so this change is required for that as well.

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/tx.c | 51 +++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 66e1a3d..1cb793a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -873,6 +873,19 @@ int iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
return 0;
}

+static void iwl_mvm_tx_info_from_ba_notif(struct ieee80211_tx_info *info,
+ struct iwl_mvm_ba_notif *ba_notif,
+ struct iwl_mvm_tid_data *tid_data)
+{
+ info->flags |= IEEE80211_TX_STAT_AMPDU;
+ info->status.ampdu_ack_len = ba_notif->txed_2_done;
+ info->status.ampdu_len = ba_notif->txed;
+ iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags,
+ info);
+ info->status.status_driver_data[0] =
+ (void *)(uintptr_t)tid_data->reduced_tpc;
+}
+
int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd)
{
@@ -959,21 +972,37 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
*/
info->flags |= IEEE80211_TX_STAT_ACK;

- if (freed == 1) {
- /* this is the first skb we deliver in this batch */
- /* put the rate scaling data there */
- info->flags |= IEEE80211_TX_STAT_AMPDU;
- info->status.ampdu_ack_len = ba_notif->txed_2_done;
- info->status.ampdu_len = ba_notif->txed;
- iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags,
- info);
- info->status.status_driver_data[0] =
- (void *)(uintptr_t)tid_data->reduced_tpc;
- }
+ /* this is the first skb we deliver in this batch */
+ /* put the rate scaling data there */
+ if (freed == 1)
+ iwl_mvm_tx_info_from_ba_notif(info, ba_notif, tid_data);
}

spin_unlock_bh(&mvmsta->lock);

+ /* We got a BA notif with 0 acked or scd_ssn didn't progress which is
+ * possible (i.e. first MPDU in the aggregation wasn't acked)
+ * Still it's important to update RS about sent vs. acked.
+ */
+ if (skb_queue_empty(&reclaimed_skbs)) {
+ struct ieee80211_tx_info ba_info = {};
+ struct ieee80211_chanctx_conf *chanctx_conf = NULL;
+
+ if (mvmsta->vif)
+ chanctx_conf =
+ rcu_dereference(mvmsta->vif->chanctx_conf);
+
+ if (WARN_ON_ONCE(!chanctx_conf))
+ goto out;
+
+ ba_info.band = chanctx_conf->def.chan->band;
+ iwl_mvm_tx_info_from_ba_notif(&ba_info, ba_notif, tid_data);
+
+ IWL_DEBUG_TX_REPLY(mvm, "No reclaim. Update rs directly\n");
+ iwl_mvm_rs_tx_status(mvm, sta, tid, &ba_info);
+ }
+
+out:
rcu_read_unlock();

while (!skb_queue_empty(&reclaimed_skbs)) {
--
1.9.1


2014-09-21 19:22:49

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 15/17] iwlwifi: mvm: rs: fix logic in case of multiple TIDs

From: Eyal Shapira <[email protected]>

In case of traffic on multiple TIDs where one is aggregated
and the other is not RS would toggle between considering
traffic vs. the station as aggregated and not aggregated.
Instead consider the sta state as aggregated as long as
there's at least one TID aggregated.
This limitation is because the rates table is kept per
station and not per TID.

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/rs.c | 11 +----------
drivers/net/wireless/iwlwifi/mvm/sta.c | 8 ++++++++
drivers/net/wireless/iwlwifi/mvm/sta.h | 2 ++
3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 1865ba6..18a5399 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1980,16 +1980,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
struct iwl_mvm_tid_data *tid_data;
struct rs_rate *rate;

- if ((tid != IWL_MAX_TID_COUNT) &&
- (lq_sta->tx_agg_tid_en & (1 << tid))) {
- tid_data = &sta_priv->tid_data[tid];
- if (tid_data->state == IWL_AGG_OFF)
- lq_sta->is_agg = 0;
- else
- lq_sta->is_agg = 1;
- } else {
- lq_sta->is_agg = 0;
- }
+ lq_sta->is_agg = !!sta_priv->agg_tids;

/*
* Select rate-scale / modulation-mode table to work with in
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index bccd787..1731c20 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -247,6 +247,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
memset(&mvm_sta->tid_data[i], 0, sizeof(mvm_sta->tid_data[i]));
mvm_sta->tid_data[i].seq_number = seq;
}
+ mvm_sta->agg_tids = 0;

ret = iwl_mvm_sta_send_to_fw(mvm, sta, false);
if (ret)
@@ -872,12 +873,16 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
int queue, fifo, ret;
u16 ssn;

+ BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE)
+ != IWL_MAX_TID_COUNT);
+
buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);

spin_lock_bh(&mvmsta->lock);
ssn = tid_data->ssn;
queue = tid_data->txq_id;
tid_data->state = IWL_AGG_ON;
+ mvmsta->agg_tids |= BIT(tid);
tid_data->ssn = 0xffff;
spin_unlock_bh(&mvmsta->lock);

@@ -932,6 +937,8 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
IWL_DEBUG_TX_QUEUES(mvm, "Stop AGG: sta %d tid %d q %d state %d\n",
mvmsta->sta_id, tid, txq_id, tid_data->state);

+ mvmsta->agg_tids &= ~BIT(tid);
+
switch (tid_data->state) {
case IWL_AGG_ON:
tid_data->ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
@@ -1005,6 +1012,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
mvmsta->sta_id, tid, txq_id, tid_data->state);
old_state = tid_data->state;
tid_data->state = IWL_AGG_OFF;
+ mvmsta->agg_tids &= ~BIT(tid);
spin_unlock_bh(&mvmsta->lock);

if (old_state >= IWL_AGG_ON) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index aeb3a7f..d9c0d7b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -299,6 +299,7 @@ static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data)
* @tx_protection: reference counter for controlling the Tx protection.
* @tt_tx_protection: is thermal throttling enable Tx protection?
* @disable_tx: is tx to this STA disabled?
+ * @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is placed in that
@@ -323,6 +324,7 @@ struct iwl_mvm_sta {
bool tt_tx_protection;

bool disable_tx;
+ u8 agg_tids;
};

static inline struct iwl_mvm_sta *
--
1.9.1


2014-09-21 19:22:30

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 03/17] iwlwifi: mvm: Announce Quiet Period support

From: Assaf Krauss <[email protected]>

Add a ucode capability flag for support of Quiet Period (part of RRM).
If this flag is set, advertise device support.

Signed-off-by: Assaf Krauss <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-fw.h | 6 ++++--
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 +++
2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 6ab40bc..081a93d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -148,10 +148,12 @@ enum iwl_ucode_tlv_api {
* @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
* tx power value into TPC Report action frame and Link Measurement Report
* action frame
+ * @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
*/
enum iwl_ucode_tlv_capa {
- IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
- IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
+ IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
+ IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
+ IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
};

/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index ba029f6..5a169ab 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -415,6 +415,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
if (mvm->fw->ucode_capa.capa[0] &
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT)
hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION;
+ if (mvm->fw->ucode_capa.capa[0] &
+ IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT)
+ hw->wiphy->features |= NL80211_FEATURE_QUIET;

mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;

--
1.9.1


2014-09-21 19:22:53

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 17/17] iwlwifi: mvm: Refactor and fix max probe len computation

From: Andrei Otcheretianski <[email protected]>

Move iwl_mvm_max_scan_ie_len function to scan.c and fix the
implementation to conform with the LMAC scan API.
Since the correct implementation would leave us with unacceptably
tiny probes, add a workaround which returns a larger value.
In current implementation it's possible that unified_scan_lmac and
unified_sched_scan_lmac would return -ENOBUFS.

Signed-off-by: Andrei Otcheretianski <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 10 +----
drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 +
drivers/net/wireless/iwlwifi/mvm/scan.c | 64 ++++++++++++++++++++++++-----
3 files changed, 55 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 412a8a0..c7a73c6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -279,14 +279,6 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
}
}

-static int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
-{
- /* we create the 802.11 header and SSID element */
- if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID)
- return mvm->fw->ucode_capa.max_probe_length - 24 - 2;
- return mvm->fw->ucode_capa.max_probe_length - 24 - 34;
-}
-
int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
{
struct ieee80211_hw *hw = mvm->hw;
@@ -379,7 +371,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)

iwl_mvm_reset_phy_ctxts(mvm);

- hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm);
+ hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm, false);

hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;

diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 7d0194b..b153ced 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -935,6 +935,7 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct iwl_device_cmd *cmd);
int iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
+int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);

/* Scheduled scan */
int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 076fe1b..cb85e63 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -346,6 +346,48 @@ static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm)
IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT;
}

+static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm,
+ bool is_sched_scan)
+{
+ int max_probe_len;
+
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
+ max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
+ else
+ max_probe_len = mvm->fw->ucode_capa.max_probe_length;
+
+ /* we create the 802.11 header and SSID element */
+ max_probe_len -= 24 + 2;
+
+ /* basic ssid is added only for hw_scan with and old api */
+ if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) &&
+ !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) &&
+ !is_sched_scan)
+ max_probe_len -= 32;
+
+ return max_probe_len;
+}
+
+int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
+{
+ int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan);
+
+ if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN))
+ return max_ie_len;
+
+ /* TODO: [BUG] This function should return the maximum allowed size of
+ * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
+ * in the same command. So the correct implementation of this function
+ * is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan
+ * command has only 512 bytes and it would leave us with about 240
+ * bytes for scan IEs, which is clearly not enough. So meanwhile
+ * we will report an incorrect value. This may result in a failure to
+ * issue a scan in unified_scan_lmac and unified_sched_scan_lmac
+ * functions with -ENOBUFS, if a large enough probe will be provided.
+ */
+ return max_ie_len;
+}
+
int iwl_mvm_scan_request(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req)
@@ -1191,13 +1233,12 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
if (WARN_ON(mvm->scan_cmd == NULL))
return -ENOMEM;

- if (WARN_ON_ONCE(req->req.n_ssids > PROBE_OPTION_MAX ||
- req->ies.common_ie_len + req->ies.len[0] +
- req->ies.len[1] + 24 + 2 >
- SCAN_OFFLOAD_PROBE_REQ_SIZE ||
- req->req.n_channels >
- mvm->fw->ucode_capa.n_scan_channels))
- return -1;
+ if (req->req.n_ssids > PROBE_OPTION_MAX ||
+ req->ies.common_ie_len + req->ies.len[NL80211_BAND_2GHZ] +
+ req->ies.len[NL80211_BAND_5GHZ] >
+ iwl_mvm_max_scan_ie_fw_cmd_room(mvm, false) ||
+ req->req.n_channels > mvm->fw->ucode_capa.n_scan_channels)
+ return -ENOBUFS;

mvm->scan_status = IWL_MVM_SCAN_OS;

@@ -1285,10 +1326,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
if (WARN_ON(mvm->scan_cmd == NULL))
return -ENOMEM;

- if (WARN_ON_ONCE(req->n_ssids > PROBE_OPTION_MAX ||
- ies->common_ie_len + ies->len[0] + ies->len[1] + 24 + 2
- > SCAN_OFFLOAD_PROBE_REQ_SIZE ||
- req->n_channels > mvm->fw->ucode_capa.n_scan_channels))
+ if (req->n_ssids > PROBE_OPTION_MAX ||
+ ies->common_ie_len + ies->len[NL80211_BAND_2GHZ] +
+ ies->len[NL80211_BAND_5GHZ] >
+ iwl_mvm_max_scan_ie_fw_cmd_room(mvm, true) ||
+ req->n_channels > mvm->fw->ucode_capa.n_scan_channels)
return -ENOBUFS;

iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
--
1.9.1


2014-09-21 19:22:43

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 11/17] iwlwifi: Add missing PCI IDs for the 7260 series

From: Oren Givon <[email protected]>

Add 4 missing PCI IDs for the 7260 series.

Cc: <[email protected]> [3.10+]
Signed-off-by: Oren Givon <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/pcie/drv.c | 4 ++++
1 file changed, 4 insertions(+)

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)},
--
1.9.1


2014-09-21 19:22:31

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 04/17] iwlwifi: mvm: Set RRM_ENABLED bit in scan commands

From: Andrei Otcheretianski <[email protected]>

Set RRM_ENABLED (bit 6) flag in scan commands. When this flag is set
the fw will add WFA vendor-specific TPC report and DS parameter set
IEs into probe requests.
This bit is set for SCAN_OFFLOAD_REQUEST_CMD(0x51).

Signed-off-by: Andrei Otcheretianski <[email protected]>
Reviewed-by: Assaf Krauss <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-fw.h | 6 ++++++
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 3 +++
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 9 +++++++++
drivers/net/wireless/iwlwifi/mvm/scan.c | 15 +++++++++++++--
4 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 081a93d..e337546 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -148,11 +148,17 @@ enum iwl_ucode_tlv_api {
* @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
* tx power value into TPC Report action frame and Link Measurement Report
* action frame
+ * @IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT: supports adding DS params
+ * element in probe requests.
+ * @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
+ * probe requests.
* @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
*/
enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
+ IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
+ IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10),
IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
};

diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 8f22166..1354c68 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -670,6 +670,8 @@ struct iwl_scan_channel_opt {
* @IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE: send iteration complete notification
* @IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS multiple SSID matching
* @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
+ * @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report
+ * and DS parameter set IEs into probe requests.
*/
enum iwl_mvm_lmac_scan_flags {
IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0),
@@ -678,6 +680,7 @@ enum iwl_mvm_lmac_scan_flags {
IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE = BIT(3),
IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4),
IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5),
+ IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6),
};

enum iwl_scan_priority {
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 5a169ab..bd12f8e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -419,6 +419,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT)
hw->wiphy->features |= NL80211_FEATURE_QUIET;

+ if (mvm->fw->ucode_capa.capa[0] &
+ IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT)
+ hw->wiphy->features |=
+ NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES;
+
+ if (mvm->fw->ucode_capa.capa[0] &
+ IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)
+ hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES;
+
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;

/* currently FW API supports only one optional cipher scheme */
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 09545f2..076fe1b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -339,6 +339,13 @@ not_bound:
}
}

+static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm)
+{
+ /* require rrm scan whenever the fw supports it */
+ return mvm->fw->ucode_capa.capa[0] &
+ IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT;
+}
+
int iwl_mvm_scan_request(struct iwl_mvm *mvm,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req)
@@ -1153,6 +1160,10 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
}
+
+ if (iwl_mvm_rrm_scan_needed(mvm))
+ cmd->scan_flags |=
+ cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED);
}

int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
@@ -1208,7 +1219,7 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
if (req->req.n_ssids == 0)
flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;

- cmd->scan_flags = cpu_to_le32(flags);
+ cmd->scan_flags |= cpu_to_le32(flags);

cmd->flags = iwl_mvm_scan_rxon_flags(req->req.channels[0]->band);
cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
@@ -1305,7 +1316,7 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
if (req->n_ssids == 0)
flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;

- cmd->scan_flags = cpu_to_le32(flags);
+ cmd->scan_flags |= cpu_to_le32(flags);

cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
--
1.9.1


2014-09-21 19:22:34

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 06/17] iwlwifi: mvm: add debugfs entry to read the current temperature

From: Luciano Coelho <[email protected]>

When read, this new debugfs entry requests the current temperature
from the firmware and outputs it.

Signed-off-by: Luciano Coelho <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/debugfs.c | 25 +++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 +
drivers/net/wireless/iwlwifi/mvm/tt.c | 2 +-
3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 95eb9a5..50527a9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -326,6 +326,29 @@ out:
return count;
}

+static ssize_t iwl_dbgfs_nic_temp_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_mvm *mvm = file->private_data;
+ char buf[16];
+ int pos, temp;
+
+ if (!mvm->ucode_loaded)
+ return -EIO;
+
+ mutex_lock(&mvm->mutex);
+ temp = iwl_mvm_get_temp(mvm);
+ mutex_unlock(&mvm->mutex);
+
+ if (temp < 0)
+ return temp;
+
+ pos = scnprintf(buf , sizeof(buf), "%d\n", temp);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1378,6 +1401,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
+MVM_DEBUGFS_READ_FILE_OPS(nic_temp);
MVM_DEBUGFS_READ_FILE_OPS(stations);
MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
@@ -1420,6 +1444,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir,
S_IWUSR | S_IRUSR);
+ MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 8eacebb..c913d5e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -1188,6 +1188,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff);
void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
+int iwl_mvm_get_temp(struct iwl_mvm *mvm);

/* smart fifo */
int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index c750ca7..acca44a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -135,7 +135,7 @@ static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
sizeof(cmd), &cmd);
}

-static int iwl_mvm_get_temp(struct iwl_mvm *mvm)
+int iwl_mvm_get_temp(struct iwl_mvm *mvm)
{
struct iwl_notification_wait wait_temp_notif;
static const u8 temp_notif[] = { DTS_MEASUREMENT_NOTIFICATION };
--
1.9.1


2014-09-23 11:38:24

by Grumbach, Emmanuel

[permalink] [raw]
Subject: RE: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision

PiAiR3J1bWJhY2gsIEVtbWFudWVsIiA8ZW1tYW51ZWwuZ3J1bWJhY2hAaW50ZWwuY29tPiB3cml0
ZXM6DQo+ID4+IEVtbWFudWVsIEdydW1iYWNoIDxlZ3J1bWJhY2hAZ21haWwuY29tPiB3cml0ZXM6
DQo+ID4+DQo+ID4+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2l3bHdpZmkv
aXdsLTgwMDAuYw0KPiA+PiA+IGIvZHJpdmVycy9uZXQvd2lyZWxlc3MvaXdsd2lmaS9pd2wtODAw
MC5jDQo+ID4+ID4gaW5kZXggNGFlOGJhNi4uZTQzNTE0OCAxMDA2NDQNCj4gPj4gPiAtLS0gYS9k
cml2ZXJzL25ldC93aXJlbGVzcy9pd2x3aWZpL2l3bC04MDAwLmMNCj4gPj4gPiArKysgYi9kcml2
ZXJzL25ldC93aXJlbGVzcy9pd2x3aWZpL2l3bC04MDAwLmMNCj4gPj4gPiBAQCAtODEsNyArODEs
NyBAQA0KPiA+PiA+ICAjZGVmaW5lIElXTDgwMDBfTlZNX1ZFUlNJT04JCTB4MGExZA0KPiA+PiA+
ICAjZGVmaW5lIElXTDgwMDBfVFhfUE9XRVJfVkVSU0lPTgkweGZmZmYgLyogbWVhbmluZ2xlc3Mg
Ki8NCj4gPj4gPg0KPiA+PiA+IC0jZGVmaW5lIElXTDgwMDBfRldfUFJFICJpd2x3aWZpLTgwMDAt
Ig0KPiA+PiA+ICsjZGVmaW5lIElXTDgwMDBfRldfUFJFICJpd2x3aWZpLTgwMDAiDQo+ID4+ID4g
ICNkZWZpbmUgSVdMODAwMF9NT0RVTEVfRklSTVdBUkUoYXBpKSBJV0w4MDAwX0ZXX1BSRQ0KPiA+
PiBfX3N0cmluZ2lmeShhcGkpICIudWNvZGUiDQo+ID4+DQo+ID4+IElzbid0IHRoaXMgZ29pbmcg
dG8gY3JlYXRlIGEgbWlzbGVhZGluZyBNT0RVTEVfRklSTVdBUkUgZW50cnksDQo+ID4+IG1hdGNo
aW5nIG5laXRoZXIgb2YgdGhlIGZpcm13YXJlIHZhcmlhbnRzPw0KPiA+Pg0KPiA+Pg0KPiA+IFll
cyBwcm9iYWJseSAtIE9UT0gsIHRoaXMgZGV2aWNlIGlzIGZhciBmcm9tIGJlaW5nIG9uIHRoZSBz
aGVsdmVzLiBCeSB0aGUNCj4gdGltZSBpdCB3aWxsIGhpdCB0aGUgc2hlbHZlcywgd2Ugd2lsbCBo
YXZlIHJlbW92ZWQgYWxsIHRoZSBoYWNrcyBmb3IgdGhlIGVhcmx5DQo+IHN0ZXBzIG9mIHRoZSBo
YXJkd2FyZS4NCj4gPiBJZGVhcyB0byBtYWtlIGl0IGJldHRlcj8NCj4gDQo+IE5vdCBleGFjdGx5
IGVsZWdhbnQsIGJ1dCBJIHdvdWxkIGp1c3QgaGF2ZSBkdXBsaWNhdGVkIHRoZSBtYWNyb3MgZm9y
IGVhY2gNCj4gbmV3IGhhcmR3YXJlIHJldmlzaW9uLiAgRS5nOg0KPiANCj4gI2RlZmluZSBJV0w4
MDAwX01PRFVMRV9GSVJNV0FSRShhcGkpIElXTDgwMDBfRldfUFJFICItIg0KPiBfX3N0cmluZ2lm
eShhcGkpICIudWNvZGUiDQo+ICNkZWZpbmUgSVdMODAwMEJfTU9EVUxFX0ZJUk1XQVJFKGFwaSkg
SVdMODAwMF9GV19QUkUgIkItIg0KPiBfX3N0cmluZ2lmeShhcGkpICIudWNvZGUiDQo+IE1PRFVM
RV9GSVJNV0FSRShJV0w4MDAwX01PRFVMRV9GSVJNV0FSRShJV0w4MDAwX1VDT0RFX0FQSQ0KPiBf
T0spKTsNCj4gTU9EVUxFX0ZJUk1XQVJFKElXTDgwMDBCX01PRFVMRV9GSVJNV0FSRShJV0w4MDAw
X1VDT0RFX0FQDQo+IElfT0spKTsNCj4gDQo+IE9yIG1heWJlIG1ha2UgdGhlIHJldmlzaW9uIHBh
cnQgb2YgdGhlIG1hY3JvIG9yIHNvbWV0aGluZy4NCj4gDQo+IA0KPiA+IEdvb2QgdG8ga25vdyB0
aGF0IHNvbWVvbmUgaXMgYWN0dWFsbHkgbG9va2luZyBhdCB0aGUgcGF0Y2hlcyBJIHRha2UNCj4g
PiBjYXJlIHRvIHNlbmQgOikNCj4gDQo+IEFsd2F5cyBsb29raW5nIGZvciBuZXcgZ29vZGllcyB0
byB0cnkgb3V0IDotKSAgVGhlIHRlbXBlcmF0dXJlIHNlbnNvcg0KPiByZWFkb3V0IHdhcyBvbmUg
dGhpcyB0aW1lLiAgQWx0aG91Z2ggSSB3b3VsZCBoYXZlIHByZWZlcnJlZCBpdCBhcyBhIHByb3Bl
cg0KPiBod21vbiBkZXZpY2UgaW5zdGVhZCBvZiBhIGRlYnVnZnMgZmlsZS4gIEhhcyB0aGlzIGJl
ZW4gZGlzY3Vzc2VkPw0KPiANCg0KTm90IHJlYWxseSAtIHNpbmNlIEkgZG9uJ3QgdGhpbmsgdGhh
dCB0aGlzIGlzIHdvcnRoIGl0Lg0KVGhlIFdpRmkgZGV2aWNlIGhlYXRzIHVwIHdoZW4gd2UgVHgs
IGFuZCBJIHRoaW5rIGl0J2QgYmUgd29ydGggbWFraW5nIHRoaXMgZGF0YSBwdWJsaWMgaW4gdGhl
IHN5c3RlbS4gVGhlIHRlbXBlcmF0dXJlIHNlbnNvciBpcyBtb3N0bHkgdG8gYXZvaWQgYnVybmlu
ZyB0aGluZ3Mgb3V0IDopDQo=

2014-09-21 19:22:33

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 05/17] iwlwifi: mvm: prepare for scheduler config command

From: Avri Altman <[email protected]>

The scheduler is a HW sub-block that directs the work of the Flow
Handler by issuing requests for frame transfers, specifying source
and destination. Its primary function is to allocate flows into the
TX FIFOs based upon a pre-determined mapping.

The driver has some responsibilities to the scheduler, namely
initialising and maintaining the hardware registers. This is
currently done by directly accessing them, which can cause races
with the firmware also accessing the registers.

To address this problem, change the driver to no longer directly
access the registers but go through the firmware for this if the
firmware has support for DQA and thus the new command.

Signed-off-by: Avri Altman <[email protected]>
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-fw.h | 3 ++
drivers/net/wireless/iwlwifi/mvm/fw-api.h | 60 +++++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 20 +++++-----
drivers/net/wireless/iwlwifi/mvm/mvm.h | 38 ++++++++++++++++++
drivers/net/wireless/iwlwifi/mvm/ops.c | 1 +
drivers/net/wireless/iwlwifi/mvm/sta.c | 12 +++---
drivers/net/wireless/iwlwifi/mvm/tx.c | 4 +-
drivers/net/wireless/iwlwifi/mvm/utils.c | 46 ++++++++++++++++++++++
8 files changed, 165 insertions(+), 19 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index e337546..4f6e668 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -153,6 +153,8 @@ enum iwl_ucode_tlv_api {
* @IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT: supports adding TPC Report IE in
* probe requests.
* @IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT: supports Quiet Period requests
+ * @IWL_UCODE_TLV_CAPA_DQA_SUPPORT: supports dynamic queue allocation (DQA),
+ * which also implies support for the scheduler configuration command
*/
enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
@@ -160,6 +162,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT = BIT(10),
IWL_UCODE_TLV_CAPA_QUIET_PERIOD_SUPPORT = BIT(11),
+ IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
};

/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index a2c6628..667a922 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -116,6 +116,9 @@ enum {
TXPATH_FLUSH = 0x1e,
MGMT_MCAST_KEY = 0x1f,

+ /* scheduler config */
+ SCD_QUEUE_CFG = 0x1d,
+
/* global key */
WEP_KEY = 0x20,

@@ -1650,4 +1653,61 @@ struct iwl_dts_measurement_notif {
__le32 voltage;
} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */

+/**
+ * enum iwl_scd_control - scheduler config command control flags
+ * @IWL_SCD_CONTROL_RM_TID: remove TID from this queue
+ * @IWL_SCD_CONTROL_SET_SSN: use the SSN and program it into HW
+ */
+enum iwl_scd_control {
+ IWL_SCD_CONTROL_RM_TID = BIT(4),
+ IWL_SCD_CONTROL_SET_SSN = BIT(5),
+};
+
+/**
+ * enum iwl_scd_flags - scheduler config command flags
+ * @IWL_SCD_FLAGS_SHARE_TID: multiple TIDs map to this queue
+ * @IWL_SCD_FLAGS_SHARE_RA: multiple RAs map to this queue
+ * @IWL_SCD_FLAGS_DQA_ENABLED: DQA is enabled
+ */
+enum iwl_scd_flags {
+ IWL_SCD_FLAGS_SHARE_TID = BIT(0),
+ IWL_SCD_FLAGS_SHARE_RA = BIT(1),
+ IWL_SCD_FLAGS_DQA_ENABLED = BIT(2),
+};
+
+#define IWL_SCDQ_INVALID_STA 0xff
+
+/**
+ * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command
+ * @token: dialog token addba - unused legacy
+ * @sta_id: station id 4-bit
+ * @tid: TID 0..7
+ * @scd_queue: TFD queue num 0 .. 31
+ * @enable: 1 queue enable, 0 queue disable
+ * @aggregate: 1 aggregated queue, 0 otherwise
+ * @tx_fifo: tx fifo num 0..7
+ * @window: up to 64
+ * @ssn: starting seq num 12-bit
+ * @control: command control flags
+ * @flags: flags - see &enum iwl_scd_flags
+ *
+ * Note that every time the command is sent, all parameters must
+ * be filled with the exception of
+ * - the SSN, which is only used with @IWL_SCD_CONTROL_SET_SSN
+ * - the window, which is only relevant when starting aggregation
+ */
+struct iwl_scd_txq_cfg_cmd {
+ u8 token;
+ u8 sta_id;
+ u8 tid;
+ u8 scd_queue;
+ u8 enable;
+ u8 aggregate;
+ u8 tx_fifo;
+ u8 window;
+ __le16 ssn;
+ u8 control;
+ u8 flags;
+} __packed;
+
#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 8342671..0c5c0b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -427,17 +427,17 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)

switch (vif->type) {
case NL80211_IFTYPE_P2P_DEVICE:
- iwl_trans_ac_txq_enable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
- IWL_MVM_TX_FIFO_VO);
+ iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
+ IWL_MVM_TX_FIFO_VO);
break;
case NL80211_IFTYPE_AP:
- iwl_trans_ac_txq_enable(mvm->trans, vif->cab_queue,
- IWL_MVM_TX_FIFO_MCAST);
+ iwl_mvm_enable_ac_txq(mvm, vif->cab_queue,
+ IWL_MVM_TX_FIFO_MCAST);
/* fall through */
default:
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
- iwl_trans_ac_txq_enable(mvm->trans, vif->hw_queue[ac],
- iwl_mvm_ac_to_tx_fifo[ac]);
+ iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac],
+ iwl_mvm_ac_to_tx_fifo[ac]);
break;
}

@@ -452,16 +452,14 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)

switch (vif->type) {
case NL80211_IFTYPE_P2P_DEVICE:
- iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
- true);
+ iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE);
break;
case NL80211_IFTYPE_AP:
- iwl_trans_txq_disable(mvm->trans, vif->cab_queue, true);
+ iwl_mvm_disable_txq(mvm, vif->cab_queue);
/* fall through */
default:
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
- iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac],
- true);
+ iwl_mvm_disable_txq(mvm, vif->hw_queue[ac]);
}
}

diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 5529958..8eacebb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -779,6 +779,11 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
}

+static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm)
+{
+ return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_DQA_SUPPORT;
+}
+
extern const u8 iwl_mvm_ac_to_tx_fifo[];

struct iwl_rate_info {
@@ -1141,6 +1146,39 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
return mvmvif->low_latency;
}

+/* hw scheduler queue config */
+void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
+ const struct iwl_trans_txq_scd_cfg *cfg);
+void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue);
+
+static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
+ u8 fifo)
+{
+ struct iwl_trans_txq_scd_cfg cfg = {
+ .fifo = fifo,
+ .tid = IWL_MAX_TID_COUNT,
+ .aggregate = false,
+ .frame_limit = IWL_FRAME_LIMIT,
+ };
+
+ iwl_mvm_enable_txq(mvm, queue, 0, &cfg);
+}
+
+static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
+ int fifo, int sta_id, int tid,
+ int frame_limit, u16 ssn)
+{
+ struct iwl_trans_txq_scd_cfg cfg = {
+ .fifo = fifo,
+ .sta_id = sta_id,
+ .tid = tid,
+ .frame_limit = frame_limit,
+ .aggregate = true,
+ };
+
+ iwl_mvm_enable_txq(mvm, queue, ssn, &cfg);
+}
+
/* Assoc status */
bool iwl_mvm_is_idle(struct iwl_mvm *mvm);

diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index f887779..9bf9de7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -342,6 +342,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(BT_COEX_UPDATE_REDUCED_TXP),
CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
CMD(ANTENNA_COUPLING_NOTIFICATION),
+ CMD(SCD_QUEUE_CFG),
};
#undef CMD

diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 666f16b..bccd787 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -535,8 +535,8 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
lockdep_assert_held(&mvm->mutex);

/* Map Aux queue to fifo - needs to happen before adding Aux station */
- iwl_trans_ac_txq_enable(mvm->trans, mvm->aux_queue,
- IWL_MVM_TX_FIFO_MCAST);
+ iwl_mvm_enable_ac_txq(mvm, mvm->aux_queue,
+ IWL_MVM_TX_FIFO_MCAST);

/* Allocate aux station and assign to it the aux queue */
ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, BIT(mvm->aux_queue),
@@ -887,8 +887,8 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
if (ret)
return -EIO;

- iwl_trans_txq_enable(mvm->trans, queue, fifo, mvmsta->sta_id, tid,
- buf_size, ssn);
+ iwl_mvm_enable_agg_txq(mvm, queue, fifo, mvmsta->sta_id, tid,
+ buf_size, ssn);

/*
* Even though in theory the peer could have different
@@ -956,7 +956,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,

iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);

- iwl_trans_txq_disable(mvm->trans, txq_id, true);
+ iwl_mvm_disable_txq(mvm, txq_id);
return 0;
case IWL_AGG_STARTING:
case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1013,7 +1013,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,

iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);

- iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
+ iwl_mvm_disable_txq(mvm, tid_data->txq_id);
}

mvm->queue_to_mac80211[tid_data->txq_id] =
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index d84f3ca..66e1a3d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -493,11 +493,11 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
IWL_DEBUG_TX_QUEUES(mvm,
"Can continue DELBA flow ssn = next_recl = %d\n",
tid_data->next_reclaimed);
- iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
+ iwl_mvm_disable_txq(mvm, tid_data->txq_id);
tid_data->state = IWL_AGG_OFF;
/*
* we can't hold the mutex - but since we are after a sequence
- * point (call to iwl_trans_txq_disable), so we don't even need
+ * point (call to iwl_mvm_disable_txq(), so we don't even need
* a memory barrier.
*/
mvm->queue_to_mac80211[tid_data->txq_id] =
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 1958f29..8021f6e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -530,6 +530,52 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
iwl_mvm_dump_umac_error_log(mvm);
}

+void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
+ const struct iwl_trans_txq_scd_cfg *cfg)
+{
+ if (iwl_mvm_is_dqa_supported(mvm)) {
+ struct iwl_scd_txq_cfg_cmd cmd = {
+ .scd_queue = queue,
+ .enable = 1,
+ .window = cfg->frame_limit,
+ .sta_id = cfg->sta_id,
+ .ssn = cpu_to_le16(ssn),
+ .tx_fifo = cfg->fifo,
+ .aggregate = cfg->aggregate,
+ .flags = IWL_SCD_FLAGS_DQA_ENABLED,
+ .tid = cfg->tid,
+ .control = IWL_SCD_CONTROL_SET_SSN,
+ };
+ int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(mvm,
+ "Failed to configure queue %d on FIFO %d\n",
+ queue, cfg->fifo);
+ }
+
+ iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn,
+ iwl_mvm_is_dqa_supported(mvm) ? NULL : cfg);
+}
+
+void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue)
+{
+ iwl_trans_txq_disable(mvm->trans, queue,
+ !iwl_mvm_is_dqa_supported(mvm));
+
+ if (iwl_mvm_is_dqa_supported(mvm)) {
+ struct iwl_scd_txq_cfg_cmd cmd = {
+ .scd_queue = queue,
+ .enable = 0,
+ };
+ int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, CMD_ASYNC,
+ sizeof(cmd), &cmd);
+ if (ret)
+ IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
+ queue, ret);
+ }
+}
+
/**
* iwl_mvm_send_lq_cmd() - Send link quality command
* @init: This command is sent as part of station initialization right
--
1.9.1


2014-09-21 19:22:45

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision

From: Liad Kaufman <[email protected]>

The 8000 HW series also includes the revision in the FW
name.

Signed-off-by: Liad Kaufman <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-8000.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-drv.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 4ae8ba6..e435148 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -81,7 +81,7 @@
#define IWL8000_NVM_VERSION 0x0a1d
#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */

-#define IWL8000_FW_PRE "iwlwifi-8000-"
+#define IWL8000_FW_PRE "iwlwifi-8000"
#define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE __stringify(api) ".ucode"

#define NVM_HW_SECTION_NUM_FAMILY_8000 10
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index ed673ba..0f1084f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -69,6 +69,7 @@
#include <linux/vmalloc.h>

#include "iwl-drv.h"
+#include "iwl-csr.h"
#include "iwl-debug.h"
#include "iwl-trans.h"
#include "iwl-op-mode.h"
@@ -244,6 +245,23 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
snprintf(drv->firmware_name, sizeof(drv->firmware_name), "%s%s.ucode",
name_pre, tag);

+ /*
+ * Starting 8000B - FW name format has changed. This overwrites the
+ * previous name and uses the new format.
+ */
+ if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
+ char rev_step[2] = {
+ 'A' + CSR_HW_REV_STEP(drv->trans->hw_rev), 0
+ };
+
+ /* A-step doesn't have an indication */
+ if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP)
+ rev_step[0] = 0;
+
+ snprintf(drv->firmware_name, sizeof(drv->firmware_name),
+ "%s%s-%s.ucode", name_pre, rev_step, tag);
+ }
+
IWL_DEBUG_INFO(drv, "attempting to load firmware %s'%s'\n",
(drv->fw_index == UCODE_EXPERIMENTAL_INDEX)
? "EXPERIMENTAL " : "",
--
1.9.1


2014-09-21 19:22:42

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 10/17] iwlwifi: mvm: limit aggregation size in low latency to 6

From: Eyal Shapira <[email protected]>

This is a tradeoff between enabling better throughput for
bursty traffic and low latency. The number 6 was found to be
a good tradeoff for the Miracast use case which is the
major use case for low latency.

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/ops.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 9bf9de7..15aa298 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -422,7 +422,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm->first_agg_queue = 12;
}
mvm->sf_state = SF_UNINIT;
- mvm->low_latency_agg_frame_limit = 1;
+ mvm->low_latency_agg_frame_limit = 6;

mutex_init(&mvm->mutex);
mutex_init(&mvm->d0i3_suspend_mutex);
--
1.9.1


2014-09-21 19:22:29

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 02/17] iwlwifi: mvm: Update TX power in TPC reports

From: Andrei Otcheretianski <[email protected]>

Introduce new tx command flag (TX_CMD_FLG_WRITE_TX_POWER) which requests the
fw to update the tx power value at some constant offset.
Set this flag when transmitting either TPC report or Link measurement report
action frames.
In addition, introduce new tlv which indicates whether the fw supports power
insertion (IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT) and publish the
corresponding nl80211 feature.

Signed-off-by: Andrei Otcheretianski <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-fw.h | 4 ++++
drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h | 2 ++
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 4 ++++
drivers/net/wireless/iwlwifi/mvm/tx.c | 5 +++++
4 files changed, 15 insertions(+)

diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 62c46eb..6ab40bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -145,9 +145,13 @@ enum iwl_ucode_tlv_api {
/**
* enum iwl_ucode_tlv_capa - ucode capabilities
* @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
+ * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
+ * tx power value into TPC Report action frame and Link Measurement Report
+ * action frame
*/
enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
+ IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
};

/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index d6073f6..5bca1f8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -66,6 +66,7 @@
/**
* enum iwl_tx_flags - bitmasks for tx_flags in TX command
* @TX_CMD_FLG_PROT_REQUIRE: use RTS or CTS-to-self to protect the frame
+ * @TX_CMD_FLG_WRITE_TX_POWER: update current tx power value in the mgmt frame
* @TX_CMD_FLG_ACK: expect ACK from receiving station
* @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command.
* Otherwise, use rate_n_flags from the TX command
@@ -97,6 +98,7 @@
*/
enum iwl_tx_flags {
TX_CMD_FLG_PROT_REQUIRE = BIT(0),
+ TX_CMD_FLG_WRITE_TX_POWER = BIT(1),
TX_CMD_FLG_ACK = BIT(3),
TX_CMD_FLG_STA_RATE = BIT(4),
TX_CMD_FLG_BAR = BIT(6),
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 5f5a893..ba029f6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -412,6 +412,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
NL80211_FEATURE_DYNAMIC_SMPS |
NL80211_FEATURE_STATIC_SMPS;

+ if (mvm->fw->ucode_capa.capa[0] &
+ IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT)
+ hw->wiphy->features |= NL80211_FEATURE_TX_POWER_INSERTION;
+
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;

/* currently FW API supports only one optional cipher scheme */
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index c67296e..d84f3ca 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -133,6 +133,11 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
!is_multicast_ether_addr(ieee80211_get_DA(hdr)))
tx_flags |= TX_CMD_FLG_PROT_REQUIRE;

+ if ((mvm->fw->ucode_capa.capa[0] &
+ IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT) &&
+ ieee80211_action_contains_tpc(skb))
+ tx_flags |= TX_CMD_FLG_WRITE_TX_POWER;
+
tx_cmd->tx_flags = cpu_to_le32(tx_flags);
/* Total # bytes to be transmitted */
tx_cmd->len = cpu_to_le16((u16)skb->len);
--
1.9.1


2014-09-21 19:22:27

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 01/17] iwlwifi: mvm: support cloned tx skbs

From: Ido Yariv <[email protected]>

Since tx skbs are not modified by the driver, let mac80211 know the
driver can handle cloned skbs.

Signed-off-by: Ido Yariv <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 4c21210..5f5a893 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -303,7 +303,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_TIMING_BEACON_ONLY |
IEEE80211_HW_CONNECTION_MONITOR |
- IEEE80211_HW_CHANCTX_STA_CSA;
+ IEEE80211_HW_CHANCTX_STA_CSA |
+ IEEE80211_HW_SUPPORTS_CLONED_SKBS;

hw->queues = mvm->first_agg_queue;
hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
--
1.9.1


2014-09-27 06:42:10

by Bjørn Mork

[permalink] [raw]
Subject: Re: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision



On 26 September 2014 21:44:38 CEST, Luca Coelho <[email protected]> wrote:

>Yeah, the temperature sensor is used to avoid heating the NIC too much
>and potentially damaging things. We do things like throttle down the
>data flow and, in the most dramatic cases, turn the chip entirely off.
>
>The mean reason for the new debugfs entry is for, well, debugging. :)
>
>Bjørn, do you have any ideas on how this information could be used in a
>useful way so that it would be worth the effort of exporting it in a
>more "official" way?

No, not really. It was just a random thought that this should be made available for monitoring applications.

It sounds like this sensor is similar to the sensors associated with each CPU core. Which have been made available through the coretemp driver although I don't think that was the intention of the hardware designer. But I don't know if exporting it has any practical value.


Bjørn

2014-09-26 17:45:11

by John W. Linville

[permalink] [raw]
Subject: Re: pull request: iwlwifi-next 2014-09-21

On Sun, Sep 21, 2014 at 10:21:00PM +0300, Emmanuel Grumbach wrote:
>
>
> On 09/21/2014 10:15 PM, Emmanuel Grumbach wrote:
> > Hi John,
> >
> > Here is another (last?) pull request for 3.18.
> >
> > I have here a few things that depend on the latest mac80211's changes: RRM, TPC, Quiet Period etc...
> > Eyal keeps improving our rate control and we have a new device ID. This last patch should probably
> > have gone to wireless.git, but at that stage, I preferred to send it to -next and CC stable.
> >
> > Let me know if you have issues!
> >
> > The following changes since commit 6bd2bd27baf12fa0f2e6d611509fc0e1bffb0f97:
> >
> > Merge tag 'mac80211-next-for-john-2014-09-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next (2014-09-15 14:51:23 -0400)
> >
> > are available in the git repository at:
> >
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git master
> >
> > for you to fetch changes up to 908f324b609320a8839211922f8c4946c891d56c:
> >
> I had to edit one commit message - new HEAD: 48849a4150e353656dc5d207f2a56ebd00484ce6

I'm pulling this now, but I don't plan to push it back out until
after Dave pulls my earlier pull request...

John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2014-09-23 11:09:47

by Bjørn Mork

[permalink] [raw]
Subject: Re: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision

"Grumbach, Emmanuel" <[email protected]> writes:
>> Emmanuel Grumbach <[email protected]> writes:
>>
>> > diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c
>> > b/drivers/net/wireless/iwlwifi/iwl-8000.c
>> > index 4ae8ba6..e435148 100644
>> > --- a/drivers/net/wireless/iwlwifi/iwl-8000.c
>> > +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
>> > @@ -81,7 +81,7 @@
>> > #define IWL8000_NVM_VERSION 0x0a1d
>> > #define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
>> >
>> > -#define IWL8000_FW_PRE "iwlwifi-8000-"
>> > +#define IWL8000_FW_PRE "iwlwifi-8000"
>> > #define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE
>> __stringify(api) ".ucode"
>>
>> Isn't this going to create a misleading MODULE_FIRMWARE entry, matching
>> neither of the firmware variants?
>>
>>
> Yes probably - OTOH, this device is far from being on the shelves. By the time it will hit the shelves, we will have removed all the hacks for the early steps of the hardware.
> Ideas to make it better?

Not exactly elegant, but I would just have duplicated the macros for
each new hardware revision. E.g:

#define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE "-" __stringify(api) ".ucode"
#define IWL8000B_MODULE_FIRMWARE(api) IWL8000_FW_PRE "B-" __stringify(api) ".ucode"
MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK));
MODULE_FIRMWARE(IWL8000B_MODULE_FIRMWARE(IWL8000_UCODE_API_OK));

Or maybe make the revision part of the macro or something.


> Good to know that someone is actually looking at the patches I take care to send :)

Always looking for new goodies to try out :-) The temperature sensor
readout was one this time. Although I would have preferred it as a
proper hwmon device instead of a debugfs file. Has this been discussed?




Bjørn

2014-09-21 19:22:44

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 12/17] iwlwifi: pcie: fix HW_REV saving for 8000 series

From: Liad Kaufman <[email protected]>

Align the trans->hw_rev variable format with previous series
format.

Signed-off-by: Liad Kaufman <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

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),
--
1.9.1


2014-09-21 19:21:08

by Emmanuel Grumbach

[permalink] [raw]
Subject: Re: pull request: iwlwifi-next 2014-09-21



On 09/21/2014 10:15 PM, Emmanuel Grumbach wrote:
> Hi John,
>
> Here is another (last?) pull request for 3.18.
>
> I have here a few things that depend on the latest mac80211's changes: RRM, TPC, Quiet Period etc...
> Eyal keeps improving our rate control and we have a new device ID. This last patch should probably
> have gone to wireless.git, but at that stage, I preferred to send it to -next and CC stable.
>
> Let me know if you have issues!
>
> The following changes since commit 6bd2bd27baf12fa0f2e6d611509fc0e1bffb0f97:
>
> Merge tag 'mac80211-next-for-john-2014-09-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next (2014-09-15 14:51:23 -0400)
>
> are available in the git repository at:
>
>
> git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git master
>
> for you to fetch changes up to 908f324b609320a8839211922f8c4946c891d56c:
>
I had to edit one commit message - new HEAD: 48849a4150e353656dc5d207f2a56ebd00484ce6


Attachments:
signature.asc (819.00 B)
OpenPGP digital signature

2014-09-22 17:28:36

by Grumbach, Emmanuel

[permalink] [raw]
Subject: RE: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision

IA0KPiBFbW1hbnVlbCBHcnVtYmFjaCA8ZWdydW1iYWNoQGdtYWlsLmNvbT4gd3JpdGVzOg0KPiAN
Cj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9uZXQvd2lyZWxlc3MvaXdsd2lmaS9pd2wtODAwMC5j
DQo+ID4gYi9kcml2ZXJzL25ldC93aXJlbGVzcy9pd2x3aWZpL2l3bC04MDAwLmMNCj4gPiBpbmRl
eCA0YWU4YmE2Li5lNDM1MTQ4IDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvbmV0L3dpcmVsZXNz
L2l3bHdpZmkvaXdsLTgwMDAuYw0KPiA+ICsrKyBiL2RyaXZlcnMvbmV0L3dpcmVsZXNzL2l3bHdp
ZmkvaXdsLTgwMDAuYw0KPiA+IEBAIC04MSw3ICs4MSw3IEBADQo+ID4gICNkZWZpbmUgSVdMODAw
MF9OVk1fVkVSU0lPTgkJMHgwYTFkDQo+ID4gICNkZWZpbmUgSVdMODAwMF9UWF9QT1dFUl9WRVJT
SU9OCTB4ZmZmZiAvKiBtZWFuaW5nbGVzcyAqLw0KPiA+DQo+ID4gLSNkZWZpbmUgSVdMODAwMF9G
V19QUkUgIml3bHdpZmktODAwMC0iDQo+ID4gKyNkZWZpbmUgSVdMODAwMF9GV19QUkUgIml3bHdp
ZmktODAwMCINCj4gPiAgI2RlZmluZSBJV0w4MDAwX01PRFVMRV9GSVJNV0FSRShhcGkpIElXTDgw
MDBfRldfUFJFDQo+IF9fc3RyaW5naWZ5KGFwaSkgIi51Y29kZSINCj4gDQo+IElzbid0IHRoaXMg
Z29pbmcgdG8gY3JlYXRlIGEgbWlzbGVhZGluZyBNT0RVTEVfRklSTVdBUkUgZW50cnksIG1hdGNo
aW5nDQo+IG5laXRoZXIgb2YgdGhlIGZpcm13YXJlIHZhcmlhbnRzPw0KPiANCj4NClllcyBwcm9i
YWJseSAtIE9UT0gsIHRoaXMgZGV2aWNlIGlzIGZhciBmcm9tIGJlaW5nIG9uIHRoZSBzaGVsdmVz
LiBCeSB0aGUgdGltZSBpdCB3aWxsIGhpdCB0aGUgc2hlbHZlcywgd2Ugd2lsbCBoYXZlIHJlbW92
ZWQgYWxsIHRoZSBoYWNrcyBmb3IgdGhlIGVhcmx5IHN0ZXBzIG9mIHRoZSBoYXJkd2FyZS4NCklk
ZWFzIHRvIG1ha2UgaXQgYmV0dGVyPw0KDQpHb29kIHRvIGtub3cgdGhhdCBzb21lb25lIGlzIGFj
dHVhbGx5IGxvb2tpbmcgYXQgdGhlIHBhdGNoZXMgSSB0YWtlIGNhcmUgdG8gc2VuZCA6KQ0K

2014-09-21 19:22:40

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 09/17] iwlwifi: mvm: rs: refactor to allow direct rs updating

From: Eyal Shapira <[email protected]>

Enable RS to get updated directly via iwl_mvm_rs_tx_status
which will be called by the driver and not via mac80211
rate control. This is required for a following patch to
report on BAs which do not cause the BA window to progress.
Also this is a first step in decoupling rs from the
mac80211 rate control.

Signed-off-by: Eyal Shapira <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/rs.c | 98 +++++++++++++++++------------------
drivers/net/wireless/iwlwifi/mvm/rs.h | 4 ++
2 files changed, 52 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index d179a8e..1865ba6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -377,9 +377,9 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
}

static void rs_rate_scale_perform(struct iwl_mvm *mvm,
- struct sk_buff *skb,
- struct ieee80211_sta *sta,
- struct iwl_lq_sta *lq_sta);
+ struct ieee80211_sta *sta,
+ struct iwl_lq_sta *lq_sta,
+ int tid);
static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta,
@@ -1007,27 +1007,35 @@ static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
return RATE_MCS_CHAN_WIDTH_20;
}

-/*
- * mac80211 sends us Tx status
- */
-static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
- struct ieee80211_sta *sta, void *priv_sta,
- struct sk_buff *skb)
+static u8 rs_get_tid(struct ieee80211_hdr *hdr)
+{
+ u8 tid = IWL_MAX_TID_COUNT;
+
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ u8 *qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ }
+
+ if (unlikely(tid > IWL_MAX_TID_COUNT))
+ tid = IWL_MAX_TID_COUNT;
+
+ return tid;
+}
+
+void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+ int tid, struct ieee80211_tx_info *info)
{
int legacy_success;
int retries;
int mac_index, i;
- struct iwl_lq_sta *lq_sta = priv_sta;
struct iwl_lq_cmd *table;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r;
- struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
enum mac80211_rate_control_flags mac_flags;
u32 ucode_rate;
struct rs_rate rate;
struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
+ struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;

/* Treat uninitialized rate scaling data same as non-existing. */
if (!lq_sta) {
@@ -1045,10 +1053,6 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
return;
}
#endif
- if (!ieee80211_is_data(hdr->frame_control) ||
- info->flags & IEEE80211_TX_CTL_NO_ACK)
- return;
-
/* This packet was aggregated but doesn't carry status info */
if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
!(info->flags & IEEE80211_TX_STAT_AMPDU))
@@ -1094,7 +1098,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
ieee80211_stop_tx_ba_session(sta, tid);

- iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
+ iwl_mvm_rs_rate_init(mvm, sta, info->band, false);
return;
}
lq_sta->last_tx = jiffies;
@@ -1221,8 +1225,28 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
done:
/* See if there's a better rate or modulation mode to try. */
- if (sta && sta->supp_rates[sband->band])
- rs_rate_scale_perform(mvm, skb, sta, lq_sta);
+ if (sta && sta->supp_rates[info->band])
+ rs_rate_scale_perform(mvm, sta, lq_sta, tid);
+}
+
+/*
+ * mac80211 sends us Tx status
+ */
+static void rs_mac80211_tx_status(void *mvm_r,
+ struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_r;
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+ if (!ieee80211_is_data(hdr->frame_control) ||
+ info->flags & IEEE80211_TX_CTL_NO_ACK)
+ return;
+
+ iwl_mvm_rs_tx_status(mvm, sta, rs_get_tid(hdr), info);
}

/*
@@ -1493,22 +1517,6 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
}

-static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
- struct ieee80211_hdr *hdr)
-{
- u8 tid = IWL_MAX_TID_COUNT;
-
- if (ieee80211_is_data_qos(hdr->frame_control)) {
- u8 *qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & 0xf;
- }
-
- if (unlikely(tid > IWL_MAX_TID_COUNT))
- tid = IWL_MAX_TID_COUNT;
-
- return tid;
-}
-
static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_sta,
struct ieee80211_sta *sta,
@@ -1947,12 +1955,10 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
* Do rate scaling and search for new modulation mode.
*/
static void rs_rate_scale_perform(struct iwl_mvm *mvm,
- struct sk_buff *skb,
struct ieee80211_sta *sta,
- struct iwl_lq_sta *lq_sta)
+ struct iwl_lq_sta *lq_sta,
+ int tid)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
int low = IWL_RATE_INVALID;
int high = IWL_RATE_INVALID;
int index;
@@ -1969,19 +1975,11 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
u8 done_search = 0;
u16 high_low;
s32 sr;
- u8 tid = IWL_MAX_TID_COUNT;
u8 prev_agg = lq_sta->is_agg;
struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv;
struct iwl_mvm_tid_data *tid_data;
struct rs_rate *rate;

- /* Send management frames and NO_ACK data using lowest rate. */
- /* TODO: this could probably be improved.. */
- if (!ieee80211_is_data(hdr->frame_control) ||
- info->flags & IEEE80211_TX_CTL_NO_ACK)
- return;
-
- tid = rs_get_tid(lq_sta, hdr);
if ((tid != IWL_MAX_TID_COUNT) &&
(lq_sta->tx_agg_tid_en & (1 << tid))) {
tid_data = &sta_priv->tid_data[tid];
@@ -3323,7 +3321,7 @@ static void rs_rate_init_stub(void *mvm_r,

static const struct rate_control_ops rs_mvm_ops = {
.name = RS_NAME,
- .tx_status = rs_tx_status,
+ .tx_status = rs_mac80211_tx_status,
.get_rate = rs_get_rate,
.rate_init = rs_rate_init_stub,
.alloc = rs_alloc,
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 95c4b96..eb34c12 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -376,6 +376,10 @@ struct iwl_lq_sta {
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
enum ieee80211_band band, bool init);

+/* Notify RS about Tx status */
+void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+ int tid, struct ieee80211_tx_info *info);
+
/**
* iwl_rate_control_register - Register the rate control algorithm callbacks
*
--
1.9.1


2014-09-21 19:22:36

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 07/17] iwlwifi: mvm: Allow schedule scan while connected

From: Alexander Bondar <[email protected]>

In the past when schedule scan was started while connected on one of
interfaces FW crashes were observed. In the newest FW this issue is
solved, so remove limitaion after examining corresponding TLV flag.

Signed-off-by: Alexander Bondar <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index bd12f8e..412a8a0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -2152,7 +2152,13 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,

mutex_lock(&mvm->mutex);

- if (!iwl_mvm_is_idle(mvm)) {
+ /* Newest FW fixes sched scan while connected on another interface */
+ if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
+ if (!vif->bss_conf.idle) {
+ ret = -EBUSY;
+ goto out;
+ }
+ } else if (!iwl_mvm_is_idle(mvm)) {
ret = -EBUSY;
goto out;
}
--
1.9.1


2014-09-22 10:45:45

by Bjørn Mork

[permalink] [raw]
Subject: Re: [PATCH 13/17] iwlwifi: 8000: fix fw name to account for revision

Emmanuel Grumbach <[email protected]> writes:

> diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
> index 4ae8ba6..e435148 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-8000.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
> @@ -81,7 +81,7 @@
> #define IWL8000_NVM_VERSION 0x0a1d
> #define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
>
> -#define IWL8000_FW_PRE "iwlwifi-8000-"
> +#define IWL8000_FW_PRE "iwlwifi-8000"
> #define IWL8000_MODULE_FIRMWARE(api) IWL8000_FW_PRE __stringify(api) ".ucode"

Isn't this going to create a misleading MODULE_FIRMWARE entry, matching
neither of the firmware variants?


Bjørn

2014-09-21 19:22:38

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 08/17] iwlwifi: mvm: choose an initial tx rate based on rssi conditions

From: Eyal Shapira <[email protected]>

Improve the initial tx rate and antenna selection to be based on
the rssi of the last rx. This avoids starting at the lowest legacy
rate always and requiring more tx traffic to "climb" up the rates.
Since this option might cause trouble in certain setups, allow to
disable it by default.

Signed-off-by: Eyal Shapira <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/constants.h | 1 +
drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +
drivers/net/wireless/iwlwifi/mvm/rs.c | 131 ++++++++++++++++++++++-----
drivers/net/wireless/iwlwifi/mvm/rx.c | 41 +++++----
4 files changed, 136 insertions(+), 40 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index a355788..f47f458 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -94,5 +94,6 @@
#define IWL_MVM_BT_COEX_MPLUT 1
#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
#define IWL_MVM_QUOTA_THRESHOLD 8
+#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0

#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index c913d5e..7d0194b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -989,6 +989,9 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm,
struct iwl_mvm_frame_stats *stats,
u32 rate, bool agg);
int rs_pretty_print_rate(char *buf, const u32 rate);
+void rs_update_last_rssi(struct iwl_mvm *mvm,
+ struct iwl_lq_sta *lq_sta,
+ struct ieee80211_rx_status *rx_status);

/* power management */
int iwl_mvm_power_update_device(struct iwl_mvm *mvm);
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index f77dfe4..d179a8e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -2288,6 +2288,110 @@ out:
lq_sta->last_txrate_idx = index;
}

+struct rs_init_rate_info {
+ s8 rssi;
+ u8 rate_idx;
+};
+
+static const struct rs_init_rate_info rs_init_rates_24ghz[] = {
+ { -60, IWL_RATE_54M_INDEX },
+ { -64, IWL_RATE_48M_INDEX },
+ { -68, IWL_RATE_36M_INDEX },
+ { -80, IWL_RATE_24M_INDEX },
+ { -84, IWL_RATE_18M_INDEX },
+ { -85, IWL_RATE_12M_INDEX },
+ { -86, IWL_RATE_11M_INDEX },
+ { -88, IWL_RATE_5M_INDEX },
+ { -90, IWL_RATE_2M_INDEX },
+ { S8_MIN, IWL_RATE_1M_INDEX },
+};
+
+static const struct rs_init_rate_info rs_init_rates_5ghz[] = {
+ { -60, IWL_RATE_54M_INDEX },
+ { -64, IWL_RATE_48M_INDEX },
+ { -72, IWL_RATE_36M_INDEX },
+ { -80, IWL_RATE_24M_INDEX },
+ { -84, IWL_RATE_18M_INDEX },
+ { -85, IWL_RATE_12M_INDEX },
+ { -87, IWL_RATE_9M_INDEX },
+ { S8_MIN, IWL_RATE_6M_INDEX },
+};
+
+/* Choose an initial legacy rate and antenna to use based on the RSSI
+ * of last Rx
+ */
+static void rs_get_initial_rate(struct iwl_mvm *mvm,
+ struct iwl_lq_sta *lq_sta,
+ enum ieee80211_band band,
+ struct rs_rate *rate)
+{
+ int i, nentries;
+ s8 best_rssi = S8_MIN;
+ u8 best_ant = ANT_NONE;
+ u8 valid_tx_ant = mvm->fw->valid_tx_ant;
+ const struct rs_init_rate_info *initial_rates;
+
+ for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {
+ if (!(lq_sta->pers.chains & BIT(i)))
+ continue;
+
+ if (lq_sta->pers.chain_signal[i] > best_rssi) {
+ best_rssi = lq_sta->pers.chain_signal[i];
+ best_ant = BIT(i);
+ }
+ }
+
+ IWL_DEBUG_RATE(mvm, "Best ANT: %s Best RSSI: %d\n",
+ rs_pretty_ant(best_ant), best_rssi);
+
+ if (best_ant != ANT_A && best_ant != ANT_B)
+ rate->ant = first_antenna(valid_tx_ant);
+ else
+ rate->ant = best_ant;
+
+ rate->sgi = false;
+ rate->ldpc = false;
+ rate->bw = RATE_MCS_CHAN_WIDTH_20;
+
+ rate->index = find_first_bit(&lq_sta->active_legacy_rate,
+ BITS_PER_LONG);
+
+ if (band == IEEE80211_BAND_5GHZ) {
+ rate->type = LQ_LEGACY_A;
+ initial_rates = rs_init_rates_5ghz;
+ nentries = ARRAY_SIZE(rs_init_rates_5ghz);
+ } else {
+ rate->type = LQ_LEGACY_G;
+ initial_rates = rs_init_rates_24ghz;
+ nentries = ARRAY_SIZE(rs_init_rates_24ghz);
+ }
+
+ if (IWL_MVM_RS_RSSI_BASED_INIT_RATE) {
+ for (i = 0; i < nentries; i++) {
+ int rate_idx = initial_rates[i].rate_idx;
+ if ((best_rssi >= initial_rates[i].rssi) &&
+ (BIT(rate_idx) & lq_sta->active_legacy_rate)) {
+ rate->index = rate_idx;
+ break;
+ }
+ }
+ }
+
+ IWL_DEBUG_RATE(mvm, "rate_idx %d ANT %s\n", rate->index,
+ rs_pretty_ant(rate->ant));
+}
+
+/* Save info about RSSI of last Rx */
+void rs_update_last_rssi(struct iwl_mvm *mvm,
+ struct iwl_lq_sta *lq_sta,
+ struct ieee80211_rx_status *rx_status)
+{
+ lq_sta->pers.chains = rx_status->chains;
+ lq_sta->pers.chain_signal[0] = rx_status->chain_signal[0];
+ lq_sta->pers.chain_signal[1] = rx_status->chain_signal[1];
+ lq_sta->pers.chain_signal[2] = rx_status->chain_signal[2];
+}
+
/**
* rs_initialize_lq - Initialize a station's hardware rate table
*
@@ -2310,17 +2414,11 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
{
struct iwl_scale_tbl_info *tbl;
struct rs_rate *rate;
- int i;
u8 active_tbl = 0;
- u8 valid_tx_ant;

if (!sta || !lq_sta)
return;

- i = lq_sta->last_txrate_idx;
-
- valid_tx_ant = mvm->fw->valid_tx_ant;
-
if (!lq_sta->search_better_tbl)
active_tbl = lq_sta->active_tbl;
else
@@ -2329,18 +2427,8 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
tbl = &(lq_sta->lq_info[active_tbl]);
rate = &tbl->rate;

- if ((i < 0) || (i >= IWL_RATE_COUNT))
- i = 0;
-
- rate->index = i;
- rate->ant = first_antenna(valid_tx_ant);
- rate->sgi = false;
- rate->ldpc = false;
- rate->bw = RATE_MCS_CHAN_WIDTH_20;
- if (band == IEEE80211_BAND_5GHZ)
- rate->type = LQ_LEGACY_A;
- else
- rate->type = LQ_LEGACY_G;
+ rs_get_initial_rate(mvm, lq_sta, band, rate);
+ lq_sta->last_txrate_idx = rate->index;

WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
if (rate->ant == ANT_A)
@@ -2397,6 +2485,8 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
lq_sta->pers.dbg_fixed_rate = 0;
lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID;
#endif
+ lq_sta->pers.chains = 0;
+ memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));

return &sta_priv->lq_sta;
}
@@ -2630,11 +2720,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,

/* as default allow aggregation for all tids */
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
-
- /* Set last_txrate_idx to lowest rate */
- lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
- if (sband->band == IEEE80211_BAND_5GHZ)
- lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
lq_sta->is_agg = 0;
#ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index a6cb84e..3cf40f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -246,6 +246,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_rx_phy_info *phy_info;
struct iwl_rx_mpdu_res_start *rx_res;
+ struct ieee80211_sta *sta;
u32 len;
u32 ampdu_status;
u32 rate_n_flags;
@@ -261,23 +262,6 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
memset(&rx_status, 0, sizeof(rx_status));

/*
- * We have tx blocked stations (with CS bit). If we heard frames from
- * a blocked station on a new channel we can TX to it again.
- */
- if (unlikely(mvm->csa_tx_block_bcn_timeout)) {
- struct ieee80211_sta *sta;
-
- rcu_read_lock();
-
- sta = ieee80211_find_sta(
- rcu_dereference(mvm->csa_tx_blocked_vif), hdr->addr2);
- if (sta)
- iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, false);
-
- rcu_read_unlock();
- }
-
- /*
* drop the packet if it has failed being decrypted by HW
*/
if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) {
@@ -325,6 +309,29 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
IWL_DEBUG_STATS_LIMIT(mvm, "Rssi %d, TSF %llu\n", rx_status.signal,
(unsigned long long)rx_status.mactime);

+ rcu_read_lock();
+ /*
+ * We have tx blocked stations (with CS bit). If we heard frames from
+ * a blocked station on a new channel we can TX to it again.
+ */
+ if (unlikely(mvm->csa_tx_block_bcn_timeout)) {
+ sta = ieee80211_find_sta(
+ rcu_dereference(mvm->csa_tx_blocked_vif), hdr->addr2);
+ if (sta)
+ iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, false);
+ }
+
+ /* This is fine since we don't support multiple AP interfaces */
+ sta = ieee80211_find_sta_by_ifaddr(mvm->hw, hdr->addr2, NULL);
+ if (sta) {
+ struct iwl_mvm_sta *mvmsta;
+ mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ rs_update_last_rssi(mvm, &mvmsta->lq_sta,
+ &rx_status);
+ }
+
+ rcu_read_unlock();
+
/* set the preamble flag if appropriate */
if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
rx_status.flag |= RX_FLAG_SHORTPRE;
--
1.9.1


2015-11-26 15:46:38

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] iwlwifi: mvm: add hwmon device for the temperature sensor

Hi Bjørn,

> I got bored and made an attempt on this. Still just for fun.  I don't
> have a real usecase.  What do you think?  Completely useless?

It's not so bad :)

However, it's (soon going to be) redundant, we're planning to implement
a thermal_zone_device in this code, and if you then set the Kconfig
option THERMAL_HWMON you'll get a hwmon to go along with it. So I'd
rather not take this patch since we'd otherwise end up with two ways to
do the same thing in the driver.

johannes

2015-11-21 21:12:59

by Bjørn Mork

[permalink] [raw]
Subject: [PATCH] iwlwifi: mvm: add hwmon device for the temperature sensor

Enabling nic temperature monitoring using lmsensors:
$ sensors
..
phy0-pci-0300
Adapter: PCI adapter
temp1: +50.0°C (high = +114.0°C, crit = +118.0°C)

Signed-off-by: Bjørn Mork <[email protected]>
---

Bjørn Mork <[email protected]> writes:
> On 26 September 2014 21:44:38 CEST, Luca Coelho <[email protected]> wrote:
>
>>Yeah, the temperature sensor is used to avoid heating the NIC too much
>>and potentially damaging things. We do things like throttle down the
>>data flow and, in the most dramatic cases, turn the chip entirely off.
>>
>>The mean reason for the new debugfs entry is for, well, debugging. :)
>>
>>Bjørn, do you have any ideas on how this information could be used in a
>>useful way so that it would be worth the effort of exporting it in a
>>more "official" way?
>
> No, not really. It was just a random thought that this should be made
> available for monitoring applications.
>
> It sounds like this sensor is similar to the sensors associated with
> each CPU core. Which have been made available through the coretemp
> driver although I don't think that was the intention of the hardware
> designer. But I don't know if exporting it has any practical value.

Reviving an old discussion...

I got bored and made an attempt on this. Still just for fun. I don't
have a real usecase. What do you think? Completely useless?

FWIW, in my laptop the nic temperature seems to align pretty well to
other temperature sensors:

bjorn@nemi:~$ sensors
acpitz-virtual-0
Adapter: Virtual device
temp1: +48.0°C (crit = +127.0°C)
temp2: +45.0°C (crit = +105.0°C)

thinkpad-isa-0000
Adapter: ISA adapter
fan1: 4951 RPM
temp1: +48.0°C
temp2: +43.0°C
temp3: +42.0°C
temp4: N/A
temp5: +28.0°C
temp6: N/A
temp7: +25.0°C
temp8: N/A
temp9: +39.0°C
temp10: N/A
temp11: +45.0°C
temp12: N/A
temp13: N/A
temp14: N/A
temp15: N/A
temp16: N/A

coretemp-isa-0000
Adapter: ISA adapter
Core 0: +46.0°C (high = +105.0°C, crit = +105.0°C)
Core 1: +46.0°C (high = +105.0°C, crit = +105.0°C)

phy0-pci-0300
Adapter: PCI adapter
temp1: +44.0°C (high = +114.0°C, crit = +118.0°C)


drivers/net/wireless/iwlwifi/mvm/mvm.h | 11 ++++++
drivers/net/wireless/iwlwifi/mvm/ops.c | 2 ++
drivers/net/wireless/iwlwifi/mvm/tt.c | 62 ++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+)

diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 4bde2d027dcd..25c6d14b3543 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -788,6 +788,10 @@ struct iwl_mvm {
*/
bool temperature_test; /* Debug test temperature is enabled */

+#if IS_ENABLED(CONFIG_HWMON)
+ struct device *hwmon;
+#endif
+
struct iwl_time_quota_cmd last_quota_cmd;

#ifdef CONFIG_NL80211_TESTMODE
@@ -1416,6 +1420,13 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff);
void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
int iwl_mvm_get_temp(struct iwl_mvm *mvm);
+#if IS_ENABLED(CONFIG_HWMON)
+int iwl_mvm_hwmon_register(struct iwl_mvm *mvm);
+void iwl_mvm_hwmon_unregister(struct iwl_mvm *mvm);
+#else
+static inline int iwl_mvm_hwmon_register(struct iwl_mvm *mvm) { return 0; }
+static inline void iwl_mvm_hwmon_unregister(struct iwl_mvm *mvm) {}
+#endif

/* Location Aware Regulatory */
struct iwl_mcc_update_resp *
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 13c97f665ba8..903b30986e65 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -595,6 +595,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
mvm->refs[IWL_MVM_REF_UCODE_DOWN] = 1;

iwl_mvm_tof_init(mvm);
+ iwl_mvm_hwmon_register(mvm);

return op_mode;

@@ -616,6 +617,7 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
int i;

+ iwl_mvm_hwmon_unregister(mvm);
iwl_mvm_leds_exit(mvm);

iwl_mvm_tt_exit(mvm);
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index cadfc0460597..38b36251c883 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -64,6 +64,7 @@
*
*****************************************************************************/

+#include <linux/hwmon.h>
#include "mvm.h"

#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
@@ -414,6 +415,67 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
}
}

+#if IS_ENABLED(CONFIG_HWMON)
+static ssize_t temp1_input_show(struct device *device,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct iwl_mvm *mvm = dev_get_drvdata(device);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", mvm->temperature * 1000);
+}
+static DEVICE_ATTR_RO(temp1_input);
+
+static ssize_t temp1_crit_show(struct device *device,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct iwl_mvm *mvm = dev_get_drvdata(device);
+ struct iwl_tt_params *params = &mvm->thermal_throttle.params;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", params->ct_kill_entry * 1000);
+}
+static DEVICE_ATTR_RO(temp1_crit);
+
+static ssize_t temp1_max_show(struct device *device,
+ struct device_attribute *devattr,
+ char *buf)
+{
+ struct iwl_mvm *mvm = dev_get_drvdata(device);
+ struct iwl_tt_params *params = &mvm->thermal_throttle.params;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", params->tx_protection_entry * 1000);
+}
+static DEVICE_ATTR_RO(temp1_max);
+
+static struct attribute *mvm_hwmon_attrs[] = {
+ &dev_attr_temp1_input.attr,
+ &dev_attr_temp1_crit.attr,
+ &dev_attr_temp1_max.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(mvm_hwmon);
+
+int iwl_mvm_hwmon_register(struct iwl_mvm *mvm)
+{
+ struct wiphy *wiphy = mvm->hw->wiphy;
+ struct device *hwmon;
+
+ hwmon = hwmon_device_register_with_groups(mvm->dev, wiphy_name(wiphy),
+ mvm, mvm_hwmon_groups);
+ if (!IS_ERR(hwmon))
+ mvm->hwmon = hwmon;
+ return PTR_ERR_OR_ZERO(hwmon);
+}
+
+void iwl_mvm_hwmon_unregister(struct iwl_mvm *mvm)
+{
+ if (mvm->hwmon)
+ hwmon_device_unregister(mvm->hwmon);
+ mvm->hwmon = NULL;
+}
+#endif /* CONFIG_HWMON */
+
static const struct iwl_tt_params iwl_mvm_default_tt_params = {
.ct_kill_entry = 118,
.ct_kill_exit = 96,
--
2.1.4


2015-11-26 16:52:48

by Bjørn Mork

[permalink] [raw]
Subject: Re: [PATCH] iwlwifi: mvm: add hwmon device for the temperature sensor

Johannes Berg <[email protected]> writes:

> Hi Bjørn,
>
>> I got bored and made an attempt on this. Still just for fun.  I don't
>> have a real usecase.  What do you think?  Completely useless?
>
> It's not so bad :)
>
> However, it's (soon going to be) redundant, we're planning to implement
> a thermal_zone_device in this code, and if you then set the Kconfig
> option THERMAL_HWMON you'll get a hwmon to go along with it. So I'd
> rather not take this patch since we'd otherwise end up with two ways to
> do the same thing in the driver.

Ah, right. I wondered a bit about that, but concluded that you probably
didn't want it since you had all your own temp limit handling.

Sounds like a good plan to me


Bjørn

2015-11-26 17:05:00

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] iwlwifi: mvm: add hwmon device for the temperature sensor


> Ah, right.  I wondered a bit about that, but concluded that you
> probably
> didn't want it since you had all your own temp limit handling.
>

:)

We do, but we're going to have to be able to handle requests from the
platform to ask the device to do its part to reduce heating.

johannes