Skip to content

Commit 0581276

Browse files
author
Kalle Valo
committed
* fix firmware API for -13.ucode * fix RSSI handling that avoid bad roaming decision * fix firmware debug * fix MFUART operation * fix ASSERT while restart the hardware (because of another ASSERT e.g)
2 parents 414b7e3 + e7afe89 commit 0581276

File tree

13 files changed

+135
-116
lines changed

13 files changed

+135
-116
lines changed

drivers/net/wireless/iwlwifi/iwl-fw-file.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ enum iwl_ucode_tlv_flag {
244244
* longer than the passive one, which is essential for fragmented scan.
245245
* @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
246246
* IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
247+
* @IWL_UCODE_TLV_API_TX_POWER_DEV: new API for tx power.
247248
* @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
248249
* regardless of the band or the number of the probes. FW will calculate
249250
* the actual dwell time.
@@ -260,6 +261,7 @@ enum iwl_ucode_tlv_api {
260261
IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
261262
IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = BIT(9),
262263
IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
264+
IWL_UCODE_TLV_API_TX_POWER_DEV = BIT(11),
263265
IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13),
264266
IWL_UCODE_TLV_API_SCD_CFG = BIT(15),
265267
IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16),

drivers/net/wireless/iwlwifi/iwl-trans.h

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* GPL LICENSE SUMMARY
77
*
88
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
9-
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9+
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
1010
*
1111
* This program is free software; you can redistribute it and/or modify
1212
* it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
3232
* BSD LICENSE
3333
*
3434
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35-
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
35+
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3636
* All rights reserved.
3737
*
3838
* Redistribution and use in source and binary forms, with or without
@@ -421,8 +421,9 @@ struct iwl_trans_txq_scd_cfg {
421421
*
422422
* All the handlers MUST be implemented
423423
*
424-
* @start_hw: starts the HW- from that point on, the HW can send interrupts
425-
* May sleep
424+
* @start_hw: starts the HW. If low_power is true, the NIC needs to be taken
425+
* out of a low power state. From that point on, the HW can send
426+
* interrupts. May sleep.
426427
* @op_mode_leave: Turn off the HW RF kill indication if on
427428
* May sleep
428429
* @start_fw: allocates and inits all the resources for the transport
@@ -432,10 +433,11 @@ struct iwl_trans_txq_scd_cfg {
432433
* the SCD base address in SRAM, then provide it here, or 0 otherwise.
433434
* May sleep
434435
* @stop_device: stops the whole device (embedded CPU put to reset) and stops
435-
* the HW. From that point on, the HW will be in low power but will still
436-
* issue interrupt if the HW RF kill is triggered. This callback must do
437-
* the right thing and not crash even if start_hw() was called but not
438-
* start_fw(). May sleep
436+
* the HW. If low_power is true, the NIC will be put in low power state.
437+
* From that point on, the HW will be stopped but will still issue an
438+
* interrupt if the HW RF kill switch is triggered.
439+
* This callback must do the right thing and not crash even if %start_hw()
440+
* was called but not &start_fw(). May sleep.
439441
* @d3_suspend: put the device into the correct mode for WoWLAN during
440442
* suspend. This is optional, if not implemented WoWLAN will not be
441443
* supported. This callback may sleep.
@@ -491,14 +493,14 @@ struct iwl_trans_txq_scd_cfg {
491493
*/
492494
struct iwl_trans_ops {
493495

494-
int (*start_hw)(struct iwl_trans *iwl_trans);
496+
int (*start_hw)(struct iwl_trans *iwl_trans, bool low_power);
495497
void (*op_mode_leave)(struct iwl_trans *iwl_trans);
496498
int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw,
497499
bool run_in_rfkill);
498500
int (*update_sf)(struct iwl_trans *trans,
499501
struct iwl_sf_region *st_fwrd_space);
500502
void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
501-
void (*stop_device)(struct iwl_trans *trans);
503+
void (*stop_device)(struct iwl_trans *trans, bool low_power);
502504

503505
void (*d3_suspend)(struct iwl_trans *trans, bool test);
504506
int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status,
@@ -652,11 +654,16 @@ static inline void iwl_trans_configure(struct iwl_trans *trans,
652654
trans->ops->configure(trans, trans_cfg);
653655
}
654656

655-
static inline int iwl_trans_start_hw(struct iwl_trans *trans)
657+
static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power)
656658
{
657659
might_sleep();
658660

659-
return trans->ops->start_hw(trans);
661+
return trans->ops->start_hw(trans, low_power);
662+
}
663+
664+
static inline int iwl_trans_start_hw(struct iwl_trans *trans)
665+
{
666+
return trans->ops->start_hw(trans, true);
660667
}
661668

662669
static inline void iwl_trans_op_mode_leave(struct iwl_trans *trans)
@@ -703,15 +710,21 @@ static inline int iwl_trans_update_sf(struct iwl_trans *trans,
703710
return 0;
704711
}
705712

706-
static inline void iwl_trans_stop_device(struct iwl_trans *trans)
713+
static inline void _iwl_trans_stop_device(struct iwl_trans *trans,
714+
bool low_power)
707715
{
708716
might_sleep();
709717

710-
trans->ops->stop_device(trans);
718+
trans->ops->stop_device(trans, low_power);
711719

712720
trans->state = IWL_TRANS_NO_FW;
713721
}
714722

723+
static inline void iwl_trans_stop_device(struct iwl_trans *trans)
724+
{
725+
_iwl_trans_stop_device(trans, true);
726+
}
727+
715728
static inline void iwl_trans_d3_suspend(struct iwl_trans *trans, bool test)
716729
{
717730
might_sleep();

drivers/net/wireless/iwlwifi/mvm/d3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1726,7 +1726,7 @@ iwl_mvm_netdetect_query_results(struct iwl_mvm *mvm,
17261726
results->matched_profiles = le32_to_cpu(query->matched_profiles);
17271727
memcpy(results->matches, query->matches, sizeof(results->matches));
17281728

1729-
#ifdef CPTCFG_IWLWIFI_DEBUGFS
1729+
#ifdef CONFIG_IWLWIFI_DEBUGFS
17301730
mvm->last_netdetect_scans = le32_to_cpu(query->n_scans_done);
17311731
#endif
17321732

drivers/net/wireless/iwlwifi/mvm/fw-api-power.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,40 @@ struct iwl_uapsd_misbehaving_ap_notif {
297297
u8 reserved[3];
298298
} __packed;
299299

300+
/**
301+
* struct iwl_reduce_tx_power_cmd - TX power reduction command
302+
* REDUCE_TX_POWER_CMD = 0x9f
303+
* @flags: (reserved for future implementation)
304+
* @mac_context_id: id of the mac ctx for which we are reducing TX power.
305+
* @pwr_restriction: TX power restriction in dBms.
306+
*/
307+
struct iwl_reduce_tx_power_cmd {
308+
u8 flags;
309+
u8 mac_context_id;
310+
__le16 pwr_restriction;
311+
} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
312+
313+
/**
314+
* struct iwl_dev_tx_power_cmd - TX power reduction command
315+
* REDUCE_TX_POWER_CMD = 0x9f
316+
* @set_mode: 0 - MAC tx power, 1 - device tx power
317+
* @mac_context_id: id of the mac ctx for which we are reducing TX power.
318+
* @pwr_restriction: TX power restriction in 1/8 dBms.
319+
* @dev_24: device TX power restriction in 1/8 dBms
320+
* @dev_52_low: device TX power restriction upper band - low
321+
* @dev_52_high: device TX power restriction upper band - high
322+
*/
323+
struct iwl_dev_tx_power_cmd {
324+
__le32 set_mode;
325+
__le32 mac_context_id;
326+
__le16 pwr_restriction;
327+
__le16 dev_24;
328+
__le16 dev_52_low;
329+
__le16 dev_52_high;
330+
} __packed; /* TX_REDUCED_POWER_API_S_VER_2 */
331+
332+
#define IWL_DEV_MAX_TX_POWER 0x7FFF
333+
300334
/**
301335
* struct iwl_beacon_filter_cmd
302336
* REPLY_BEACON_FILTERING_CMD = 0xd2 (command)

drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -122,46 +122,6 @@ enum iwl_scan_complete_status {
122122
SCAN_COMP_STATUS_ERR_ALLOC_TE = 0x0C,
123123
};
124124

125-
/**
126-
* struct iwl_scan_results_notif - scan results for one channel
127-
* ( SCAN_RESULTS_NOTIFICATION = 0x83 )
128-
* @channel: which channel the results are from
129-
* @band: 0 for 5.2 GHz, 1 for 2.4 GHz
130-
* @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
131-
* @num_probe_not_sent: # of request that weren't sent due to not enough time
132-
* @duration: duration spent in channel, in usecs
133-
* @statistics: statistics gathered for this channel
134-
*/
135-
struct iwl_scan_results_notif {
136-
u8 channel;
137-
u8 band;
138-
u8 probe_status;
139-
u8 num_probe_not_sent;
140-
__le32 duration;
141-
__le32 statistics[SCAN_RESULTS_STATISTICS];
142-
} __packed; /* SCAN_RESULT_NTF_API_S_VER_2 */
143-
144-
/**
145-
* struct iwl_scan_complete_notif - notifies end of scanning (all channels)
146-
* ( SCAN_COMPLETE_NOTIFICATION = 0x84 )
147-
* @scanned_channels: number of channels scanned (and number of valid results)
148-
* @status: one of SCAN_COMP_STATUS_*
149-
* @bt_status: BT on/off status
150-
* @last_channel: last channel that was scanned
151-
* @tsf_low: TSF timer (lower half) in usecs
152-
* @tsf_high: TSF timer (higher half) in usecs
153-
* @results: array of scan results, only "scanned_channels" of them are valid
154-
*/
155-
struct iwl_scan_complete_notif {
156-
u8 scanned_channels;
157-
u8 status;
158-
u8 bt_status;
159-
u8 last_channel;
160-
__le32 tsf_low;
161-
__le32 tsf_high;
162-
struct iwl_scan_results_notif results[];
163-
} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
164-
165125
/* scan offload */
166126
#define IWL_SCAN_MAX_BLACKLIST_LEN 64
167127
#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
@@ -554,15 +514,15 @@ struct iwl_scan_req_unified_lmac {
554514
} __packed;
555515

556516
/**
557-
* struct iwl_lmac_scan_results_notif - scan results for one channel -
517+
* struct iwl_scan_results_notif - scan results for one channel -
558518
* SCAN_RESULT_NTF_API_S_VER_3
559519
* @channel: which channel the results are from
560520
* @band: 0 for 5.2 GHz, 1 for 2.4 GHz
561521
* @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
562522
* @num_probe_not_sent: # of request that weren't sent due to not enough time
563523
* @duration: duration spent in channel, in usecs
564524
*/
565-
struct iwl_lmac_scan_results_notif {
525+
struct iwl_scan_results_notif {
566526
u8 channel;
567527
u8 band;
568528
u8 probe_status;

drivers/net/wireless/iwlwifi/mvm/fw-api.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -281,19 +281,6 @@ struct iwl_tx_ant_cfg_cmd {
281281
__le32 valid;
282282
} __packed;
283283

284-
/**
285-
* struct iwl_reduce_tx_power_cmd - TX power reduction command
286-
* REDUCE_TX_POWER_CMD = 0x9f
287-
* @flags: (reserved for future implementation)
288-
* @mac_context_id: id of the mac ctx for which we are reducing TX power.
289-
* @pwr_restriction: TX power restriction in dBms.
290-
*/
291-
struct iwl_reduce_tx_power_cmd {
292-
u8 flags;
293-
u8 mac_context_id;
294-
__le16 pwr_restriction;
295-
} __packed; /* TX_REDUCED_POWER_API_S_VER_1 */
296-
297284
/*
298285
* Calibration control struct.
299286
* Sent as part of the phy configuration command.

drivers/net/wireless/iwlwifi/mvm/fw.c

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* GPL LICENSE SUMMARY
77
*
88
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9-
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
9+
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
1010
*
1111
* This program is free software; you can redistribute it and/or modify
1212
* it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
3232
* BSD LICENSE
3333
*
3434
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35-
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
35+
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
3636
* All rights reserved.
3737
*
3838
* Redistribution and use in source and binary forms, with or without
@@ -322,7 +322,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
322322

323323
lockdep_assert_held(&mvm->mutex);
324324

325-
if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating))
325+
if (WARN_ON_ONCE(mvm->calibrating))
326326
return 0;
327327

328328
iwl_init_notification_wait(&mvm->notif_wait,
@@ -396,8 +396,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
396396
*/
397397
ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait,
398398
MVM_UCODE_CALIB_TIMEOUT);
399-
if (!ret)
400-
mvm->init_ucode_complete = true;
401399

402400
if (ret && iwl_mvm_is_radio_killed(mvm)) {
403401
IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
@@ -494,15 +492,6 @@ int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
494492

495493
mvm->fw_dump_desc = desc;
496494

497-
/* stop recording */
498-
if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
499-
iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
500-
} else {
501-
iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
502-
/* wait before we collect the data till the DBGC stop */
503-
udelay(100);
504-
}
505-
506495
queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);
507496

508497
return 0;
@@ -658,25 +647,24 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
658647
* module loading, load init ucode now
659648
* (for example, if we were in RFKILL)
660649
*/
661-
if (!mvm->init_ucode_complete) {
662-
ret = iwl_run_init_mvm_ucode(mvm, false);
663-
if (ret && !iwlmvm_mod_params.init_dbg) {
664-
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
665-
/* this can't happen */
666-
if (WARN_ON(ret > 0))
667-
ret = -ERFKILL;
668-
goto error;
669-
}
670-
if (!iwlmvm_mod_params.init_dbg) {
671-
/*
672-
* should stop and start HW since that INIT
673-
* image just loaded
674-
*/
675-
iwl_trans_stop_device(mvm->trans);
676-
ret = iwl_trans_start_hw(mvm->trans);
677-
if (ret)
678-
return ret;
679-
}
650+
ret = iwl_run_init_mvm_ucode(mvm, false);
651+
if (ret && !iwlmvm_mod_params.init_dbg) {
652+
IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret);
653+
/* this can't happen */
654+
if (WARN_ON(ret > 0))
655+
ret = -ERFKILL;
656+
goto error;
657+
}
658+
if (!iwlmvm_mod_params.init_dbg) {
659+
/*
660+
* Stop and start the transport without entering low power
661+
* mode. This will save the state of other components on the
662+
* device that are triggered by the INIT firwmare (MFUART).
663+
*/
664+
_iwl_trans_stop_device(mvm->trans, false);
665+
_iwl_trans_start_hw(mvm->trans, false);
666+
if (ret)
667+
return ret;
680668
}
681669

682670
if (iwlmvm_mod_params.init_dbg)

drivers/net/wireless/iwlwifi/mvm/mac80211.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
13221322

13231323
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
13241324
iwl_mvm_d0i3_enable_tx(mvm, NULL);
1325-
ret = iwl_mvm_update_quotas(mvm, false, NULL);
1325+
ret = iwl_mvm_update_quotas(mvm, true, NULL);
13261326
if (ret)
13271327
IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
13281328
ret);
@@ -1471,8 +1471,8 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
14711471
return NULL;
14721472
}
14731473

1474-
static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1475-
s8 tx_power)
1474+
static int iwl_mvm_set_tx_power_old(struct iwl_mvm *mvm,
1475+
struct ieee80211_vif *vif, s8 tx_power)
14761476
{
14771477
/* FW is in charge of regulatory enforcement */
14781478
struct iwl_reduce_tx_power_cmd reduce_txpwr_cmd = {
@@ -1485,6 +1485,26 @@ static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
14851485
&reduce_txpwr_cmd);
14861486
}
14871487

1488+
static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1489+
s16 tx_power)
1490+
{
1491+
struct iwl_dev_tx_power_cmd cmd = {
1492+
.set_mode = 0,
1493+
.mac_context_id =
1494+
cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
1495+
.pwr_restriction = cpu_to_le16(8 * tx_power),
1496+
};
1497+
1498+
if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_TX_POWER_DEV))
1499+
return iwl_mvm_set_tx_power_old(mvm, vif, tx_power);
1500+
1501+
if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
1502+
cmd.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
1503+
1504+
return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0,
1505+
sizeof(cmd), &cmd);
1506+
}
1507+
14881508
static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
14891509
struct ieee80211_vif *vif)
14901510
{

0 commit comments

Comments
 (0)