Skip to content

Commit 3968e3c

Browse files
committed
Merge tag 'wireless-drivers-2021-12-01' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says: ==================== wireless-drivers fixes for v5.16 First set of fixes for v5.16. Mostly crash and driver initialisation fixes, the fix for rtw89 being most important. iwlwifi * compiler, lockdep and smatch warning fixes * fix for a rare driver initialisation failure * fix a memory leak rtw89 * fix const buffer modification causing a kernel crash mt76 * fix null pointer access * fix idr leak rt2x00 * fix driver initialisation errors, a regression since v5.2-rc1 ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 4326d04 + 191587c commit 3968e3c

File tree

17 files changed

+116
-49
lines changed

17 files changed

+116
-49
lines changed

drivers/net/wireless/intel/iwlwifi/fw/uefi.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
8686
if (len < tlv_len) {
8787
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
8888
len, tlv_len);
89+
kfree(reduce_power_data);
8990
reduce_power_data = ERR_PTR(-EINVAL);
9091
goto out;
9192
}
@@ -105,6 +106,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
105106
IWL_DEBUG_FW(trans,
106107
"Couldn't allocate (more) reduce_power_data\n");
107108

109+
kfree(reduce_power_data);
108110
reduce_power_data = ERR_PTR(-ENOMEM);
109111
goto out;
110112
}
@@ -134,6 +136,10 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
134136
done:
135137
if (!size) {
136138
IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n");
139+
/* Better safe than sorry, but 'reduce_power_data' should
140+
* always be NULL if !size.
141+
*/
142+
kfree(reduce_power_data);
137143
reduce_power_data = ERR_PTR(-ENOENT);
138144
goto out;
139145
}

drivers/net/wireless/intel/iwlwifi/iwl-drv.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,23 +1313,31 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
13131313
const struct iwl_op_mode_ops *ops = op->ops;
13141314
struct dentry *dbgfs_dir = NULL;
13151315
struct iwl_op_mode *op_mode = NULL;
1316+
int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;
1317+
1318+
for (retry = 0; retry <= max_retry; retry++) {
13161319

13171320
#ifdef CONFIG_IWLWIFI_DEBUGFS
1318-
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
1319-
drv->dbgfs_drv);
1320-
dbgfs_dir = drv->dbgfs_op_mode;
1321+
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
1322+
drv->dbgfs_drv);
1323+
dbgfs_dir = drv->dbgfs_op_mode;
13211324
#endif
13221325

1323-
op_mode = ops->start(drv->trans, drv->trans->cfg, &drv->fw, dbgfs_dir);
1326+
op_mode = ops->start(drv->trans, drv->trans->cfg,
1327+
&drv->fw, dbgfs_dir);
1328+
1329+
if (op_mode)
1330+
return op_mode;
1331+
1332+
IWL_ERR(drv, "retry init count %d\n", retry);
13241333

13251334
#ifdef CONFIG_IWLWIFI_DEBUGFS
1326-
if (!op_mode) {
13271335
debugfs_remove_recursive(drv->dbgfs_op_mode);
13281336
drv->dbgfs_op_mode = NULL;
1329-
}
13301337
#endif
1338+
}
13311339

1332-
return op_mode;
1340+
return NULL;
13331341
}
13341342

13351343
static void _iwl_op_mode_stop(struct iwl_drv *drv)

drivers/net/wireless/intel/iwlwifi/iwl-drv.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,7 @@ void iwl_drv_stop(struct iwl_drv *drv);
8989
#define IWL_EXPORT_SYMBOL(sym)
9090
#endif
9191

92+
/* max retry for init flow */
93+
#define IWL_MAX_INIT_RETRY 2
94+
9295
#endif /* __iwl_drv_h__ */

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <net/ieee80211_radiotap.h>
1717
#include <net/tcp.h>
1818

19+
#include "iwl-drv.h"
1920
#include "iwl-op-mode.h"
2021
#include "iwl-io.h"
2122
#include "mvm.h"
@@ -1117,9 +1118,30 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
11171118
{
11181119
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
11191120
int ret;
1121+
int retry, max_retry = 0;
11201122

11211123
mutex_lock(&mvm->mutex);
1122-
ret = __iwl_mvm_mac_start(mvm);
1124+
1125+
/* we are starting the mac not in error flow, and restart is enabled */
1126+
if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
1127+
iwlwifi_mod_params.fw_restart) {
1128+
max_retry = IWL_MAX_INIT_RETRY;
1129+
/*
1130+
* This will prevent mac80211 recovery flows to trigger during
1131+
* init failures
1132+
*/
1133+
set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
1134+
}
1135+
1136+
for (retry = 0; retry <= max_retry; retry++) {
1137+
ret = __iwl_mvm_mac_start(mvm);
1138+
if (!ret)
1139+
break;
1140+
1141+
IWL_ERR(mvm, "mac start retry %d\n", retry);
1142+
}
1143+
clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
1144+
11231145
mutex_unlock(&mvm->mutex);
11241146

11251147
return ret;

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,8 @@ struct iwl_mvm {
11231123
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
11241124
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
11251125
* @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it)
1126+
* @IWL_MVM_STATUS_STARTING: starting mac,
1127+
* used to disable restart flow while in STARTING state
11261128
*/
11271129
enum iwl_mvm_status {
11281130
IWL_MVM_STATUS_HW_RFKILL,
@@ -1134,6 +1136,7 @@ enum iwl_mvm_status {
11341136
IWL_MVM_STATUS_FIRMWARE_RUNNING,
11351137
IWL_MVM_STATUS_NEED_FLUSH_P2P,
11361138
IWL_MVM_STATUS_IN_D3,
1139+
IWL_MVM_STATUS_STARTING,
11371140
};
11381141

11391142
/* Keep track of completed init configuration */

drivers/net/wireless/intel/iwlwifi/mvm/ops.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,7 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm)
686686
int ret;
687687

