Skip to content

Commit 732d06e

Browse files
striebitlucacoelho
authored andcommitted
iwlwifi: mvm: add station before allocating a queue
One of the queue config params is the associated station id. Hence the FW must know about the station prior to the queue allocation. In a000 devices, allocating a queue without a valid station results with assert 0x2B00. In FW restart flow the queues are allocated before adding the station so first add the station. Signed-off-by: Shaul Triebitz <[email protected]> Signed-off-by: Luca Coelho <[email protected]>
1 parent 0bef1b8 commit 732d06e

File tree

1 file changed

+63
-45
lines changed
  • drivers/net/wireless/intel/iwlwifi/mvm

1 file changed

+63
-45
lines changed

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

Lines changed: 63 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,50 @@ static void iwl_mvm_realloc_queues_after_restart(struct iwl_mvm *mvm,
12771277
}
12781278
}
12791279

1280+
static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
1281+
struct iwl_mvm_int_sta *sta,
1282+
const u8 *addr,
1283+
u16 mac_id, u16 color)
1284+
{
1285+
struct iwl_mvm_add_sta_cmd cmd;
1286+
int ret;
1287+
u32 status;
1288+
1289+
lockdep_assert_held(&mvm->mutex);
1290+
1291+
memset(&cmd, 0, sizeof(cmd));
1292+
cmd.sta_id = sta->sta_id;
1293+
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
1294+
color));
1295+
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
1296+
cmd.station_type = sta->type;
1297+
1298+
if (!iwl_mvm_has_new_tx_api(mvm))
1299+
cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
1300+
cmd.tid_disable_tx = cpu_to_le16(0xffff);
1301+
1302+
if (addr)
1303+
memcpy(cmd.addr, addr, ETH_ALEN);
1304+
1305+
ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
1306+
iwl_mvm_add_sta_cmd_size(mvm),
1307+
&cmd, &status);
1308+
if (ret)
1309+
return ret;
1310+
1311+
switch (status & IWL_ADD_STA_STATUS_MASK) {
1312+
case ADD_STA_SUCCESS:
1313+
IWL_DEBUG_INFO(mvm, "Internal station added.\n");
1314+
return 0;
1315+
default:
1316+
ret = -EIO;
1317+
IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
1318+
status);
1319+
break;
1320+
}
1321+
return ret;
1322+
}
1323+
12801324
int iwl_mvm_add_sta(struct iwl_mvm *mvm,
12811325
struct ieee80211_vif *vif,
12821326
struct ieee80211_sta *sta)
@@ -1285,6 +1329,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
12851329
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
12861330
struct iwl_mvm_rxq_dup_data *dup_data;
12871331
int i, ret, sta_id;
1332+
bool sta_update = false;
1333+
unsigned int sta_flags = 0;
12881334

12891335
lockdep_assert_held(&mvm->mutex);
12901336

@@ -1301,7 +1347,23 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
13011347

13021348
/* if this is a HW restart re-alloc existing queues */
13031349
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1350+
struct iwl_mvm_int_sta tmp_sta = {
1351+
.sta_id = sta_id,
1352+
.type = mvm_sta->sta_type,
1353+
};
1354+
1355+
/*
1356+
* First add an empty station since allocating
1357+
* a queue requires a valid station
1358+
*/
1359+
ret = iwl_mvm_add_int_sta_common(mvm, &tmp_sta, sta->addr,
1360+
mvmvif->id, mvmvif->color);
1361+
if (ret)
1362+
goto err;
1363+
13041364
iwl_mvm_realloc_queues_after_restart(mvm, mvm_sta);
1365+
sta_update = true;
1366+
sta_flags = iwl_mvm_has_new_tx_api(mvm) ? 0 : STA_MODIFY_QUEUES;
13051367
goto update_fw;
13061368
}
13071369

@@ -1368,7 +1430,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
13681430
}
13691431

13701432
update_fw:
1371-
ret = iwl_mvm_sta_send_to_fw(mvm, sta, false, 0);
1433+
ret = iwl_mvm_sta_send_to_fw(mvm, sta, sta_update, sta_flags);
13721434
if (ret)
13731435
goto err;
13741436

@@ -1637,50 +1699,6 @@ void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
16371699
sta->sta_id = IWL_MVM_INVALID_STA;
16381700
}
16391701

1640-
static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
1641-
struct iwl_mvm_int_sta *sta,
1642-
const u8 *addr,
1643-
u16 mac_id, u16 color)
1644-
{
1645-
struct iwl_mvm_add_sta_cmd cmd;
1646-
int ret;
1647-
u32 status;
1648-
1649-
lockdep_assert_held(&mvm->mutex);
1650-
1651-
memset(&cmd, 0, sizeof(cmd));
1652-
cmd.sta_id = sta->sta_id;
1653-
cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
1654-
color));
1655-
if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
1656-
cmd.station_type = sta->type;
1657-
1658-
if (!iwl_mvm_has_new_tx_api(mvm))
1659-
cmd.tfd_queue_msk = cpu_to_le32(sta->tfd_queue_msk);
1660-
cmd.tid_disable_tx = cpu_to_le16(0xffff);
1661-
1662-
if (addr)
1663-
memcpy(cmd.addr, addr, ETH_ALEN);
1664-
1665-
ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA,
1666-
iwl_mvm_add_sta_cmd_size(mvm),
1667-
&cmd, &status);
1668-
if (ret)
1669-
return ret;
1670-
1671-
switch (status & IWL_ADD_STA_STATUS_MASK) {
1672-
case ADD_STA_SUCCESS:
1673-
IWL_DEBUG_INFO(mvm, "Internal station added.\n");
1674-
return 0;
1675-
default:
1676-
ret = -EIO;
1677-
IWL_ERR(mvm, "Add internal station failed, status=0x%x\n",
1678-
status);
1679-
break;
1680-
}
1681-
return ret;
1682-
}
1683-
16841702
static void iwl_mvm_enable_aux_queue(struct iwl_mvm *mvm)
16851703
{
16861704
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?

0 commit comments

Comments
 (0)