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 -----BEGIN PGP SIGNATURE----- iQFFBAABCgAvFiEEiBjanGPFTz4PRfLobhckVSbrbZsFAmGnNJoRHGt2YWxvQGtl cm5lbC5vcmcACgkQbhckVSbrbZvHDwf/QYH4ZJyVGzMxo86BQ490ePJbe9uK26F0 uhshAiYj8yjv1PvqjVcSEvDDn+BH1lxLd3lKuWeyGfVCR7m2ZLqRFcESq7QyPMhJ jY6RUxoj6RAjr/A/zxHFDCTgCWu61ccUgdCuXaOtU3HwOlFHkVgKL94E6EbovKD7 ExAS6eN/+Ga3Rr3eIz0inl637PiiQlVy6/ajVu95YBv/FE5dca1BYEPe/RdSkaWC IRBlqjYNkrQ2nkqLg3x6M5mrZcJEDZJfomywbEx+JpPfm3hlGlUtwlhUS3v9GBBa qflM3q1TohqFQmuhA8jOy98/o6Vm/HMvdOHzwoGT1DaXNZzeSYGEEA== =QUeE -----END PGP SIGNATURE----- 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 <davem@davemloft.net>
This commit is contained in:
commit
3968e3cafa
@ -86,6 +86,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
|
||||
if (len < tlv_len) {
|
||||
IWL_ERR(trans, "invalid TLV len: %zd/%u\n",
|
||||
len, tlv_len);
|
||||
kfree(reduce_power_data);
|
||||
reduce_power_data = ERR_PTR(-EINVAL);
|
||||
goto out;
|
||||
}
|
||||
@ -105,6 +106,7 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
|
||||
IWL_DEBUG_FW(trans,
|
||||
"Couldn't allocate (more) reduce_power_data\n");
|
||||
|
||||
kfree(reduce_power_data);
|
||||
reduce_power_data = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
@ -134,6 +136,10 @@ static void *iwl_uefi_reduce_power_section(struct iwl_trans *trans,
|
||||
done:
|
||||
if (!size) {
|
||||
IWL_DEBUG_FW(trans, "Empty REDUCE_POWER, skipping.\n");
|
||||
/* Better safe than sorry, but 'reduce_power_data' should
|
||||
* always be NULL if !size.
|
||||
*/
|
||||
kfree(reduce_power_data);
|
||||
reduce_power_data = ERR_PTR(-ENOENT);
|
||||
goto out;
|
||||
}
|
||||
|
@ -1313,23 +1313,31 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
|
||||
const struct iwl_op_mode_ops *ops = op->ops;
|
||||
struct dentry *dbgfs_dir = NULL;
|
||||
struct iwl_op_mode *op_mode = NULL;
|
||||
int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;
|
||||
|
||||
for (retry = 0; retry <= max_retry; retry++) {
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
|
||||
drv->dbgfs_drv);
|
||||
dbgfs_dir = drv->dbgfs_op_mode;
|
||||
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
|
||||
drv->dbgfs_drv);
|
||||
dbgfs_dir = drv->dbgfs_op_mode;
|
||||
#endif
|
||||
|
||||
op_mode = ops->start(drv->trans, drv->trans->cfg, &drv->fw, dbgfs_dir);
|
||||
op_mode = ops->start(drv->trans, drv->trans->cfg,
|
||||
&drv->fw, dbgfs_dir);
|
||||
|
||||
if (op_mode)
|
||||
return op_mode;
|
||||
|
||||
IWL_ERR(drv, "retry init count %d\n", retry);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
if (!op_mode) {
|
||||
debugfs_remove_recursive(drv->dbgfs_op_mode);
|
||||
drv->dbgfs_op_mode = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return op_mode;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _iwl_op_mode_stop(struct iwl_drv *drv)
|
||||
|
@ -89,4 +89,7 @@ void iwl_drv_stop(struct iwl_drv *drv);
|
||||
#define IWL_EXPORT_SYMBOL(sym)
|
||||
#endif
|
||||
|
||||
/* max retry for init flow */
|
||||
#define IWL_MAX_INIT_RETRY 2
|
||||
|
||||
#endif /* __iwl_drv_h__ */
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
#include "iwl-drv.h"
|
||||
#include "iwl-op-mode.h"
|
||||
#include "iwl-io.h"
|
||||
#include "mvm.h"
|
||||
@ -1117,9 +1118,30 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
int retry, max_retry = 0;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
|
||||
/* we are starting the mac not in error flow, and restart is enabled */
|
||||
if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
|
||||
iwlwifi_mod_params.fw_restart) {
|
||||
max_retry = IWL_MAX_INIT_RETRY;
|
||||
/*
|
||||
* This will prevent mac80211 recovery flows to trigger during
|
||||
* init failures
|
||||
*/
|
||||
set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
|
||||
}
|
||||
|
||||
for (retry = 0; retry <= max_retry; retry++) {
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
IWL_ERR(mvm, "mac start retry %d\n", retry);
|
||||
}
|
||||
clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return ret;
|
||||
|
@ -1123,6 +1123,8 @@ struct iwl_mvm {
|
||||
* @IWL_MVM_STATUS_FIRMWARE_RUNNING: firmware is running
|
||||
* @IWL_MVM_STATUS_NEED_FLUSH_P2P: need to flush P2P bcast STA
|
||||
* @IWL_MVM_STATUS_IN_D3: in D3 (or at least about to go into it)
|
||||
* @IWL_MVM_STATUS_STARTING: starting mac,
|
||||
* used to disable restart flow while in STARTING state
|
||||
*/
|
||||
enum iwl_mvm_status {
|
||||
IWL_MVM_STATUS_HW_RFKILL,
|
||||
@ -1134,6 +1136,7 @@ enum iwl_mvm_status {
|
||||
IWL_MVM_STATUS_FIRMWARE_RUNNING,
|
||||
IWL_MVM_STATUS_NEED_FLUSH_P2P,
|
||||
IWL_MVM_STATUS_IN_D3,
|
||||
IWL_MVM_STATUS_STARTING,
|
||||
};
|
||||
|
||||
/* Keep track of completed init configuration */
|
||||
|
@ -686,6 +686,7 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm)
|
||||
int ret;
|
||||
|
||||
rtnl_lock();
|
||||
wiphy_lock(mvm->hw->wiphy);
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
ret = iwl_run_init_mvm_ucode(mvm);
|
||||
@ -701,6 +702,7 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm)
|
||||
iwl_mvm_stop_device(mvm);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
wiphy_unlock(mvm->hw->wiphy);
|
||||
rtnl_unlock();
|
||||
|
||||
if (ret < 0)
|
||||
@ -1600,6 +1602,9 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
|
||||
*/
|
||||
if (!mvm->fw_restart && fw_error) {
|
||||
iwl_fw_error_collect(&mvm->fwrt, false);
|
||||
} else if (test_bit(IWL_MVM_STATUS_STARTING,
|
||||
&mvm->status)) {
|
||||
IWL_ERR(mvm, "Starting mac, retry will be triggered anyway\n");
|
||||
} else if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
struct iwl_mvm_reprobe *reprobe;
|
||||
|
||||
|
@ -1339,9 +1339,13 @@ iwl_pci_find_dev_info(u16 device, u16 subsystem_device,
|
||||
u16 mac_type, u8 mac_step,
|
||||
u16 rf_type, u8 cdb, u8 rf_id, u8 no_160, u8 cores)
|
||||
{
|
||||
int num_devices = ARRAY_SIZE(iwl_dev_info_table);
|
||||
int i;
|
||||
|
||||
for (i = ARRAY_SIZE(iwl_dev_info_table) - 1; i >= 0; i--) {
|
||||
if (!num_devices)
|
||||
return NULL;
|
||||
|
||||
for (i = num_devices - 1; i >= 0; i--) {
|
||||
const struct iwl_dev_info *dev_info = &iwl_dev_info_table[i];
|
||||
|
||||
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)
|
||||
*/
|
||||
if (iwl_trans->trans_cfg->rf_id &&
|
||||
iwl_trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_9000 &&
|
||||
!CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans))
|
||||
!CSR_HW_RFID_TYPE(iwl_trans->hw_rf_id) && get_crf_id(iwl_trans)) {
|
||||
ret = -EINVAL;
|
||||
goto out_free_trans;
|
||||
}
|
||||
|
||||
dev_info = iwl_pci_find_dev_info(pdev->device, pdev->subsystem_device,
|
||||
CSR_HW_REV_TYPE(iwl_trans->hw_rev),
|
||||
|
@ -143,8 +143,6 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
if (!wcid)
|
||||
wcid = &dev->mt76.global_wcid;
|
||||
|
||||
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
||||
|
||||
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) {
|
||||
struct mt7615_phy *phy = &dev->phy;
|
||||
|
||||
@ -164,6 +162,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
if (id < 0)
|
||||
return id;
|
||||
|
||||
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
||||
mt7615_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, sta,
|
||||
pid, key, false);
|
||||
|
||||
|
@ -43,19 +43,11 @@ EXPORT_SYMBOL_GPL(mt7663_usb_sdio_reg_map);
|
||||
static void
|
||||
mt7663_usb_sdio_write_txwi(struct mt7615_dev *dev, struct mt76_wcid *wcid,
|
||||
enum mt76_txq_id qid, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key, int pid,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||
__le32 *txwi;
|
||||
int pid;
|
||||
__le32 *txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
|
||||
|
||||
if (!wcid)
|
||||
wcid = &dev->mt76.global_wcid;
|
||||
|
||||
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
||||
|
||||
txwi = (__le32 *)(skb->data - MT_USB_TXD_SIZE);
|
||||
memset(txwi, 0, MT_USB_TXD_SIZE);
|
||||
mt7615_mac_write_txwi(dev, txwi, skb, wcid, sta, pid, key, false);
|
||||
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,
|
||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
struct sk_buff *skb = tx_info->skb;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||
struct mt7615_sta *msta;
|
||||
int pad;
|
||||
int pad, err, pktid;
|
||||
|
||||
msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL;
|
||||
if (!wcid)
|
||||
wcid = &dev->mt76.global_wcid;
|
||||
|
||||
if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) &&
|
||||
msta && !msta->rate_probe) {
|
||||
/* request to configure sampling rate */
|
||||
@ -207,7 +203,8 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
spin_unlock_bh(&dev->mt76.lock);
|
||||
}
|
||||
|
||||
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, skb);
|
||||
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
||||
mt7663_usb_sdio_write_txwi(dev, wcid, qid, sta, key, pktid, skb);
|
||||
if (mt76_is_usb(mdev)) {
|
||||
u32 len = skb->len;
|
||||
|
||||
@ -217,7 +214,12 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
pad = round_up(skb->len, 4) - skb->len;
|
||||
}
|
||||
|
||||
return mt76_skb_adjust_pad(skb, pad);
|
||||
err = mt76_skb_adjust_pad(skb, pad);
|
||||
if (err)
|
||||
/* Release pktid in case of error. */
|
||||
idr_remove(&wcid->pktid, pktid);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7663_usb_sdio_tx_prepare_skb);
|
||||
|
||||
|
@ -72,6 +72,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
|
||||
bool ampdu = IEEE80211_SKB_CB(tx_info->skb)->flags & IEEE80211_TX_CTL_AMPDU;
|
||||
enum mt76_qsel qsel;
|
||||
u32 flags;
|
||||
int err;
|
||||
|
||||
mt76_insert_hdr_pad(tx_info->skb);
|
||||
|
||||
@ -106,7 +107,12 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
|
||||
ewma_pktlen_add(&msta->pktlen, tx_info->skb->len);
|
||||
}
|
||||
|
||||
return mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
|
||||
err = mt76x02u_skb_dma_info(tx_info->skb, WLAN_PORT, flags);
|
||||
if (err && wcid)
|
||||
/* Release pktid in case of error. */
|
||||
idr_remove(&wcid->pktid, pid);
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02u_tx_prepare_skb);
|
||||
|
||||
|
@ -1151,8 +1151,14 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
||||
t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
|
||||
t->skb = tx_info->skb;
|
||||
|
||||
id = mt76_token_consume(mdev, &t);
|
||||
if (id < 0)
|
||||
return id;
|
||||
|
||||
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
|
||||
mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key,
|
||||
false);
|
||||
|
||||
@ -1178,13 +1184,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
txp->bss_idx = mvif->idx;
|
||||
}
|
||||
|
||||
t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size);
|
||||
t->skb = tx_info->skb;
|
||||
|
||||
id = mt76_token_consume(mdev, &t);
|
||||
if (id < 0)
|
||||
return id;
|
||||
|
||||
txp->token = cpu_to_le16(id);
|
||||
if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags))
|
||||
txp->rept_wds_wcid = cpu_to_le16(wcid->idx);
|
||||
|
@ -176,7 +176,7 @@ mt7915_get_phy_mode(struct ieee80211_vif *vif, struct ieee80211_sta *sta)
|
||||
if (ht_cap->ht_supported)
|
||||
mode |= PHY_MODE_GN;
|
||||
|
||||
if (he_cap->has_he)
|
||||
if (he_cap && he_cap->has_he)
|
||||
mode |= PHY_MODE_AX_24G;
|
||||
} else if (band == NL80211_BAND_5GHZ) {
|
||||
mode |= PHY_MODE_A;
|
||||
@ -187,7 +187,7 @@ mt7915_get_phy_mode(struct ieee80211_vif *vif, struct ieee80211_sta *sta)
|
||||
if (vht_cap->vht_supported)
|
||||
mode |= PHY_MODE_AC;
|
||||
|
||||
if (he_cap->has_he)
|
||||
if (he_cap && he_cap->has_he)
|
||||
mode |= PHY_MODE_AX_5G;
|
||||
}
|
||||
|
||||
|
@ -142,15 +142,11 @@ out:
|
||||
static void
|
||||
mt7921s_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid,
|
||||
enum mt76_txq_id qid, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key, int pid,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||
__le32 *txwi;
|
||||
int pid;
|
||||
__le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
|
||||
|
||||
pid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
||||
txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE);
|
||||
memset(txwi, 0, MT_SDIO_TXD_SIZE);
|
||||
mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false);
|
||||
skb_push(skb, MT_SDIO_TXD_SIZE);
|
||||
@ -163,8 +159,9 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb);
|
||||
struct ieee80211_key_conf *key = info->control.hw_key;
|
||||
struct sk_buff *skb = tx_info->skb;
|
||||
int pad;
|
||||
int err, pad, pktid;
|
||||
|
||||
if (unlikely(tx_info->skb->len <= ETH_HLEN))
|
||||
return -EINVAL;
|
||||
@ -181,12 +178,18 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
mt7921s_write_txwi(dev, wcid, qid, sta, skb);
|
||||
pktid = mt76_tx_status_skb_add(&dev->mt76, wcid, skb);
|
||||
mt7921s_write_txwi(dev, wcid, qid, sta, key, pktid, skb);
|
||||
|
||||
mt7921_skb_add_sdio_hdr(skb, MT7921_SDIO_DATA);
|
||||
pad = round_up(skb->len, 4) - skb->len;
|
||||
|
||||
return mt76_skb_adjust_pad(skb, pad);
|
||||
err = mt76_skb_adjust_pad(skb, pad);
|
||||
if (err)
|
||||
/* Release pktid in case of error. */
|
||||
idr_remove(&wcid->pktid, pktid);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e)
|
||||
|
@ -173,7 +173,7 @@ mt76_tx_status_skb_get(struct mt76_dev *dev, struct mt76_wcid *wcid, int pktid,
|
||||
if (!(cb->flags & MT_TX_CB_DMA_DONE))
|
||||
continue;
|
||||
|
||||
if (!time_is_after_jiffies(cb->jiffies +
|
||||
if (time_is_after_jiffies(cb->jiffies +
|
||||
MT_TX_STATUS_SKB_TIMEOUT))
|
||||
continue;
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status)
|
||||
if (status == -ENODEV || status == -ENOENT)
|
||||
return true;
|
||||
|
||||
if (!test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
|
||||
return false;
|
||||
|
||||
if (status == -EPROTO || status == -ETIMEDOUT)
|
||||
rt2x00dev->num_proto_errs++;
|
||||
else
|
||||
|
@ -91,7 +91,6 @@ static int rtw89_fw_hdr_parser(struct rtw89_dev *rtwdev, const u8 *fw, u32 len,
|
||||
info->section_num = GET_FW_HDR_SEC_NUM(fw);
|
||||
info->hdr_len = RTW89_FW_HDR_SIZE +
|
||||
info->section_num * RTW89_FW_SECTION_HDR_SIZE;
|
||||
SET_FW_HDR_PART_SIZE(fw, FWDL_SECTION_PER_PKT_LEN);
|
||||
|
||||
bin = fw + info->hdr_len;
|
||||
|
||||
@ -275,6 +274,7 @@ static int __rtw89_fw_download_hdr(struct rtw89_dev *rtwdev, const u8 *fw, u32 l
|
||||
}
|
||||
|
||||
skb_put_data(skb, fw, len);
|
||||
SET_FW_HDR_PART_SIZE(skb->data, FWDL_SECTION_PER_PKT_LEN);
|
||||
rtw89_h2c_pkt_set_hdr_fwdl(rtwdev, skb, FWCMD_TYPE_H2C,
|
||||
H2C_CAT_MAC, H2C_CL_MAC_FWDL,
|
||||
H2C_FUNC_MAC_FWHDR_DL, len);
|
||||
|
@ -282,8 +282,10 @@ struct rtw89_h2creg_sch_tx_en {
|
||||
le32_get_bits(*((__le32 *)(fwhdr) + 6), GENMASK(15, 8))
|
||||
#define GET_FW_HDR_CMD_VERSERION(fwhdr) \
|
||||
le32_get_bits(*((__le32 *)(fwhdr) + 7), GENMASK(31, 24))
|
||||
#define SET_FW_HDR_PART_SIZE(fwhdr, val) \
|
||||
le32p_replace_bits((__le32 *)(fwhdr) + 7, val, GENMASK(15, 0))
|
||||
static inline void SET_FW_HDR_PART_SIZE(void *fwhdr, u32 val)
|
||||
{
|
||||
le32p_replace_bits((__le32 *)fwhdr + 7, val, GENMASK(15, 0));
|
||||
}
|
||||
|
||||
#define SET_CTRL_INFO_MACID(table, val) \
|
||||
le32p_replace_bits((__le32 *)(table) + 0, val, GENMASK(6, 0))
|
||||
|
Loading…
Reference in New Issue
Block a user