688688
rtnl_lock();
689+
wiphy_lock(mvm->hw->wiphy);
689690
mutex_lock(&mvm->mutex);
690691

691692
ret = iwl_run_init_mvm_ucode(mvm);
@@ -701,6 +702,7 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm)
701702
iwl_mvm_stop_device(mvm);
702703

703704
mutex_unlock(&mvm->mutex);
705+
wiphy_unlock(mvm->hw->wiphy);
704706
rtnl_unlock();
705707

706708
if (ret < 0)
@@ -1600,6 +1602,9 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
16001602
*/
16011603
if (!mvm->fw_restart && fw_error) {
16021604
iwl_fw_error_collect(&mvm->fwrt, false);
1605+
} else if (test_bit(IWL_MVM_STATUS_STARTING,
1606+
&mvm->status)) {
1607+
IWL_ERR(mvm, "Starting mac, retry will be triggered anyway\n");
16031608
} else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
16041609
struct iwl_mvm_reprobe *reprobe;
16051610

drivers/net/wireless/intel/iwlwifi/pcie/drv.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,9 +1339,13 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device,
13391339
u16 mac_type, u8 mac_step,
13401340
u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores)
13411341
{
1342+
int num_devices = ARRAY_SIZE(iwl_dev_info_table);
13421343
int i;
13431344

1344-
for (i = ARRAY_SIZE(iwl_dev_info_table) - 1; i >= 0; i--) {
1345+
if (!num_devices)
1346+
return NULL;
1347+
1348+
for (i = num_devices - 1; i >= 0; i--) {
13451349
const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i];
13461350

13471351
if (dev_info->device != (u16)IWL_CFG_ANY &&
@@ -1442,8 +1446,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14421446
*/
14431447
if (iwl_trans->trans_cfg->rf_id &&
14441448
iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 &&
1445-
!CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans))
1449+
!CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans)) {
1450+
ret = -EINVAL;
14461451
goto out_free_trans;
1452+
}
14471453

14481454
dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
14491455
CSR_HW_REV_TYPE(iwl_trans->hw_rev),

drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
143143
if (!wcid)
144144
wcid = &dev->mt76.global_wcid;
145145

146-
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
147-
148146
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
149147
struct mt7615_phy *phy = &dev->phy;
150148

@@ -164,6 +162,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
164162
if (id < 0)
165163
return id;
166164

165+
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
167166
mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta,
168167
pid, key, false);
169168

drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,11 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_reg_map);
4343
static void
4444
mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
4545
enum mt76_txq_id qid, struct ieee80211_sta *sta,
46+
struct ieee80211_key_conf *key, int pid,
4647
struct sk_buff *skb)
4748
{
48-
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
49-
struct ieee80211_key_conf *key = info->control.hw_key;
50-
__le32 *txwi;
51-
int pid;
52-
53-
if (!wcid)
54-
wcid = &dev->mt76.global_wcid;
55-
56-
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
49+
__le32 *txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
5750

58-
txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
5951
memset(txwi, 0, MT_USB_TXD_SIZE);
6052
mt7615_mac_write_txwi(dev, txwi, skb, wcid, sta, pid, key, false);
6153
skb_push(skb, MT_USB_TXD_SIZE);
@@ -194,10 +186,14 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
194186
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
195187
struct sk_buff *skb = tx_info->skb;
196188
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
189+
struct ieee80211_key_conf *key = info->control.hw_key;
197190
struct mt7615_sta *msta;
198-
int pad;
191+
int pad, err, pktid;
199192

200193
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
194+
if (!wcid)
195+
wcid = &dev->mt76.global_wcid;
196+
201197
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
202198
msta && !msta->rate_probe) {
203199
/* request to configure sampling rate */
@@ -207,7 +203,8 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
207203
spin_unlock_bh(&dev->mt76.lock);
208204
}
209205

210-
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, skb);
206+
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
207+
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, key, pktid, skb);
211208
if (mt76_is_usb(mdev)) {
212209
u32 len = skb->len;
213210

@@ -217,7 +214,12 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
217214
pad = round_up(skb->len, 4) - skb->len;
218215
}
219216

220-
return mt76_skb_adjust_pad(skb, pad);
217+
err = mt76_skb_adjust_pad(skb, pad);
218+
if (err)
219+
/* Release pktid in case of error. */
220+
idr_remove(&wcid->pktid, pktid);
221+
222+
return err;
221223
}
222224
EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb);
223225

drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
7272
bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU;
7373
enum mt76_qsel qsel;
7474
u32 flags;
75+
int err;
7576

7677
mt76_insert_hdr_pad(tx_info->skb);
7778

@@ -106,7 +107,12 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
106107
ewma_pktlen_add(&msta->pktlen, tx_info->skb->len);
107108
}
108109

109-
return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
110+
err = mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
111+
if (err && wcid)
112+
/* Release pktid in case of error. */
113+
idr_remove(&wcid->pktid, pid);
114+
115+
return err;
110116
}
111117
EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
112118

0 commit comments

Comments
 (0)