Skip to content

Commit ee146e1

Browse files
Karthikeyan PeriyasamyJeff Johnson
authored andcommitted
wifi: ath12k: refactor core start based on hardware group
Currently, mac allocate/register and core_pdev_create are initiated immediately when QMI firmware ready event is received for a particular device. With hardware device group abstraction, QMI firmware ready event can be received simultaneously for different devices in the group and so, it should not be registered immediately rather it has to be deferred until all devices in the group has received QMI firmware ready. To handle this, refactor the code of core start to have registering within ath12k_core_hw_group_start() and unregistering in ath12k_core_hw_group_stop(). Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Karthikeyan Periyasamy <[email protected]> Co-developed-by: Harshitha Prem <[email protected]> Signed-off-by: Harshitha Prem <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jeff Johnson <[email protected]>
1 parent 6f245ea commit ee146e1

File tree

3 files changed

+170
-51
lines changed

3 files changed

+170
-51
lines changed

drivers/net/wireless/ath/ath12k/core.c

Lines changed: 146 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,8 @@ u32 ath12k_core_get_max_num_tids(struct ath12k_base *ab)
604604

605605
static void ath12k_core_stop(struct ath12k_base *ab)
606606
{
607+
ath12k_core_stopped(ab);
608+
607609
if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
608610
ath12k_qmi_firmware_stop(ab);
609611

@@ -743,6 +745,8 @@ static int ath12k_core_start(struct ath12k_base *ab,
743745
{
744746
int ret;
745747

748+
lockdep_assert_held(&ab->core_lock);
749+
746750
ret = ath12k_wmi_attach(ab);
747751
if (ret) {
748752
ath12k_err(ab, "failed to attach wmi: %d\n", ret);
@@ -836,6 +840,10 @@ static int ath12k_core_start(struct ath12k_base *ab,
836840
/* ACPI is optional so continue in case of an error */
837841
ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi failed: %d\n", ret);
838842

843+
if (!test_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags))
844+
/* Indicate the core start in the appropriate group */
845+
ath12k_core_started(ab);
846+
839847
return 0;
840848

841849
err_reo_cleanup:
@@ -847,6 +855,96 @@ static int ath12k_core_start(struct ath12k_base *ab,
847855
return ret;
848856
}
849857

858+
static void ath12k_core_device_cleanup(struct ath12k_base *ab)
859+
{
860+
mutex_lock(&ab->core_lock);
861+
862+
ath12k_hif_irq_disable(ab);
863+
ath12k_core_pdev_destroy(ab);
864+
ath12k_mac_unregister(ab);
865+
ath12k_mac_destroy(ab);
866+
867+
mutex_unlock(&ab->core_lock);
868+
}
869+
870+
static void ath12k_core_hw_group_stop(struct ath12k_hw_group *ag)
871+
{
872+
struct ath12k_base *ab;
873+
int i;
874+
875+
lockdep_assert_held(&ag->mutex);
876+
877+
for (i = ag->num_devices - 1; i >= 0; i--) {
878+
ab = ag->ab[i];
879+
if (!ab)
880+
continue;
881+
ath12k_core_device_cleanup(ab);
882+
}
883+
}
884+
885+
static int ath12k_core_hw_group_start(struct ath12k_hw_group *ag)
886+
{
887+
struct ath12k_base *ab;
888+
int ret, i;
889+
890+
lockdep_assert_held(&ag->mutex);
891+
892+
for (i = 0; i < ag->num_devices; i++) {
893+
ab = ag->ab[i];
894+
if (!ab)
895+
continue;
896+
897+
mutex_lock(&ab->core_lock);
898+
899+
/* Check if already registered or not, since same flow
900+
* execute for HW restart case.
901+
*/
902+
if (test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags))
903+
goto core_pdev_create;
904+
905+
ret = ath12k_mac_allocate(ab);
906+
if (ret) {
907+
ath12k_err(ab, "failed to create new hw device with mac80211 :%d\n",
908+
ret);
909+
mutex_unlock(&ab->core_lock);
910+
return ret;
911+
}
912+
913+
ret = ath12k_mac_register(ab);
914+
if (ret) {
915+
ath12k_err(ab, "failed to register radio with mac80211: %d\n",
916+
ret);
917+
mutex_unlock(&ab->core_lock);
918+
goto err;
919+
}
920+
921+
core_pdev_create:
922+
ret = ath12k_core_pdev_create(ab);
923+
if (ret) {
924+
ath12k_err(ab, "failed to create pdev core %d\n", ret);
925+
mutex_unlock(&ab->core_lock);
926+
goto err;
927+
}
928+
929+
ath12k_hif_irq_enable(ab);
930+
931+
ret = ath12k_core_rfkill_config(ab);
932+
if (ret && ret != -EOPNOTSUPP) {
933+
mutex_unlock(&ab->core_lock);
934+
goto err;
935+
}
936+
937+
mutex_unlock(&ab->core_lock);
938+
}
939+
940+
return 0;
941+
942+
err:
943+
ath12k_core_hw_group_stop(ag);
944+
945+
return ret;
946+
}
947+
850948
static int ath12k_core_start_firmware(struct ath12k_base *ab,
851949
enum ath12k_firmware_mode mode)
852950
{
@@ -864,9 +962,18 @@ static int ath12k_core_start_firmware(struct ath12k_base *ab,
864962
return ret;
865963
}
866964

965+
static inline
966+
bool ath12k_core_hw_group_start_ready(struct ath12k_hw_group *ag)
967+
{
968+
lockdep_assert_held(&ag->mutex);
969+
970+
return (ag->num_started == ag->num_devices);
971+
}
972+
867973
int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
868974
{
869-
int ret;
975+
struct ath12k_hw_group *ag = ath12k_ab_to_ag(ab);
976+
int ret, i;
870977

871978
ret = ath12k_core_start_firmware(ab, ATH12K_FIRMWARE_MODE_NORMAL);
872979
if (ret) {
@@ -886,59 +993,50 @@ int ath12k_core_qmi_firmware_ready(struct ath12k_base *ab)
886993
goto err_firmware_stop;
887994
}
888995

996+
mutex_lock(&ag->mutex);
889997
mutex_lock(&ab->core_lock);
998+
890999
ret = ath12k_core_start(ab, ATH12K_FIRMWARE_MODE_NORMAL);
8911000
if (ret) {
8921001
ath12k_err(ab, "failed to start core: %d\n", ret);
8931002
goto err_dp_free;
8941003
}
8951004

896-
ret = ath12k_mac_allocate(ab);
897-
if (ret) {
898-
ath12k_err(ab, "failed to create new hw device with mac80211 :%d\n",
899-
ret);
900-
goto err_core_stop;
901-
}
902-
903-
ret = ath12k_mac_register(ab);
904-
if (ret) {
905-
ath12k_err(ab, "failed register the radio with mac80211: %d\n", ret);
906-
goto err_mac_destroy;
907-
}
908-
909-
ret = ath12k_core_pdev_create(ab);
910-
if (ret) {
911-
ath12k_err(ab, "failed to create pdev core: %d\n", ret);
912-
goto err_mac_unregister;
913-
}
914-
915-
ath12k_hif_irq_enable(ab);
1005+
mutex_unlock(&ab->core_lock);
9161006

917-
ret = ath12k_core_rfkill_config(ab);
918-
if (ret && ret != -EOPNOTSUPP) {
919-
ath12k_err(ab, "failed to config rfkill: %d\n", ret);
920-
goto err_hif_irq_disable;
1007+
if (ath12k_core_hw_group_start_ready(ag)) {
1008+
ret = ath12k_core_hw_group_start(ag);
1009+
if (ret) {
1010+
ath12k_warn(ab, "unable to start hw group\n");
1011+
goto err_core_stop;
1012+
}
1013+
ath12k_dbg(ab, ATH12K_DBG_BOOT, "group %d started\n", ag->id);
9211014
}
9221015

923-
mutex_unlock(&ab->core_lock);
1016+
mutex_unlock(&ag->mutex);
9241017

9251018
return 0;
9261019

927-
err_hif_irq_disable:
928-
ath12k_hif_irq_disable(ab);
929-
ath12k_core_pdev_destroy(ab);
930-
err_mac_unregister:
931-
ath12k_mac_unregister(ab);
932-
err_mac_destroy:
933-
ath12k_mac_destroy(ab);
9341020
err_core_stop:
935-
ath12k_core_stop(ab);
1021+
for (i = ag->num_devices - 1; i >= 0; i--) {
1022+
ab = ag->ab[i];
1023+
if (!ab)
1024+
continue;
1025+
1026+
mutex_lock(&ab->core_lock);
1027+
ath12k_core_stop(ab);
1028+
mutex_unlock(&ab->core_lock);
1029+
}
1030+
goto exit;
1031+
9361032
err_dp_free:
9371033
ath12k_dp_free(ab);
9381034
mutex_unlock(&ab->core_lock);
9391035
err_firmware_stop:
9401036
ath12k_qmi_firmware_stop(ab);
9411037

1038+
exit:
1039+
mutex_unlock(&ag->mutex);
9421040
return ret;
9431041
}
9441042

@@ -1135,6 +1233,14 @@ static void ath12k_core_restart(struct work_struct *work)
11351233
}
11361234

11371235
if (ab->is_reset) {
1236+
if (!test_bit(ATH12K_FLAG_REGISTERED, &ab->dev_flags)) {
1237+
atomic_dec(&ab->reset_count);
1238+
complete(&ab->reset_complete);
1239+
ab->is_reset = false;
1240+
atomic_set(&ab->fail_cont_count, 0);
1241+
ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset success\n");
1242+
}
1243+
11381244
for (i = 0; i < ath12k_get_num_hw(ab); i++) {
11391245
ah = ath12k_ab_to_ah(ab, i);
11401246
ieee80211_restart_hw(ah->hw);
@@ -1319,7 +1425,7 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a
13191425

13201426
void ath12k_core_hw_group_unassign(struct ath12k_base *ab)
13211427
{
1322-
struct ath12k_hw_group *ag = ab->ag;
1428+
struct ath12k_hw_group *ag = ath12k_ab_to_ag(ab);
13231429
u8 device_id = ab->device_id;
13241430
int num_probed;
13251431

@@ -1353,19 +1459,6 @@ void ath12k_core_hw_group_unassign(struct ath12k_base *ab)
13531459
ath12k_core_hw_group_free(ag);
13541460
}
13551461

1356-
static void ath12k_core_device_cleanup(struct ath12k_base *ab)
1357-
{
1358-
mutex_lock(&ab->core_lock);
1359-
1360-
ath12k_hif_irq_disable(ab);
1361-
ath12k_core_pdev_destroy(ab);
1362-
ath12k_mac_unregister(ab);
1363-
ath12k_mac_destroy(ab);
1364-
ath12k_core_stop(ab);
1365-
1366-
mutex_unlock(&ab->core_lock);
1367-
}
1368-
13691462
static void ath12k_core_hw_group_destroy(struct ath12k_hw_group *ag)
13701463
{
13711464
struct ath12k_base *ab;
@@ -1393,12 +1486,16 @@ static void ath12k_core_hw_group_cleanup(struct ath12k_hw_group *ag)
13931486

13941487
mutex_lock(&ag->mutex);
13951488

1489+
ath12k_core_hw_group_stop(ag);
1490+
13961491
for (i = 0; i < ag->num_devices; i++) {
13971492
ab = ag->ab[i];
13981493
if (!ab)
13991494
continue;
14001495

1401-
ath12k_core_device_cleanup(ab);
1496+
mutex_lock(&ab->core_lock);
1497+
ath12k_core_stop(ab);
1498+
mutex_unlock(&ab->core_lock);
14021499
}
14031500

14041501
mutex_unlock(&ag->mutex);

drivers/net/wireless/ath/ath12k/core.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,8 @@ struct ath12k_hw_group {
824824
u8 id;
825825
u8 num_devices;
826826
u8 num_probed;
827+
u8 num_started;
828+
unsigned long flags;
827829
struct ath12k_base *ab[ATH12K_MAX_SOCS];
828830

829831
/* protects access to this struct */
@@ -1175,4 +1177,24 @@ static inline int ath12k_get_num_hw(struct ath12k_base *ab)
11751177
{
11761178
return ab->num_hw;
11771179
}
1180+
1181+
static inline struct ath12k_hw_group *ath12k_ab_to_ag(struct ath12k_base *ab)
1182+
{
1183+
return ab->ag;
1184+
}
1185+
1186+
static inline void ath12k_core_started(struct ath12k_base *ab)
1187+
{
1188+
lockdep_assert_held(&ab->ag->mutex);
1189+
1190+
ab->ag->num_started++;
1191+
}
1192+
1193+
static inline void ath12k_core_stopped(struct ath12k_base *ab)
1194+
{
1195+
lockdep_assert_held(&ab->ag->mutex);
1196+
1197+
ab->ag->num_started--;
1198+
}
1199+
11781200
#endif /* _CORE_H_ */

drivers/net/wireless/ath/ath12k/qmi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3321,7 +3321,6 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
33213321
break;
33223322
case ATH12K_QMI_EVENT_SERVER_EXIT:
33233323
set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
3324-
set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
33253324
break;
33263325
case ATH12K_QMI_EVENT_REQUEST_MEM:
33273326
ret = ath12k_qmi_event_mem_request(qmi);
@@ -3338,13 +3337,14 @@ static void ath12k_qmi_driver_event_work(struct work_struct *work)
33383337
if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) {
33393338
if (ab->is_reset)
33403339
ath12k_hal_dump_srng_stats(ab);
3340+
3341+
set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
33413342
queue_work(ab->workqueue, &ab->restart_work);
33423343
break;
33433344
}
33443345

33453346
clear_bit(ATH12K_FLAG_CRASH_FLUSH,
33463347
&ab->dev_flags);
3347-
clear_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
33483348
ret = ath12k_core_qmi_firmware_ready(ab);
33493349
if (!ret)
33503350
set_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE,

0 commit comments

Comments
 (0)