pull request: iwlwifi-next 2013_11_24
Hi John,
This is the first batch for 3.14.
I have a bunch of small improvements and fixes. Avri made a thorough work checking what bit to set to firmware w.r.t protection. Eliad worked on WoWLAN, so did Luca. Johannes contributes a whole bunch of clean ups, and Alex tries to handle better cases where the firmware dies. Eyal survived his deep dive into the rate control algorigthm and provides a new set of fixes for VHT. I am still playing a bit with BT Coex.
Note that I had to merge iwlwifi-fixes to avoid conflicts before they hit linux-next.
Let me know about any issues!
The following changes since commit 6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae:
Linux 3.13-rc1 (2013-11-22 11:30:55 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git
for-john
for you to fetch changes up to b407dd53844e0d66e726583bae3a084cecdd59a4:
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
(2013-11-24 21:49:45 +0200)
----------------------------------------------------------------
Alexander Bondar (2):
iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
iwlwifi: pcie: stop sending commands to dead firmware
Avri Altman (1):
iwlwifi: mvm: fix ht protection flags
Eliad Peller (4):
iwlwifi: mvm: enable d3_test even if d3_test_pme_ptr is not available
iwlwifi: mvm: disconnect on disconnection wakeup event
iwlwifi: mvm: allow keeping connections in d3_test
iwlwifi: mvm: fix scan offloading flag definition
Emmanuel Grumbach (10):
iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
iwlwifi: mvm: BT Coex - don't enable MULTI_PRIO_LUT
iwlwifi: mvm: BT Coex fix another NULL pointer dereference
iwlwifi: mvm: don't WARN about unsuccessful time event
iwlwifi: bump required firmware API version for 3160/7260
iwlwifi: remove TX_CMD id from transport layer
iwlwifi: mvm: BT Coex - fine tune the aggregation size
iwlwifi: mvm: a few more SKUs for 7260 and 3160
iwlwifi: mvm: dump NVM from debugfs
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
Eyal Shapira (9):
iwlwifi: mvm: fix and improve printing of rate scale table
iwlwifi: mvm: simplify iwl_mvm_send_lq_cmd
iwlwifi: mvm: refactor iwl_mvm_rs_rate_init
iwlwifi: mvm: implement rate_update hook in rs
iwlwifi: mvm: add LQ flags definitions
iwlwifi: fix check for a single rx antenna
iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
iwlwifi: mvm: don't configure mimo rates if nss is limited to 1
Haim Dreyfuss (1):
iwlwifi: mvm: Implement low-priority scan
Johannes Berg (8):
iwlwifi: mvm: check sta_id/drain values in debugfs
iwlwifi: pcie: remove useless condition test
iwlwifi: mvm: small debugfs cleanups
iwlwifi: mvm: move interface-specific debugfs to a new file
iwlwifi: mvm: don't use void pointers in debugfs
iwlwifi: mvm: refactor debugfs copy_from_user()
iwlwifi: mvm: add iwl_mvm_sta_from_mac80211
iwlwifi: mvm: quota command max_duration should be zero
Luciano Coelho (3):
iwlwifi: mvm: set seqno also when no keys are set
iwlwifi: mvm: use a cast to calculate the last seqno from the next one
iwlwifi: mvm: don't restart HW if suspending fails before D3 image
is loaded
Michal Nazarewicz (1):
iwlwifi: pcie: remove minor dead code
Oren Givon (1):
iwlwifi: add new HW - 7265 series
drivers/net/wireless/iwlwifi/dvm/rs.h | 7 - drivers/net/wireless/iwlwifi/dvm/tx.c | 1 + drivers/net/wireless/iwlwifi/iwl-7000.c | 29 +- drivers/net/wireless/iwlwifi/iwl-config.h | 11 + drivers/net/wireless/iwlwifi/iwl-csr.h | 5 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 3 + drivers/net/wireless/iwlwifi/mvm/Makefile | 1 + drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 16 +- drivers/net/wireless/iwlwifi/mvm/d3.c | 43 +- drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 190 +++++++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 640 ++---------------------- drivers/net/wireless/iwlwifi/mvm/debugfs.h | 101 ++++ drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 27 +- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 5 +- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 51 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 11 +- drivers/net/wireless/iwlwifi/mvm/nvm.c | 23 + drivers/net/wireless/iwlwifi/mvm/quota.c | 3 +- drivers/net/wireless/iwlwifi/mvm/rs.c | 223 ++++++--- drivers/net/wireless/iwlwifi/mvm/rs.h | 23 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 55 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 14 +- drivers/net/wireless/iwlwifi/mvm/sta.h | 6 + drivers/net/wireless/iwlwifi/mvm/time-event.c | 7 +- drivers/net/wireless/iwlwifi/mvm/tt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 11 +- drivers/net/wireless/iwlwifi/mvm/utils.c | 8 +- drivers/net/wireless/iwlwifi/pcie/drv.c | 26 + drivers/net/wireless/iwlwifi/pcie/internal.h | 8 + drivers/net/wireless/iwlwifi/pcie/rx.c | 33 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 - drivers/net/wireless/iwlwifi/pcie/tx.c | 37 +- 34 files changed, 832 insertions(+), 813 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h
PATCH 1/29 iwlwifi: remove TX_CMD id from transport layer
From: Emmanuel Grumbach <[email protected]>
The transport layer doesn't need to know the TX_CMD id. It can be set by the op_mode.
The transport layer still needs to know the layout of the Tx command because of alignment issues and because of the scratch pointer.
--- drivers/net/wireless/iwlwifi/dvm/tx.c | 1 + drivers/net/wireless/iwlwifi/mvm/tx.c | 1 + drivers/net/wireless/iwlwifi/pcie/tx.c | 1 - 3 files changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/dvm/tx.c +1 -0
@@ -368,6 +368,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, goto drop_unlock_priv;memset (dev_cmd,0 ,sizeof (*dev_cmd)); + dev_cmd->hdr.cmd =REPLY_TX ; tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;/* Total # bytes to be transmitted */
drivers/net/wireless/iwlwifi/mvm/tx.c +1 -0
@@ -276,6 +276,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,return NULL ;memset (dev_cmd,0 ,sizeof (*dev_cmd)); + dev_cmd->hdr.cmd =TX_CMD ; tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;if (info->control.hw_key)
drivers/net/wireless/iwlwifi/pcie/tx.c +0 -1
@@ -1674,7 +1674,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, txq->entries[q->write_ptr].skb = skb; txq->entries[q->write_ptr].cmd = dev_cmd; - dev_cmd->hdr.cmd =REPLY_TX ; dev_cmd->hdr.sequence =cpu_to_le16 ((u16)(QUEUE_TO_SEQ (txq_id) |INDEX_TO_SEQ (q->write_ptr)));
Signature · 1 line
1.7.9.5
PATCH 2/29 iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
In reply to Emmanuel GrumbachFrom: Alexander Bondar <[email protected]>
Writting to fw_nmi entry will set DEVICE_SET_NMI_REG (0x00a01c30) generating NMI that halts NIC CPU.
--- drivers/net/wireless/iwlwifi/iwl-prph.h | 3 +++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+)
drivers/net/wireless/iwlwifi/iwl-prph.h +3 -0
@@ -102,6 +102,9 @@/* Device system time */ #define DEVICE_SYSTEM_TIME_REG 0xA0206C +/* Device NMI register */ +#define DEVICE_SET_NMI_REG 0x00a01c30 +/***************************************************************************** * 7000/3000 series SHR DTS addresses * *****************************************************************************/
drivers/net/wireless/iwlwifi/mvm/debugfs.c +14 -0
@@ -63,6 +63,7 @@#include "mvm.h" #include "sta.h" #include "iwl-io.h" +#include "iwl-prph.h" struct iwl_dbgfs_mvm_ctx {struct iwl_mvm *mvm;
@@ -800,6 +801,17 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,return count; } +static ssize_t iwl_dbgfs_fw_nmi_write (struct file *file, +const char __user *user_buf, +size_t count,loff_t *ppos) +{ +struct iwl_mvm *mvm = file->private_data; + +iwl_write_prph (mvm->trans,DEVICE_SET_NMI_REG ,1 ); + +return count; +} + static ssize_t iwl_dbgfs_scan_ant_rxchain_read(struct file *file, char __user *user_buf,
@@ -1164,6 +1176,7 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);MVM_DEBUGFS_READ_WRITE_FILE_OPS (disable_power_off);MVM_DEBUGFS_READ_FILE_OPS (fw_rx_stats);MVM_DEBUGFS_WRITE_FILE_OPS (fw_restart); +MVM_DEBUGFS_WRITE_FILE_OPS (fw_nmi);MVM_DEBUGFS_READ_WRITE_FILE_OPS (scan_ant_rxchain);#ifdef CONFIG_PM_SLEEP
@@ -1192,6 +1205,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) S_IRUSR | S_IWUSR);MVM_DEBUGFS_ADD_FILE (fw_rx_stats, mvm->debugfs_dir,S_IRUSR );MVM_DEBUGFS_ADD_FILE (fw_restart, mvm->debugfs_dir,S_IWUSR ); +MVM_DEBUGFS_ADD_FILE (fw_nmi, mvm->debugfs_dir,S_IWUSR );MVM_DEBUGFS_ADD_FILE (scan_ant_rxchain, mvm->debugfs_dir,S_IWUSR |S_IRUSR );#ifdef CONFIG_PM_SLEEP
Signature · 1 line
1.7.9.5
PATCH 3/29 iwlwifi: pcie: remove useless condition test
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
After wait_event_timeout(), the condition must still be true if it returns >0, in fact almost the last thing in it is checking the condition again. It's therefore not useful to check yet again in our code, clean it up.
--- drivers/net/wireless/iwlwifi/pcie/tx.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-)
drivers/net/wireless/iwlwifi/pcie/tx.c +13 -19
@@ -1542,30 +1542,24 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, }if (!ret) { -if (test_bit (STATUS_HCMD_ACTIVE , &trans_pcie->status)) { -struct iwl_txq *txq = - &trans_pcie->txq[trans_pcie->cmd_queue]; -struct iwl_queue *q = &txq->q; +struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; +struct iwl_queue *q = &txq->q; -IWL_ERR (trans, -"Error sending %s: time out after %dms.\n" , -get_cmd_string (trans_pcie, cmd->id), -jiffies_to_msecs (HOST_COMPLETE_TIMEOUT )); +IWL_ERR (trans,"Error sending %s: time out after %dms.\n" , +get_cmd_string (trans_pcie, cmd->id), +jiffies_to_msecs (HOST_COMPLETE_TIMEOUT )); -IWL_ERR (trans, -"Current CMD queue read_ptr %d write_ptr %d\n" , - q->read_ptr, q->write_ptr); +IWL_ERR (trans,"Current CMD queue read_ptr %d write_ptr %d\n" , + q->read_ptr, q->write_ptr); -clear_bit (STATUS_HCMD_ACTIVE , &trans_pcie->status); -IWL_DEBUG_INFO (trans, -"Clearing HCMD_ACTIVE for command %s\n" , -get_cmd_string (trans_pcie, cmd->id)); - ret = -ETIMEDOUT ; +clear_bit (STATUS_HCMD_ACTIVE , &trans_pcie->status); +IWL_DEBUG_INFO (trans,"Clearing HCMD_ACTIVE for command %s\n" , +get_cmd_string (trans_pcie, cmd->id)); + ret = -ETIMEDOUT ; -iwl_op_mode_nic_error (trans->op_mode); +iwl_op_mode_nic_error (trans->op_mode); - goto cancel; - } + goto cancel; }if (test_bit (STATUS_FW_ERROR , &trans_pcie->status)) {
Signature · 1 line
1.7.9.5
PATCH 4/29 iwlwifi: mvm: fix and improve printing of rate scale table
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Info about VHT/HT rates wasn't printed properly when dumping the rate scale table. Fix that and print more info. While at it fix some other minor issues in the printing and prevent overflowing the print buffer.
--- drivers/net/wireless/iwlwifi/mvm/rs.c | 91 ++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 18 deletions(-)
drivers/net/wireless/iwlwifi/mvm/rs.c +73 -18
@@ -2566,13 +2566,75 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,return count; } +static int rs_pretty_print_rate (char *buf,const u32 rate) +{ +static const char *const ant_name[] = { + [ANT_NONE ] ="None" , + [ANT_A ] ="A" , + [ANT_B ] ="B" , + [ANT_AB ] ="AB" , + [ANT_C ] ="C" , + [ANT_AC ] ="AC" , + [ANT_BC ] ="BC" , + [ANT_ABC ] ="ABC" , + }; + +char *type, *bw; +u8 mcs =0 , nss =0 ; +u8 ant = (rate &RATE_MCS_ANT_ABC_MSK ) >>RATE_MCS_ANT_POS ; + +if (!(rate &RATE_MCS_HT_MSK ) && + !(rate &RATE_MCS_VHT_MSK )) { +int index =iwl_hwrate_to_plcp_idx (rate); + +return sprintf (buf,"Legacy | ANT: %s Rate: %s Mbps\n" , + ant_name[ant], iwl_rate_mcs[index].mbps); + } + +if (rate &RATE_MCS_VHT_MSK ) { + type ="VHT" ; + mcs = rate &RATE_VHT_MCS_RATE_CODE_MSK ; + nss = ((rate &RATE_VHT_MCS_NSS_MSK ) + >>RATE_VHT_MCS_NSS_POS ) +1 ; + }else if (rate &RATE_MCS_HT_MSK ) { + type ="HT" ; + mcs = rate &RATE_HT_MCS_INDEX_MSK ; + }else { + type ="Unknown" ;/* shouldn't happen */ + } + +switch (rate &RATE_MCS_CHAN_WIDTH_MSK ) { +case RATE_MCS_CHAN_WIDTH_20 : + bw ="20Mhz" ; +break ; +case RATE_MCS_CHAN_WIDTH_40 : + bw ="40Mhz" ; +break ; +case RATE_MCS_CHAN_WIDTH_80 : + bw ="80Mhz" ; +break ; +case RATE_MCS_CHAN_WIDTH_160 : + bw ="160Mhz" ; +break ; +default : + bw ="BAD BW" ; + } + +return sprintf (buf,"%s | ANT: %s BW: %s MCS: %d NSS: %d %s%s%s%s%s\n" , + type, ant_name[ant], bw, mcs, nss, + (rate &RATE_MCS_SGI_MSK ) ?"SGI " :"NGI " , + (rate &RATE_MCS_STBC_MSK ) ?"STBC " :"" , + (rate &RATE_MCS_LDPC_MSK ) ?"LDPC " :"" , + (rate &RATE_MCS_BF_MSK ) ?"BF " :"" , + (rate &RATE_MCS_ZLF_MSK ) ?"ZLF " :"" ); +} +static ssize_t rs_sta_dbgfs_scale_table_read (struct file *file,char __user *user_buf,size_t count,loff_t *ppos) {char *buff;int desc =0 ;int i =0 ; -int index =0 ;ssize_t ret;struct iwl_lq_sta *lq_sta = file->private_data;
@@ -2580,7 +2642,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); mvm = lq_sta->drv; - buff =kmalloc (1024 ,GFP_KERNEL ); + buff =kmalloc (2048 ,GFP_KERNEL );if (!buff)return -ENOMEM ;
@@ -2597,7 +2659,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, desc +=sprintf (buff+desc,"lq type %s\n" , (is_legacy (tbl->lq_type)) ?"legacy" :is_vht (tbl->lq_type) ?"VHT" :"HT" ); -if (is_ht (tbl->lq_type)) { +if (!is_legacy (tbl->lq_type)) { desc +=sprintf (buff+desc," %s" , (is_siso (tbl->lq_type)) ?"SISO" :"MIMO2" ); desc += sprintf(buff+desc, " %s",
@@ -2605,13 +2667,13 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, (is_ht40 (tbl)) ?"40MHz" : (is_ht80(tbl)) ? "80Mhz" : "BAD BW"); desc +=sprintf (buff+desc," %s %s\n" , - (tbl->is_SGI) ?"SGI" :"" , + (tbl->is_SGI) ?"SGI" :"NGI" , (lq_sta->is_agg) ?"AGG on" :"" ); } desc +=sprintf (buff+desc,"last tx rate=0x%X\n" , lq_sta->last_rate_n_flags); desc += sprintf(buff+desc, - "general: flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", + "general: flags=0x%X mimo-d=%d s-ant=0x%x d-ant=0x%x\n", lq_sta->lq.flags, lq_sta->lq.mimo_delim, lq_sta->lq.single_stream_ant_msk,
@@ -2631,19 +2693,12 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, lq_sta->lq.initial_rate_index[3]);for (i =0 ; i <LINK_QUAL_MAX_RETRY_NUM ; i++) { - index =iwl_hwrate_to_plcp_idx ( -le32_to_cpu (lq_sta->lq.rs_table[i])); -if (is_legacy (tbl->lq_type)) { - desc +=sprintf (buff+desc," rate[%d] 0x%X %smbps\n" , - i,le32_to_cpu (lq_sta->lq.rs_table[i]), - iwl_rate_mcs[index].mbps); - }else { - desc +=sprintf (buff+desc, -" rate[%d] 0x%X %smbps (%s)\n" , - i,le32_to_cpu (lq_sta->lq.rs_table[i]), - iwl_rate_mcs[index].mbps, - iwl_rate_mcs[index].mcs); - } +u32 rate =le32_to_cpu (lq_sta->lq.rs_table[i]); + desc +=sprintf (buff+desc, +" rate[%d] 0x%X " , + i, rate); + + desc +=rs_pretty_print_rate (buff+desc, rate); } ret =simple_read_from_buffer (user_buf, count, ppos, buff, desc);
Signature · 1 line
1.7.9.5
PATCH 5/29 iwlwifi: mvm: simplify iwl_mvm_send_lq_cmd
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Remove the flags parameter which should be set to sync or async according to whether this is called during sta init or not.
--- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 +-- drivers/net/wireless/iwlwifi/mvm/rs.c | 12 ++++++------ drivers/net/wireless/iwlwifi/mvm/sta.c | 2 +- drivers/net/wireless/iwlwifi/mvm/utils.c | 8 ++------ 4 files changed, 10 insertions(+), 15 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -2
@@ -750,8 +750,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)#endif /* CONFIG_IWLWIFI_DEBUGFS */ /* rate scaling */ -int iwl_mvm_send_lq_cmd (struct iwl_mvm *mvm,struct iwl_lq_cmd *lq, -u8 flags,bool init); +int iwl_mvm_send_lq_cmd (struct iwl_mvm *mvm,struct iwl_lq_cmd *lq,bool init);/* power managment */ static inline int iwl_mvm_power_update_mode(struct iwl_mvm *mvm,
drivers/net/wireless/iwlwifi/mvm/rs.c +6 -6
@@ -298,7 +298,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,if (lq_sta->dbg_fixed_rate) {rs_fill_link_cmd (NULL ,NULL , lq_sta, lq_sta->dbg_fixed_rate); -iwl_mvm_send_lq_cmd (lq_sta->drv, &lq_sta->lq,CMD_ASYNC , false); +iwl_mvm_send_lq_cmd (lq_sta->drv, &lq_sta->lq, false); } }#endif
@@ -855,7 +855,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband, lq_sta->missed_rate_counter++;if (lq_sta->missed_rate_counter >IWL_MISSED_RATE_MAX ) { lq_sta->missed_rate_counter =0 ; -iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq,CMD_ASYNC , false); +iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq, false); }/* Regardless, ignore this status info for outdated rate */ return ;
@@ -1667,7 +1667,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,/* Update uCode's rate table. */ rate =rate_n_flags_from_tbl (mvm, tbl, index);rs_fill_link_cmd (mvm, sta, lq_sta, rate); -iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq,CMD_ASYNC , false); +iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq, false); } static u8 rs_get_tid(struct iwl_lq_sta *lq_data,
@@ -2064,7 +2064,7 @@ lq_update:"Switch current mcs: %X index: %d\n" , tbl->current_rate, index);rs_fill_link_cmd (mvm, sta, lq_sta, tbl->current_rate); -iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq,CMD_ASYNC , false); +iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq, false); }else { done_search =1 ; }
@@ -2168,7 +2168,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,rs_set_expected_tpt_table (lq_sta, tbl);rs_fill_link_cmd (NULL ,NULL , lq_sta, rate);/* TODO restore station should remember the lq cmd */ -iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq,CMD_SYNC , true); +iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq, true); } static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2841,5 +2841,5 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK ; } -return iwl_mvm_send_lq_cmd (mvm, lq,CMD_ASYNC , false); +return iwl_mvm_send_lq_cmd (mvm, lq, false); }
drivers/net/wireless/iwlwifi/mvm/sta.c +1 -1
@@ -945,7 +945,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,*/ } -return iwl_mvm_send_lq_cmd (mvm, &mvmsta->lq_sta.lq,CMD_ASYNC , false); +return iwl_mvm_send_lq_cmd (mvm, &mvmsta->lq_sta.lq, false); } int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
drivers/net/wireless/iwlwifi/mvm/utils.c +2 -6
@@ -486,22 +486,18 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm)* this case to clear the state indicating that station creation is in * progress. */ -int iwl_mvm_send_lq_cmd (struct iwl_mvm *mvm,struct iwl_lq_cmd *lq, -u8 flags,bool init) +int iwl_mvm_send_lq_cmd (struct iwl_mvm *mvm,struct iwl_lq_cmd *lq,bool init) {struct iwl_host_cmd cmd = { .id =LQ_CMD , .len = {sizeof (struct iwl_lq_cmd ), }, - .flags = flags, + .flags = init ?CMD_SYNC :CMD_ASYNC , .data = { lq, }, };if (WARN_ON (lq->sta_id ==IWL_MVM_STATION_COUNT ))return -EINVAL ; -if (WARN_ON (init && (cmd.flags &CMD_ASYNC ))) -return -EINVAL ; -return iwl_mvm_send_cmd (mvm, &cmd); }
Signature · 1 line
1.7.9.5
PATCH 6/29 iwlwifi: mvm: refactor iwl_mvm_rs_rate_init
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Refactor setting of VHT enabled rates in preparation of adding some more logic there.
--- drivers/net/wireless/iwlwifi/mvm/rs.c | 49 +++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 21 deletions(-)
drivers/net/wireless/iwlwifi/mvm/rs.c +28 -21
@@ -2242,6 +2242,33 @@ static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap,return -1 ; } +static void rs_vht_set_enabled_rates (struct ieee80211_sta *sta, +struct ieee80211_sta_vht_cap *vht_cap, +struct iwl_lq_sta *lq_sta) +{ +int i; +int highest_mcs =rs_vht_highest_rx_mcs_index (vht_cap,1 ); + +if (highest_mcs >=IWL_RATE_MCS_0_INDEX ) { +for (i =IWL_RATE_MCS_0_INDEX ; i <= highest_mcs; i++) { +if (i ==IWL_RATE_9M_INDEX ) +continue ; + + lq_sta->active_siso_rate |=BIT (i); + } + } + + highest_mcs =rs_vht_highest_rx_mcs_index (vht_cap,2 ); +if (highest_mcs >=IWL_RATE_MCS_0_INDEX ) { +for (i =IWL_RATE_MCS_0_INDEX ; i <= highest_mcs; i++) { +if (i ==IWL_RATE_9M_INDEX ) +continue ; + + lq_sta->active_mimo2_rate |=BIT (i); + } + } +} +/* * Called after adding a new station to initialize rate scaling */
@@ -2308,27 +2335,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, lq_sta->is_vht = false; }else { -int highest_mcs =rs_vht_highest_rx_mcs_index (vht_cap,1 ); -if (highest_mcs >=IWL_RATE_MCS_0_INDEX ) { -for (i =IWL_RATE_MCS_0_INDEX ; i <= highest_mcs; i++) { -if (i ==IWL_RATE_9M_INDEX ) -continue ; - - lq_sta->active_siso_rate |=BIT (i); - } - } - - highest_mcs =rs_vht_highest_rx_mcs_index (vht_cap,2 ); -if (highest_mcs >=IWL_RATE_MCS_0_INDEX ) { -for (i =IWL_RATE_MCS_0_INDEX ; i <= highest_mcs; i++) { -if (i ==IWL_RATE_9M_INDEX ) -continue ; - - lq_sta->active_mimo2_rate |=BIT (i); - } - } - -/* TODO: avoid MCS9 in 20Mhz which isn't valid for 11ac */ +rs_vht_set_enabled_rates (sta, vht_cap, lq_sta); lq_sta->is_vht = true; }
Signature · 1 line
1.7.9.5
PATCH 7/29 iwlwifi: mvm: enable d3_test even if d3_test_pme_ptr is not available
In reply to Emmanuel GrumbachFrom: Eliad Peller <[email protected]>
Even if d3_test_pme_ptr is not available, d3_test can still be useful, e.g. by manually triggering resume (with ctrl-c), and reading the wakeup reasons.
--- drivers/net/wireless/iwlwifi/mvm/d3.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/iwlwifi/mvm/d3.c +8 -8
@@ -1216,10 +1216,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,if (len >=sizeof (u32) *2 ) { mvm->d3_test_pme_ptr =le32_to_cpup ((__le32 *)d3_cfg_cmd.resp_pkt->data); - }else if (test) { -/* in test mode we require the pointer */ - ret = -EIO ; - goto out; }#endif iwl_free_resp (&d3_cfg_cmd);
@@ -1870,10 +1866,14 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,u32 pme_asserted;while (true) { - pme_asserted =iwl_trans_read_mem32 (mvm->trans, - mvm->d3_test_pme_ptr); -if (pme_asserted) -break ; +/* read pme_ptr if available */ +if (mvm->d3_test_pme_ptr) { + pme_asserted =iwl_trans_read_mem32 (mvm->trans, + mvm->d3_test_pme_ptr); +if (pme_asserted) +break ; + } +if (msleep_interruptible (100 ))break ; }
Signature · 1 line
1.7.9.5
PATCH 8/29 iwlwifi: mvm: disconnect on disconnection wakeup event
In reply to Emmanuel GrumbachFrom: Eliad Peller <[email protected]>
When waking up from d3 due to disconnection event (e.g. because of beacon loss), we should disconnect immediately.
--- drivers/net/wireless/iwlwifi/mvm/d3.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/wireless/iwlwifi/mvm/d3.c +6 -0
@@ -1533,10 +1533,16 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,struct iwl_mvm_d3_gtk_iter_data gtkdata = { .status = status, }; +u32 disconnection_reasons = +IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | +IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH ;if (!status || !vif->bss_conf.bssid)return false; +if (le32_to_cpu (status->wakeup_reasons) & disconnection_reasons) +return false; +/* find last GTK that we used initially, if any */ gtkdata.find_phase = true; ieee80211_iter_keys(mvm->hw, vif,
Signature · 1 line
1.7.9.5
PATCH 9/29 iwlwifi: mvm: implement rate_update hook in rs
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Re-initialize rs when we get a rate_update hook called which happens when remote STA changes bandwidth or sends a VHT opmode notification.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 ++- drivers/net/wireless/iwlwifi/mvm/rs.c | 30 +++++++++++++++++++++++---- drivers/net/wireless/iwlwifi/mvm/rs.h | 2 +- 3 files changed, 29 insertions(+), 6 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +2 -1
@@ -1149,7 +1149,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, ret =iwl_mvm_update_sta (mvm, vif, sta);if (ret ==0 )iwl_mvm_rs_rate_init (mvm, sta, - mvmvif->phy_ctxt->channel->band); + mvmvif->phy_ctxt->channel->band, + true); }else if (old_state ==IEEE80211_STA_ASSOC && new_state ==IEEE80211_STA_AUTHORIZED ) {/* enable beacon filtering */
drivers/net/wireless/iwlwifi/mvm/rs.c +26 -4
@@ -2126,7 +2126,8 @@ out:static void rs_initialize_lq (struct iwl_mvm *mvm,struct ieee80211_sta *sta,struct iwl_lq_sta *lq_sta, -enum ieee80211_band band) +enum ieee80211_band band, +bool init) {struct iwl_scale_tbl_info *tbl;int rate_idx;
@@ -2168,7 +2169,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,rs_set_expected_tpt_table (lq_sta, tbl);rs_fill_link_cmd (NULL ,NULL , lq_sta, rate);/* TODO restore station should remember the lq cmd */ -iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq, true); +iwl_mvm_send_lq_cmd (mvm, &lq_sta->lq, init); } static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
@@ -2273,7 +2274,7 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,* Called after adding a new station to initialize rate scaling */ void iwl_mvm_rs_rate_init (struct iwl_mvm *mvm,struct ieee80211_sta *sta, -enum ieee80211_band band) +enum ieee80211_band band,bool init) {int i, j;struct ieee80211_hw *hw = mvm->hw;
@@ -2286,6 +2287,8 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; lq_sta = &sta_priv->lq_sta; +memset (lq_sta,0 ,sizeof (*lq_sta)); + sband = hw->wiphy->bands[band]; lq_sta->lq.sta_id = sta_priv->sta_id;
@@ -2371,7 +2374,25 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, lq_sta->dbg_fixed_rate =0 ;#endif -rs_initialize_lq (mvm, sta, lq_sta, band); +rs_initialize_lq (mvm, sta, lq_sta, band, init); +} + +static void rs_rate_update (void *mvm_r, +struct ieee80211_supported_band *sband, +struct cfg80211_chan_def *chandef, +struct ieee80211_sta *sta,void *priv_sta, +u32 changed) +{ +u8 tid; +struct iwl_op_mode *op_mode = + (struct iwl_op_mode *)mvm_r; +struct iwl_mvm *mvm =IWL_OP_MODE_GET_MVM (op_mode); + +/* Stop any ongoing aggregations as rs starts off assuming no agg */ +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); } static void rs_fill_link_cmd(struct iwl_mvm *mvm,
@@ -2808,6 +2829,7 @@ static struct rate_control_ops rs_mvm_ops = { .free = rs_free, .alloc_sta = rs_alloc_sta, .free_sta = rs_free_sta, + .rate_update = rs_rate_update, #ifdef CONFIG_MAC80211_DEBUGFS .add_sta_debugfs = rs_add_debugfs, .remove_sta_debugfs = rs_remove_debugfs,
drivers/net/wireless/iwlwifi/mvm/rs.h +1 -1
@@ -353,7 +353,7 @@ static inline u8 num_of_ant(u8 mask)/* Initialize station's rate scaling information after adding station */ void iwl_mvm_rs_rate_init (struct iwl_mvm *mvm,struct ieee80211_sta *sta, -enum ieee80211_band band); +enum ieee80211_band band,bool init);/** * iwl_rate_control_register - Register the rate control algorithm callbacks
Signature · 1 line
1.7.9.5
PATCH 10/29 iwlwifi: mvm: allow keeping connections in d3_test
In reply to Emmanuel GrumbachFrom: Eliad Peller <[email protected]>
Keeping connection can be useful also when testing d3 using the debugfs file (d3_test).
Save the vif to keep connection on, and consider it when iterating over the interfaces.
--- drivers/net/wireless/iwlwifi/mvm/d3.c | 11 ++++++++++- drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/mvm/d3.c +10 -1
@@ -1806,6 +1806,10 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)iwl_mvm_read_d3_sram (mvm); keep =iwl_mvm_query_wakeup_reasons (mvm, vif); +#ifdef CONFIG_IWLWIFI_DEBUGFS +if (keep) + mvm->keep_vif = vif; +#endif /* has unlocked the mutex, so skip that */ goto out;
@@ -1862,6 +1866,7 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)return err; } mvm->d3_test_active = true; + mvm->keep_vif =NULL ;return 0 ; }
@@ -1890,6 +1895,10 @@ static ssize_t iwl_mvm_d3_test_read(struct file *file, char __user *user_buf,static void iwl_mvm_d3_test_disconn_work_iter (void *_data,u8 *mac,struct ieee80211_vif *vif) { +/* skip the one we keep connection on */ +if (_data == vif) +return ; +if (vif->type ==NL80211_IFTYPE_STATION )ieee80211_connection_loss (vif); }
@@ -1916,7 +1925,7 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)ieee80211_iterate_active_interfaces_atomic ( mvm->hw,IEEE80211_IFACE_ITER_NORMAL , - iwl_mvm_d3_test_disconn_work_iter,NULL ); + iwl_mvm_d3_test_disconn_work_iter, mvm->keep_vif);ieee80211_wake_queues (mvm->hw);
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -0
@@ -531,6 +531,7 @@ struct iwl_mvm {bool store_d3_resume_sram;void *d3_resume_sram;u32 d3_test_pme_ptr; +struct ieee80211_vif *keep_vif;#endif #endif
Signature · 1 line
1.7.9.5
PATCH 11/29 iwlwifi: mvm: fix ht protection flags
In reply to Emmanuel GrumbachFrom: Avri Altman <[email protected]>
The HT protection flags have been a mess for a long time, this patch fixes all this.
The proper source of information for this is the protection in the HT operation mode IE which is propagated to bss_conf by mac80211.
1) No need to set the HT protection flags when the link doesn't support HT.
2) We need to set the TGG protection when ERP is active.
--- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 51 ++++++++++++++++++++++----- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 11 ++++++ 2 files changed, 53 insertions(+), 9 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +42 -9
@@ -488,6 +488,40 @@ static void iwl_mvm_ack_rates(struct iwl_mvm *mvm, *ofdm_rates = ofdm; } +static void iwl_mvm_mac_ctxt_set_ht_flags (struct iwl_mvm *mvm, +struct ieee80211_vif *vif, +struct iwl_mac_ctx_cmd *cmd) +{ +/* for both sta and ap, ht_operation_mode hold the protection_mode */ +u8 protection_mode = vif->bss_conf.ht_operation_mode & +IEEE80211_HT_OP_MODE_PROTECTION ; +/* The fw does not distinguish between ht and fat */ +u32 ht_flag =MAC_PROT_FLG_HT_PROT |MAC_PROT_FLG_FAT_PROT ; + +IWL_DEBUG_RATE (mvm,"protection mode set to %d\n" , protection_mode); +/* +* See section 9.23.3.1 of IEEE 80211-2012. +* Nongreenfield HT STAs Present is not supported. +*/ +switch (protection_mode) { +case IEEE80211_HT_OP_MODE_PROTECTION_NONE : +break ; +case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER : +case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED : + cmd->protection_flags |=cpu_to_le32 (ht_flag); +break ; +case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ : +/* Protect when channel wider than 20MHz */ +if (vif->bss_conf.chandef.width >NL80211_CHAN_WIDTH_20 ) + cmd->protection_flags |=cpu_to_le32 (ht_flag); +break ; +default : +IWL_ERR (mvm,"Illegal protection mode %d\n" , + protection_mode); +break ; + } +} + static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mac_ctx_cmd *cmd,
@@ -495,6 +529,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, {struct iwl_mvm_vif *mvmvif =iwl_mvm_vif_from_mac80211 (vif);struct ieee80211_chanctx_conf *chanctx; +bool ht_enabled = !!(vif->bss_conf.ht_operation_mode & +IEEE80211_HT_OP_MODE_PROTECTION );u8 cck_ack_rates, ofdm_ack_rates;int i;
@@ -573,16 +609,13 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, cmd->protection_flags |=cpu_to_le32 (MAC_PROT_FLG_SELF_CTS_EN ); } - -/* -* I think that we should enable these 2 flags regardless the HT PROT -* fields in the HT IE, but I am not sure. Someone knows whom to ask?... -*/ -if (vif->bss_conf.chandef.width !=NL80211_CHAN_WIDTH_20_NOHT ) { +IWL_DEBUG_RATE (mvm,"use_cts_prot %d, ht_operation_mode %d\n" , + vif->bss_conf.use_cts_prot, + vif->bss_conf.ht_operation_mode); +if (vif->bss_conf.chandef.width !=NL80211_CHAN_WIDTH_20_NOHT ) cmd->qos_flags |=cpu_to_le32 (MAC_QOS_FLG_TGN ); - cmd->protection_flags |=cpu_to_le32 (MAC_PROT_FLG_HT_PROT | -MAC_PROT_FLG_FAT_PROT ); - } +if (ht_enabled) +iwl_mvm_mac_ctxt_set_ht_flags (mvm, vif, cmd); cmd->filter_flags =cpu_to_le32 (MAC_FILTER_ACCEPT_GRP ); }
drivers/net/wireless/iwlwifi/mvm/mac80211.c +11 -0
@@ -990,6 +990,17 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm, struct ieee80211_bss_conf *bss_conf, u32 changes) { +enum ieee80211_bss_change ht_change =BSS_CHANGED_ERP_CTS_PROT | +BSS_CHANGED_HT | +BSS_CHANGED_BANDWIDTH ; +int ret; + +if (changes & ht_change) { + ret =iwl_mvm_mac_ctxt_changed (mvm, vif); +if (ret) +IWL_ERR (mvm,"failed to update MAC %pM\n" , vif->addr); + } +/* Need to send a new beacon template to the FW */ if (changes &BSS_CHANGED_BEACON ) {if (iwl_mvm_mac_ctxt_beacon_changed (mvm, vif))
Signature · 1 line
1.7.9.5
PATCH 12/29 iwlwifi: mvm: small debugfs cleanups
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
Just clean up the code a bit, in particular
* make all the debugfs writes follow the same pattern with respect to buf/buf_size variables
* get rid of useless comments
* check return values of all file creations
* drop unnecessary parentheses
* remove an unused struct definition
* fix some whitespace
--- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 77 ++++++++++------------------ 1 file changed, 27 insertions(+), 50 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +27 -50
@@ -65,26 +65,19 @@#include "iwl-io.h" #include "iwl-prph.h" -struct iwl_dbgfs_mvm_ctx { -struct iwl_mvm *mvm; -struct ieee80211_vif *vif; -}; -static ssize_t iwl_dbgfs_tx_flush_write (struct file *file,const char __user *user_buf,size_t count,loff_t *ppos) {struct iwl_mvm *mvm = file->private_data; - -char buf[16 ]; -int buf_size, ret; +char buf[16 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 ); +int ret;u32 scd_q_msk;if (!mvm->ucode_loaded || mvm->cur_ucode !=IWL_UCODE_REGULAR )return -EIO ; -memset (buf,0 ,sizeof (buf)); - buf_size =min (count,sizeof (buf) -1 );if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;
@@ -106,15 +99,13 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct file *file, {struct iwl_mvm *mvm = file->private_data;struct ieee80211_sta *sta; - -char buf[8 ]; -int buf_size, sta_id, drain, ret; +char buf[8 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 ); +int sta_id, drain, ret;if (!mvm->ucode_loaded || mvm->cur_ucode !=IWL_UCODE_REGULAR )return -EIO ; -memset (buf,0 ,sizeof (buf)); - buf_size =min (count,sizeof (buf) -1 );if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;
@@ -196,12 +187,10 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file, loff_t *ppos) {struct iwl_mvm *mvm = file->private_data; -char buf[64 ]; -int buf_size; +char buf[64 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 );u32 offset, len; -memset (buf,0 ,sizeof (buf)); - buf_size =min (count,sizeof (buf) -1 );if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;
@@ -270,14 +259,14 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, {struct iwl_mvm *mvm = file->private_data;char buf[64 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 );int ret;int val;if (!mvm->ucode_loaded)return -EIO ; - count =min_t (size_t, count,sizeof (buf) -1 ); -if (copy_from_user (buf, user_buf, count)) +if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;if (!strncmp ("disable_power_off_d0=" , buf,21 )) {
@@ -315,11 +304,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,int dtimper_msec = dtimper * vif->bss_conf.beacon_int;IWL_DEBUG_POWER (mvm,"debugfs: set keep_alive= %d sec\n" , val); -if (val *MSEC_PER_SEC <3 * dtimper_msec) { +if (val *MSEC_PER_SEC <3 * dtimper_msec)IWL_WARN (mvm,"debugfs: keep alive period (%ld msec) is less than minimum required (%d msec)\n" , val *MSEC_PER_SEC ,3 * dtimper_msec); - } dbgfs_pm->keep_alive_seconds = val;break ; }
@@ -368,11 +356,11 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,struct iwl_mvm *mvm = mvmvif->dbgfs_data;enum iwl_dbgfs_pm_mask param;char buf[32 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 );int val;int ret; - count =min_t (size_t, count,sizeof (buf) -1 ); -if (copy_from_user (buf, user_buf, count)) +if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;if (!strncmp ("keep_alive=" , buf,11 )) {
@@ -467,7 +455,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file, pos +=scnprintf (buf+pos, bufsz-pos,"bssid: %pM\n" , vif->bss_conf.bssid); pos +=scnprintf (buf+pos, bufsz-pos,"QoS:\n" ); -for (i =0 ; i <ARRAY_SIZE (mvmvif->queue_params); i++) { +for (i =0 ; i <ARRAY_SIZE (mvmvif->queue_params); i++) pos += scnprintf(buf+pos, bufsz-pos, "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n", i, mvmvif->queue_params[i].txop,
@@ -475,7 +463,6 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file, mvmvif->queue_params[i].cw_max, mvmvif->queue_params[i].aifs, mvmvif->queue_params[i].uapsd); - }if (vif->type ==NL80211_IFTYPE_STATION && ap_sta_id !=IWL_MVM_STATION_COUNT ) {
@@ -492,12 +479,11 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,rcu_read_lock (); chanctx_conf =rcu_dereference (vif->chanctx_conf); -if (chanctx_conf) { +if (chanctx_conf) pos +=scnprintf (buf+pos, bufsz-pos,"idle rx chains %d, active rx chains: %d\n" , chanctx_conf->rx_chains_static, chanctx_conf->rx_chains_dynamic); - }rcu_read_unlock ();mutex_unlock (&mvm->mutex);
@@ -841,14 +827,10 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file, size_t count, loff_t *ppos) { struct iwl_mvm *mvm = file->private_data; -char buf[8 ]; -int buf_size; +char buf[8 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 );u8 scan_rx_ant; -memset (buf,0 ,sizeof (buf)); - buf_size =min (count,sizeof (buf) -1 ); - -/* get the argument from the user and check if it is valid */ if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;if (sscanf (buf,"%hhx" , &scan_rx_ant) !=1 )
@@ -858,7 +840,6 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file,if (scan_rx_ant & ~iwl_fw_valid_rx_ant (mvm->fw))return -EINVAL ; -/* change the rx antennas for scan command */ mvm->scan_rx_ant = scan_rx_ant;return count;
@@ -918,13 +899,10 @@ static ssize_t iwl_dbgfs_bf_params_write(struct file *file,struct iwl_mvm_vif *mvmvif =iwl_mvm_vif_from_mac80211 (vif);struct iwl_mvm *mvm = mvmvif->dbgfs_data;enum iwl_dbgfs_bf_mask param; -char buf[256 ]; -int buf_size; -int value; -int ret =0 ; +char buf[256 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 ); +int value, ret =0 ; -memset (buf,0 ,sizeof (buf)); - buf_size =min (count,sizeof (buf) -1 );if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;
@@ -1008,11 +986,10 @@ static ssize_t iwl_dbgfs_bf_params_write(struct file *file,mutex_lock (&mvm->mutex);iwl_dbgfs_update_bf (vif, param, value); -if (param ==MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) { +if (param ==MVM_DEBUGFS_BF_ENABLE_BEACON_FILTER && !value) ret =iwl_mvm_disable_beacon_filter (mvm, vif); - }else { +else ret =iwl_mvm_enable_beacon_filter (mvm, vif); - }mutex_unlock (&mvm->mutex);return ret ?: count;
@@ -1074,10 +1051,10 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, {struct iwl_mvm *mvm = file->private_data;char buf[8 ] = {}; +size_t buf_size =min (count,sizeof (buf) -1 );int store; - count =min_t (size_t, count,sizeof (buf) -1 ); -if (copy_from_user (buf, user_buf, count)) +if (copy_from_user (buf, user_buf, buf_size))return -EFAULT ;if (sscanf (buf,"%d" , &store) !=1 )
@@ -1133,14 +1110,14 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,#endif #define MVM_DEBUGFS_READ_FILE_OPS (name) \ -static const struct file_operations iwl_dbgfs_##name##_ops = { \ +static const struct file_operations iwl_dbgfs_##name##_ops = { \ .read = iwl_dbgfs_##name##_read, \ .open = simple_open, \ .llseek = generic_file_llseek, \ }#define MVM_DEBUGFS_READ_WRITE_FILE_OPS (name) \ -static const struct file_operations iwl_dbgfs_##name##_ops = { \ +static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ .read = iwl_dbgfs_##name##_read, \ .open = simple_open, \
@@ -1148,7 +1125,7 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ };#define MVM_DEBUGFS_WRITE_FILE_OPS (name) \ -static const struct file_operations iwl_dbgfs_##name##_ops = { \ +static const struct file_operations iwl_dbgfs_##name##_ops = { \ .write = iwl_dbgfs_##name##_write, \ .open = simple_open, \ .llseek = generic_file_llseek, \
Signature · 1 line
1.7.9.5
PATCH 13/29 iwlwifi: mvm: move interface-specific debugfs to a new file
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
The debugfs file is getting pretty large and mixed up between code for the hardware and code for each interface (the two aren't even clearly separated in the code). Make it easier to handle by splitting the per-interface code into a separate file called debugfs-vif.c.
--- drivers/net/wireless/iwlwifi/mvm/Makefile | 1 + drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 190 +++++++++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 505 +----------------------- drivers/net/wireless/iwlwifi/mvm/debugfs.h | 84 ++++ 4 files changed, 276 insertions(+), 504 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h
drivers/net/wireless/iwlwifi/mvm/Makefile +1 -0
@@ -5,6 +5,7 @@ iwlmvm-y += scan.o time-event.o rs.o iwlmvm-y += power.o power_legacy.o bt-coex.o iwlmvm-y += led.o tt.o iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o +iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o iwlmvm-$(CONFIG_PM_SLEEP) += d3.o ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c new file +190 -0
190 lines not on this page · raw message
drivers/net/wireless/iwlwifi/mvm/debugfs.c +1 -504
544 lines not on this page · raw message
drivers/net/wireless/iwlwifi/mvm/debugfs.h new file +84 -0
84 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH 14/29 iwlwifi: mvm: don't use void pointers in debugfs
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
There's really no reason to use void *dbgfs_data
rather than a struct iwl_mvm *mvm, so do that.
--- drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 4 ++-- drivers/net/wireless/iwlwifi/mvm/mvm.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c +2 -2
@@ -69,7 +69,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file, {struct ieee80211_vif *vif = file->private_data;struct iwl_mvm_vif *mvmvif =iwl_mvm_vif_from_mac80211 (vif); -struct iwl_mvm *mvm = mvmvif->dbgfs_data; +struct iwl_mvm *mvm = mvmvif->mvm;u8 ap_sta_id;struct ieee80211_chanctx_conf *chanctx_conf;char buf[512 ];
@@ -144,7 +144,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)return ; mvmvif->dbgfs_dir =debugfs_create_dir ("iwlmvm" , dbgfs_dir); - mvmvif->dbgfs_data = mvm; + mvmvif->mvm = mvm;if (!mvmvif->dbgfs_dir) { IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
drivers/net/wireless/iwlwifi/mvm/mvm.h +1 -1
@@ -323,9 +323,9 @@ struct iwl_mvm_vif {#endif #ifdef CONFIG_IWLWIFI_DEBUGFS +struct iwl_mvm *mvm;struct dentry *dbgfs_dir;struct dentry *dbgfs_slink; -void *dbgfs_data;struct iwl_dbgfs_pm dbgfs_pm;struct iwl_dbgfs_bf dbgfs_bf;#endif
Signature · 1 line
1.7.9.5
PATCH 15/29 iwlwifi: mvm: refactor debugfs copy_from_user()
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
Abstract the copy_from_user() pattern into the macros defining debugfs files, reducing the code and making adding new files safer by avoiding having deal with copy_from_user() directly.
--- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 87 +++++++--------------------- drivers/net/wireless/iwlwifi/mvm/debugfs.h | 25 ++++++-- 2 files changed, 43 insertions(+), 69 deletions(-)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +22 -65
@@ -66,22 +66,15 @@#include "iwl-prph.h" #include "debugfs.h" -static ssize_t iwl_dbgfs_tx_flush_write (struct file *file, -const char __user *user_buf, +static ssize_t iwl_dbgfs_tx_flush_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data; -char buf[16 ] = {}; -size_t buf_size =min (count,sizeof (buf) -1 );int ret;u32 scd_q_msk;if (!mvm->ucode_loaded || mvm->cur_ucode !=IWL_UCODE_REGULAR )return -EIO ; -if (copy_from_user (buf, user_buf, buf_size)) -return -EFAULT ; -if (sscanf (buf,"%x" , &scd_q_msk) !=1 )return -EINVAL ;
@@ -94,22 +87,15 @@ static ssize_t iwl_dbgfs_tx_flush_write(struct file *file,return ret; } -static ssize_t iwl_dbgfs_sta_drain_write (struct file *file, -const char __user *user_buf, +static ssize_t iwl_dbgfs_sta_drain_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data;struct ieee80211_sta *sta; -char buf[8 ] = {}; -size_t buf_size =min (count,sizeof (buf) -1 );int sta_id, drain, ret;if (!mvm->ucode_loaded || mvm->cur_ucode !=IWL_UCODE_REGULAR )return -EIO ; -if (copy_from_user (buf, user_buf, buf_size)) -return -EFAULT ; -if (sscanf (buf,"%d %d" , &sta_id, &drain) !=2 )return -EINVAL ;
@@ -183,18 +169,11 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,return ret; } -static ssize_t iwl_dbgfs_sram_write (struct file *file, -const char __user *user_buf,size_t count, -loff_t *ppos) +static ssize_t iwl_dbgfs_sram_write (struct iwl_mvm *mvm,char *buf, +size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data; -char buf[64 ] = {}; -size_t buf_size =min (count,sizeof (buf) -1 );u32 offset, len; -if (copy_from_user (buf, user_buf, buf_size)) -return -EFAULT ; -if (sscanf (buf,"%x,%x" , &offset, &len) ==2 ) {if ((offset &0x3 ) || (len &0x3 ))return -EINVAL ;
@@ -254,22 +233,14 @@ static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file,return simple_read_from_buffer (user_buf, count, ppos, buf, pos); } -static ssize_t iwl_dbgfs_disable_power_off_write (struct file *file, -const char __user *user_buf, +static ssize_t iwl_dbgfs_disable_power_off_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data; -char buf[64 ] = {}; -size_t buf_size =min (count,sizeof (buf) -1 ); -int ret; -int val; +int ret, val;if (!mvm->ucode_loaded)return -EIO ; -if (copy_from_user (buf, user_buf, buf_size)) -return -EFAULT ; -if (!strncmp ("disable_power_off_d0=" , buf,21 )) {if (sscanf (buf +21 ,"%d" , &val) !=1 )return -EINVAL ;
@@ -564,11 +535,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, }#undef PRINT_STAT_LE32 -static ssize_t iwl_dbgfs_fw_restart_write (struct file *file, -const char __user *user_buf, +static ssize_t iwl_dbgfs_fw_restart_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data;int ret;mutex_lock (&mvm->mutex);
@@ -585,12 +554,9 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file,return count; } -static ssize_t iwl_dbgfs_fw_nmi_write (struct file *file, -const char __user *user_buf, +static ssize_t iwl_dbgfs_fw_nmi_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data; -iwl_write_prph (mvm->trans,DEVICE_SET_NMI_REG ,1 );return count;
@@ -620,17 +586,11 @@ iwl_dbgfs_scan_ant_rxchain_read(struct file *file, }static ssize_t -iwl_dbgfs_scan_ant_rxchain_write (struct file *file, -const char __user *user_buf, +iwl_dbgfs_scan_ant_rxchain_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data; -char buf[8 ] = {}; -size_t buf_size =min (count,sizeof (buf) -1 );u8 scan_rx_ant; -if (copy_from_user (buf, user_buf, buf_size)) -return -EFAULT ;if (sscanf (buf,"%hhx" , &scan_rx_ant) !=1 )return -EINVAL ;if (scan_rx_ant >ANT_ABC )
@@ -644,18 +604,11 @@ iwl_dbgfs_scan_ant_rxchain_write(struct file *file, }#ifdef CONFIG_PM_SLEEP -static ssize_t iwl_dbgfs_d3_sram_write (struct file *file, -const char __user *user_buf, +static ssize_t iwl_dbgfs_d3_sram_write (struct iwl_mvm *mvm,char *buf,size_t count,loff_t *ppos) { -struct iwl_mvm *mvm = file->private_data; -char buf[8 ] = {}; -size_t buf_size =min (count,sizeof (buf) -1 );int store; -if (copy_from_user (buf, user_buf, buf_size)) -return -EFAULT ; -if (sscanf (buf,"%d" , &store) !=1 )return -EINVAL ;
@@ -708,6 +661,10 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf, }#endif +#define MVM_DEBUGFS_WRITE_FILE_OPS (name, bufsz) \ + _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) +#define MVM_DEBUGFS_READ_WRITE_FILE_OPS (name, bufsz) \ + _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)#define MVM_DEBUGFS_ADD_FILE (name, parent, mode) do { \ if (!debugfs_create_file(#name, mode, parent, mvm, \ &iwl_dbgfs_##name##_ops)) \
@@ -715,20 +672,20 @@ static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf, }while (0 )/* Device wide debugfs entries */ -MVM_DEBUGFS_WRITE_FILE_OPS (tx_flush); -MVM_DEBUGFS_WRITE_FILE_OPS (sta_drain); -MVM_DEBUGFS_READ_WRITE_FILE_OPS (sram); +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_FILE_OPS (stations);MVM_DEBUGFS_READ_FILE_OPS (bt_notif);MVM_DEBUGFS_READ_FILE_OPS (bt_cmd); -MVM_DEBUGFS_READ_WRITE_FILE_OPS (disable_power_off); +MVM_DEBUGFS_READ_WRITE_FILE_OPS (disable_power_off,64 );MVM_DEBUGFS_READ_FILE_OPS (fw_rx_stats); -MVM_DEBUGFS_WRITE_FILE_OPS (fw_restart); -MVM_DEBUGFS_WRITE_FILE_OPS (fw_nmi); -MVM_DEBUGFS_READ_WRITE_FILE_OPS (scan_ant_rxchain); +MVM_DEBUGFS_WRITE_FILE_OPS (fw_restart,10 ); +MVM_DEBUGFS_WRITE_FILE_OPS (fw_nmi,10 ); +MVM_DEBUGFS_READ_WRITE_FILE_OPS (scan_ant_rxchain,8 );#ifdef CONFIG_PM_SLEEP -MVM_DEBUGFS_READ_WRITE_FILE_OPS (d3_sram); +MVM_DEBUGFS_READ_WRITE_FILE_OPS (d3_sram,8 );#endif int iwl_mvm_dbgfs_register (struct iwl_mvm *mvm,struct dentry *dbgfs_dir)
drivers/net/wireless/iwlwifi/mvm/debugfs.h +21 -4
@@ -68,17 +68,34 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ .llseek = generic_file_llseek, \ } -#define MVM_DEBUGFS_READ_WRITE_FILE_OPS (name) \ +#define MVM_DEBUGFS_WRITE_WRAPPER (name, buflen, argtype) \ +static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \ + const char __user *user_buf, \ + size_t count, loff_t *ppos) \ +{ \ + argtype *arg = file->private_data; \ + char buf[buflen] = {}; \ + size_t buf_size = min(count, sizeof(buf) - 1); \ + \ + if (copy_from_user(buf, user_buf, buf_size)) \ + return -EFAULT; \ + \ + return iwl_dbgfs_##name##_write(arg, buf, buf_size, ppos); \ +} \ + +#define _MVM_DEBUGFS_READ_WRITE_FILE_OPS (name, buflen, argtype) \ +MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ - .write = iwl_dbgfs_##name##_write, \ + .write = _iwl_dbgfs_##name##_write, \ .read = iwl_dbgfs_##name##_read, \ .open = simple_open, \ .llseek = generic_file_llseek, \ }; -#define MVM_DEBUGFS_WRITE_FILE_OPS (name) \ +#define _MVM_DEBUGFS_WRITE_FILE_OPS (name, buflen, argtype) \ +MVM_DEBUGFS_WRITE_WRAPPER(name, buflen, argtype) \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ - .write = iwl_dbgfs_##name##_write, \ + .write = _iwl_dbgfs_##name##_write, \ .open = simple_open, \ .llseek = generic_file_llseek, \ };
Signature · 1 line
1.7.9.5
PATCH 16/29 iwlwifi: mvm: add LQ flags definitions
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Add more bit field definitions used in LQ flags. Also rename the first bit to a shorter name.
--- drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 27 ++++++++++++++++++++++++-- drivers/net/wireless/iwlwifi/mvm/rs.c | 4 ++-- 2 files changed, 27 insertions(+), 4 deletions(-)
drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +25 -2
@@ -281,8 +281,31 @@ enum {/* # entries in rate scale table to support Tx retries */ #define LQ_MAX_RETRY_NUM 16 -/* Link quality command flags, only this one is available */ -#define LQ_FLAG_SET_STA_TLC_RTS_MSK BIT(0) +/* Link quality command flags bit fields */ + +/* Bit 0: (0) Don't use RTS (1) Use RTS */ +#define LQ_FLAG_USE_RTS_POS 0 +#define LQ_FLAG_USE_RTS_MSK (1 << LQ_FLAG_USE_RTS_POS) + +/* Bit 1-3: LQ command color. Used to match responses to LQ commands */ +#define LQ_FLAG_COLOR_POS 1 +#define LQ_FLAG_COLOR_MSK (7 << LQ_FLAG_COLOR_POS) + +/* Bit 4-5: Tx RTS BW Signalling +* (0) No RTS BW signalling +* (1) Static BW signalling +* (2) Dynamic BW signalling +*/ +#define LQ_FLAG_RTS_BW_SIG_POS 4 +#define LQ_FLAG_RTS_BW_SIG_NONE (0 << LQ_FLAG_RTS_BW_SIG_POS) +#define LQ_FLAG_RTS_BW_SIG_STATIC (1 << LQ_FLAG_RTS_BW_SIG_POS) +#define LQ_FLAG_RTS_BW_SIG_DYNAMIC (2 << LQ_FLAG_RTS_BW_SIG_POS) + +/* Bit 6: (0) No dynamic BW selection (1) Allow dynamic BW selection +* Dyanmic BW selection allows Tx with narrower BW then requested in rates +*/ +#define LQ_FLAG_DYNAMIC_BW_POS 6 +#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS)/** * struct iwl_lq_cmd - link quality command
drivers/net/wireless/iwlwifi/mvm/rs.c +2 -2
@@ -2862,12 +2862,12 @@ int iwl_mvm_tx_protection(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,if (enable) {if (mvmsta->tx_protection ==0 ) - lq->flags |=LQ_FLAG_SET_STA_TLC_RTS_MSK ; + lq->flags |=LQ_FLAG_USE_RTS_MSK ; mvmsta->tx_protection++; }else { mvmsta->tx_protection--;if (mvmsta->tx_protection ==0 ) - lq->flags &= ~LQ_FLAG_SET_STA_TLC_RTS_MSK ; + lq->flags &= ~LQ_FLAG_USE_RTS_MSK ; }return iwl_mvm_send_lq_cmd (mvm, lq, false);
Signature · 1 line
1.7.9.5
PATCH 17/29 iwlwifi: mvm: BT Coex - fine tune the aggregation size
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
Latest tests have shown that when BT is active and has connections but the traffic is low, the WiFi aggregation can be large up to 4000us without noticeable impact on BT.
--- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/iwlwifi/mvm/bt-coex.c +1 -1
@@ -917,7 +917,7 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,enum iwl_bt_coex_lut_type lut_type;if (le32_to_cpu (mvm->last_bt_notif.bt_activity_grading) < -BT_LOW_TRAFFIC ) +BT_HIGH_TRAFFIC )return LINK_QUAL_AGG_TIME_LIMIT_DEF ; lut_type =iwl_get_coex_type (mvm, mvmsta->vif);
Signature · 1 line
1.7.9.5
PATCH 18/29 iwlwifi: mvm: a few more SKUs for 7260 and 3160
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
These devices are not sold as discrete modules but are rather soldered down to the board.
--- drivers/net/wireless/iwlwifi/pcie/drv.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/wireless/iwlwifi/pcie/drv.c +5 -0
@@ -297,6 +297,9 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x08B2, 0x4370, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B2, 0x4360, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x5070, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5072, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5170, iwl7260_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B1, 0x5770, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4020, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x402A, iwl7260_2n_cfg)}, {IWL_PCI_DEVICE(0x08B2, 0x4220, iwl7260_2n_cfg)},
@@ -350,6 +353,8 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x1070, iwl3160_2ac_cfg)}, + {IWL_PCI_DEVICE(0x08B3, 0x1170, iwl3160_2ac_cfg)},/* 7265 Series */ {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
Signature · 1 line
1.7.9.5
PATCH 19/29 iwlwifi: pcie: remove minor dead code
In reply to Emmanuel GrumbachFrom: Michal Nazarewicz <[email protected]>
inta is checked to be zero in a IRQ_NONE branch so afterwards it cannot be zero as it is never modified.
--- drivers/net/wireless/iwlwifi/pcie/rx.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-)
drivers/net/wireless/iwlwifi/pcie/rx.c +11 -15
@@ -1121,7 +1121,6 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)struct iwl_trans *trans = data;struct iwl_trans_pcie *trans_pcie =IWL_TRANS_GET_PCIE_TRANS (trans);u32 inta, inta_mask; -irqreturn_t ret =IRQ_NONE ;lockdep_assert_held (&trans_pcie->irq_lock);
@@ -1150,7 +1149,16 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data)* or due to sporadic interrupts thrown from our NIC. */ if (!inta) {IWL_DEBUG_ISR (trans,"Ignore interrupt, inta == 0\n" ); - goto none; +/* +* Re-enable interrupts here since we don't have anything to +* service, but only in case the handler won't run. Note that +* the handler can be scheduled because of a previous +* interrupt. +*/ +if (test_bit (STATUS_INT_ENABLED , &trans_pcie->status) && + !trans_pcie->inta) +iwl_enable_interrupts (trans); +return IRQ_NONE ; }if ((inta ==0xFFFFFFFF ) || ((inta &0xFFFFFFF0 ) ==0xa5a5a5a0 )) {
@@ -1168,19 +1176,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data) trans_pcie->inta |= inta;/* the thread will service interrupts and re-enable them */ -if (likely (inta)) -return IRQ_WAKE_THREAD ; - - ret =IRQ_HANDLED ; - -none: -/* re-enable interrupts here since we don't have anything to service. */ -/* only Re-enable if disabled by irq and no schedules tasklet. */ -if (test_bit (STATUS_INT_ENABLED , &trans_pcie->status) && - !trans_pcie->inta) -iwl_enable_interrupts (trans); - -return ret; +return IRQ_WAKE_THREAD ; }/* interrupt handler using ict table, with this interrupt driver will
Signature · 1 line
1.7.9.5
PATCH 20/29 iwlwifi: fix check for a single rx antenna
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
valid_rx_ant is a bitmask of available antennas and not the number of Rx antennas. Use num_of_ant and remove duplicate definitions in both dvm and mvm.
--- drivers/net/wireless/iwlwifi/dvm/rs.h | 7 ------- drivers/net/wireless/iwlwifi/iwl-config.h | 6 ++++++ drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 ++- drivers/net/wireless/iwlwifi/mvm/rs.h | 8 -------- 4 files changed, 8 insertions(+), 16 deletions(-)
drivers/net/wireless/iwlwifi/dvm/rs.h +0 -7
@@ -389,13 +389,6 @@ struct iwl_lq_sta {u8 last_bt_traffic; }; -static inline u8 num_of_ant (u8 mask) -{ -return !!((mask) &ANT_A ) + - !!((mask) &ANT_B ) + - !!((mask) &ANT_C ); -} -static inline u8 first_antenna (u8 mask) {if (mask &ANT_A )
drivers/net/wireless/iwlwifi/iwl-config.h +6 -0
@@ -129,6 +129,12 @@ enum iwl_led_mode {#define ANT_BC (ANT_B | ANT_C)#define ANT_ABC (ANT_A | ANT_B | ANT_C) +static inline u8 num_of_ant (u8 mask) +{ +return !!((mask) &ANT_A ) + + !!((mask) &ANT_B ) + + !!((mask) &ANT_C ); +}/* * @max_ll_items: max number of OTP blocks
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +2 -1
@@ -283,7 +283,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,IEEE80211_VHT_MCS_NOT_SUPPORTED <<12 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); -if (data->valid_rx_ant ==1 || cfg->rx_with_siso_diversity) { +if (num_of_ant (data->valid_rx_ant) ==1 || + cfg->rx_with_siso_diversity) { vht_cap->cap |=IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN ;/* this works because NOT_SUPPORTED == 3 */
drivers/net/wireless/iwlwifi/mvm/rs.h +0 -8
@@ -343,14 +343,6 @@ enum iwl_bt_coex_profile_traffic_load {*/ }; - -static inline u8 num_of_ant (u8 mask) -{ -return !!((mask) &ANT_A ) + - !!((mask) &ANT_B ) + - !!((mask) &ANT_C ); -} -/* Initialize station's rate scaling information after adding station */ void iwl_mvm_rs_rate_init (struct iwl_mvm *mvm,struct ieee80211_sta *sta,enum ieee80211_band band,bool init);
Signature · 1 line
1.7.9.5
PATCH 21/29 iwlwifi: mvm: add iwl_mvm_sta_from_mac80211
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
This is just a helper function to go from the mac80211 station struct to our internal one, to later allow us to avoid temporary 'mvmsta' variables.
--- drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 8 ++++---- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 12 ++++++------ drivers/net/wireless/iwlwifi/mvm/sta.h | 6 ++++++ drivers/net/wireless/iwlwifi/mvm/tt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 10 +++++----- 6 files changed, 23 insertions(+), 17 deletions(-)
drivers/net/wireless/iwlwifi/mvm/bt-coex.c +4 -4
@@ -515,7 +515,7 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,if (IS_ERR_OR_NULL (sta))return 0 ; - mvmsta = (void *)sta->drv_priv; + mvmsta =iwl_mvm_sta_from_mac80211 (sta);/* nothing to do */ if (mvmsta->bt_reduced_txpower == enable)
@@ -842,7 +842,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, sta =rcu_dereference_protected (mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],lockdep_is_held (&mvm->mutex)); - mvmsta = (void *)sta->drv_priv; + mvmsta =iwl_mvm_sta_from_mac80211 (sta); data->num_bss_ifaces++;
@@ -913,7 +913,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,u16 iwl_mvm_bt_coex_agg_time_limit (struct iwl_mvm *mvm,struct ieee80211_sta *sta) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);enum iwl_bt_coex_lut_type lut_type; if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
@@ -932,7 +932,7 @@ u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm,bool iwl_mvm_bt_coex_is_mimo_allowed (struct iwl_mvm *mvm,struct ieee80211_sta *sta) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);if (le32_to_cpu (mvm->last_bt_notif.bt_activity_grading) <BT_HIGH_TRAFFIC )
drivers/net/wireless/iwlwifi/mvm/mac80211.c +1 -1
@@ -1091,7 +1091,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw, struct ieee80211_sta *sta) {struct iwl_mvm *mvm =IWL_MAC80211_GET_MVM (hw); -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);switch (cmd) {case STA_NOTIFY_SLEEP :
drivers/net/wireless/iwlwifi/mvm/sta.c +6 -6
@@ -840,7 +840,7 @@ static const u8 tid_to_ac[] = {int iwl_mvm_sta_tx_agg_start (struct iwl_mvm *mvm,struct ieee80211_vif *vif,struct ieee80211_sta *sta,u16 tid,u16 *ssn) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_tid_data *tid_data;int txq_id;
@@ -895,7 +895,7 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,int iwl_mvm_sta_tx_agg_oper (struct iwl_mvm *mvm,struct ieee80211_vif *vif,struct ieee80211_sta *sta,u16 tid,u8 buf_size) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];int queue, fifo, ret;u16 ssn;
@@ -951,7 +951,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,int iwl_mvm_sta_tx_agg_stop (struct iwl_mvm *mvm,struct ieee80211_vif *vif,struct ieee80211_sta *sta,u16 tid) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];u16 txq_id;int err;
@@ -1023,7 +1023,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,int iwl_mvm_sta_tx_agg_flush (struct iwl_mvm *mvm,struct ieee80211_vif *vif,struct ieee80211_sta *sta,u16 tid) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];u16 txq_id;enum iwl_mvm_agg_state old_state;
@@ -1416,7 +1416,7 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,void iwl_mvm_sta_modify_ps_wake (struct iwl_mvm *mvm,struct ieee80211_sta *sta) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_add_sta_cmd_v6 cmd = { .add_modify =STA_MODE_MODIFY , .sta_id = mvmsta->sta_id,
@@ -1438,7 +1438,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,u16 sleep_state_flags = (reason ==IEEE80211_FRAME_RELEASE_UAPSD ) ?STA_SLEEP_STATE_UAPSD :STA_SLEEP_STATE_PS_POLL ; -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_add_sta_cmd_v6 cmd = { .add_modify =STA_MODE_MODIFY , .sta_id = mvmsta->sta_id,
drivers/net/wireless/iwlwifi/mvm/sta.h +6 -0
@@ -298,6 +298,12 @@ struct iwl_mvm_sta {bool tt_tx_protection; }; +static inline struct iwl_mvm_sta * +iwl_mvm_sta_from_mac80211 (struct ieee80211_sta *sta) +{ +return (void *)sta->drv_priv; +} +/** * struct iwl_mvm_int_sta - representation of an internal station (auxiliary or * broadcast)
drivers/net/wireless/iwlwifi/mvm/tt.c +1 -1
@@ -388,7 +388,7 @@ static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable) lockdep_is_held(&mvm->mutex));if (IS_ERR_OR_NULL (sta))continue ; - mvmsta = (void *)sta->drv_priv; + mvmsta =iwl_mvm_sta_from_mac80211 (sta);if (enable == mvmsta->tt_tx_protection)continue ; err =iwl_mvm_tx_protection (mvm, mvmsta, enable);
drivers/net/wireless/iwlwifi/mvm/tx.c +5 -5
@@ -362,7 +362,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,u8 txq_id = info->hw_queue;bool is_data_qos = false, is_ampdu = false; - mvmsta = (void *)sta->drv_priv; + mvmsta =iwl_mvm_sta_from_mac80211 (sta); fc = hdr->frame_control;if (WARN_ON_ONCE (!mvmsta))
@@ -433,7 +433,7 @@ drop:static void iwl_mvm_check_ratid_empty (struct iwl_mvm *mvm,struct ieee80211_sta *sta,u8 tid) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];struct ieee80211_vif *vif = mvmsta->vif;
@@ -663,7 +663,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, sta =rcu_dereference (mvm->fw_id_to_mac_id[sta_id]);if (!IS_ERR_OR_NULL (sta)) { - mvmsta = (void *)sta->drv_priv; + mvmsta =iwl_mvm_sta_from_mac80211 (sta);if (tid !=IWL_TID_NON_QOS ) { struct iwl_mvm_tid_data *tid_data =
@@ -794,7 +794,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, sta =rcu_dereference (mvm->fw_id_to_mac_id[sta_id]);if (!WARN_ON_ONCE (IS_ERR_OR_NULL (sta))) { -struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta); mvmsta->tid_data[tid].rate_n_flags =le32_to_cpu (tx_resp->initial_rate); }
@@ -850,7 +850,7 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,return 0 ; } - mvmsta = (void *)sta->drv_priv; + mvmsta =iwl_mvm_sta_from_mac80211 (sta); tid_data = &mvmsta->tid_data[tid]; if (WARN_ONCE(tid_data->txq_id != scd_flow, "Q %d, tid %d, flow %d",
Signature · 1 line
1.7.9.5
PATCH 22/29 iwlwifi: mvm: don't restart HW if suspending fails before D3 image is loaded
In reply to Emmanuel GrumbachFrom: Luciano Coelho <[email protected]>
If we haven't loaded the D3 image yet and a failure in the suspend process occurs, we shouldn't restart the HW, because we're still running the D0 image.
--- drivers/net/wireless/iwlwifi/mvm/d3.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/d3.c +3 -2
@@ -1227,10 +1227,11 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mvm->aux_sta.sta_id = old_aux_sta_id; mvm_ap_sta->sta_id = old_ap_sta_id; mvmvif->ap_sta_id = old_ap_sta_id; - out_noreset: -kfree (key_data.rsc_tsc); +if (ret <0 )ieee80211_restart_hw (mvm->hw); + out_noreset: +kfree (key_data.rsc_tsc);mutex_unlock (&mvm->mutex);
Signature · 1 line
1.7.9.5
PATCH 23/29 iwlwifi: mvm: dump NVM from debugfs
In reply to Emmanuel GrumbachFrom: Emmanuel Grumbach <[email protected]>
This allows to see the content of the NVM the driver reads. Note that the output is in binary, and requires some external user space tool to display the data properly.
--- drivers/net/wireless/iwlwifi/mvm/debugfs.c | 13 +++++++++++++ drivers/net/wireless/iwlwifi/mvm/mvm.h | 5 +++++ drivers/net/wireless/iwlwifi/mvm/nvm.c | 23 +++++++++++++++++++++++ 3 files changed, 41 insertions(+)
drivers/net/wireless/iwlwifi/mvm/debugfs.c +13 -0
@@ -716,6 +716,19 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) goto err;#endif +if (!debugfs_create_blob ("nvm_hw" ,S_IRUSR , + mvm->debugfs_dir, &mvm->nvm_hw_blob)) + goto err; +if (!debugfs_create_blob ("nvm_sw" ,S_IRUSR , + mvm->debugfs_dir, &mvm->nvm_sw_blob)) + goto err; +if (!debugfs_create_blob ("nvm_calib" ,S_IRUSR , + mvm->debugfs_dir, &mvm->nvm_calib_blob)) + goto err; +if (!debugfs_create_blob ("nvm_prod" ,S_IRUSR , + mvm->debugfs_dir, &mvm->nvm_prod_blob)) + goto err; +/* * Create a symlink with mac80211. It will be removed when mac80211 * exists (before the opmode exists which removes the target.)
drivers/net/wireless/iwlwifi/mvm/mvm.h +5 -0
@@ -494,6 +494,11 @@ struct iwl_mvm {u32 dbgfs_sram_offset, dbgfs_sram_len;bool disable_power_off;bool disable_power_off_d3; + +struct debugfs_blob_wrapper nvm_hw_blob; +struct debugfs_blob_wrapper nvm_sw_blob; +struct debugfs_blob_wrapper nvm_calib_blob; +struct debugfs_blob_wrapper nvm_prod_blob;#endif struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX ];
drivers/net/wireless/iwlwifi/mvm/nvm.c +23 -0
@@ -443,6 +443,29 @@ int iwl_nvm_init(struct iwl_mvm *mvm) } mvm->nvm_sections[section].data = temp; mvm->nvm_sections[section].length = ret; + +#ifdef CONFIG_IWLWIFI_DEBUGFS +switch (section) { +case NVM_SECTION_TYPE_HW : + mvm->nvm_hw_blob.data = temp; + mvm->nvm_hw_blob.size = ret; +break ; +case NVM_SECTION_TYPE_SW : + mvm->nvm_sw_blob.data = temp; + mvm->nvm_sw_blob.size = ret; +break ; +case NVM_SECTION_TYPE_CALIBRATION : + mvm->nvm_calib_blob.data = temp; + mvm->nvm_calib_blob.size = ret; +break ; +case NVM_SECTION_TYPE_PRODUCTION : + mvm->nvm_prod_blob.data = temp; + mvm->nvm_prod_blob.size = ret; +break ; +default : +WARN (1 ,"section: %d" , section); + }; +#endif }kfree (nvm_buffer);if (ret <0 )
Signature · 1 line
1.7.9.5
PATCH 24/29 iwlwifi: mvm: fix scan offloading flag definition
In reply to Emmanuel GrumbachFrom: Eliad Peller <[email protected]>
Bit 0 in the scan offloading flags asks the filter to pass all the results (instead of filtering them, by default), rather than the other way around (like it is defined and used today).
Fix the flag name appropriately, and fix its user.
--- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 5 ++--- drivers/net/wireless/iwlwifi/mvm/scan.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-)
drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +2 -3
@@ -530,14 +530,13 @@ struct iwl_scan_offload_schedule {/* * iwl_scan_offload_flags * -* IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID: filter mode - upload every beacon or match -* ssid list. +* IWL_SCAN_OFFLOAD_FLAG_PASS_ALL: pass all results - no filtering. * IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL: add cached channels to partial scan. * IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN: use energy based scan before partial scan * on A band. */ enum iwl_scan_offload_flags { -IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID =BIT (0 ), +IWL_SCAN_OFFLOAD_FLAG_PASS_ALL =BIT (0 ),IWL_SCAN_OFFLOAD_FLAG_CACHED_CHANNEL =BIT (2 ),IWL_SCAN_OFFLOAD_FLAG_ENERGY_SCAN =BIT (3 ), };
drivers/net/wireless/iwlwifi/mvm/scan.c +1 -2
@@ -817,11 +817,10 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,IWL_DEBUG_SCAN (mvm,"Sending scheduled scan with filtering, filter len %d\n" , req->n_match_sets); - scan_req.flags |= -cpu_to_le16 (IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID ); }else {IWL_DEBUG_SCAN (mvm,"Sending Scheduled scan without filtering\n" ); + scan_req.flags |=cpu_to_le16 (IWL_SCAN_OFFLOAD_FLAG_PASS_ALL ); } return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC,
Signature · 1 line
1.7.9.5
PATCH 25/29 iwlwifi: mvm: Implement low-priority scan
In reply to Emmanuel GrumbachFrom: Haim Dreyfuss <[email protected]>
Advertise driver's support for low priority scan.
Notice that this overwrites current setting by mac80211 which depends only on hw scan support.
This scan priority can be configured by user space application and it affects scan continuity, low priority scan
will be more fragmented scan.
--- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 3 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 52 ++++++++++++++++++++------- 2 files changed, 41 insertions(+), 14 deletions(-)
drivers/net/wireless/iwlwifi/mvm/mac80211.c +2 -1
@@ -256,7 +256,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) } hw->wiphy->features |=NL80211_FEATURE_P2P_GO_CTWIN | -NL80211_FEATURE_P2P_GO_OPPPS ; +NL80211_FEATURE_P2P_GO_OPPPS | +NL80211_FEATURE_LOW_PRIORITY_SCAN ; mvm->rts_threshold =IEEE80211_MAX_RTS_THRESHOLD ;
drivers/net/wireless/iwlwifi/mvm/scan.c +39 -13
104 lines not on this page · raw message
Signature · 1 line
1.7.9.5
PATCH 26/29 iwlwifi: mvm: quota command max_duration should be zero
In reply to Emmanuel GrumbachFrom: Johannes Berg <[email protected]>
For now, the firmware doesn't really use the field, but it should be set to zero if there's no specific request. Setting it to the max quota doesn't make sense.
--- drivers/net/wireless/iwlwifi/mvm/quota.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/wireless/iwlwifi/mvm/quota.c +1 -2
@@ -217,8 +217,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) }else { cmd.quotas[idx].quota =cpu_to_le32 (quota * data.n_interfaces[i]); - cmd.quotas[idx].max_duration = -cpu_to_le32 (IWL_MVM_MAX_QUOTA ); + cmd.quotas[idx].max_duration =cpu_to_le32 (0 ); } idx++; }
Signature · 1 line
1.7.9.5
PATCH 27/29 iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Switch to using the new btcoex decision api regarding MIMO and stop accessing the internal btcoex structs.
In case MIMO should be disabled it would detect this upon the next Tx and force a search. The search will switch to SISO on a antenna A which isn't used by BT.
--- drivers/net/wireless/iwlwifi/mvm/rs.c | 26 ++++++-------------------- drivers/net/wireless/iwlwifi/mvm/rs.h | 13 ------------- 2 files changed, 6 insertions(+), 33 deletions(-)
drivers/net/wireless/iwlwifi/mvm/rs.c +6 -20
@@ -1499,6 +1499,9 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm,u8 update_search_tbl_counter =0 ;int ret; +if (!iwl_mvm_bt_coex_is_mimo_allowed (mvm, sta)) + tbl->action =IWL_MIMO2_SWITCH_SISO_A ; + start_action = tbl->action;while (1 ) { lq_sta->action_counter++;
@@ -1970,26 +1973,9 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, (current_tpt > (100 * tbl->expected_tpt[low])))) scale_action =0 ; -if ((le32_to_cpu (mvm->last_bt_notif.bt_activity_grading) >= -IWL_BT_COEX_TRAFFIC_LOAD_HIGH ) && (is_mimo (tbl->lq_type))) { -if (lq_sta->last_bt_traffic > -le32_to_cpu (mvm->last_bt_notif.bt_activity_grading)) { -/* -* don't set scale_action, don't want to scale up if -* the rate scale doesn't otherwise think that is a -* good idea. -*/ - }else if (lq_sta->last_bt_traffic <= -le32_to_cpu (mvm->last_bt_notif.bt_activity_grading)) { - scale_action =-1 ; - } - } - lq_sta->last_bt_traffic = -le32_to_cpu (mvm->last_bt_notif.bt_activity_grading); - -if ((le32_to_cpu (mvm->last_bt_notif.bt_activity_grading) >= -IWL_BT_COEX_TRAFFIC_LOAD_HIGH ) &&is_mimo (tbl->lq_type)) { -/* search for a new modulation */ +/* Force a search in case BT doesn't like us being in MIMO */ +if (is_mimo (tbl->lq_type) && + !iwl_mvm_bt_coex_is_mimo_allowed (mvm, sta)) {rs_stay_in_table (lq_sta, true); goto lq_update; }
drivers/net/wireless/iwlwifi/mvm/rs.h +0 -13
@@ -328,19 +328,6 @@ struct iwl_lq_sta {u32 last_rate_n_flags;/* packets destined for this STA are aggregated */ u8 is_agg; -/* BT traffic this sta was last updated in */ -u8 last_bt_traffic; -}; - -enum iwl_bt_coex_profile_traffic_load { -IWL_BT_COEX_TRAFFIC_LOAD_NONE =0 , -IWL_BT_COEX_TRAFFIC_LOAD_LOW =1 , -IWL_BT_COEX_TRAFFIC_LOAD_HIGH =2 , -IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS =3 , -/* -* There are no more even though below is a u8, the -* indication from the BT device only has two bits. -*/ };/* Initialize station's rate scaling information after adding station */
Signature · 1 line
1.7.9.5
PATCH 28/29 iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
MCS9 in NSS=1 or NSS=2 isn't valid for 20Mhz so don't enable it in case we're dealing with a 20Mhz sta. Trying to configure an MCS9 rate with 20Mhz in the LQ rate table would lead to a FW assert.
--- drivers/net/wireless/iwlwifi/mvm/rs.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/wireless/iwlwifi/mvm/rs.c +10 -0
@@ -2241,6 +2241,11 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,if (i ==IWL_RATE_9M_INDEX )continue ; +/* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ +if (i ==IWL_RATE_MCS_9_INDEX && + sta->bandwidth ==IEEE80211_STA_RX_BW_20 ) +continue ; + lq_sta->active_siso_rate |=BIT (i); } }
@@ -2251,6 +2256,11 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,if (i ==IWL_RATE_9M_INDEX )continue ; +/* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ +if (i ==IWL_RATE_MCS_9_INDEX && + sta->bandwidth ==IEEE80211_STA_RX_BW_20 ) +continue ; + lq_sta->active_mimo2_rate |=BIT (i); } }
Signature · 1 line
1.7.9.5
PATCH 29/29 iwlwifi: mvm: don't configure mimo rates if nss is limited to 1
In reply to Emmanuel GrumbachFrom: Eyal Shapira <[email protected]>
Remote peer can publish a different number of supported nss via the operating mode notification IE or action frame. If it limits to 1 then we don't want mimo rates configured in the rate table.
--- drivers/net/wireless/iwlwifi/mvm/rs.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/iwlwifi/mvm/rs.c +3 -0
@@ -2250,6 +2250,9 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta, } } +if (sta->rx_nss <2 ) +return ; + highest_mcs =rs_vht_highest_rx_mcs_index (vht_cap,2 );if (highest_mcs >=IWL_RATE_MCS_0_INDEX ) {for (i =IWL_RATE_MCS_0_INDEX ; i <= highest_mcs; i++) {
Signature · 1 line
1.7.9.5
Quoted 122 lines · Emmanuel Grumbach
Hi John,
This is the first batch for 3.14.
I have a bunch of small improvements and fixes. Avri made a thorough work checking what bit to set to firmware w.r.t protection. Eliad worked on WoWLAN, so did Luca. Johannes contributes a whole bunch of clean ups, and Alex tries to handle better cases where the firmware dies. Eyal survived his deep dive into the rate control algorigthm and provides a new set of fixes for VHT. I am still playing a bit with BT Coex.
Note that I had to merge iwlwifi-fixes to avoid conflicts before they hit linux-next.
Let me know about any issues!The following changes since commit
6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae:Linux 3.13-rc1 (2013-11-22 11:30:55 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git
for-johnfor you to fetch changes up to
b407dd53844e0d66e726583bae3a084cecdd59a4:Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
(2013-11-24 21:49:45 +0200)----------------------------------------------------------------
Alexander Bondar (2):
iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
iwlwifi: pcie: stop sending commands to dead firmwareAvri Altman (1):
iwlwifi: mvm: fix ht protection flagsEliad Peller (4):
iwlwifi: mvm: enabled3_testeven ifd3_test_pme_ptris not available
iwlwifi: mvm: disconnect on disconnection wakeup event
iwlwifi: mvm: allow keeping connections ind3_test
iwlwifi: mvm: fix scan offloading flag definitionEmmanuel Grumbach (10):
iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
iwlwifi: mvm: BT Coex - don't enableMULTI_PRIO_LUT
iwlwifi: mvm: BT Coex fix another NULL pointer dereference
iwlwifi: mvm: don't WARN about unsuccessful time event
iwlwifi: bump required firmware API version for 3160/7260
iwlwifi: removeTX_CMDid from transport layer
iwlwifi: mvm: BT Coex - fine tune the aggregation size
iwlwifi: mvm: a few more SKUs for 7260 and 3160
iwlwifi: mvm: dump NVM from debugfs
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-nextEyal Shapira (9):
iwlwifi: mvm: fix and improve printing of rate scale table
iwlwifi: mvm: simplifyiwl_mvm_send_lq_cmd
iwlwifi: mvm: refactoriwl_mvm_rs_rate_init
iwlwifi: mvm: implementrate_updatehook in rs
iwlwifi: mvm: add LQ flags definitions
iwlwifi: fix check for a single rx antenna
iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
iwlwifi: mvm: don't configure mimo rates if nss is limited to 1Haim Dreyfuss (1):
iwlwifi: mvm: Implement low-priority scanJohannes Berg (8):
iwlwifi: mvm: check sta_id/drain values in debugfs
iwlwifi: pcie: remove useless condition test
iwlwifi: mvm: small debugfs cleanups
iwlwifi: mvm: move interface-specific debugfs to a new file
iwlwifi: mvm: don't use void pointers in debugfs
iwlwifi: mvm: refactor debugfscopy_from_user()
iwlwifi: mvm: addiwl_mvm_sta_from_mac80211
iwlwifi: mvm: quota commandmax_durationshould be zeroLuciano Coelho (3):
iwlwifi: mvm: set seqno also when no keys are set
iwlwifi: mvm: use a cast to calculate the last seqno from the next one
iwlwifi: mvm: don't restart HW if suspending fails before D3 image
is loadedMichal Nazarewicz (1):
iwlwifi: pcie: remove minor dead codeOren Givon (1):
iwlwifi: add new HW - 7265 seriesdrivers/net/wireless/iwlwifi/dvm/rs.h | 7 - drivers/net/wireless/iwlwifi/dvm/tx.c | 1 + drivers/net/wireless/iwlwifi/iwl-7000.c | 29 +- drivers/net/wireless/iwlwifi/iwl-config.h | 11 + drivers/net/wireless/iwlwifi/iwl-csr.h | 5 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 3 + drivers/net/wireless/iwlwifi/mvm/Makefile | 1 + drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 16 +- drivers/net/wireless/iwlwifi/mvm/d3.c | 43 +- drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 190 +++++++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 640 ++---------------------- drivers/net/wireless/iwlwifi/mvm/debugfs.h | 101 ++++ drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 27 +- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 5 +- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 51 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 11 +- drivers/net/wireless/iwlwifi/mvm/nvm.c | 23 + drivers/net/wireless/iwlwifi/mvm/quota.c | 3 +- drivers/net/wireless/iwlwifi/mvm/rs.c | 223 ++++++--- drivers/net/wireless/iwlwifi/mvm/rs.h | 23 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 55 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 14 +- drivers/net/wireless/iwlwifi/mvm/sta.h | 6 + drivers/net/wireless/iwlwifi/mvm/time-event.c | 7 +- drivers/net/wireless/iwlwifi/mvm/tt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 11 +- drivers/net/wireless/iwlwifi/mvm/utils.c | 8 +-
Quoted 8 lines
drivers/net/wireless/iwlwifi/pcie/drv.c | 26 + drivers/net/wireless/iwlwifi/pcie/internal.h | 8 + drivers/net/wireless/iwlwifi/pcie/rx.c | 33 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 - drivers/net/wireless/iwlwifi/pcie/tx.c | 37 +- 34 files changed, 832 insertions(+), 813 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.h
Pulling now...
Signature · 2 lines
John W. Linville Someday the world will need a hero, and you [email protected] might be all we have. Be ready.
Emmanuel pointed-out that this was based on the wrong HEAD. I'll drop this merge and wait for his new request...
Quoted 142 lines · John W. Linville
Quoted 122 lines · Emmanuel Grumbach
Hi John,
This is the first batch for 3.14.
I have a bunch of small improvements and fixes. Avri made a thorough work checking what bit to set to firmware w.r.t protection. Eliad worked on WoWLAN, so did Luca. Johannes contributes a whole bunch of clean ups, and Alex tries to handle better cases where the firmware dies. Eyal survived his deep dive into the rate control algorigthm and provides a new set of fixes for VHT. I am still playing a bit with BT Coex.
Note that I had to merge iwlwifi-fixes to avoid conflicts before they hit linux-next.
Let me know about any issues!The following changes since commit
6ce4eac1f600b34f2f7f58f9cd8f0503d79e42ae:Linux 3.13-rc1 (2013-11-22 11:30:55 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next.git
for-johnfor you to fetch changes up to
b407dd53844e0d66e726583bae3a084cecdd59a4:Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-next
(2013-11-24 21:49:45 +0200)----------------------------------------------------------------
Alexander Bondar (2):
iwlwifi: mvm: Add debugfs entry to generate NMI to NIC
iwlwifi: pcie: stop sending commands to dead firmwareAvri Altman (1):
iwlwifi: mvm: fix ht protection flagsEliad Peller (4):
iwlwifi: mvm: enabled3_testeven ifd3_test_pme_ptris not available
iwlwifi: mvm: disconnect on disconnection wakeup event
iwlwifi: mvm: allow keeping connections ind3_test
iwlwifi: mvm: fix scan offloading flag definitionEmmanuel Grumbach (10):
iwlwifi: pcie: fix interrupt coalescing for 7260 / 3160
iwlwifi: mvm: BT Coex - don't enableMULTI_PRIO_LUT
iwlwifi: mvm: BT Coex fix another NULL pointer dereference
iwlwifi: mvm: don't WARN about unsuccessful time event
iwlwifi: bump required firmware API version for 3160/7260
iwlwifi: removeTX_CMDid from transport layer
iwlwifi: mvm: BT Coex - fine tune the aggregation size
iwlwifi: mvm: a few more SKUs for 7260 and 3160
iwlwifi: mvm: dump NVM from debugfs
Merge remote-tracking branch 'iwlwifi-fixes/master' into iwlwifi-nextEyal Shapira (9):
iwlwifi: mvm: fix and improve printing of rate scale table
iwlwifi: mvm: simplifyiwl_mvm_send_lq_cmd
iwlwifi: mvm: refactoriwl_mvm_rs_rate_init
iwlwifi: mvm: implementrate_updatehook in rs
iwlwifi: mvm: add LQ flags definitions
iwlwifi: fix check for a single rx antenna
iwlwifi: mvm: stop using MIMO in case BT doesn't allow it
iwlwifi: mvm: don't enable VHT MCS9 in 20Mhz
iwlwifi: mvm: don't configure mimo rates if nss is limited to 1Haim Dreyfuss (1):
iwlwifi: mvm: Implement low-priority scanJohannes Berg (8):
iwlwifi: mvm: check sta_id/drain values in debugfs
iwlwifi: pcie: remove useless condition test
iwlwifi: mvm: small debugfs cleanups
iwlwifi: mvm: move interface-specific debugfs to a new file
iwlwifi: mvm: don't use void pointers in debugfs
iwlwifi: mvm: refactor debugfscopy_from_user()
iwlwifi: mvm: addiwl_mvm_sta_from_mac80211
iwlwifi: mvm: quota commandmax_durationshould be zeroLuciano Coelho (3):
iwlwifi: mvm: set seqno also when no keys are set
iwlwifi: mvm: use a cast to calculate the last seqno from the next one
iwlwifi: mvm: don't restart HW if suspending fails before D3 image
is loadedMichal Nazarewicz (1):
iwlwifi: pcie: remove minor dead codeOren Givon (1):
iwlwifi: add new HW - 7265 seriesdrivers/net/wireless/iwlwifi/dvm/rs.h | 7 - drivers/net/wireless/iwlwifi/dvm/tx.c | 1 + drivers/net/wireless/iwlwifi/iwl-7000.c | 29 +- drivers/net/wireless/iwlwifi/iwl-config.h | 11 + drivers/net/wireless/iwlwifi/iwl-csr.h | 5 +- drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 3 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 3 + drivers/net/wireless/iwlwifi/mvm/Makefile | 1 + drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 16 +- drivers/net/wireless/iwlwifi/mvm/d3.c | 43 +- drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c | 190 +++++++ drivers/net/wireless/iwlwifi/mvm/debugfs.c | 640 ++---------------------- drivers/net/wireless/iwlwifi/mvm/debugfs.h | 101 ++++ drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h | 27 +- drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h | 5 +- drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | 51 +- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 +- drivers/net/wireless/iwlwifi/mvm/mvm.h | 11 +- drivers/net/wireless/iwlwifi/mvm/nvm.c | 23 + drivers/net/wireless/iwlwifi/mvm/quota.c | 3 +- drivers/net/wireless/iwlwifi/mvm/rs.c | 223 ++++++--- drivers/net/wireless/iwlwifi/mvm/rs.h | 23 +- drivers/net/wireless/iwlwifi/mvm/scan.c | 55 +- drivers/net/wireless/iwlwifi/mvm/sta.c | 14 +- drivers/net/wireless/iwlwifi/mvm/sta.h | 6 + drivers/net/wireless/iwlwifi/mvm/time-event.c | 7 +- drivers/net/wireless/iwlwifi/mvm/tt.c | 2 +- drivers/net/wireless/iwlwifi/mvm/tx.c | 11 +- drivers/net/wireless/iwlwifi/mvm/utils.c | 8 +-Quoted 8 lines
drivers/net/wireless/iwlwifi/pcie/drv.c | 26 + drivers/net/wireless/iwlwifi/pcie/internal.h | 8 + drivers/net/wireless/iwlwifi/pcie/rx.c | 33 +- drivers/net/wireless/iwlwifi/pcie/trans.c | 3 - drivers/net/wireless/iwlwifi/pcie/tx.c | 37 +- 34 files changed, 832 insertions(+), 813 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c create mode 100644 drivers/net/wireless/iwlwifi/mvm/debugfs.hPulling now...
Signature · 6 lines
John W. Linville Someday the world will need a hero, and you [email protected] might be all we have. Be ready. -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
John W. Linville Someday the world will need a hero, and you [email protected] might be all we have. Be ready.